From 923f1ff5274ce3072df55e5e3bbaa7db457fc35d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Jun 2022 20:47:29 +1000 Subject: drm/nouveau/fifo: move PBDMA intr to runq - merges gf100/gk104- NV_PFIFO_INTR_0_PBDMA and NV_PPBDMA_INTR_0 code Signed-off-by: Ben Skeggs Reviewed-by: Lyude Paul --- drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c | 65 ++++++++++------- drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c | 92 ++++++++---------------- drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h | 3 - drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c | 2 + drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c | 2 + drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h | 6 ++ drivers/gpu/drm/nouveau/nvkm/engine/fifo/runq.h | 3 + drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.c | 13 +--- 8 files changed, 84 insertions(+), 102 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c index 7deb88ec8a9f..177ae02e78ee 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c @@ -30,7 +30,6 @@ #include "changf100.h" #include -#include #include #include #include @@ -52,27 +51,28 @@ gf100_engn_sw = { }; static const struct nvkm_bitfield -gf100_fifo_pbdma_intr[] = { +gf100_runq_intr_0_names[] = { /* { 0x00008000, "" } seen with null ib push */ { 0x00200000, "ILLEGAL_MTHD" }, { 0x00800000, "EMPTY_SUBC" }, {} }; -static void -gf100_fifo_intr_pbdma(struct gf100_fifo *fifo, int unit) +bool +gf100_runq_intr(struct nvkm_runq *runq, struct nvkm_runl *null) { - struct nvkm_subdev *subdev = &fifo->base.engine.subdev; + struct nvkm_subdev *subdev = &runq->fifo->engine.subdev; struct nvkm_device *device = subdev->device; - u32 stat = nvkm_rd32(device, 0x040108 + (unit * 0x2000)); - u32 addr = nvkm_rd32(device, 0x0400c0 + (unit * 0x2000)); - u32 data = nvkm_rd32(device, 0x0400c4 + (unit * 0x2000)); - u32 chid = nvkm_rd32(device, 0x040120 + (unit * 0x2000)) & 0x7f; + u32 mask = nvkm_rd32(device, 0x04010c + (runq->id * 0x2000)); + u32 stat = nvkm_rd32(device, 0x040108 + (runq->id * 0x2000)) & mask; + u32 addr = nvkm_rd32(device, 0x0400c0 + (runq->id * 0x2000)); + u32 data = nvkm_rd32(device, 0x0400c4 + (runq->id * 0x2000)); + u32 chid = nvkm_rd32(device, 0x040120 + (runq->id * 0x2000)) & runq->fifo->chid->mask; u32 subc = (addr & 0x00070000) >> 16; u32 mthd = (addr & 0x00003ffc); - struct nvkm_fifo_chan *chan; - unsigned long flags; u32 show = stat; + struct nvkm_chan *chan; + unsigned long flags; char msg[128]; if (stat & 0x00800000) { @@ -83,18 +83,19 @@ gf100_fifo_intr_pbdma(struct gf100_fifo *fifo, int unit) } if (show) { - nvkm_snprintbf(msg, sizeof(msg), gf100_fifo_pbdma_intr, show); - chan = nvkm_fifo_chan_chid(&fifo->base, chid, &flags); + nvkm_snprintbf(msg, sizeof(msg), runq->func->intr_0_names, show); + chan = nvkm_fifo_chan_chid(runq->fifo, chid, &flags); nvkm_error(subdev, "PBDMA%d: %08x [%s] ch %d [%010llx %s] " "subc %d mthd %04x data %08x\n", - unit, show, msg, chid, chan ? chan->inst->addr : 0, + runq->id, show, msg, chid, chan ? chan->inst->addr : 0, chan ? chan->object.client->name : "unknown", subc, mthd, data); - nvkm_fifo_chan_put(&fifo->base, flags, &chan); + nvkm_fifo_chan_put(runq->fifo, flags, &chan); } - nvkm_wr32(device, 0x0400c0 + (unit * 0x2000), 0x80600008); - nvkm_wr32(device, 0x040108 + (unit * 0x2000), stat); + nvkm_wr32(device, 0x0400c0 + (runq->id * 0x2000), 0x80600008); + nvkm_wr32(device, 0x040108 + (runq->id * 0x2000), stat); + return true; } void @@ -110,6 +111,8 @@ gf100_runq_init(struct nvkm_runq *runq) static const struct nvkm_runq_func gf100_runq = { .init = gf100_runq_init, + .intr = gf100_runq_intr, + .intr_0_names = gf100_runq_intr_0_names, }; void @@ -495,6 +498,24 @@ gf100_fifo_intr_mmu_fault_unit(struct nvkm_fifo *fifo, int unit) nvkm_fifo_fault(fifo, &info); } +bool +gf100_fifo_intr_pbdma(struct nvkm_fifo *fifo) +{ + struct nvkm_device *device = fifo->engine.subdev.device; + struct nvkm_runq *runq; + u32 mask = nvkm_rd32(device, 0x0025a0); + bool handled = false; + + nvkm_runq_foreach_cond(runq, fifo, mask & BIT(runq->id)) { + if (runq->func->intr(runq, NULL)) + handled = true; + + nvkm_wr32(device, 0x0025a0, BIT(runq->id)); + } + + return handled; +} + static void gf100_fifo_intr_runlist(struct gf100_fifo *fifo) { @@ -599,14 +620,8 @@ gf100_fifo_intr(struct nvkm_inth *inth) } if (stat & 0x20000000) { - u32 mask = nvkm_rd32(device, 0x0025a0); - while (mask) { - u32 unit = __ffs(mask); - gf100_fifo_intr_pbdma(gf100_fifo(fifo), unit); - nvkm_wr32(device, 0x0025a0, (1 << unit)); - mask &= ~(1 << unit); - } - stat &= ~0x20000000; + if (gf100_fifo_intr_pbdma(fifo)) + stat &= ~0x20000000; } if (stat & 0x40000000) { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c index 8b6bc79843c7..6295389bfbea 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c @@ -37,7 +37,6 @@ #include #include #include -#include #include @@ -100,7 +99,8 @@ const struct nvkm_engn_func gk104_engn_ce = { }; -static const struct nvkm_bitfield gk104_fifo_pbdma_intr_1[] = { +static const struct nvkm_bitfield +gk104_runq_intr_1_names[] = { { 0x00000001, "HCE_RE_ILLEGAL_OP" }, { 0x00000002, "HCE_RE_ALIGNB" }, { 0x00000004, "HCE_PRIV" }, @@ -109,28 +109,30 @@ static const struct nvkm_bitfield gk104_fifo_pbdma_intr_1[] = { {} }; -void -gk104_fifo_intr_pbdma_1(struct gk104_fifo *fifo, int unit) +static bool +gk104_runq_intr_1(struct nvkm_runq *runq) { - struct nvkm_subdev *subdev = &fifo->base.engine.subdev; + struct nvkm_subdev *subdev = &runq->fifo->engine.subdev; struct nvkm_device *device = subdev->device; - u32 mask = nvkm_rd32(device, 0x04014c + (unit * 0x2000)); - u32 stat = nvkm_rd32(device, 0x040148 + (unit * 0x2000)) & mask; - u32 chid = nvkm_rd32(device, 0x040120 + (unit * 0x2000)) & 0xfff; + u32 mask = nvkm_rd32(device, 0x04014c + (runq->id * 0x2000)); + u32 stat = nvkm_rd32(device, 0x040148 + (runq->id * 0x2000)) & mask; + u32 chid = nvkm_rd32(device, 0x040120 + (runq->id * 0x2000)) & 0xfff; char msg[128]; if (stat) { - nvkm_snprintbf(msg, sizeof(msg), gk104_fifo_pbdma_intr_1, stat); + nvkm_snprintbf(msg, sizeof(msg), gk104_runq_intr_1_names, stat); nvkm_error(subdev, "PBDMA%d: %08x [%s] ch %d %08x %08x\n", - unit, stat, msg, chid, - nvkm_rd32(device, 0x040150 + (unit * 0x2000)), - nvkm_rd32(device, 0x040154 + (unit * 0x2000))); + runq->id, stat, msg, chid, + nvkm_rd32(device, 0x040150 + (runq->id * 0x2000)), + nvkm_rd32(device, 0x040154 + (runq->id * 0x2000))); } - nvkm_wr32(device, 0x040148 + (unit * 0x2000), stat); + nvkm_wr32(device, 0x040148 + (runq->id * 0x2000), stat); + return true; } -static const struct nvkm_bitfield gk104_fifo_pbdma_intr_0[] = { +const struct nvkm_bitfield +gk104_runq_intr_0_names[] = { { 0x00000001, "MEMREQ" }, { 0x00000002, "MEMACK_TIMEOUT" }, { 0x00000004, "MEMACK_EXTRA" }, @@ -164,6 +166,15 @@ static const struct nvkm_bitfield gk104_fifo_pbdma_intr_0[] = { {} }; +bool +gk104_runq_intr(struct nvkm_runq *runq, struct nvkm_runl *null) +{ + bool intr0 = gf100_runq_intr(runq, NULL); + bool intr1 = gk104_runq_intr_1(runq); + + return intr0 || intr1; +} + void gk104_runq_init(struct nvkm_runq *runq) { @@ -184,6 +195,8 @@ gk104_runq_runm(struct nvkm_runq *runq) const struct nvkm_runq_func gk104_runq = { .init = gk104_runq_init, + .intr = gk104_runq_intr, + .intr_0_names = gk104_runq_intr_0_names, }; void @@ -806,46 +819,6 @@ gk104_fifo_intr_dropped_fault(struct nvkm_fifo *fifo) nvkm_error(subdev, "DROPPED_MMU_FAULT %08x\n", stat); } -void -gk104_fifo_intr_pbdma_0(struct gk104_fifo *fifo, int unit) -{ - struct nvkm_subdev *subdev = &fifo->base.engine.subdev; - struct nvkm_device *device = subdev->device; - u32 mask = nvkm_rd32(device, 0x04010c + (unit * 0x2000)); - u32 stat = nvkm_rd32(device, 0x040108 + (unit * 0x2000)) & mask; - u32 addr = nvkm_rd32(device, 0x0400c0 + (unit * 0x2000)); - u32 data = nvkm_rd32(device, 0x0400c4 + (unit * 0x2000)); - u32 chid = nvkm_rd32(device, 0x040120 + (unit * 0x2000)) & 0xfff; - u32 subc = (addr & 0x00070000) >> 16; - u32 mthd = (addr & 0x00003ffc); - u32 show = stat; - struct nvkm_fifo_chan *chan; - unsigned long flags; - char msg[128]; - - if (stat & 0x00800000) { - if (device->sw) { - if (nvkm_sw_mthd(device->sw, chid, subc, mthd, data)) - show &= ~0x00800000; - } - } - - nvkm_wr32(device, 0x0400c0 + (unit * 0x2000), 0x80600008); - - if (show) { - nvkm_snprintbf(msg, sizeof(msg), gk104_fifo_pbdma_intr_0, show); - chan = nvkm_fifo_chan_chid(&fifo->base, chid, &flags); - nvkm_error(subdev, "PBDMA%d: %08x [%s] ch %d [%010llx %s] " - "subc %d mthd %04x data %08x\n", - unit, show, msg, chid, chan ? chan->inst->addr : 0, - chan ? chan->object.client->name : "unknown", - subc, mthd, data); - nvkm_fifo_chan_put(&fifo->base, flags, &chan); - } - - nvkm_wr32(device, 0x040108 + (unit * 0x2000), stat); -} - void gk104_fifo_intr_runlist(struct gk104_fifo *fifo) { @@ -922,15 +895,8 @@ gk104_fifo_intr(struct nvkm_inth *inth) } if (stat & 0x20000000) { - u32 mask = nvkm_rd32(device, 0x0025a0); - while (mask) { - u32 unit = __ffs(mask); - gk104_fifo_intr_pbdma_0(gk104_fifo(fifo), unit); - gk104_fifo_intr_pbdma_1(gk104_fifo(fifo), unit); - nvkm_wr32(device, 0x0025a0, (1 << unit)); - mask &= ~(1 << unit); - } - stat &= ~0x20000000; + if (gf100_fifo_intr_pbdma(fifo)) + stat &= ~0x20000000; } if (stat & 0x40000000) { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h index 99ae200b2f89..f7e6c26a2a45 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h @@ -5,7 +5,6 @@ #include "priv.h" struct nvkm_fifo_cgrp; -#include #include #define gk104_fifo_func nvkm_fifo_func @@ -64,8 +63,6 @@ void gk104_fifo_runlist_remove(struct gk104_fifo *, struct gk104_fifo_chan *); void gk104_fifo_runlist_update(struct gk104_fifo *, int runl); void gk104_fifo_engine_status(struct gk104_fifo *fifo, int engn, struct gk104_fifo_engine_status *status); -void gk104_fifo_intr_pbdma_0(struct gk104_fifo *fifo, int unit); -void gk104_fifo_intr_pbdma_1(struct gk104_fifo *fifo, int unit); void gk104_fifo_intr_runlist(struct gk104_fifo *fifo); void *gk104_fifo_dtor(struct nvkm_fifo *base); int gk104_fifo_oneinit(struct nvkm_fifo *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c index 0b48fb1b3da4..87601c35581c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c @@ -38,6 +38,8 @@ gk208_runq_init(struct nvkm_runq *runq) const struct nvkm_runq_func gk208_runq = { .init = gk208_runq_init, + .intr = gk104_runq_intr, + .intr_0_names = gk104_runq_intr_0_names, }; static int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c index 251d5e5826db..dc1586e2ab72 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c @@ -46,6 +46,8 @@ gv100_engn_ce = { const struct nvkm_runq_func gv100_runq = { .init = gk208_runq_init, + .intr = gk104_runq_intr, + .intr_0_names = gk104_runq_intr_0_names, }; void diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h index c30d7ac07803..00f23c39978e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h @@ -3,8 +3,10 @@ #define __NVKM_FIFO_PRIV_H__ #define nvkm_fifo(p) container_of((p), struct nvkm_fifo, engine) #include +#include struct nvkm_cgrp; struct nvkm_memory; +struct nvkm_runl; struct nvkm_runq; struct gk104_fifo; struct gk104_fifo_chan; @@ -113,9 +115,11 @@ extern const struct nvkm_chan_func g84_chan; int gf100_fifo_chid_ctor(struct nvkm_fifo *, int); int gf100_fifo_runq_nr(struct nvkm_fifo *); +bool gf100_fifo_intr_pbdma(struct nvkm_fifo *); void gf100_fifo_intr_mmu_fault_unit(struct nvkm_fifo *, int); extern const struct nvkm_event_func gf100_fifo_nonstall; void gf100_runq_init(struct nvkm_runq *); +bool gf100_runq_intr(struct nvkm_runq *, struct nvkm_runl *); extern const struct nvkm_engn_func gf100_engn_sw; int gk104_fifo_chid_nr(struct nvkm_fifo *); @@ -130,6 +134,8 @@ void gk104_fifo_recover_chan(struct nvkm_fifo *, int); int gk104_fifo_engine_id(struct nvkm_fifo *, struct nvkm_engine *); extern const struct nvkm_runq_func gk104_runq; void gk104_runq_init(struct nvkm_runq *); +bool gk104_runq_intr(struct nvkm_runq *, struct nvkm_runl *); +extern const struct nvkm_bitfield gk104_runq_intr_0_names[]; extern const struct nvkm_engn_func gk104_engn; extern const struct nvkm_engn_func gk104_engn_ce; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/runq.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/runq.h index e4909161c9bc..f939d3500cb6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/runq.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/runq.h @@ -2,10 +2,13 @@ #ifndef __NVKM_RUNQ_H__ #define __NVKM_RUNQ_H__ #include +struct nvkm_runl; struct nvkm_runq { const struct nvkm_runq_func { void (*init)(struct nvkm_runq *); + bool (*intr)(struct nvkm_runq *, struct nvkm_runl *); + const struct nvkm_bitfield *intr_0_names; } *func; struct nvkm_fifo *fifo; int id; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.c index 5fcc4ebb9f5b..2d14795b9842 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.c @@ -395,17 +395,8 @@ tu102_fifo_intr(struct nvkm_inth *inth) } if (stat & 0x20000000) { - u32 mask = nvkm_rd32(device, 0x0025a0); - - while (mask) { - u32 unit = __ffs(mask); - - gk104_fifo_intr_pbdma_0(gk104_fifo(fifo), unit); - gk104_fifo_intr_pbdma_1(gk104_fifo(fifo), unit); - nvkm_wr32(device, 0x0025a0, (1 << unit)); - mask &= ~(1 << unit); - } - stat &= ~0x20000000; + if (gf100_fifo_intr_pbdma(fifo)) + stat &= ~0x20000000; } if (stat & 0x40000000) { -- cgit v1.2.3