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

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/imx/dcss/dcss-dpr.c
Extension
.c
Size
13069 bytes
Lines
548
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_dpr_ch {
	struct dcss_dpr *dpr;
	void __iomem *base_reg;
	u32 base_ofs;

	struct drm_format_info format;
	enum dcss_pix_size pix_size;
	enum dcss_tile_type tile;
	bool rtram_4line_en;
	bool rtram_3buf_en;

	u32 frame_ctrl;
	u32 mode_ctrl;
	u32 sys_ctrl;
	u32 rtram_ctrl;

	bool sys_ctrl_chgd;

	int ch_num;
	int irq;
};

struct dcss_dpr {
	struct device *dev;
	struct dcss_ctxld *ctxld;
	u32  ctx_id;

	struct dcss_dpr_ch ch[3];
};

static void dcss_dpr_write(struct dcss_dpr_ch *ch, u32 val, u32 ofs)
{
	struct dcss_dpr *dpr = ch->dpr;

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

static int dcss_dpr_ch_init_all(struct dcss_dpr *dpr, unsigned long dpr_base)
{
	struct dcss_dpr_ch *ch;
	int i;

	for (i = 0; i < 3; i++) {
		ch = &dpr->ch[i];

		ch->base_ofs = dpr_base + i * 0x1000;

		ch->base_reg = devm_ioremap(dpr->dev, ch->base_ofs, SZ_4K);
		if (!ch->base_reg) {
			dev_err(dpr->dev, "dpr: unable to remap ch %d base\n",
				i);
			return -ENOMEM;
		}

		ch->dpr = dpr;
		ch->ch_num = i;

		dcss_writel(0xff, ch->base_reg + DCSS_DPR_IRQ_MASK);
	}

	return 0;
}

int dcss_dpr_init(struct dcss_dev *dcss, unsigned long dpr_base)
{
	struct dcss_dpr *dpr;

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

	dcss->dpr = dpr;
	dpr->dev = dcss->dev;
	dpr->ctxld = dcss->ctxld;
	dpr->ctx_id = CTX_SB_HP;

	if (dcss_dpr_ch_init_all(dpr, dpr_base))
		return -ENOMEM;

	return 0;
}

void dcss_dpr_exit(struct dcss_dpr *dpr)
{
	int ch_no;

	/* stop DPR on all channels */
	for (ch_no = 0; ch_no < 3; ch_no++) {
		struct dcss_dpr_ch *ch = &dpr->ch[ch_no];

Annotation

Implementation Notes