0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #include "priv.h"
0023
0024 #include <core/memory.h>
0025 #include <subdev/mc.h>
0026 #include <subdev/mmu.h>
0027 #include <engine/fifo.h>
0028
0029 #include <nvif/class.h>
0030
0031 static void
0032 tu102_fault_buffer_intr(struct nvkm_fault_buffer *buffer, bool enable)
0033 {
0034
0035
0036
0037
0038 struct nvkm_device *device = buffer->fault->subdev.device;
0039
0040 nvkm_mc_intr_mask(device, NVKM_SUBDEV_FAULT, 0, enable);
0041 }
0042
0043 static void
0044 tu102_fault_buffer_fini(struct nvkm_fault_buffer *buffer)
0045 {
0046 struct nvkm_device *device = buffer->fault->subdev.device;
0047 const u32 foff = buffer->id * 0x20;
0048
0049
0050 nvkm_wr32(device, 0xb81408, 0x1);
0051 nvkm_wr32(device, 0xb81410, 0x10);
0052
0053 nvkm_mask(device, 0xb83010 + foff, 0x80000000, 0x00000000);
0054 }
0055
0056 static void
0057 tu102_fault_buffer_init(struct nvkm_fault_buffer *buffer)
0058 {
0059 struct nvkm_device *device = buffer->fault->subdev.device;
0060 const u32 foff = buffer->id * 0x20;
0061
0062
0063 nvkm_wr32(device, 0xb81208, 0x1);
0064 nvkm_wr32(device, 0xb81210, 0x10);
0065
0066 nvkm_mask(device, 0xb83010 + foff, 0xc0000000, 0x40000000);
0067 nvkm_wr32(device, 0xb83004 + foff, upper_32_bits(buffer->addr));
0068 nvkm_wr32(device, 0xb83000 + foff, lower_32_bits(buffer->addr));
0069 nvkm_mask(device, 0xb83010 + foff, 0x80000000, 0x80000000);
0070 }
0071
0072 static void
0073 tu102_fault_buffer_info(struct nvkm_fault_buffer *buffer)
0074 {
0075 struct nvkm_device *device = buffer->fault->subdev.device;
0076 const u32 foff = buffer->id * 0x20;
0077
0078 nvkm_mask(device, 0xb83010 + foff, 0x40000000, 0x40000000);
0079
0080 buffer->entries = nvkm_rd32(device, 0xb83010 + foff) & 0x000fffff;
0081 buffer->get = 0xb83008 + foff;
0082 buffer->put = 0xb8300c + foff;
0083 }
0084
0085 static void
0086 tu102_fault_intr_fault(struct nvkm_fault *fault)
0087 {
0088 struct nvkm_subdev *subdev = &fault->subdev;
0089 struct nvkm_device *device = subdev->device;
0090 struct nvkm_fault_data info;
0091 const u32 addrlo = nvkm_rd32(device, 0xb83080);
0092 const u32 addrhi = nvkm_rd32(device, 0xb83084);
0093 const u32 info0 = nvkm_rd32(device, 0xb83088);
0094 const u32 insthi = nvkm_rd32(device, 0xb8308c);
0095 const u32 info1 = nvkm_rd32(device, 0xb83090);
0096
0097 info.addr = ((u64)addrhi << 32) | addrlo;
0098 info.inst = ((u64)insthi << 32) | (info0 & 0xfffff000);
0099 info.time = 0;
0100 info.engine = (info0 & 0x000000ff);
0101 info.valid = (info1 & 0x80000000) >> 31;
0102 info.gpc = (info1 & 0x1f000000) >> 24;
0103 info.hub = (info1 & 0x00100000) >> 20;
0104 info.access = (info1 & 0x000f0000) >> 16;
0105 info.client = (info1 & 0x00007f00) >> 8;
0106 info.reason = (info1 & 0x0000001f);
0107
0108 nvkm_fifo_fault(device->fifo, &info);
0109 }
0110
0111 static void
0112 tu102_fault_intr(struct nvkm_fault *fault)
0113 {
0114 struct nvkm_subdev *subdev = &fault->subdev;
0115 struct nvkm_device *device = subdev->device;
0116 u32 stat = nvkm_rd32(device, 0xb83094);
0117
0118 if (stat & 0x80000000) {
0119 tu102_fault_intr_fault(fault);
0120 nvkm_wr32(device, 0xb83094, 0x80000000);
0121 stat &= ~0x80000000;
0122 }
0123
0124 if (stat & 0x00000200) {
0125
0126 nvkm_wr32(device, 0xb81010, 0x10);
0127
0128 if (fault->buffer[0]) {
0129 nvkm_event_send(&fault->event, 1, 0, NULL, 0);
0130 stat &= ~0x00000200;
0131 }
0132 }
0133
0134
0135 if (stat & 0x00000100) {
0136
0137 nvkm_wr32(device, 0xb81008, 0x1);
0138
0139 if (fault->buffer[1]) {
0140 nvkm_event_send(&fault->event, 1, 1, NULL, 0);
0141 stat &= ~0x00000100;
0142 }
0143 }
0144
0145 if (stat) {
0146 nvkm_debug(subdev, "intr %08x\n", stat);
0147 }
0148 }
0149
0150 static void
0151 tu102_fault_fini(struct nvkm_fault *fault)
0152 {
0153 nvkm_notify_put(&fault->nrpfb);
0154 if (fault->buffer[0])
0155 fault->func->buffer.fini(fault->buffer[0]);
0156
0157 }
0158
0159 static void
0160 tu102_fault_init(struct nvkm_fault *fault)
0161 {
0162
0163 fault->func->buffer.init(fault->buffer[0]);
0164 nvkm_notify_get(&fault->nrpfb);
0165 }
0166
0167 static const struct nvkm_fault_func
0168 tu102_fault = {
0169 .oneinit = gv100_fault_oneinit,
0170 .init = tu102_fault_init,
0171 .fini = tu102_fault_fini,
0172 .intr = tu102_fault_intr,
0173 .buffer.nr = 2,
0174 .buffer.entry_size = 32,
0175 .buffer.info = tu102_fault_buffer_info,
0176 .buffer.pin = gp100_fault_buffer_pin,
0177 .buffer.init = tu102_fault_buffer_init,
0178 .buffer.fini = tu102_fault_buffer_fini,
0179 .buffer.intr = tu102_fault_buffer_intr,
0180 .user = { { 0, 0, VOLTA_FAULT_BUFFER_A }, 1 },
0181 };
0182
0183 int
0184 tu102_fault_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
0185 struct nvkm_fault **pfault)
0186 {
0187 return nvkm_fault_new_(&tu102_fault, device, type, inst, pfault);
0188 }