drivers/gpu/drm/imx/dcss/dcss-dtg.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/imx/dcss/dcss-dtg.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/imx/dcss/dcss-dtg.c
Extension
.c
Size
10283 bytes
Lines
392
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 dcss_dtg {
	struct device *dev;
	struct dcss_ctxld *ctxld;
	void __iomem *base_reg;
	u32 base_ofs;

	u32 ctx_id;

	bool in_use;

	u32 dis_ulc_x;
	u32 dis_ulc_y;

	u32 control_status;
	u32 alpha;
	u32 alpha_cfg;

	int ctxld_kick_irq;
	bool ctxld_kick_irq_en;
};

static void dcss_dtg_write(struct dcss_dtg *dtg, u32 val, u32 ofs)
{
	if (!dtg->in_use)
		dcss_writel(val, dtg->base_reg + ofs);

	dcss_ctxld_write(dtg->ctxld, dtg->ctx_id,
			 val, dtg->base_ofs + ofs);
}

static irqreturn_t dcss_dtg_irq_handler(int irq, void *data)
{
	struct dcss_dtg *dtg = data;
	u32 status;

	status = dcss_readl(dtg->base_reg + DCSS_DTG_INT_STATUS);

	if (!(status & LINE0_IRQ))
		return IRQ_NONE;

	dcss_ctxld_kick(dtg->ctxld);

	dcss_writel(status & LINE0_IRQ, dtg->base_reg + DCSS_DTG_INT_CONTROL);

	return IRQ_HANDLED;
}

static int dcss_dtg_irq_config(struct dcss_dtg *dtg,
			       struct platform_device *pdev)
{
	int ret;

	dtg->ctxld_kick_irq = platform_get_irq_byname(pdev, "ctxld_kick");
	if (dtg->ctxld_kick_irq < 0)
		return dtg->ctxld_kick_irq;

	dcss_update(0, LINE0_IRQ | LINE1_IRQ,
		    dtg->base_reg + DCSS_DTG_INT_MASK);

	ret = request_irq(dtg->ctxld_kick_irq, dcss_dtg_irq_handler,
			  IRQF_NO_AUTOEN, "dcss_ctxld_kick", dtg);
	if (ret) {
		dev_err(dtg->dev, "dtg: irq request failed.\n");
		return ret;
	}

	dtg->ctxld_kick_irq_en = false;

	return 0;
}

int dcss_dtg_init(struct dcss_dev *dcss, unsigned long dtg_base)
{
	int ret = 0;
	struct dcss_dtg *dtg;

	dtg = devm_kzalloc(dcss->dev, sizeof(*dtg), GFP_KERNEL);
	if (!dtg)
		return -ENOMEM;

	dcss->dtg = dtg;
	dtg->dev = dcss->dev;
	dtg->ctxld = dcss->ctxld;

	dtg->base_reg = devm_ioremap(dtg->dev, dtg_base, SZ_4K);
	if (!dtg->base_reg) {
		dev_err(dtg->dev, "dtg: unable to remap dtg base\n");
		return -ENOMEM;
	}

Annotation

Implementation Notes