drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c
Extension
.c
Size
8530 bytes
Lines
360
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 (pgsize_bitmap & PAGE_SIZE) {
			tdev->iommu.pgshift = PAGE_SHIFT;
		} else {
			tdev->iommu.pgshift = fls(pgsize_bitmap & ~PAGE_MASK);
			if (tdev->iommu.pgshift == 0) {
				dev_warn(dev, "unsupported IOMMU page size\n");
				goto free_domain;
			}
			tdev->iommu.pgshift -= 1;
		}

		ret = iommu_attach_device(tdev->iommu.domain, dev);
		if (ret)
			goto free_domain;

		ret = nvkm_mm_init(&tdev->iommu.mm, 0, 0,
				   (1ULL << tdev->func->iommu_bit) >>
				   tdev->iommu.pgshift, 1);
		if (ret)
			goto detach_device;
	}

	return;

detach_device:
	iommu_detach_device(tdev->iommu.domain, dev);

free_domain:
	iommu_domain_free(tdev->iommu.domain);

error:
	tdev->iommu.domain = NULL;
	tdev->iommu.pgshift = 0;
	dev_err(dev, "cannot initialize IOMMU MM\n");
#endif
}

static void
nvkm_device_tegra_remove_iommu(struct nvkm_device_tegra *tdev)
{
#if IS_ENABLED(CONFIG_IOMMU_API)
	if (tdev->iommu.domain) {
		nvkm_mm_fini(&tdev->iommu.mm);
		iommu_detach_device(tdev->iommu.domain, tdev->device.dev);
		iommu_domain_free(tdev->iommu.domain);
	}
#endif
}

static struct nvkm_device_tegra *
nvkm_device_tegra(struct nvkm_device *device)
{
	return container_of(device, struct nvkm_device_tegra, device);
}

static struct resource *
nvkm_device_tegra_resource(struct nvkm_device *device, enum nvkm_bar_id bar)
{
	struct nvkm_device_tegra *tdev = nvkm_device_tegra(device);
	int idx;

	switch (bar) {
	case NVKM_BAR0_PRI: idx = 0; break;
	case NVKM_BAR1_FB : idx = 1; break;
	default:
		WARN_ON(1);
		return NULL;
	}

	return platform_get_resource(tdev->pdev, IORESOURCE_MEM, idx);
}

static resource_size_t
nvkm_device_tegra_resource_addr(struct nvkm_device *device, enum nvkm_bar_id bar)
{
	struct resource *res = nvkm_device_tegra_resource(device, bar);
	return res ? res->start : 0;
}

static resource_size_t
nvkm_device_tegra_resource_size(struct nvkm_device *device, enum nvkm_bar_id bar)
{
	struct resource *res = nvkm_device_tegra_resource(device, bar);
	return res ? resource_size(res) : 0;
}

static int
nvkm_device_tegra_irq(struct nvkm_device *device)
{
	struct nvkm_device_tegra *tdev = nvkm_device_tegra(device);

Annotation

Implementation Notes