drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c
Extension
.c
Size
56328 bytes
Lines
2348
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 (init->outp) {
			conn = init->outp->connector;
			conn = nvbios_connEp(bios, conn, &ver, &hdr, &connE);
			if (conn)
				return connE.type;
		}

		error("script needs connector type\n");
	}

	return 0xff;
}

static inline u32
init_nvreg(struct nvbios_init *init, u32 reg)
{
	struct nvkm_devinit *devinit = init->subdev->device->devinit;

	/* C51 (at least) sometimes has the lower bits set which the VBIOS
	 * interprets to mean that access needs to go through certain IO
	 * ports instead.  The NVIDIA binary driver has been seen to access
	 * these through the NV register address, so lets assume we can
	 * do the same
	 */
	reg &= ~0x00000003;

	/* GF8+ display scripts need register addresses mangled a bit to
	 * select a specific CRTC/OR
	 */
	if (init->subdev->device->card_type >= NV_50) {
		if (reg & 0x80000000) {
			reg += init_head(init) * 0x800;
			reg &= ~0x80000000;
		}

		if (reg & 0x40000000) {
			reg += init_or(init) * 0x800;
			reg &= ~0x40000000;
			if (reg & 0x20000000) {
				reg += init_link(init) * 0x80;
				reg &= ~0x20000000;
			}
		}
	}

	if (reg & ~0x00fffffc)
		warn("unknown bits in register 0x%08x\n", reg);

	return nvkm_devinit_mmio(devinit, reg);
}

static u32
init_rd32(struct nvbios_init *init, u32 reg)
{
	struct nvkm_device *device = init->subdev->device;
	reg = init_nvreg(init, reg);
	if (reg != ~0 && init_exec(init))
		return nvkm_rd32(device, reg);
	return 0x00000000;
}

static void
init_wr32(struct nvbios_init *init, u32 reg, u32 val)
{
	struct nvkm_device *device = init->subdev->device;
	reg = init_nvreg(init, reg);
	if (reg != ~0 && init_exec(init))
		nvkm_wr32(device, reg, val);
}

static u32
init_mask(struct nvbios_init *init, u32 reg, u32 mask, u32 val)
{
	struct nvkm_device *device = init->subdev->device;
	reg = init_nvreg(init, reg);
	if (reg != ~0 && init_exec(init)) {
		u32 tmp = nvkm_rd32(device, reg);
		nvkm_wr32(device, reg, (tmp & ~mask) | val);
		return tmp;
	}
	return 0x00000000;
}

static u8
init_rdport(struct nvbios_init *init, u16 port)
{
	if (init_exec(init))
		return nvkm_rdport(init->subdev->device, init->head, port);
	return 0x00;
}

Annotation

Implementation Notes