Commit 3968d692 authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/fault: add explicit control over fault buffer interrupts

The GPU will continually fire interrupts while a fault buffer GET != PUT,
and to stop the spurious interrupts while the handler does its thing, we
were disabling the fault buffer temporarily.

This is not actually a great idea to begin with, and made worse by Volta
resetting GET/PUT when it's reactivated.  So, let's not do that.
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 80972456
...@@ -28,14 +28,14 @@ static void ...@@ -28,14 +28,14 @@ static void
nvkm_fault_ntfy_fini(struct nvkm_event *event, int type, int index) nvkm_fault_ntfy_fini(struct nvkm_event *event, int type, int index)
{ {
struct nvkm_fault *fault = container_of(event, typeof(*fault), event); struct nvkm_fault *fault = container_of(event, typeof(*fault), event);
fault->func->buffer.fini(fault->buffer[index]); fault->func->buffer.intr(fault->buffer[index], false);
} }
static void static void
nvkm_fault_ntfy_init(struct nvkm_event *event, int type, int index) nvkm_fault_ntfy_init(struct nvkm_event *event, int type, int index)
{ {
struct nvkm_fault *fault = container_of(event, typeof(*fault), event); struct nvkm_fault *fault = container_of(event, typeof(*fault), event);
fault->func->buffer.init(fault->buffer[index]); fault->func->buffer.intr(fault->buffer[index], true);
} }
static int static int
......
...@@ -21,6 +21,15 @@ ...@@ -21,6 +21,15 @@
*/ */
#include "priv.h" #include "priv.h"
#include <subdev/mc.h>
static void
gp100_fault_buffer_intr(struct nvkm_fault_buffer *buffer, bool enable)
{
struct nvkm_device *device = buffer->fault->subdev.device;
nvkm_mc_intr_mask(device, NVKM_SUBDEV_FAULT, enable);
}
static void static void
gp100_fault_buffer_fini(struct nvkm_fault_buffer *buffer) gp100_fault_buffer_fini(struct nvkm_fault_buffer *buffer)
{ {
...@@ -59,6 +68,7 @@ gp100_fault = { ...@@ -59,6 +68,7 @@ gp100_fault = {
.buffer.info = gp100_fault_buffer_info, .buffer.info = gp100_fault_buffer_info,
.buffer.init = gp100_fault_buffer_init, .buffer.init = gp100_fault_buffer_init,
.buffer.fini = gp100_fault_buffer_fini, .buffer.fini = gp100_fault_buffer_fini,
.buffer.intr = gp100_fault_buffer_intr,
}; };
int int
......
...@@ -69,13 +69,21 @@ gv100_fault_buffer_process(struct nvkm_fault_buffer *buffer) ...@@ -69,13 +69,21 @@ gv100_fault_buffer_process(struct nvkm_fault_buffer *buffer)
} }
static void static void
gv100_fault_buffer_fini(struct nvkm_fault_buffer *buffer) gv100_fault_buffer_intr(struct nvkm_fault_buffer *buffer, bool enable)
{ {
struct nvkm_device *device = buffer->fault->subdev.device; struct nvkm_device *device = buffer->fault->subdev.device;
const u32 intr = buffer->id ? 0x08000000 : 0x20000000; const u32 intr = buffer->id ? 0x08000000 : 0x20000000;
const u32 foff = buffer->id * 0x14; if (enable)
nvkm_mask(device, 0x100a2c, intr, intr);
else
nvkm_mask(device, 0x100a34, intr, intr); nvkm_mask(device, 0x100a34, intr, intr);
}
static void
gv100_fault_buffer_fini(struct nvkm_fault_buffer *buffer)
{
struct nvkm_device *device = buffer->fault->subdev.device;
const u32 foff = buffer->id * 0x14;
nvkm_mask(device, 0x100e34 + foff, 0x80000000, 0x00000000); nvkm_mask(device, 0x100e34 + foff, 0x80000000, 0x00000000);
} }
...@@ -83,14 +91,12 @@ static void ...@@ -83,14 +91,12 @@ static void
gv100_fault_buffer_init(struct nvkm_fault_buffer *buffer) gv100_fault_buffer_init(struct nvkm_fault_buffer *buffer)
{ {
struct nvkm_device *device = buffer->fault->subdev.device; struct nvkm_device *device = buffer->fault->subdev.device;
const u32 intr = buffer->id ? 0x08000000 : 0x20000000;
const u32 foff = buffer->id * 0x14; const u32 foff = buffer->id * 0x14;
nvkm_mask(device, 0x100e34 + foff, 0xc0000000, 0x40000000); nvkm_mask(device, 0x100e34 + foff, 0xc0000000, 0x40000000);
nvkm_wr32(device, 0x100e28 + foff, upper_32_bits(buffer->addr)); nvkm_wr32(device, 0x100e28 + foff, upper_32_bits(buffer->addr));
nvkm_wr32(device, 0x100e24 + foff, lower_32_bits(buffer->addr)); nvkm_wr32(device, 0x100e24 + foff, lower_32_bits(buffer->addr));
nvkm_mask(device, 0x100e34 + foff, 0x80000000, 0x80000000); nvkm_mask(device, 0x100e34 + foff, 0x80000000, 0x80000000);
nvkm_mask(device, 0x100a2c, intr, intr);
} }
static void static void
...@@ -169,6 +175,8 @@ static void ...@@ -169,6 +175,8 @@ static void
gv100_fault_fini(struct nvkm_fault *fault) gv100_fault_fini(struct nvkm_fault *fault)
{ {
nvkm_notify_put(&fault->nrpfb); nvkm_notify_put(&fault->nrpfb);
if (fault->buffer[0])
fault->func->buffer.fini(fault->buffer[0]);
nvkm_mask(fault->subdev.device, 0x100a34, 0x80000000, 0x80000000); nvkm_mask(fault->subdev.device, 0x100a34, 0x80000000, 0x80000000);
} }
...@@ -176,6 +184,7 @@ static void ...@@ -176,6 +184,7 @@ static void
gv100_fault_init(struct nvkm_fault *fault) gv100_fault_init(struct nvkm_fault *fault)
{ {
nvkm_mask(fault->subdev.device, 0x100a2c, 0x80000000, 0x80000000); nvkm_mask(fault->subdev.device, 0x100a2c, 0x80000000, 0x80000000);
fault->func->buffer.init(fault->buffer[0]);
nvkm_notify_get(&fault->nrpfb); nvkm_notify_get(&fault->nrpfb);
} }
...@@ -183,7 +192,7 @@ static int ...@@ -183,7 +192,7 @@ static int
gv100_fault_oneinit(struct nvkm_fault *fault) gv100_fault_oneinit(struct nvkm_fault *fault)
{ {
return nvkm_notify_init(&fault->buffer[0]->object, &fault->event, return nvkm_notify_init(&fault->buffer[0]->object, &fault->event,
gv100_fault_ntfy_nrpfb, false, NULL, 0, 0, gv100_fault_ntfy_nrpfb, true, NULL, 0, 0,
&fault->nrpfb); &fault->nrpfb);
} }
...@@ -198,6 +207,7 @@ gv100_fault = { ...@@ -198,6 +207,7 @@ gv100_fault = {
.buffer.info = gv100_fault_buffer_info, .buffer.info = gv100_fault_buffer_info,
.buffer.init = gv100_fault_buffer_init, .buffer.init = gv100_fault_buffer_init,
.buffer.fini = gv100_fault_buffer_fini, .buffer.fini = gv100_fault_buffer_fini,
.buffer.intr = gv100_fault_buffer_intr,
}; };
int int
......
...@@ -32,6 +32,7 @@ struct nvkm_fault_func { ...@@ -32,6 +32,7 @@ struct nvkm_fault_func {
void (*info)(struct nvkm_fault_buffer *); void (*info)(struct nvkm_fault_buffer *);
void (*init)(struct nvkm_fault_buffer *); void (*init)(struct nvkm_fault_buffer *);
void (*fini)(struct nvkm_fault_buffer *); void (*fini)(struct nvkm_fault_buffer *);
void (*intr)(struct nvkm_fault_buffer *, bool enable);
} buffer; } buffer;
}; };
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment