Commit b8a90901 authored by Ben Skeggs's avatar Ben Skeggs Committed by Dave Airlie
Browse files

drm/nouveau/gsp: remove gsp-specific chid allocation path



In order to specify a channel ID to RM during channel allocation, the
channel ID is broken down into a "userd page" index and an index into
that page.

It was assumed that RM would enforce that the same physical block of
memory be used for all CHIDs within a "userd page", and the GSP paths
override NVKM's normal CHID allocation to handle this.

However, none of that turns out to be necessary.

Remove the GSP-specific code and use the regular CHID allocation path.

Signed-off-by: default avatarBen Skeggs <bskeggs@nvidia.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 7904bcdc
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -78,9 +78,6 @@ struct nvkm_fifo {
	struct {
		struct nvkm_memory *mem;
		struct nvkm_vma *bar1;

		struct mutex mutex;
		struct list_head list;
	} userd;

	struct {
+0 −5
Original line number Diff line number Diff line
@@ -349,8 +349,6 @@ nvkm_fifo_dtor(struct nvkm_engine *engine)
	nvkm_chid_unref(&fifo->cgid);
	nvkm_chid_unref(&fifo->chid);

	mutex_destroy(&fifo->userd.mutex);

	nvkm_event_fini(&fifo->nonstall.event);
	mutex_destroy(&fifo->mutex);

@@ -391,8 +389,5 @@ nvkm_fifo_new_(const struct nvkm_fifo_func *func, struct nvkm_device *device,
	spin_lock_init(&fifo->lock);
	mutex_init(&fifo->mutex);

	INIT_LIST_HEAD(&fifo->userd.list);
	mutex_init(&fifo->userd.mutex);

	return nvkm_engine_ctor(&nvkm_fifo, device, type, inst, true, &fifo->engine);
}
+19 −27
Original line number Diff line number Diff line
@@ -275,11 +275,7 @@ nvkm_chan_del(struct nvkm_chan **pchan)
	nvkm_gpuobj_del(&chan->ramfc);

	if (chan->cgrp) {
		if (!chan->func->id_put)
		nvkm_chid_put(chan->cgrp->runl->chid, chan->id, &chan->cgrp->lock);
		else
			chan->func->id_put(chan);

		nvkm_cgrp_unref(&chan->cgrp);
	}

@@ -441,7 +437,6 @@ nvkm_chan_new_(const struct nvkm_chan_func *func, struct nvkm_runl *runl, int ru
	}

	/* Allocate channel ID. */
	if (!chan->func->id_get) {
	chan->id = nvkm_chid_get(runl->chid, chan);
	if (chan->id >= 0) {
		if (func->userd->bar < 0) {
@@ -463,9 +458,6 @@ nvkm_chan_new_(const struct nvkm_chan_func *func, struct nvkm_runl *runl, int ru
			chan->userd.base = chan->id * chan->func->userd->size;
		}
	}
	} else {
		chan->id = chan->func->id_get(chan, userd, ouserd);
	}

	if (chan->id < 0) {
		RUNL_ERROR(runl, "!chids");
+0 −3
Original line number Diff line number Diff line
@@ -17,9 +17,6 @@ struct nvkm_cctx {
};

struct nvkm_chan_func {
	int (*id_get)(struct nvkm_chan *, struct nvkm_memory *userd, u64 ouserd);
	void (*id_put)(struct nvkm_chan *);

	const struct nvkm_chan_func_inst {
		u32 size;
		bool zero;
+0 −115
Original line number Diff line number Diff line
@@ -215,123 +215,8 @@ r535_chan_ramfc = {
	.priv = true,
};

struct r535_chan_userd {
	struct nvkm_memory *mem;
	struct nvkm_memory *map;
	int chid;
	u32 used;

	struct list_head head;
} *userd;

static void
r535_chan_id_put(struct nvkm_chan *chan)
{
	struct nvkm_runl *runl = chan->cgrp->runl;
	struct nvkm_fifo *fifo = runl->fifo;
	struct r535_chan_userd *userd;

	mutex_lock(&fifo->userd.mutex);
	list_for_each_entry(userd, &fifo->userd.list, head) {
		if (userd->map == chan->userd.mem) {
			u32 chid = chan->userd.base / chan->func->userd->size;

			userd->used &= ~BIT(chid);
			if (!userd->used) {
				nvkm_memory_unref(&userd->map);
				nvkm_memory_unref(&userd->mem);
				nvkm_chid_put(runl->chid, userd->chid, &chan->cgrp->lock);
				list_del(&userd->head);
				kfree(userd);
			}

			break;
		}
	}
	mutex_unlock(&fifo->userd.mutex);

}

static int
r535_chan_id_get_locked(struct nvkm_chan *chan, struct nvkm_memory *muserd, u64 ouserd)
{
	const u32 userd_size = CHID_PER_USERD * chan->func->userd->size;
	struct nvkm_runl *runl = chan->cgrp->runl;
	struct nvkm_fifo *fifo = runl->fifo;
	struct r535_chan_userd *userd;
	u32 chid;
	int ret;

	if (ouserd + chan->func->userd->size >= userd_size ||
	    (ouserd & (chan->func->userd->size - 1))) {
		RUNL_DEBUG(runl, "ouserd %llx", ouserd);
		return -EINVAL;
	}

	chid = div_u64(ouserd, chan->func->userd->size);

	list_for_each_entry(userd, &fifo->userd.list, head) {
		if (userd->mem == muserd) {
			if (userd->used & BIT(chid))
				return -EBUSY;
			break;
		}
	}

	if (&userd->head == &fifo->userd.list) {
		if (nvkm_memory_size(muserd) < userd_size) {
			RUNL_DEBUG(runl, "userd too small");
			return -EINVAL;
		}

		userd = kzalloc(sizeof(*userd), GFP_KERNEL);
		if (!userd)
			return -ENOMEM;

		userd->chid = nvkm_chid_get(runl->chid, chan);
		if (userd->chid < 0) {
			ret = userd->chid;
			kfree(userd);
			return ret;
		}

		userd->mem = nvkm_memory_ref(muserd);

		ret = nvkm_memory_kmap(userd->mem, &userd->map);
		if (ret) {
			nvkm_chid_put(runl->chid, userd->chid, &chan->cgrp->lock);
			kfree(userd);
			return ret;
		}


		list_add(&userd->head, &fifo->userd.list);
	}

	userd->used |= BIT(chid);

	chan->userd.mem = nvkm_memory_ref(userd->map);
	chan->userd.base = ouserd;

	return (userd->chid * CHID_PER_USERD) + chid;
}

static int
r535_chan_id_get(struct nvkm_chan *chan, struct nvkm_memory *muserd, u64 ouserd)
{
	struct nvkm_fifo *fifo = chan->cgrp->runl->fifo;
	int ret;

	mutex_lock(&fifo->userd.mutex);
	ret = r535_chan_id_get_locked(chan, muserd, ouserd);
	mutex_unlock(&fifo->userd.mutex);
	return ret;
}

static const struct nvkm_chan_func
r535_chan = {
	.id_get = r535_chan_id_get,
	.id_put = r535_chan_id_put,
	.inst = &gf100_chan_inst,
	.userd = &gv100_chan_userd,
	.ramfc = &r535_chan_ramfc,
Loading