From 3968d6920bf3fef56eab1f21e71d135ef43e7b88 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 11 Dec 2018 14:50:02 +1000 Subject: [PATCH] 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: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/subdev/fault/base.c | 4 ++-- .../gpu/drm/nouveau/nvkm/subdev/fault/gp100.c | 10 +++++++++ .../gpu/drm/nouveau/nvkm/subdev/fault/gv100.c | 22 ++++++++++++++----- .../gpu/drm/nouveau/nvkm/subdev/fault/priv.h | 1 + 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c index 75587cafa0ce..4ba1e21e8fda 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c @@ -28,14 +28,14 @@ static void nvkm_fault_ntfy_fini(struct nvkm_event *event, int type, int index) { 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 nvkm_fault_ntfy_init(struct nvkm_event *event, int type, int index) { 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 diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/gp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/gp100.c index 67d587a50f14..8fb96fe614f9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/gp100.c @@ -21,6 +21,15 @@ */ #include "priv.h" +#include + +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 gp100_fault_buffer_fini(struct nvkm_fault_buffer *buffer) { @@ -59,6 +68,7 @@ gp100_fault = { .buffer.info = gp100_fault_buffer_info, .buffer.init = gp100_fault_buffer_init, .buffer.fini = gp100_fault_buffer_fini, + .buffer.intr = gp100_fault_buffer_intr, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/gv100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/gv100.c index c5f735cf8eb3..5de916fc5ccd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/gv100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/gv100.c @@ -69,13 +69,21 @@ gv100_fault_buffer_process(struct nvkm_fault_buffer *buffer) } 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; 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); } @@ -83,14 +91,12 @@ static void gv100_fault_buffer_init(struct nvkm_fault_buffer *buffer) { struct nvkm_device *device = buffer->fault->subdev.device; - const u32 intr = buffer->id ? 0x08000000 : 0x20000000; const u32 foff = buffer->id * 0x14; nvkm_mask(device, 0x100e34 + foff, 0xc0000000, 0x40000000); nvkm_wr32(device, 0x100e28 + foff, upper_32_bits(buffer->addr)); nvkm_wr32(device, 0x100e24 + foff, lower_32_bits(buffer->addr)); nvkm_mask(device, 0x100e34 + foff, 0x80000000, 0x80000000); - nvkm_mask(device, 0x100a2c, intr, intr); } static void @@ -169,6 +175,8 @@ static void gv100_fault_fini(struct nvkm_fault *fault) { nvkm_notify_put(&fault->nrpfb); + if (fault->buffer[0]) + fault->func->buffer.fini(fault->buffer[0]); nvkm_mask(fault->subdev.device, 0x100a34, 0x80000000, 0x80000000); } @@ -176,6 +184,7 @@ static void gv100_fault_init(struct nvkm_fault *fault) { nvkm_mask(fault->subdev.device, 0x100a2c, 0x80000000, 0x80000000); + fault->func->buffer.init(fault->buffer[0]); nvkm_notify_get(&fault->nrpfb); } @@ -183,7 +192,7 @@ static int gv100_fault_oneinit(struct nvkm_fault *fault) { 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); } @@ -198,6 +207,7 @@ gv100_fault = { .buffer.info = gv100_fault_buffer_info, .buffer.init = gv100_fault_buffer_init, .buffer.fini = gv100_fault_buffer_fini, + .buffer.intr = gv100_fault_buffer_intr, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/priv.h index b9a30a6f6aaf..ec085dcb5c5c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/priv.h @@ -32,6 +32,7 @@ struct nvkm_fault_func { void (*info)(struct nvkm_fault_buffer *); void (*init)(struct nvkm_fault_buffer *); void (*fini)(struct nvkm_fault_buffer *); + void (*intr)(struct nvkm_fault_buffer *, bool enable); } buffer; }; #endif -- 2.30.2