drm/nouveau/fifo/gk104: make use of topology info during fault recovery
authorBen Skeggs <bskeggs@redhat.com>
Fri, 11 Mar 2016 03:09:28 +0000 (13:09 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Mon, 14 Mar 2016 00:13:42 +0000 (10:13 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h

index cc9bb77..c7b5707 100644 (file)
@@ -108,37 +108,40 @@ gk104_fifo_recover_work(struct work_struct *w)
        struct nvkm_device *device = fifo->base.engine.subdev.device;
        struct nvkm_engine *engine;
        unsigned long flags;
-       u32 engn, engm = 0;
-       u64 mask, todo;
+       u32 engm, runm, todo;
+       int engn, runl;
 
        spin_lock_irqsave(&fifo->base.lock, flags);
-       mask = fifo->recover.mask;
-       fifo->recover.mask = 0ULL;
+       runm = fifo->recover.runm;
+       engm = fifo->recover.engm;
+       fifo->recover.engm = 0;
+       fifo->recover.runm = 0;
        spin_unlock_irqrestore(&fifo->base.lock, flags);
 
-       for (todo = mask; engn = __ffs64(todo), todo; todo &= ~(1 << engn))
-               engm |= 1 << gk104_fifo_subdev_engine(engn);
-       nvkm_mask(device, 0x002630, engm, engm);
+       nvkm_mask(device, 0x002630, runm, runm);
 
-       for (todo = mask; engn = __ffs64(todo), todo; todo &= ~(1 << engn)) {
-               if ((engine = nvkm_device_engine(device, engn))) {
+       for (todo = engm; engn = __ffs(todo), todo; todo &= ~BIT(engn)) {
+               if ((engine = fifo->engine[engn].engine)) {
                        nvkm_subdev_fini(&engine->subdev, false);
                        WARN_ON(nvkm_subdev_init(&engine->subdev));
                }
-               gk104_fifo_runlist_commit(fifo, gk104_fifo_subdev_engine(engn));
        }
 
-       nvkm_wr32(device, 0x00262c, engm);
-       nvkm_mask(device, 0x002630, engm, 0x00000000);
+       for (todo = runm; runl = __ffs(todo), todo; todo &= ~BIT(runl))
+               gk104_fifo_runlist_commit(fifo, runl);
+
+       nvkm_wr32(device, 0x00262c, runm);
+       nvkm_mask(device, 0x002630, runm, 0x00000000);
 }
 
 static void
 gk104_fifo_recover(struct gk104_fifo *fifo, struct nvkm_engine *engine,
-                 struct gk104_fifo_chan *chan)
+                  struct gk104_fifo_chan *chan)
 {
        struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
        struct nvkm_device *device = subdev->device;
        u32 chid = chan->base.chid;
+       int engn;
 
        nvkm_error(subdev, "%s engine fault on channel %d, recovering...\n",
                   nvkm_subdev_name[engine->subdev.index], chid);
@@ -148,7 +151,14 @@ gk104_fifo_recover(struct gk104_fifo *fifo, struct nvkm_engine *engine,
        list_del_init(&chan->head);
        chan->killed = true;
 
-       fifo->recover.mask |= 1ULL << engine->subdev.index;
+       for (engn = 0; engn < fifo->engine_nr; engn++) {
+               if (fifo->engine[engn].engine == engine) {
+                       fifo->recover.engm |= BIT(engn);
+                       break;
+               }
+       }
+
+       fifo->recover.runm |= BIT(chan->runl);
        schedule_work(&fifo->recover.work);
 }
 
index cfd0f8e..9e5d00b 100644 (file)
@@ -11,7 +11,8 @@ struct gk104_fifo {
 
        struct {
                struct work_struct work;
-               u64 mask;
+               u32 engm;
+               u32 runm;
        } recover;
 
        int pbdma_nr;
@@ -69,23 +70,4 @@ gk104_fifo_engine_subdev(int engine)
                return 0;
        }
 }
-
-static inline int
-gk104_fifo_subdev_engine(int subdev)
-{
-       switch (subdev) {
-       case NVKM_ENGINE_GR:
-       case NVKM_ENGINE_SW:
-       case NVKM_ENGINE_CE2   : return 0;
-       case NVKM_ENGINE_MSPDEC: return 1;
-       case NVKM_ENGINE_MSPPP : return 2;
-       case NVKM_ENGINE_MSVLD : return 3;
-       case NVKM_ENGINE_CE0   : return 4;
-       case NVKM_ENGINE_CE1   : return 5;
-       case NVKM_ENGINE_MSENC : return 6;
-       default:
-               WARN_ON(1);
-               return 0;
-       }
-}
 #endif