drivers/gpu/drm/mediatek/mtk_disp_gamma.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/mediatek/mtk_disp_gamma.c
Extension
.c
Size
9623 bytes
Lines
336
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_gamma_data {
	bool has_dither;
	bool lut_diff;
	u16 lut_bank_size;
	u16 lut_size;
	u8 lut_bits;
};

/**
 * struct mtk_disp_gamma - Display Gamma driver structure
 * @clk:      clock for DISP_GAMMA block
 * @regs:     MMIO registers base
 * @cmdq_reg: CMDQ Client register
 * @data:     platform data for DISP_GAMMA
 */
struct mtk_disp_gamma {
	struct clk *clk;
	void __iomem *regs;
	struct cmdq_client_reg cmdq_reg;
	const struct mtk_disp_gamma_data *data;
};

int mtk_gamma_clk_enable(struct device *dev)
{
	struct mtk_disp_gamma *gamma = dev_get_drvdata(dev);

	return clk_prepare_enable(gamma->clk);
}

void mtk_gamma_clk_disable(struct device *dev)
{
	struct mtk_disp_gamma *gamma = dev_get_drvdata(dev);

	clk_disable_unprepare(gamma->clk);
}

unsigned int mtk_gamma_get_lut_size(struct device *dev)
{
	struct mtk_disp_gamma *gamma = dev_get_drvdata(dev);

	if (gamma && gamma->data)
		return gamma->data->lut_size;
	return 0;
}

static bool mtk_gamma_lut_is_descending(struct drm_color_lut *lut, u32 lut_size)
{
	u64 first, last;
	int last_entry = lut_size - 1;

	first = lut[0].red + lut[0].green + lut[0].blue;
	last = lut[last_entry].red + lut[last_entry].green + lut[last_entry].blue;

	return !!(first > last);
}

/*
 * SoCs supporting 12-bits LUTs are using a new register layout that does
 * always support (by HW) both 12-bits and 10-bits LUT but, on those, we
 * ignore the support for 10-bits in this driver and always use 12-bits.
 *
 * Summarizing:
 * - SoC HW support 9/10-bits LUT only
 *   - Old register layout
 *     - 10-bits LUT supported
 *     - 9-bits LUT not supported
 * - SoC HW support both 10/12bits LUT
 *   - New register layout
 *     - 12-bits LUT supported
 *     - 10-its LUT not supported
 */
void mtk_gamma_set(struct device *dev, struct drm_crtc_state *state)
{
	struct mtk_disp_gamma *gamma = dev_get_drvdata(dev);
	void __iomem *lut0_base = gamma->regs + DISP_GAMMA_LUT;
	void __iomem *lut1_base = gamma->regs + DISP_GAMMA_LUT1;
	u32 cfg_val, data_mode, lbank_val, word[2];
	u8 lut_bits = gamma->data->lut_bits;
	int cur_bank, num_lut_banks;
	struct drm_color_lut *lut;
	unsigned int i;

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

	num_lut_banks = gamma->data->lut_size / gamma->data->lut_bank_size;
	lut = (struct drm_color_lut *)state->gamma_lut->data;

	/* Switch to 12 bits data mode if supported */

Annotation

Implementation Notes