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

Commit 4391d7f5 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/disp/nv50-: split chid into chid.ctrl and chid.user



GP102/GP104 make life difficult by redefining the channel indices for
some registers, but not others.

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 3a6536c5
Loading
Loading
Loading
Loading
+12 −11
Original line number Diff line number Diff line
@@ -82,7 +82,7 @@ nv50_disp_chan_mthd(struct nv50_disp_chan *chan, int debug)

			if (mthd->addr) {
				snprintf(cname_, sizeof(cname_), "%s %d",
					 mthd->name, chan->chid);
					 mthd->name, chan->chid.user);
				cname = cname_;
			}

@@ -139,7 +139,7 @@ nv50_disp_chan_uevent_ctor(struct nvkm_object *object, void *data, u32 size,
	if (!(ret = nvif_unvers(ret, &data, &size, args->none))) {
		notify->size  = sizeof(struct nvif_notify_uevent_rep);
		notify->types = 1;
		notify->index = chan->chid;
		notify->index = chan->chid.user;
		return 0;
	}

@@ -159,7 +159,7 @@ nv50_disp_chan_rd32(struct nvkm_object *object, u64 addr, u32 *data)
	struct nv50_disp_chan *chan = nv50_disp_chan(object);
	struct nv50_disp *disp = chan->root->disp;
	struct nvkm_device *device = disp->base.engine.subdev.device;
	*data = nvkm_rd32(device, 0x640000 + (chan->chid * 0x1000) + addr);
	*data = nvkm_rd32(device, 0x640000 + (chan->chid.user * 0x1000) + addr);
	return 0;
}

@@ -169,7 +169,7 @@ nv50_disp_chan_wr32(struct nvkm_object *object, u64 addr, u32 data)
	struct nv50_disp_chan *chan = nv50_disp_chan(object);
	struct nv50_disp *disp = chan->root->disp;
	struct nvkm_device *device = disp->base.engine.subdev.device;
	nvkm_wr32(device, 0x640000 + (chan->chid * 0x1000) + addr, data);
	nvkm_wr32(device, 0x640000 + (chan->chid.user * 0x1000) + addr, data);
	return 0;
}

@@ -196,7 +196,7 @@ nv50_disp_chan_map(struct nvkm_object *object, u64 *addr, u32 *size)
	struct nv50_disp *disp = chan->root->disp;
	struct nvkm_device *device = disp->base.engine.subdev.device;
	*addr = device->func->resource_addr(device, 0) +
		0x640000 + (chan->chid * 0x1000);
		0x640000 + (chan->chid.user * 0x1000);
	*size = 0x001000;
	return 0;
}
@@ -243,8 +243,8 @@ nv50_disp_chan_dtor(struct nvkm_object *object)
{
	struct nv50_disp_chan *chan = nv50_disp_chan(object);
	struct nv50_disp *disp = chan->root->disp;
	if (chan->chid >= 0)
		disp->chan[chan->chid] = NULL;
	if (chan->chid.user >= 0)
		disp->chan[chan->chid.user] = NULL;
	return chan->func->dtor ? chan->func->dtor(chan) : chan;
}

@@ -273,14 +273,15 @@ nv50_disp_chan_ctor(const struct nv50_disp_chan_func *func,
	chan->func = func;
	chan->mthd = mthd;
	chan->root = root;
	chan->chid = chid;
	chan->chid.ctrl = chid;
	chan->chid.user = chid;
	chan->head = head;

	if (disp->chan[chan->chid]) {
		chan->chid = -1;
	if (disp->chan[chan->chid.user]) {
		chan->chid.user = -1;
		return -EBUSY;
	}
	disp->chan[chan->chid] = chan;
	disp->chan[chan->chid.user] = chan;
	return 0;
}

+5 −1
Original line number Diff line number Diff line
@@ -7,7 +7,11 @@ struct nv50_disp_chan {
	const struct nv50_disp_chan_func *func;
	const struct nv50_disp_chan_mthd *mthd;
	struct nv50_disp_root *root;
	int chid;

	struct {
		int ctrl;
		int user;
	} chid;
	int head;

	struct nvkm_object object;
+23 −21
Original line number Diff line number Diff line
@@ -32,8 +32,8 @@ gf119_disp_dmac_bind(struct nv50_disp_dmac *chan,
		     struct nvkm_object *object, u32 handle)
{
	return nvkm_ramht_insert(chan->base.root->ramht, object,
				 chan->base.chid, -9, handle,
				 chan->base.chid << 27 | 0x00000001);
				 chan->base.chid.user, -9, handle,
				 chan->base.chid.user << 27 | 0x00000001);
}

void
@@ -42,22 +42,23 @@ gf119_disp_dmac_fini(struct nv50_disp_dmac *chan)
	struct nv50_disp *disp = chan->base.root->disp;
	struct nvkm_subdev *subdev = &disp->base.engine.subdev;
	struct nvkm_device *device = subdev->device;
	int chid = chan->base.chid;
	int ctrl = chan->base.chid.ctrl;
	int user = chan->base.chid.user;

	/* deactivate channel */
	nvkm_mask(device, 0x610490 + (chid * 0x0010), 0x00001010, 0x00001000);
	nvkm_mask(device, 0x610490 + (chid * 0x0010), 0x00000003, 0x00000000);
	nvkm_mask(device, 0x610490 + (ctrl * 0x0010), 0x00001010, 0x00001000);
	nvkm_mask(device, 0x610490 + (ctrl * 0x0010), 0x00000003, 0x00000000);
	if (nvkm_msec(device, 2000,
		if (!(nvkm_rd32(device, 0x610490 + (chid * 0x10)) & 0x001e0000))
		if (!(nvkm_rd32(device, 0x610490 + (ctrl * 0x10)) & 0x001e0000))
			break;
	) < 0) {
		nvkm_error(subdev, "ch %d fini: %08x\n", chid,
			   nvkm_rd32(device, 0x610490 + (chid * 0x10)));
		nvkm_error(subdev, "ch %d fini: %08x\n", user,
			   nvkm_rd32(device, 0x610490 + (ctrl * 0x10)));
	}

	/* disable error reporting and completion notification */
	nvkm_mask(device, 0x610090, 0x00000001 << chid, 0x00000000);
	nvkm_mask(device, 0x6100a0, 0x00000001 << chid, 0x00000000);
	nvkm_mask(device, 0x610090, 0x00000001 << user, 0x00000000);
	nvkm_mask(device, 0x6100a0, 0x00000001 << user, 0x00000000);
}

static int
@@ -66,26 +67,27 @@ gf119_disp_dmac_init(struct nv50_disp_dmac *chan)
	struct nv50_disp *disp = chan->base.root->disp;
	struct nvkm_subdev *subdev = &disp->base.engine.subdev;
	struct nvkm_device *device = subdev->device;
	int chid = chan->base.chid;
	int ctrl = chan->base.chid.ctrl;
	int user = chan->base.chid.user;

	/* enable error reporting */
	nvkm_mask(device, 0x6100a0, 0x00000001 << chid, 0x00000001 << chid);
	nvkm_mask(device, 0x6100a0, 0x00000001 << user, 0x00000001 << user);

	/* initialise channel for dma command submission */
	nvkm_wr32(device, 0x610494 + (chid * 0x0010), chan->push);
	nvkm_wr32(device, 0x610498 + (chid * 0x0010), 0x00010000);
	nvkm_wr32(device, 0x61049c + (chid * 0x0010), 0x00000001);
	nvkm_mask(device, 0x610490 + (chid * 0x0010), 0x00000010, 0x00000010);
	nvkm_wr32(device, 0x640000 + (chid * 0x1000), 0x00000000);
	nvkm_wr32(device, 0x610490 + (chid * 0x0010), 0x00000013);
	nvkm_wr32(device, 0x610494 + (ctrl * 0x0010), chan->push);
	nvkm_wr32(device, 0x610498 + (ctrl * 0x0010), 0x00010000);
	nvkm_wr32(device, 0x61049c + (ctrl * 0x0010), 0x00000001);
	nvkm_mask(device, 0x610490 + (ctrl * 0x0010), 0x00000010, 0x00000010);
	nvkm_wr32(device, 0x640000 + (ctrl * 0x1000), 0x00000000);
	nvkm_wr32(device, 0x610490 + (ctrl * 0x0010), 0x00000013);

	/* wait for it to go inactive */
	if (nvkm_msec(device, 2000,
		if (!(nvkm_rd32(device, 0x610490 + (chid * 0x10)) & 0x80000000))
		if (!(nvkm_rd32(device, 0x610490 + (ctrl * 0x10)) & 0x80000000))
			break;
	) < 0) {
		nvkm_error(subdev, "ch %d init: %08x\n", chid,
			   nvkm_rd32(device, 0x610490 + (chid * 0x10)));
		nvkm_error(subdev, "ch %d init: %08x\n", user,
			   nvkm_rd32(device, 0x610490 + (ctrl * 0x10)));
		return -EBUSY;
	}

+12 −11
Original line number Diff line number Diff line
@@ -32,26 +32,27 @@ gp104_disp_dmac_init(struct nv50_disp_dmac *chan)
	struct nv50_disp *disp = chan->base.root->disp;
	struct nvkm_subdev *subdev = &disp->base.engine.subdev;
	struct nvkm_device *device = subdev->device;
	int chid = chan->base.chid;
	int ctrl = chan->base.chid.ctrl;
	int user = chan->base.chid.user;

	/* enable error reporting */
	nvkm_mask(device, 0x6100a0, 0x00000001 << chid, 0x00000001 << chid);
	nvkm_mask(device, 0x6100a0, 0x00000001 << user, 0x00000001 << user);

	/* initialise channel for dma command submission */
	nvkm_wr32(device, 0x611494 + (chid * 0x0010), chan->push);
	nvkm_wr32(device, 0x611498 + (chid * 0x0010), 0x00010000);
	nvkm_wr32(device, 0x61149c + (chid * 0x0010), 0x00000001);
	nvkm_mask(device, 0x610490 + (chid * 0x0010), 0x00000010, 0x00000010);
	nvkm_wr32(device, 0x640000 + (chid * 0x1000), 0x00000000);
	nvkm_wr32(device, 0x610490 + (chid * 0x0010), 0x00000013);
	nvkm_wr32(device, 0x611494 + (ctrl * 0x0010), chan->push);
	nvkm_wr32(device, 0x611498 + (ctrl * 0x0010), 0x00010000);
	nvkm_wr32(device, 0x61149c + (ctrl * 0x0010), 0x00000001);
	nvkm_mask(device, 0x610490 + (ctrl * 0x0010), 0x00000010, 0x00000010);
	nvkm_wr32(device, 0x640000 + (ctrl * 0x1000), 0x00000000);
	nvkm_wr32(device, 0x610490 + (ctrl * 0x0010), 0x00000013);

	/* wait for it to go inactive */
	if (nvkm_msec(device, 2000,
		if (!(nvkm_rd32(device, 0x610490 + (chid * 0x10)) & 0x80000000))
		if (!(nvkm_rd32(device, 0x610490 + (ctrl * 0x10)) & 0x80000000))
			break;
	) < 0) {
		nvkm_error(subdev, "ch %d init: %08x\n", chid,
			   nvkm_rd32(device, 0x610490 + (chid * 0x10)));
		nvkm_error(subdev, "ch %d init: %08x\n", user,
			   nvkm_rd32(device, 0x610490 + (ctrl * 0x10)));
		return -EBUSY;
	}

+23 −21
Original line number Diff line number Diff line
@@ -179,9 +179,9 @@ nv50_disp_dmac_bind(struct nv50_disp_dmac *chan,
		    struct nvkm_object *object, u32 handle)
{
	return nvkm_ramht_insert(chan->base.root->ramht, object,
				 chan->base.chid, -10, handle,
				 chan->base.chid << 28 |
				 chan->base.chid);
				 chan->base.chid.user, -10, handle,
				 chan->base.chid.user << 28 |
				 chan->base.chid.user);
}

static void
@@ -190,21 +190,22 @@ nv50_disp_dmac_fini(struct nv50_disp_dmac *chan)
	struct nv50_disp *disp = chan->base.root->disp;
	struct nvkm_subdev *subdev = &disp->base.engine.subdev;
	struct nvkm_device *device = subdev->device;
	int chid = chan->base.chid;
	int ctrl = chan->base.chid.ctrl;
	int user = chan->base.chid.user;

	/* deactivate channel */
	nvkm_mask(device, 0x610200 + (chid * 0x0010), 0x00001010, 0x00001000);
	nvkm_mask(device, 0x610200 + (chid * 0x0010), 0x00000003, 0x00000000);
	nvkm_mask(device, 0x610200 + (ctrl * 0x0010), 0x00001010, 0x00001000);
	nvkm_mask(device, 0x610200 + (ctrl * 0x0010), 0x00000003, 0x00000000);
	if (nvkm_msec(device, 2000,
		if (!(nvkm_rd32(device, 0x610200 + (chid * 0x10)) & 0x001e0000))
		if (!(nvkm_rd32(device, 0x610200 + (ctrl * 0x10)) & 0x001e0000))
			break;
	) < 0) {
		nvkm_error(subdev, "ch %d fini timeout, %08x\n", chid,
			   nvkm_rd32(device, 0x610200 + (chid * 0x10)));
		nvkm_error(subdev, "ch %d fini timeout, %08x\n", user,
			   nvkm_rd32(device, 0x610200 + (ctrl * 0x10)));
	}

	/* disable error reporting and completion notifications */
	nvkm_mask(device, 0x610028, 0x00010001 << chid, 0x00000000 << chid);
	nvkm_mask(device, 0x610028, 0x00010001 << user, 0x00000000 << user);
}

static int
@@ -213,26 +214,27 @@ nv50_disp_dmac_init(struct nv50_disp_dmac *chan)
	struct nv50_disp *disp = chan->base.root->disp;
	struct nvkm_subdev *subdev = &disp->base.engine.subdev;
	struct nvkm_device *device = subdev->device;
	int chid = chan->base.chid;
	int ctrl = chan->base.chid.ctrl;
	int user = chan->base.chid.user;

	/* enable error reporting */
	nvkm_mask(device, 0x610028, 0x00010000 << chid, 0x00010000 << chid);
	nvkm_mask(device, 0x610028, 0x00010000 << user, 0x00010000 << user);

	/* initialise channel for dma command submission */
	nvkm_wr32(device, 0x610204 + (chid * 0x0010), chan->push);
	nvkm_wr32(device, 0x610208 + (chid * 0x0010), 0x00010000);
	nvkm_wr32(device, 0x61020c + (chid * 0x0010), chid);
	nvkm_mask(device, 0x610200 + (chid * 0x0010), 0x00000010, 0x00000010);
	nvkm_wr32(device, 0x640000 + (chid * 0x1000), 0x00000000);
	nvkm_wr32(device, 0x610200 + (chid * 0x0010), 0x00000013);
	nvkm_wr32(device, 0x610204 + (ctrl * 0x0010), chan->push);
	nvkm_wr32(device, 0x610208 + (ctrl * 0x0010), 0x00010000);
	nvkm_wr32(device, 0x61020c + (ctrl * 0x0010), ctrl);
	nvkm_mask(device, 0x610200 + (ctrl * 0x0010), 0x00000010, 0x00000010);
	nvkm_wr32(device, 0x640000 + (ctrl * 0x1000), 0x00000000);
	nvkm_wr32(device, 0x610200 + (ctrl * 0x0010), 0x00000013);

	/* wait for it to go inactive */
	if (nvkm_msec(device, 2000,
		if (!(nvkm_rd32(device, 0x610200 + (chid * 0x10)) & 0x80000000))
		if (!(nvkm_rd32(device, 0x610200 + (ctrl * 0x10)) & 0x80000000))
			break;
	) < 0) {
		nvkm_error(subdev, "ch %d init timeout, %08x\n", chid,
			   nvkm_rd32(device, 0x610200 + (chid * 0x10)));
		nvkm_error(subdev, "ch %d init timeout, %08x\n", user,
			   nvkm_rd32(device, 0x610200 + (ctrl * 0x10)));
		return -EBUSY;
	}

Loading