drivers/gpu/drm/amd/display/dc/dce110/dce110_opp_csc_v.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/display/dc/dce110/dce110_opp_csc_v.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/display/dc/dce110/dce110_opp_csc_v.c
Extension
.c
Size
20217 bytes
Lines
747
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 input_csc_matrix {
	enum dc_color_space color_space;
	uint32_t regval[12];
};

static const struct input_csc_matrix input_csc_matrix[] = {
	{COLOR_SPACE_SRGB,
/*1_1   1_2   1_3   1_4   2_1   2_2   2_3   2_4   3_1   3_2   3_3   3_4 */
		{0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} },
	{COLOR_SPACE_SRGB_LIMITED,
		{0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} },
	{COLOR_SPACE_YCBCR601,
		{0x2cdd, 0x2000, 0x0, 0xe991, 0xe926, 0x2000, 0xf4fd, 0x10ef,
						0x0, 0x2000, 0x38b4, 0xe3a6} },
	{COLOR_SPACE_YCBCR601_LIMITED,
		{0x3353, 0x2568, 0x0, 0xe400, 0xe5dc, 0x2568, 0xf367, 0x1108,
						0x0, 0x2568, 0x40de, 0xdd3a} },
	{COLOR_SPACE_YCBCR709,
		{0x3265, 0x2000, 0, 0xe6ce, 0xf105, 0x2000, 0xfa01, 0xa7d, 0,
						0x2000, 0x3b61, 0xe24f} },
	{COLOR_SPACE_YCBCR709_LIMITED,
		{0x39a6, 0x2568, 0, 0xe0d6, 0xeedd, 0x2568, 0xf925, 0x9a8, 0,
						0x2568, 0x43ee, 0xdbb2} }
};

static void program_input_csc(
		struct transform *xfm, enum dc_color_space color_space)
{
	int arr_size = sizeof(input_csc_matrix)/sizeof(struct input_csc_matrix);
	struct dc_context *ctx = xfm->ctx;
	const uint32_t *regval = NULL;
	bool use_set_a;
	uint32_t value;
	int i;

	for (i = 0; i < arr_size; i++)
		if (input_csc_matrix[i].color_space == color_space) {
			regval = input_csc_matrix[i].regval;
			break;
		}
	if (regval == NULL) {
		BREAK_TO_DEBUGGER();
		return;
	}

	/*
	 * 1 == set A, the logic is 'if currently we're not using set A,
	 * then use set A, otherwise use set B'
	 */
	value = dm_read_reg(ctx, mmCOL_MAN_INPUT_CSC_CONTROL);
	use_set_a = get_reg_field_value(
		value, COL_MAN_INPUT_CSC_CONTROL, INPUT_CSC_MODE) != 1;

	if (use_set_a) {
		/* fixed S2.13 format */
		value = 0;
		set_reg_field_value(
			value, regval[0], INPUT_CSC_C11_C12_A, INPUT_CSC_C11_A);
		set_reg_field_value(
			value, regval[1], INPUT_CSC_C11_C12_A, INPUT_CSC_C12_A);
		dm_write_reg(ctx, mmINPUT_CSC_C11_C12_A, value);

		value = 0;
		set_reg_field_value(
			value, regval[2], INPUT_CSC_C13_C14_A, INPUT_CSC_C13_A);
		set_reg_field_value(
			value, regval[3], INPUT_CSC_C13_C14_A, INPUT_CSC_C14_A);
		dm_write_reg(ctx, mmINPUT_CSC_C13_C14_A, value);

		value = 0;
		set_reg_field_value(
			value, regval[4], INPUT_CSC_C21_C22_A, INPUT_CSC_C21_A);
		set_reg_field_value(
			value, regval[5], INPUT_CSC_C21_C22_A, INPUT_CSC_C22_A);
		dm_write_reg(ctx, mmINPUT_CSC_C21_C22_A, value);

		value = 0;
		set_reg_field_value(
			value, regval[6], INPUT_CSC_C23_C24_A, INPUT_CSC_C23_A);
		set_reg_field_value(
			value, regval[7], INPUT_CSC_C23_C24_A, INPUT_CSC_C24_A);
		dm_write_reg(ctx, mmINPUT_CSC_C23_C24_A, value);

		value = 0;
		set_reg_field_value(
			value, regval[8], INPUT_CSC_C31_C32_A, INPUT_CSC_C31_A);
		set_reg_field_value(
			value, regval[9], INPUT_CSC_C31_C32_A, INPUT_CSC_C32_A);
		dm_write_reg(ctx, mmINPUT_CSC_C31_C32_A, value);

Annotation

Implementation Notes