drivers/gpu/drm/nouveau/nvkm/core/ramht.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/nouveau/nvkm/core/ramht.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/nouveau/nvkm/core/ramht.c
Extension
.c
Size
4102 bytes
Lines
163
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (ramht->data[co].chid == chid) {
			if (ramht->data[co].handle == handle)
				return ramht->data[co].inst;
		}

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

	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) {
		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;
		}

		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)
{
	if (--cookie >= 0)
		nvkm_ramht_update(ramht, cookie, NULL, -1, 0, 0, 0);
}

int
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);
		vfree(*pramht);
		*pramht = NULL;

Annotation

Implementation Notes