drivers/gpu/drm/tegra/nvjpg.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/tegra/nvjpg.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/tegra/nvjpg.c
Extension
.c
Size
7530 bytes
Lines
331
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

struct nvjpg_config {
	const char *firmware;
	unsigned int version;
};

struct nvjpg {
	struct falcon falcon;

	void __iomem *regs;
	struct tegra_drm_client client;
	struct device *dev;
	struct clk *clk;

	/* Platform configuration */
	const struct nvjpg_config *config;
};

static inline struct nvjpg *to_nvjpg(struct tegra_drm_client *client)
{
	return container_of(client, struct nvjpg, client);
}

static int nvjpg_init(struct host1x_client *client)
{
	struct tegra_drm_client *drm = host1x_to_drm_client(client);
	struct drm_device *dev = dev_get_drvdata(client->host);
	struct tegra_drm *tegra = dev->dev_private;
	struct nvjpg *nvjpg = to_nvjpg(drm);
	int err;

	err = host1x_client_iommu_attach(client);
	if (err < 0 && err != -ENODEV) {
		dev_err(nvjpg->dev, "failed to attach to domain: %d\n", err);
		return err;
	}

	err = tegra_drm_register_client(tegra, drm);
	if (err < 0)
		goto detach;

	/*
	 * Inherit the DMA parameters (such as maximum segment size) from the
	 * parent host1x device.
	 */
	client->dev->dma_parms = client->host->dma_parms;

	return 0;

detach:
	host1x_client_iommu_detach(client);

	return err;
}

static int nvjpg_exit(struct host1x_client *client)
{
	struct tegra_drm_client *drm = host1x_to_drm_client(client);
	struct drm_device *dev = dev_get_drvdata(client->host);
	struct tegra_drm *tegra = dev->dev_private;
	struct nvjpg *nvjpg = to_nvjpg(drm);
	int err;

	/* avoid a dangling pointer just in case this disappears */
	client->dev->dma_parms = NULL;

	err = tegra_drm_unregister_client(tegra, drm);
	if (err < 0)
		return err;

	pm_runtime_dont_use_autosuspend(client->dev);
	pm_runtime_force_suspend(client->dev);

	host1x_client_iommu_detach(client);

	if (client->group) {
		dma_unmap_single(nvjpg->dev, nvjpg->falcon.firmware.phys,
				 nvjpg->falcon.firmware.size, DMA_TO_DEVICE);
		tegra_drm_free(tegra, nvjpg->falcon.firmware.size,
			       nvjpg->falcon.firmware.virt,
			       nvjpg->falcon.firmware.iova);
	} else {
		dma_free_coherent(nvjpg->dev, nvjpg->falcon.firmware.size,
				  nvjpg->falcon.firmware.virt,
				  nvjpg->falcon.firmware.iova);
	}

	return 0;
}

static const struct host1x_client_ops nvjpg_client_ops = {

Annotation

Implementation Notes