drm/nouveau/fifo/gk104-: separate out engine status parsing
authorBen Skeggs <bskeggs@redhat.com>
Mon, 16 Jan 2017 00:14:36 +0000 (10:14 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Fri, 17 Feb 2017 07:38:12 +0000 (17:38 +1000)
We'll be wanting to reuse this logic in more places.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c

index 67a6a514b5fa696689641fd9f56db304be84f150..6d12a2efee117437da2364ae89e9eb33f88ec2a9 100644 (file)
 
 #include <nvif/class.h>
 
+struct gk104_fifo_engine_status {
+       bool busy;
+       bool faulted;
+       bool chsw;
+       bool save;
+       bool load;
+       struct {
+               bool tsg;
+               u32 id;
+       } prev, next, *chan;
+};
+
+static void
+gk104_fifo_engine_status(struct gk104_fifo *fifo, int engn,
+                        struct gk104_fifo_engine_status *status)
+{
+       struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
+       struct nvkm_device *device = subdev->device;
+       u32 stat = nvkm_rd32(device, 0x002640 + (engn * 0x08));
+
+       status->busy     = !!(stat & 0x80000000);
+       status->faulted  = !!(stat & 0x40000000);
+       status->next.tsg = !!(stat & 0x10000000);
+       status->next.id  =   (stat & 0x0fff0000) >> 16;
+       status->chsw     = !!(stat & 0x00008000);
+       status->save     = !!(stat & 0x00004000);
+       status->load     = !!(stat & 0x00002000);
+       status->prev.tsg = !!(stat & 0x00001000);
+       status->prev.id  =   (stat & 0x00000fff);
+       status->chan     = status->load ? &status->next : &status->prev;
+
+       nvkm_debug(subdev, "engine %02d: busy %d faulted %d chsw %d "
+                          "save %d load %d %sid %d%s-> %sid %d%s\n",
+                  engn, status->busy, status->faulted,
+                  status->chsw, status->save, status->load,
+                  status->prev.tsg ? "tsg" : "ch", status->prev.id,
+                  status->chan == &status->prev ? "*" : " ",
+                  status->next.tsg ? "tsg" : "ch", status->next.id,
+                  status->chan == &status->next ? "*" : " ");
+}
+
 static int
 gk104_fifo_class_get(struct nvkm_fifo *base, int index,
                     const struct nvkm_fifo_chan_oclass **psclass)
@@ -214,7 +255,6 @@ gk104_fifo_sched_reason[] = {
 static void
 gk104_fifo_intr_sched_ctxsw(struct gk104_fifo *fifo)
 {
-       struct nvkm_device *device = fifo->base.engine.subdev.device;
        struct gk104_fifo_chan *chan;
        unsigned long flags;
        u32 engn;
@@ -223,21 +263,14 @@ gk104_fifo_intr_sched_ctxsw(struct gk104_fifo *fifo)
        for (engn = 0; engn < fifo->engine_nr; engn++) {
                struct nvkm_engine *engine = fifo->engine[engn].engine;
                int runl = fifo->engine[engn].runl;
-               u32 stat = nvkm_rd32(device, 0x002640 + (engn * 0x08));
-               u32 busy = (stat & 0x80000000);
-               u32 next = (stat & 0x0fff0000) >> 16;
-               u32 chsw = (stat & 0x00008000);
-               u32 save = (stat & 0x00004000);
-               u32 load = (stat & 0x00002000);
-               u32 prev = (stat & 0x00000fff);
-               u32 chid = load ? next : prev;
-               (void)save;
-
-               if (!busy || !chsw)
+               struct gk104_fifo_engine_status status;
+
+               gk104_fifo_engine_status(fifo, engn, &status);
+               if (!status.busy || !status.chsw)
                        continue;
 
                list_for_each_entry(chan, &fifo->runlist[runl].chan, head) {
-                       if (chan->base.chid == chid && engine) {
+                       if (chan->base.chid == status.chan->id && engine) {
                                gk104_fifo_recover(fifo, engine, chan);
                                break;
                        }