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

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c
Extension
.c
Size
21708 bytes
Lines
834
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

struct gk104_engn_status {
	bool busy;
	bool faulted;
	bool chsw;
	bool save;
	bool load;
	struct {
		bool tsg;
		u32 id;
	} prev, next, *chan;
};

static void
gk104_engn_status(struct nvkm_engn *engn, struct gk104_engn_status *status)
{
	u32 stat = nvkm_rd32(engn->runl->fifo->engine.subdev.device, 0x002640 + (engn->id * 0x08));

	status->busy     = !!(stat & 0x80000000);
	status->faulted  = !!(stat & 0x40000000);
	status->next.tsg = !!(stat & 0x10000000);
	status->next.id  =   (stat & 0x0fff0000) >> 16;
	status->chsw     = !!(stat & 0x00008000);
	status->save     = !!(stat & 0x00004000);
	status->load     = !!(stat & 0x00002000);
	status->prev.tsg = !!(stat & 0x00001000);
	status->prev.id  =   (stat & 0x00000fff);
	status->chan     = NULL;

	if (status->busy && status->chsw) {
		if (status->load && status->save) {
			if (nvkm_engine_chsw_load(engn->engine))
				status->chan = &status->next;
			else
				status->chan = &status->prev;
		} else
		if (status->load) {
			status->chan = &status->next;
		} else {
			status->chan = &status->prev;
		}
	} else
	if (status->load) {
		status->chan = &status->prev;
	}

	ENGN_DEBUG(engn, "%08x: busy %d faulted %d chsw %d save %d load %d %sid %d%s-> %sid %d%s",
		   stat, status->busy, status->faulted, status->chsw, status->save, status->load,
		   status->prev.tsg ? "tsg" : "ch", status->prev.id,
		   status->chan == &status->prev ? "*" : " ",
		   status->next.tsg ? "tsg" : "ch", status->next.id,
		   status->chan == &status->next ? "*" : " ");
}

int
gk104_engn_cxid(struct nvkm_engn *engn, bool *cgid)
{
	struct gk104_engn_status status;

	gk104_engn_status(engn, &status);
	if (status.chan) {
		*cgid = status.chan->tsg;
		return status.chan->id;
	}

	return -ENODEV;
}

bool
gk104_engn_chsw(struct nvkm_engn *engn)
{
	struct gk104_engn_status status;

	gk104_engn_status(engn, &status);
	if (status.busy && status.chsw)
		return true;

	return false;
}

const struct nvkm_engn_func
gk104_engn = {
	.chsw = gk104_engn_chsw,
	.cxid = gk104_engn_cxid,
	.mmu_fault_trigger = gf100_engn_mmu_fault_trigger,
	.mmu_fault_triggered = gf100_engn_mmu_fault_triggered,
	.ctor = gk104_ectx_ctor,
	.bind = gk104_ectx_bind,
};

const struct nvkm_engn_func

Annotation

Implementation Notes