drivers/gpu/drm/tegra/nvdec.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/tegra/nvdec.c
Extension
.c
Size
13591 bytes
Lines
579
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 nvdec_config {
	const char *firmware;
	unsigned int version;
	bool supports_sid;
	bool has_riscv;
	bool has_extra_clocks;
};

struct nvdec {
	struct falcon falcon;

	void __iomem *regs;
	struct tegra_drm_client client;
	struct host1x_channel *channel;
	struct device *dev;
	struct clk_bulk_data clks[3];
	unsigned int num_clks;
	struct reset_control *reset;

	/* Platform configuration */
	const struct nvdec_config *config;

	/* RISC-V specific data */
	struct tegra_drm_riscv riscv;
	phys_addr_t carveout_base;
};

static inline struct nvdec *to_nvdec(struct tegra_drm_client *client)
{
	return container_of(client, struct nvdec, client);
}

static inline void nvdec_writel(struct nvdec *nvdec, u32 value,
				unsigned int offset)
{
	writel(value, nvdec->regs + offset);
}

static int nvdec_boot_falcon(struct nvdec *nvdec)
{
	u32 stream_id;
	int err;

	if (nvdec->config->supports_sid && tegra_dev_iommu_get_stream_id(nvdec->dev, &stream_id)) {
		u32 value;

		value = TRANSCFG_ATT(1, TRANSCFG_SID_FALCON) | TRANSCFG_ATT(0, TRANSCFG_SID_HW);
		nvdec_writel(nvdec, value, NVDEC_TFBIF_TRANSCFG);

		nvdec_writel(nvdec, stream_id, VIC_THI_STREAMID0);
		nvdec_writel(nvdec, stream_id, VIC_THI_STREAMID1);
	}

	err = falcon_boot(&nvdec->falcon);
	if (err < 0)
		return err;

	err = falcon_wait_idle(&nvdec->falcon);
	if (err < 0) {
		dev_err(nvdec->dev, "falcon boot timed out\n");
		return err;
	}

	return 0;
}

static int nvdec_wait_debuginfo(struct nvdec *nvdec, const char *phase)
{
	int err;
	u32 val;

	err = readl_poll_timeout(nvdec->regs + NVDEC_FALCON_DEBUGINFO, val, val == 0x0, 10, 100000);
	if (err) {
		dev_err(nvdec->dev, "failed to boot %s, debuginfo=0x%x\n", phase, val);
		return err;
	}

	return 0;
}

static int nvdec_boot_riscv(struct nvdec *nvdec)
{
	int err;

	err = reset_control_acquire(nvdec->reset);
	if (err)
		return err;

	nvdec_writel(nvdec, 0xabcd1234, NVDEC_FALCON_DEBUGINFO);

Annotation

Implementation Notes