Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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



Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent af83a677
Loading
Loading
Loading
Loading
+24 −14
Original line number Diff line number Diff line
@@ -108,28 +108,30 @@ 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
@@ -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_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);
}

+2 −20
Original line number Diff line number Diff line
@@ -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