drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
Extension
.c
Size
8791 bytes
Lines
351
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

while (len--) {
			*(u8 *)img++ = data & 0xff;
			data >>= 8;
		}
	}
}

static void
gm200_flcn_pio_dmem_rd_init(struct nvkm_falcon *falcon, u8 port, u32 dmem_base)
{
	nvkm_falcon_wr32(falcon, 0x1c0 + (port * 8), BIT(25) | dmem_base);
}

static void
gm200_flcn_pio_dmem_wr(struct nvkm_falcon *falcon, u8 port, const u8 *img, int len, u16 tag)
{
	while (len >= 4) {
		nvkm_falcon_wr32(falcon, 0x1c4 + (port * 8), *(u32 *)img);
		img += 4;
		len -= 4;
	}

	WARN_ON(len);
}

static void
gm200_flcn_pio_dmem_wr_init(struct nvkm_falcon *falcon, u8 port, bool sec, u32 dmem_base)
{
	nvkm_falcon_wr32(falcon, 0x1c0 + (port * 8), BIT(24) | dmem_base);
}

const struct nvkm_falcon_func_pio
gm200_flcn_dmem_pio = {
	.min = 1,
	.max = 0x100,
	.wr_init = gm200_flcn_pio_dmem_wr_init,
	.wr = gm200_flcn_pio_dmem_wr,
	.rd_init = gm200_flcn_pio_dmem_rd_init,
	.rd = gm200_flcn_pio_dmem_rd,
};

static void
gm200_flcn_pio_imem_wr_init(struct nvkm_falcon *falcon, u8 port, bool sec, u32 imem_base)
{
	nvkm_falcon_wr32(falcon, 0x180 + (port * 0x10), (sec ? BIT(28) : 0) | BIT(24) | imem_base);
}

static void
gm200_flcn_pio_imem_wr(struct nvkm_falcon *falcon, u8 port, const u8 *img, int len, u16 tag)
{
	nvkm_falcon_wr32(falcon, 0x188 + (port * 0x10), tag);
	while (len >= 4) {
		nvkm_falcon_wr32(falcon, 0x184 + (port * 0x10), *(u32 *)img);
		img += 4;
		len -= 4;
	}
}

const struct nvkm_falcon_func_pio
gm200_flcn_imem_pio = {
	.min = 0x100,
	.max = 0x100,
	.wr_init = gm200_flcn_pio_imem_wr_init,
	.wr = gm200_flcn_pio_imem_wr,
};

int
gm200_flcn_bind_stat(struct nvkm_falcon *falcon, bool intr)
{
	if (intr && !(nvkm_falcon_rd32(falcon, 0x008) & 0x00000008))
		return -1;

	return (nvkm_falcon_rd32(falcon, 0x0dc) & 0x00007000) >> 12;
}

void
gm200_flcn_bind_inst(struct nvkm_falcon *falcon, int target, u64 addr)
{
	nvkm_falcon_mask(falcon, 0x604, 0x00000007, 0x00000000); /* DMAIDX_VIRT */
	nvkm_falcon_wr32(falcon, 0x054, (1 << 30) | (target << 28) | (addr >> 12));
	nvkm_falcon_mask(falcon, 0x090, 0x00010000, 0x00010000);
	nvkm_falcon_mask(falcon, 0x0a4, 0x00000008, 0x00000008);
}

int
gm200_flcn_reset_wait_mem_scrubbing(struct nvkm_falcon *falcon)
{
	nvkm_falcon_mask(falcon, 0x040, 0x00000000, 0x00000000);

	if (nvkm_msec(falcon->owner->device, 10,

Annotation

Implementation Notes