root/drivers/gpu/drm/nouveau/nvkm/subdev/fault/tu102.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. tu102_fault_buffer_intr
  2. tu102_fault_buffer_fini
  3. tu102_fault_buffer_init
  4. tu102_fault_buffer_info
  5. tu102_fault_intr_fault
  6. tu102_fault_intr
  7. tu102_fault_fini
  8. tu102_fault_init
  9. tu102_fault_new

   1 /*
   2  * Copyright 2018 Red Hat Inc.
   3  *
   4  * Permission is hereby granted, free of charge, to any person obtaining a
   5  * copy of this software and associated documentation files (the "Software"),
   6  * to deal in the Software without restriction, including without limitation
   7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8  * and/or sell copies of the Software, and to permit persons to whom the
   9  * Software is furnished to do so, subject to the following conditions:
  10  *
  11  * The above copyright notice and this permission notice shall be included in
  12  * all copies or substantial portions of the Software.
  13  *
  14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20  * OTHER DEALINGS IN THE SOFTWARE.
  21  */
  22 #include "priv.h"
  23 
  24 #include <core/memory.h>
  25 #include <subdev/mmu.h>
  26 #include <engine/fifo.h>
  27 
  28 #include <nvif/class.h>
  29 
  30 static void
  31 tu102_fault_buffer_intr(struct nvkm_fault_buffer *buffer, bool enable)
  32 {
  33         /*XXX: Earlier versions of RM touched the old regs on Turing,
  34          *     which don't appear to actually work anymore, but newer
  35          *     versions of RM don't appear to touch anything at all..
  36          */
  37 }
  38 
  39 static void
  40 tu102_fault_buffer_fini(struct nvkm_fault_buffer *buffer)
  41 {
  42         struct nvkm_device *device = buffer->fault->subdev.device;
  43         const u32 foff = buffer->id * 0x20;
  44         nvkm_mask(device, 0xb83010 + foff, 0x80000000, 0x00000000);
  45 }
  46 
  47 static void
  48 tu102_fault_buffer_init(struct nvkm_fault_buffer *buffer)
  49 {
  50         struct nvkm_device *device = buffer->fault->subdev.device;
  51         const u32 foff = buffer->id * 0x20;
  52 
  53         nvkm_mask(device, 0xb83010 + foff, 0xc0000000, 0x40000000);
  54         nvkm_wr32(device, 0xb83004 + foff, upper_32_bits(buffer->addr));
  55         nvkm_wr32(device, 0xb83000 + foff, lower_32_bits(buffer->addr));
  56         nvkm_mask(device, 0xb83010 + foff, 0x80000000, 0x80000000);
  57 }
  58 
  59 static void
  60 tu102_fault_buffer_info(struct nvkm_fault_buffer *buffer)
  61 {
  62         struct nvkm_device *device = buffer->fault->subdev.device;
  63         const u32 foff = buffer->id * 0x20;
  64 
  65         nvkm_mask(device, 0xb83010 + foff, 0x40000000, 0x40000000);
  66 
  67         buffer->entries = nvkm_rd32(device, 0xb83010 + foff) & 0x000fffff;
  68         buffer->get = 0xb83008 + foff;
  69         buffer->put = 0xb8300c + foff;
  70 }
  71 
  72 static void
  73 tu102_fault_intr_fault(struct nvkm_fault *fault)
  74 {
  75         struct nvkm_subdev *subdev = &fault->subdev;
  76         struct nvkm_device *device = subdev->device;
  77         struct nvkm_fault_data info;
  78         const u32 addrlo = nvkm_rd32(device, 0xb83080);
  79         const u32 addrhi = nvkm_rd32(device, 0xb83084);
  80         const u32  info0 = nvkm_rd32(device, 0xb83088);
  81         const u32 insthi = nvkm_rd32(device, 0xb8308c);
  82         const u32  info1 = nvkm_rd32(device, 0xb83090);
  83 
  84         info.addr = ((u64)addrhi << 32) | addrlo;
  85         info.inst = ((u64)insthi << 32) | (info0 & 0xfffff000);
  86         info.time = 0;
  87         info.engine = (info0 & 0x000000ff);
  88         info.valid  = (info1 & 0x80000000) >> 31;
  89         info.gpc    = (info1 & 0x1f000000) >> 24;
  90         info.hub    = (info1 & 0x00100000) >> 20;
  91         info.access = (info1 & 0x000f0000) >> 16;
  92         info.client = (info1 & 0x00007f00) >> 8;
  93         info.reason = (info1 & 0x0000001f);
  94 
  95         nvkm_fifo_fault(device->fifo, &info);
  96 }
  97 
  98 static void
  99 tu102_fault_intr(struct nvkm_fault *fault)
 100 {
 101         struct nvkm_subdev *subdev = &fault->subdev;
 102         struct nvkm_device *device = subdev->device;
 103         u32 stat = nvkm_rd32(device, 0xb83094);
 104 
 105         if (stat & 0x80000000) {
 106                 tu102_fault_intr_fault(fault);
 107                 nvkm_wr32(device, 0xb83094, 0x80000000);
 108                 stat &= ~0x80000000;
 109         }
 110 
 111         if (stat & 0x00000200) {
 112                 if (fault->buffer[0]) {
 113                         nvkm_event_send(&fault->event, 1, 0, NULL, 0);
 114                         stat &= ~0x00000200;
 115                 }
 116         }
 117 
 118         /*XXX: guess, can't confirm until we get fw... */
 119         if (stat & 0x00000100) {
 120                 if (fault->buffer[1]) {
 121                         nvkm_event_send(&fault->event, 1, 1, NULL, 0);
 122                         stat &= ~0x00000100;
 123                 }
 124         }
 125 
 126         if (stat) {
 127                 nvkm_debug(subdev, "intr %08x\n", stat);
 128         }
 129 }
 130 
 131 static void
 132 tu102_fault_fini(struct nvkm_fault *fault)
 133 {
 134         nvkm_notify_put(&fault->nrpfb);
 135         if (fault->buffer[0])
 136                 fault->func->buffer.fini(fault->buffer[0]);
 137         /*XXX: disable priv faults */
 138 }
 139 
 140 static void
 141 tu102_fault_init(struct nvkm_fault *fault)
 142 {
 143         /*XXX: enable priv faults */
 144         fault->func->buffer.init(fault->buffer[0]);
 145         nvkm_notify_get(&fault->nrpfb);
 146 }
 147 
 148 static const struct nvkm_fault_func
 149 tu102_fault = {
 150         .oneinit = gv100_fault_oneinit,
 151         .init = tu102_fault_init,
 152         .fini = tu102_fault_fini,
 153         .intr = tu102_fault_intr,
 154         .buffer.nr = 2,
 155         .buffer.entry_size = 32,
 156         .buffer.info = tu102_fault_buffer_info,
 157         .buffer.init = tu102_fault_buffer_init,
 158         .buffer.fini = tu102_fault_buffer_fini,
 159         .buffer.intr = tu102_fault_buffer_intr,
 160         .user = { { 0, 0, VOLTA_FAULT_BUFFER_A }, 1 },
 161 };
 162 
 163 int
 164 tu102_fault_new(struct nvkm_device *device, int index,
 165                 struct nvkm_fault **pfault)
 166 {
 167         return nvkm_fault_new_(&tu102_fault, device, index, pfault);
 168 }

/* [<][>][^][v][top][bottom][index][help] */