drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c
Extension
.c
Size
10846 bytes
Lines
399
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 (ret) {
			RUNL_ERROR(runl, "alloc %d\n", ret);
			return ERR_PTR(ret);
		}
	} else {
		if (runl->offset + segment >= nvkm_memory_size(runl->mem)) {
			ret = runl->func->wait(runl);
			if (ret) {
				RUNL_DEBUG(runl, "rewind timeout");
				return ERR_PTR(ret);
			}

			runl->offset = 0;
		}
	}

	*offset = runl->offset;
	runl->offset += segment;
	return runl->mem;
}

int
nv50_runl_update(struct nvkm_runl *runl)
{
	struct nvkm_memory *memory;
	struct nvkm_cgrp *cgrp;
	struct nvkm_chan *chan;
	u32 start, offset, count;

	/*TODO: prio, interleaving. */

	RUNL_TRACE(runl, "RAMRL: update cgrps:%d chans:%d", runl->cgrp_nr, runl->chan_nr);
	memory = nv50_runl_alloc(runl, &start);
	if (IS_ERR(memory))
		return PTR_ERR(memory);

	RUNL_TRACE(runl, "RAMRL: update start:%08x", start);
	offset = start;

	nvkm_kmap(memory);
	nvkm_runl_foreach_cgrp(cgrp, runl) {
		if (cgrp->hw) {
			CGRP_TRACE(cgrp, "     RAMRL+%08x: chans:%d", offset, cgrp->chan_nr);
			runl->func->insert_cgrp(cgrp, memory, offset);
			offset += runl->func->size;
		}

		nvkm_cgrp_foreach_chan(chan, cgrp) {
			CHAN_TRACE(chan, "RAMRL+%08x: [%s]", offset, chan->name);
			runl->func->insert_chan(chan, memory, offset);
			offset += runl->func->size;
		}
	}
	nvkm_done(memory);

	/*TODO: look into using features on newer HW to guarantee forward progress. */
	list_rotate_left(&runl->cgrps);

	count = (offset - start) / runl->func->size;
	RUNL_TRACE(runl, "RAMRL: commit start:%08x count:%d", start, count);

	runl->func->commit(runl, memory, start, count);
	return 0;
}

const struct nvkm_runl_func
nv50_runl = {
	.size = 4,
	.update = nv50_runl_update,
	.insert_chan = nv50_runl_insert_chan,
	.commit = nv50_runl_commit,
	.wait = nv50_runl_wait,
	.pending = nv50_runl_pending,
};

void
nv50_fifo_init(struct nvkm_fifo *fifo)
{
	struct nvkm_runl *runl = nvkm_runl_first(fifo);
	struct nvkm_device *device = fifo->engine.subdev.device;
	int i;

	nvkm_mask(device, 0x000200, 0x00000100, 0x00000000);
	nvkm_mask(device, 0x000200, 0x00000100, 0x00000100);
	nvkm_wr32(device, 0x00250c, 0x6f3cfc34);
	nvkm_wr32(device, 0x002044, 0x01003fff);

	nvkm_wr32(device, 0x002100, 0xffffffff);
	nvkm_wr32(device, 0x002140, 0xbfffffff);

Annotation

Implementation Notes