drivers/gpu/drm/mediatek/mtk_disp_aal.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/mediatek/mtk_disp_aal.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/mediatek/mtk_disp_aal.c
Extension
.c
Size
5948 bytes
Lines
227
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 mtk_disp_aal_data {
	bool has_gamma;
};

 /**
  * struct mtk_disp_aal - Display Adaptive Ambient Light driver structure
  * @clk:      clock for DISP_AAL controller
  * @regs:     MMIO registers base
  * @cmdq_reg: CMDQ Client register
  * @data:     platform specific data for DISP_AAL
  */
struct mtk_disp_aal {
	struct clk *clk;
	void __iomem *regs;
	struct cmdq_client_reg cmdq_reg;
	const struct mtk_disp_aal_data *data;
};

int mtk_aal_clk_enable(struct device *dev)
{
	struct mtk_disp_aal *aal = dev_get_drvdata(dev);

	return clk_prepare_enable(aal->clk);
}

void mtk_aal_clk_disable(struct device *dev)
{
	struct mtk_disp_aal *aal = dev_get_drvdata(dev);

	clk_disable_unprepare(aal->clk);
}

void mtk_aal_config(struct device *dev, unsigned int w,
			   unsigned int h, unsigned int vrefresh,
			   unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
{
	struct mtk_disp_aal *aal = dev_get_drvdata(dev);
	u32 sz;

	sz = FIELD_PREP(DISP_AAL_SIZE_HSIZE, w);
	sz |= FIELD_PREP(DISP_AAL_SIZE_VSIZE, h);

	mtk_ddp_write(cmdq_pkt, sz, &aal->cmdq_reg, aal->regs, DISP_AAL_SIZE);
	mtk_ddp_write(cmdq_pkt, sz, &aal->cmdq_reg, aal->regs, DISP_AAL_OUTPUT_SIZE);
}

/**
 * mtk_aal_gamma_get_lut_size() - Get gamma LUT size for AAL
 * @dev: Pointer to struct device
 *
 * Return: 0 if gamma control not supported in AAL or gamma LUT size
 */
unsigned int mtk_aal_gamma_get_lut_size(struct device *dev)
{
	struct mtk_disp_aal *aal = dev_get_drvdata(dev);

	if (aal->data && aal->data->has_gamma)
		return DISP_AAL_LUT_SIZE;
	return 0;
}

void mtk_aal_gamma_set(struct device *dev, struct drm_crtc_state *state)
{
	struct mtk_disp_aal *aal = dev_get_drvdata(dev);
	struct drm_color_lut *lut;
	unsigned int i;
	u32 cfg_val;

	/* If gamma is not supported in AAL, go out immediately */
	if (!(aal->data && aal->data->has_gamma))
		return;

	/* Also, if there's no gamma lut there's nothing to do here. */
	if (!state->gamma_lut)
		return;

	lut = (struct drm_color_lut *)state->gamma_lut->data;
	for (i = 0; i < DISP_AAL_LUT_SIZE; i++) {
		struct drm_color_lut hwlut = {
			.red = drm_color_lut_extract(lut[i].red, DISP_AAL_LUT_BITS),
			.green = drm_color_lut_extract(lut[i].green, DISP_AAL_LUT_BITS),
			.blue = drm_color_lut_extract(lut[i].blue, DISP_AAL_LUT_BITS)
		};
		u32 word;

		word = FIELD_PREP(DISP_AAL_GAMMA_LUT_R, hwlut.red);
		word |= FIELD_PREP(DISP_AAL_GAMMA_LUT_G, hwlut.green);
		word |= FIELD_PREP(DISP_AAL_GAMMA_LUT_B, hwlut.blue);
		writel(word, aal->regs + DISP_AAL_GAMMA_LUT + i * 4);
	}

Annotation

Implementation Notes