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

Commit 1d2a1e53 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/ramht: remove dependence on namedb



Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent f027f491
Loading
Loading
Loading
Loading
+18 −10
Original line number Diff line number Diff line
@@ -2,19 +2,27 @@
#define __NVKM_RAMHT_H__
#include <core/gpuobj.h>

struct nvkm_ramht_data {
	struct nvkm_gpuobj *inst;
	int chid;
	u32 handle;
};

struct nvkm_ramht {
	struct nvkm_gpuobj gpuobj;
	struct nvkm_device *device;
	struct nvkm_gpuobj *parent;
	struct nvkm_gpuobj *gpuobj;
	int size;
	int bits;
	struct nvkm_ramht_data data[];
};

int  nvkm_ramht_insert(struct nvkm_ramht *, int chid, u32 handle, u32 context);
int  nvkm_ramht_new(struct nvkm_device *, u32 size, u32 align,
		    struct nvkm_gpuobj *, struct nvkm_ramht **);
void nvkm_ramht_del(struct nvkm_ramht **);
int  nvkm_ramht_insert(struct nvkm_ramht *, struct nvkm_object *,
		       int chid, int addr, u32 handle, u32 context);
void nvkm_ramht_remove(struct nvkm_ramht *, int cookie);
int  nvkm_ramht_new(struct nvkm_object *, struct nvkm_object *, u32 size,
		    u32 align, struct nvkm_ramht **);

static inline void
nvkm_ramht_ref(struct nvkm_ramht *obj, struct nvkm_ramht **ref)
{
	nvkm_gpuobj_ref(&obj->gpuobj, (struct nvkm_gpuobj **)ref);
}
struct nvkm_gpuobj *
nvkm_ramht_search(struct nvkm_ramht *, int chid, u32 handle);
#endif
+113 −44
Original line number Diff line number Diff line
@@ -33,74 +33,143 @@ nvkm_ramht_hash(struct nvkm_ramht *ramht, int chid, u32 handle)
	}

	hash ^= chid << (ramht->bits - 4);
	hash  = hash << 3;
	return hash;
}

int
nvkm_ramht_insert(struct nvkm_ramht *ramht, int chid, u32 handle, u32 context)
struct nvkm_gpuobj *
nvkm_ramht_search(struct nvkm_ramht *ramht, int chid, u32 handle)
{
	struct nvkm_gpuobj *gpuobj = &ramht->gpuobj;
	int ret = -ENOSPC;
	u32 co, ho;

	co = ho = nvkm_ramht_hash(ramht, chid, handle);
	nvkm_kmap(gpuobj);
	do {
		if (!nvkm_ro32(gpuobj, co + 4)) {
			nvkm_wo32(gpuobj, co + 0, handle);
			nvkm_wo32(gpuobj, co + 4, context);
			ret = co;
			break;
		if (ramht->data[co].chid == chid) {
			if (ramht->data[co].handle == handle)
				return ramht->data[co].inst;
		}

		co += 8;
		if (co >= nv_gpuobj(ramht)->size)
		if (++co >= ramht->size)
			co = 0;
	} while (co != ho);
	nvkm_done(gpuobj);

	return NULL;
}

static int
nvkm_ramht_update(struct nvkm_ramht *ramht, int co, struct nvkm_object *object,
		  int chid, int addr, u32 handle, u32 context)
{
	struct nvkm_ramht_data *data = &ramht->data[co];
	u64 inst = 0x00000040; /* just non-zero for <=g8x fifo ramht */
	int ret;

	nvkm_gpuobj_del(&data->inst);
	data->chid = chid;
	data->handle = handle;

	if (!object) {
		inst = 0;
		goto done;
	}

	if (nv_iclass(object, NV_GPUOBJ_CLASS)) {
		struct nvkm_gpuobj *gpuobj = nv_gpuobj(object);
		if (ramht->device->card_type >= NV_50)
			inst = gpuobj->node->offset;
		else
			inst = gpuobj->addr;
		goto done;
	}

	ret = nvkm_object_bind(object, ramht->parent, 16, &data->inst);
	if (ret) {
		if (ret != -ENODEV) {
			data->chid = -1;
			return ret;
		}
		data->inst = NULL;
	}

	if (data->inst) {
		if (ramht->device->card_type >= NV_50)
			inst = data->inst->node->offset;
		else
			inst = data->inst->addr;
	}

done:
	if (addr < 0) context |= inst << -addr;
	else          context |= inst >>  addr;

	nvkm_kmap(ramht->gpuobj);
	nvkm_wo32(ramht->gpuobj, (co << 3) + 0, handle);
	nvkm_wo32(ramht->gpuobj, (co << 3) + 4, context);
	nvkm_done(ramht->gpuobj);
	return co + 1;
}

void
nvkm_ramht_remove(struct nvkm_ramht *ramht, int cookie)
{
	struct nvkm_gpuobj *gpuobj = &ramht->gpuobj;
	nvkm_kmap(gpuobj);
	nvkm_wo32(gpuobj, cookie + 0, 0x00000000);
	nvkm_wo32(gpuobj, cookie + 4, 0x00000000);
	nvkm_done(gpuobj);
}

static struct nvkm_oclass
nvkm_ramht_oclass = {
	.handle = 0x0000abcd,
	.ofuncs = &(struct nvkm_ofuncs) {
		.ctor = NULL,
		.dtor = _nvkm_gpuobj_dtor,
		.init = _nvkm_gpuobj_init,
		.fini = _nvkm_gpuobj_fini,
		.rd32 = _nvkm_gpuobj_rd32,
		.wr32 = _nvkm_gpuobj_wr32,
	},
};
	if (--cookie >= 0)
		nvkm_ramht_update(ramht, cookie, NULL, -1, 0, 0, 0);
}

int
nvkm_ramht_new(struct nvkm_object *parent, struct nvkm_object *pargpu,
	       u32 size, u32 align, struct nvkm_ramht **pramht)
nvkm_ramht_insert(struct nvkm_ramht *ramht, struct nvkm_object *object,
		  int chid, int addr, u32 handle, u32 context)
{
	u32 co, ho;

	if (nvkm_ramht_search(ramht, chid, handle))
		return -EEXIST;

	co = ho = nvkm_ramht_hash(ramht, chid, handle);
	do {
		if (ramht->data[co].chid < 0) {
			return nvkm_ramht_update(ramht, co, object, chid,
						 addr, handle, context);
		}

		if (++co >= ramht->size)
			co = 0;
	} while (co != ho);

	return -ENOSPC;
}

void
nvkm_ramht_del(struct nvkm_ramht **pramht)
{
	struct nvkm_ramht *ramht = *pramht;
	if (ramht) {
		nvkm_gpuobj_del(&ramht->gpuobj);
		kfree(*pramht);
		*pramht = NULL;
	}
}

int
nvkm_ramht_new(struct nvkm_device *device, u32 size, u32 align,
	       struct nvkm_gpuobj *parent, struct nvkm_ramht **pramht)
{
	struct nvkm_ramht *ramht;
	int ret;
	int ret, i;

	if (!(ramht = *pramht = kzalloc(sizeof(*ramht) + (size >> 3) *
					sizeof(*ramht->data), GFP_KERNEL)))
		return -ENOMEM;

	ret = nvkm_gpuobj_create(parent, parent->engine ?
				 &parent->engine->subdev.object : NULL, /* <nv50 ramht */
				 &nvkm_ramht_oclass, 0, pargpu, size,
				 align, NVOBJ_FLAG_ZERO_ALLOC, &ramht);
	*pramht = ramht;
	ramht->device = device;
	ramht->parent = parent;
	ramht->size = size >> 3;
	ramht->bits = order_base_2(ramht->size);
	for (i = 0; i < ramht->size; i++)
		ramht->data[i].chid = -1;

	ret = nvkm_gpuobj_new(ramht->device, size, align, true,
			      ramht->parent, &ramht->gpuobj);
	if (ret)
		nvkm_ramht_del(pramht);
	return ret;

	ramht->bits = order_base_2(nv_gpuobj(ramht)->size >> 3);
	return 0;
}
+1 −1
Original line number Diff line number Diff line
@@ -80,7 +80,7 @@ gf110_disp_dmac_object_attach(struct nvkm_object *parent,
	struct nv50_disp_chan *chan = (void *)parent;
	u32 addr = nv_gpuobj(object)->node->offset;
	u32 data = (chan->chid << 27) | (addr << 9) | 0x00000001;
	return nvkm_ramht_insert(base->ramht, chan->chid, name, data);
	return nvkm_ramht_insert(base->ramht, NULL, chan->chid, 0, name, data);
}

static void
+6 −5
Original line number Diff line number Diff line
@@ -193,7 +193,7 @@ nv50_disp_dmac_object_attach(struct nvkm_object *parent,
	u32 addr = nv_gpuobj(object)->node->offset;
	u32 chid = chan->chid;
	u32 data = (chid << 28) | (addr << 10) | chid;
	return nvkm_ramht_insert(base->ramht, chid, name, data);
	return nvkm_ramht_insert(base->ramht, NULL, chid, 0, name, data);
}

static void
@@ -1153,6 +1153,8 @@ nv50_disp_main_ctor(struct nvkm_object *parent,
{
	struct nv50_disp *disp = (void *)engine;
	struct nv50_disp_base *base;
	struct nvkm_device *device = disp->base.engine.subdev.device;
	struct nvkm_gpuobj *instmem = (void *)parent;
	int ret;

	ret = nvkm_parent_create(parent, engine, oclass, 0,
@@ -1161,15 +1163,14 @@ nv50_disp_main_ctor(struct nvkm_object *parent,
	if (ret)
		return ret;

	return nvkm_ramht_new(nv_object(base), nv_object(base), 0x1000, 0,
			      &base->ramht);
	return nvkm_ramht_new(device, 0x1000, 0, instmem, &base->ramht);
}

void
nv50_disp_main_dtor(struct nvkm_object *object)
{
	struct nv50_disp_base *base = (void *)object;
	nvkm_ramht_ref(NULL, &base->ramht);
	nvkm_ramht_del(&base->ramht);
	nvkm_parent_destroy(&base->base);
}

@@ -1235,7 +1236,7 @@ nv50_disp_main_init(struct nvkm_object *object)
	}

	/* point at display engine memory area (hash table, objects) */
	nvkm_wr32(device, 0x610010, (nv_gpuobj(base->ramht)->addr >> 8) | 9);
	nvkm_wr32(device, 0x610010, (base->ramht->gpuobj->addr >> 8) | 9);

	/* enable supervisor interrupts, disable everything else */
	nvkm_wr32(device, 0x61002c, 0x00000370);
+7 −5
Original line number Diff line number Diff line
@@ -161,7 +161,7 @@ g84_fifo_object_attach(struct nvkm_object *parent,
		}
	}

	return nvkm_ramht_insert(chan->ramht, 0, handle, context);
	return nvkm_ramht_insert(chan->ramht, NULL, 0, 0, handle, context);
}

static int
@@ -172,6 +172,7 @@ g84_fifo_chan_ctor_dma(struct nvkm_object *parent, struct nvkm_object *engine,
	union {
		struct nv50_channel_dma_v0 v0;
	} *args = data;
	struct nvkm_device *device = parent->engine->subdev.device;
	struct nv50_fifo_base *base = (void *)parent;
	struct nv50_fifo_chan *chan;
	int ret;
@@ -208,7 +209,7 @@ g84_fifo_chan_ctor_dma(struct nvkm_object *parent, struct nvkm_object *engine,

	args->v0.chid = chan->base.chid;

	ret = nvkm_ramht_new(nv_object(chan), nv_object(chan), 0x8000, 16,
	ret = nvkm_ramht_new(device, 0x8000, 16, &base->base.gpuobj,
			     &chan->ramht);
	if (ret)
		return ret;
@@ -232,7 +233,7 @@ g84_fifo_chan_ctor_dma(struct nvkm_object *parent, struct nvkm_object *engine,
	nvkm_wo32(base->ramfc, 0x7c, 0x30000001);
	nvkm_wo32(base->ramfc, 0x80, ((chan->ramht->bits - 9) << 27) |
				     (4 << 24) /* SEARCH_FULL */ |
				     (chan->ramht->gpuobj.node->offset >> 4));
				     (chan->ramht->gpuobj->node->offset >> 4));
	nvkm_wo32(base->ramfc, 0x88, base->cache->addr >> 10);
	nvkm_wo32(base->ramfc, 0x98, nv_gpuobj(base)->addr >> 12);
	nvkm_done(base->ramfc);
@@ -247,6 +248,7 @@ g84_fifo_chan_ctor_ind(struct nvkm_object *parent, struct nvkm_object *engine,
	union {
		struct nv50_channel_gpfifo_v0 v0;
	} *args = data;
	struct nvkm_device *device = parent->engine->subdev.device;
	struct nv50_fifo_base *base = (void *)parent;
	struct nv50_fifo_chan *chan;
	u64 ioffset, ilength;
@@ -285,7 +287,7 @@ g84_fifo_chan_ctor_ind(struct nvkm_object *parent, struct nvkm_object *engine,

	args->v0.chid = chan->base.chid;

	ret = nvkm_ramht_new(nv_object(chan), nv_object(chan), 0x8000, 16,
	ret = nvkm_ramht_new(device, 0x8000, 16, &base->base.gpuobj,
			     &chan->ramht);
	if (ret)
		return ret;
@@ -309,7 +311,7 @@ g84_fifo_chan_ctor_ind(struct nvkm_object *parent, struct nvkm_object *engine,
	nvkm_wo32(base->ramfc, 0x7c, 0x30000001);
	nvkm_wo32(base->ramfc, 0x80, ((chan->ramht->bits - 9) << 27) |
				     (4 << 24) /* SEARCH_FULL */ |
				     (chan->ramht->gpuobj.node->offset >> 4));
				     (chan->ramht->gpuobj->node->offset >> 4));
	nvkm_wo32(base->ramfc, 0x88, base->cache->addr >> 10);
	nvkm_wo32(base->ramfc, 0x98, nv_gpuobj(base)->addr >> 12);
	nvkm_done(base->ramfc);
Loading