drivers/gpu/drm/nouveau/nvkm/subdev/acr/base.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/nouveau/nvkm/subdev/acr/base.c
Extension
.c
Size
10622 bytes
Lines
447
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

list_for_each_entry(lsf, &acr->lsf, head) {
			if (lsf->func->bootstrap_falcon)
				return lsf;
		}
	}

	return NULL;
}

static void
nvkm_acr_unload(struct nvkm_acr *acr)
{
	if (acr->done) {
		if (acr->rtos) {
			nvkm_subdev_unref(acr->rtos->falcon->owner);
			acr->rtos = NULL;
		}

		nvkm_acr_hsfw_boot(acr, "unload");
		acr->done = false;
	}
}

static int
nvkm_acr_load(struct nvkm_acr *acr)
{
	struct nvkm_subdev *subdev = &acr->subdev;
	struct nvkm_acr_lsf *rtos = nvkm_acr_rtos(acr);
	u64 start, limit;
	int ret;

	if (list_empty(&acr->lsf)) {
		nvkm_debug(subdev, "No LSF(s) present.\n");
		return 0;
	}

	ret = acr->func->init(acr);
	if (ret)
		return ret;

	acr->func->wpr_check(acr, &start, &limit);

	if (start != acr->wpr_start || limit != acr->wpr_end) {
		nvkm_error(subdev, "WPR not configured as expected: "
				   "%016llx-%016llx vs %016llx-%016llx\n",
			   acr->wpr_start, acr->wpr_end, start, limit);
		return -EIO;
	}

	acr->done = true;

	if (rtos) {
		ret = nvkm_subdev_ref(rtos->falcon->owner);
		if (ret)
			return ret;

		acr->rtos = rtos;
	}

	return ret;
}

static int
nvkm_acr_reload(struct nvkm_acr *acr)
{
	nvkm_acr_unload(acr);
	return nvkm_acr_load(acr);
}

int
nvkm_acr_bootstrap_falcons(struct nvkm_device *device, unsigned long mask)
{
	struct nvkm_acr *acr = device->acr;
	struct nvkm_acr_lsf *rtos = nvkm_acr_rtos(acr);
	unsigned long id;

	/* If there's no LS FW managing bootstrapping of other LS falcons,
	 * we depend on the HS firmware being able to do it instead.
	 */
	if (!rtos) {
		/* Which isn't possible everywhere... */
		if ((mask & acr->func->bootstrap_falcons) == mask) {
			int ret = nvkm_acr_reload(acr);
			if (ret)
				return ret;

			return acr->done ? 0 : -EINVAL;
		}
		return -ENOSYS;
	}

Annotation

Implementation Notes