Commit efa44c66 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/fifo/gk104-: separate runlist building from committing to hw



We will need to bash different registers on Turing.

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 85532bd9
Loading
Loading
Loading
Loading
+31 −22
Original line number Diff line number Diff line
@@ -149,16 +149,41 @@ gk104_fifo_uevent_init(struct nvkm_fifo *fifo)
}

void
gk104_fifo_runlist_commit(struct gk104_fifo *fifo, int runl)
gk104_fifo_runlist_commit(struct gk104_fifo *fifo, int runl,
			  struct nvkm_memory *mem, int nr)
{
	struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
	struct nvkm_device *device = subdev->device;
	int target;

	switch (nvkm_memory_target(mem)) {
	case NVKM_MEM_TARGET_VRAM: target = 0; break;
	case NVKM_MEM_TARGET_NCOH: target = 3; break;
	default:
		WARN_ON(1);
		return;
	}

	nvkm_wr32(device, 0x002270, (nvkm_memory_addr(mem) >> 12) |
				    (target << 28));
	nvkm_wr32(device, 0x002274, (runl << 20) | nr);

	if (nvkm_msec(device, 2000,
		if (!(nvkm_rd32(device, 0x002284 + (runl * 0x08)) & 0x00100000))
			break;
	) < 0)
		nvkm_error(subdev, "runlist %d update timeout\n", runl);
}

void
gk104_fifo_runlist_update(struct gk104_fifo *fifo, int runl)
{
	const struct gk104_fifo_runlist_func *func = fifo->func->runlist;
	struct gk104_fifo_chan *chan;
	struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
	struct nvkm_device *device = subdev->device;
	struct nvkm_memory *mem;
	struct nvkm_fifo_cgrp *cgrp;
	int nr = 0;
	int target;

	mutex_lock(&subdev->mutex);
	mem = fifo->runlist[runl].mem[fifo->runlist[runl].next];
@@ -177,24 +202,7 @@ gk104_fifo_runlist_commit(struct gk104_fifo *fifo, int runl)
	}
	nvkm_done(mem);

	switch (nvkm_memory_target(mem)) {
	case NVKM_MEM_TARGET_VRAM: target = 0; break;
	case NVKM_MEM_TARGET_NCOH: target = 3; break;
	default:
		WARN_ON(1);
		goto unlock;
	}

	nvkm_wr32(device, 0x002270, (nvkm_memory_addr(mem) >> 12) |
				    (target << 28));
	nvkm_wr32(device, 0x002274, (runl << 20) | nr);

	if (nvkm_msec(device, 2000,
		if (!(nvkm_rd32(device, 0x002284 + (runl * 0x08)) & 0x00100000))
			break;
	) < 0)
		nvkm_error(subdev, "runlist %d update timeout\n", runl);
unlock:
	func->commit(fifo, runl, mem, nr);
	mutex_unlock(&subdev->mutex);
}

@@ -238,6 +246,7 @@ const struct gk104_fifo_runlist_func
gk104_fifo_runlist = {
	.size = 8,
	.chan = gk104_fifo_runlist_chan,
	.commit = gk104_fifo_runlist_commit,
};

static void
@@ -267,7 +276,7 @@ gk104_fifo_recover_work(struct work_struct *w)
	}

	for (todo = runm; runl = __ffs(todo), todo; todo &= ~BIT(runl))
		gk104_fifo_runlist_commit(fifo, runl);
		gk104_fifo_runlist_update(fifo, runl);

	nvkm_wr32(device, 0x00262c, runm);
	nvkm_mask(device, 0x002630, runm, 0x00000000);
+5 −1
Original line number Diff line number Diff line
@@ -61,6 +61,8 @@ struct gk104_fifo_func {
			     struct nvkm_memory *, u32 offset);
		void (*chan)(struct gk104_fifo_chan *,
			     struct nvkm_memory *, u32 offset);
		void (*commit)(struct gk104_fifo *, int runl,
			       struct nvkm_memory *, int entries);
	} *runlist;

	struct gk104_fifo_user_user {
@@ -81,7 +83,7 @@ int gk104_fifo_new_(const struct gk104_fifo_func *, struct nvkm_device *,
		    int index, int nr, struct nvkm_fifo **);
void gk104_fifo_runlist_insert(struct gk104_fifo *, struct gk104_fifo_chan *);
void gk104_fifo_runlist_remove(struct gk104_fifo *, struct gk104_fifo_chan *);
void gk104_fifo_runlist_commit(struct gk104_fifo *, int runl);
void gk104_fifo_runlist_update(struct gk104_fifo *, int runl);

extern const struct nvkm_enum gk104_fifo_fault_access[];
extern const struct nvkm_enum gk104_fifo_fault_engine[];
@@ -91,6 +93,8 @@ extern const struct nvkm_enum gk104_fifo_fault_gpcclient[];
extern const struct gk104_fifo_runlist_func gk104_fifo_runlist;
void gk104_fifo_runlist_chan(struct gk104_fifo_chan *,
			     struct nvkm_memory *, u32);
void gk104_fifo_runlist_commit(struct gk104_fifo *, int runl,
			       struct nvkm_memory *, int);

extern const struct gk104_fifo_runlist_func gk110_fifo_runlist;
void gk110_fifo_runlist_cgrp(struct nvkm_fifo_cgrp *,
+1 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ gk110_fifo_runlist = {
	.size = 8,
	.cgrp = gk110_fifo_runlist_cgrp,
	.chan = gk104_fifo_runlist_chan,
	.commit = gk104_fifo_runlist_commit,
};

static const struct gk104_fifo_func
+1 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ gm107_fifo_runlist = {
	.size = 8,
	.cgrp = gk110_fifo_runlist_cgrp,
	.chan = gm107_fifo_runlist_chan,
	.commit = gk104_fifo_runlist_commit,
};

const struct nvkm_enum
+2 −2
Original line number Diff line number Diff line
@@ -192,7 +192,7 @@ gk104_fifo_gpfifo_fini(struct nvkm_fifo_chan *base)
		gk104_fifo_runlist_remove(fifo, chan);
		nvkm_mask(device, 0x800004 + coff, 0x00000800, 0x00000800);
		gk104_fifo_gpfifo_kick(chan);
		gk104_fifo_runlist_commit(fifo, chan->runl);
		gk104_fifo_runlist_update(fifo, chan->runl);
	}

	nvkm_wr32(device, 0x800000 + coff, 0x00000000);
@@ -213,7 +213,7 @@ gk104_fifo_gpfifo_init(struct nvkm_fifo_chan *base)
	if (list_empty(&chan->head) && !chan->killed) {
		gk104_fifo_runlist_insert(fifo, chan);
		nvkm_mask(device, 0x800004 + coff, 0x00000400, 0x00000400);
		gk104_fifo_runlist_commit(fifo, chan->runl);
		gk104_fifo_runlist_update(fifo, chan->runl);
		nvkm_mask(device, 0x800004 + coff, 0x00000400, 0x00000400);
	}
}
Loading