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

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/nouveau/nvkm/falcon/fw.c
Extension
.c
Size
9406 bytes
Lines
364
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 (nvkm_printk_ok(falcon->owner, falcon->user, NV_DBG_TRACE)) {
			if (i % 8 == 0)
				printk(KERN_INFO "sig -> %08x:", dst);
			printk(KERN_CONT " %08x", sig);
		}

		*(u32 *)(fw->fw.img + dst) = sig;
		src += 4;
		dst += 4;
	}

	return 0;
}

static void
nvkm_falcon_fw_dtor_sigs(struct nvkm_falcon_fw *fw)
{
	kfree(fw->sigs);
	fw->sigs = NULL;
}

int
nvkm_falcon_fw_boot(struct nvkm_falcon_fw *fw, struct nvkm_subdev *user,
		    bool release, u32 *pmbox0, u32 *pmbox1, u32 mbox0_ok, u32 irqsclr)
{
	struct nvkm_falcon *falcon = fw->falcon;
	int ret;

	ret = nvkm_falcon_get(falcon, user);
	if (ret)
		return ret;

	if (fw->sigs) {
		ret = nvkm_falcon_fw_patch(fw);
		if (ret)
			goto done;

		nvkm_falcon_fw_dtor_sigs(fw);
	}


	FLCNFW_DBG(fw, "resetting");
	fw->func->reset(fw);

	FLCNFW_DBG(fw, "loading");
	if (fw->func->setup) {
		ret = fw->func->setup(fw);
		if (ret)
			goto done;
	}

	/* after last write to the img, sync dma mappings */
	dma_sync_single_for_device(fw->fw.device->dev,
				   fw->fw.phys,
				   sg_dma_len(&fw->fw.mem.sgl),
				   DMA_TO_DEVICE);

	ret = fw->func->load(fw);
	if (ret)
		goto done;

	FLCNFW_DBG(fw, "booting");
	ret = fw->func->boot(fw, pmbox0, pmbox1, mbox0_ok, irqsclr);
	if (ret)
		FLCNFW_ERR(fw, "boot failed: %d", ret);
	else
		FLCNFW_DBG(fw, "booted");

done:
	if (ret || release)
		nvkm_falcon_put(falcon, user);
	return ret;
}

int
nvkm_falcon_fw_oneinit(struct nvkm_falcon_fw *fw, struct nvkm_falcon *falcon,
		       struct nvkm_vmm *vmm, struct nvkm_memory *inst)
{
	int ret;

	fw->falcon = falcon;
	fw->vmm = nvkm_vmm_ref(vmm);
	fw->inst = nvkm_memory_ref(inst);

	if (fw->boot) {
		FLCN_DBG(falcon, "mapping %s fw", fw->fw.name);
		ret = nvkm_vmm_get(fw->vmm, 12, nvkm_memory_size(&fw->fw.mem.memory), &fw->vma);
		if (ret) {
			FLCN_ERR(falcon, "get %d", ret);
			return ret;

Annotation

Implementation Notes