Commit 19f89279 authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/fifo/gk104: make use of topology info during fault recovery

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent af83a677
...@@ -108,28 +108,30 @@ gk104_fifo_recover_work(struct work_struct *w) ...@@ -108,28 +108,30 @@ gk104_fifo_recover_work(struct work_struct *w)
struct nvkm_device *device = fifo->base.engine.subdev.device; struct nvkm_device *device = fifo->base.engine.subdev.device;
struct nvkm_engine *engine; struct nvkm_engine *engine;
unsigned long flags; unsigned long flags;
u32 engn, engm = 0; u32 engm, runm, todo;
u64 mask, todo; int engn, runl;
spin_lock_irqsave(&fifo->base.lock, flags); spin_lock_irqsave(&fifo->base.lock, flags);
mask = fifo->recover.mask; runm = fifo->recover.runm;
fifo->recover.mask = 0ULL; engm = fifo->recover.engm;
fifo->recover.engm = 0;
fifo->recover.runm = 0;
spin_unlock_irqrestore(&fifo->base.lock, flags); spin_unlock_irqrestore(&fifo->base.lock, flags);
for (todo = mask; engn = __ffs64(todo), todo; todo &= ~(1 << engn)) nvkm_mask(device, 0x002630, runm, runm);
engm |= 1 << gk104_fifo_subdev_engine(engn);
nvkm_mask(device, 0x002630, engm, engm);
for (todo = mask; engn = __ffs64(todo), todo; todo &= ~(1 << engn)) { for (todo = engm; engn = __ffs(todo), todo; todo &= ~BIT(engn)) {
if ((engine = nvkm_device_engine(device, engn))) { if ((engine = fifo->engine[engn].engine)) {
nvkm_subdev_fini(&engine->subdev, false); nvkm_subdev_fini(&engine->subdev, false);
WARN_ON(nvkm_subdev_init(&engine->subdev)); WARN_ON(nvkm_subdev_init(&engine->subdev));
} }
gk104_fifo_runlist_commit(fifo, gk104_fifo_subdev_engine(engn));
} }
nvkm_wr32(device, 0x00262c, engm); for (todo = runm; runl = __ffs(todo), todo; todo &= ~BIT(runl))
nvkm_mask(device, 0x002630, engm, 0x00000000); gk104_fifo_runlist_commit(fifo, runl);
nvkm_wr32(device, 0x00262c, runm);
nvkm_mask(device, 0x002630, runm, 0x00000000);
} }
static void static void
...@@ -139,6 +141,7 @@ gk104_fifo_recover(struct gk104_fifo *fifo, struct nvkm_engine *engine, ...@@ -139,6 +141,7 @@ gk104_fifo_recover(struct gk104_fifo *fifo, struct nvkm_engine *engine,
struct nvkm_subdev *subdev = &fifo->base.engine.subdev; struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
struct nvkm_device *device = subdev->device; struct nvkm_device *device = subdev->device;
u32 chid = chan->base.chid; u32 chid = chan->base.chid;
int engn;
nvkm_error(subdev, "%s engine fault on channel %d, recovering...\n", nvkm_error(subdev, "%s engine fault on channel %d, recovering...\n",
nvkm_subdev_name[engine->subdev.index], chid); nvkm_subdev_name[engine->subdev.index], chid);
...@@ -148,7 +151,14 @@ gk104_fifo_recover(struct gk104_fifo *fifo, struct nvkm_engine *engine, ...@@ -148,7 +151,14 @@ gk104_fifo_recover(struct gk104_fifo *fifo, struct nvkm_engine *engine,
list_del_init(&chan->head); list_del_init(&chan->head);
chan->killed = true; 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); schedule_work(&fifo->recover.work);
} }
......
...@@ -11,7 +11,8 @@ struct gk104_fifo { ...@@ -11,7 +11,8 @@ struct gk104_fifo {
struct { struct {
struct work_struct work; struct work_struct work;
u64 mask; u32 engm;
u32 runm;
} recover; } recover;
int pbdma_nr; int pbdma_nr;
...@@ -69,23 +70,4 @@ gk104_fifo_engine_subdev(int engine) ...@@ -69,23 +70,4 @@ gk104_fifo_engine_subdev(int engine)
return 0; 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 #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment