drm/nouveau/fifo: move PBDMA intr to runq
authorBen Skeggs <bskeggs@redhat.com>
Wed, 1 Jun 2022 10:47:29 +0000 (20:47 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 9 Nov 2022 00:44:48 +0000 (10:44 +1000)
- merges gf100/gk104- NV_PFIFO_INTR_0_PBDMA and NV_PPBDMA_INTR_0 code

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/runq.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.c

index 7deb88e..177ae02 100644 (file)
@@ -30,7 +30,6 @@
 #include "changf100.h"
 
 #include <core/client.h>
-#include <core/enum.h>
 #include <core/gpuobj.h>
 #include <subdev/bar.h>
 #include <subdev/fault.h>
@@ -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) {
index 8b6bc79..6295389 100644 (file)
@@ -37,7 +37,6 @@
 #include <subdev/mc.h>
 #include <subdev/timer.h>
 #include <subdev/top.h>
-#include <engine/sw.h>
 
 #include <nvif/class.h>
 
@@ -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
@@ -807,46 +820,6 @@ gk104_fifo_intr_dropped_fault(struct nvkm_fifo *fifo)
 }
 
 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)
 {
        struct nvkm_device *device = fifo->base.engine.subdev.device;
@@ -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) {
index 99ae200..f7e6c26 100644 (file)
@@ -5,7 +5,6 @@
 #include "priv.h"
 struct nvkm_fifo_cgrp;
 
-#include <core/enum.h>
 #include <subdev/mmu.h>
 
 #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 *);
index 0b48fb1..87601c3 100644 (file)
@@ -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
index 251d5e5..dc1586e 100644 (file)
@@ -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
index c30d7ac..00f23c3 100644 (file)
@@ -3,8 +3,10 @@
 #define __NVKM_FIFO_PRIV_H__
 #define nvkm_fifo(p) container_of((p), struct nvkm_fifo, engine)
 #include <engine/fifo.h>
+#include <core/enum.h>
 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;
 
index e490916..f939d35 100644 (file)
@@ -2,10 +2,13 @@
 #ifndef __NVKM_RUNQ_H__
 #define __NVKM_RUNQ_H__
 #include <core/os.h>
+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;
index 5fcc4eb..2d14795 100644 (file)
@@ -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) {