Beispiel #1
0
/**
 * Convert the drm_color_lut to dc_gamma. The conversion depends on the size
 * of the lut - whether or not it's legacy.
 */
static void __drm_lut_to_dc_gamma(struct drm_color_lut *lut,
				  struct dc_gamma *gamma,
				  bool is_legacy)
{
	uint32_t r, g, b;
	int i;

	if (is_legacy) {
		for (i = 0; i < MAX_COLOR_LEGACY_LUT_ENTRIES; i++) {
			r = drm_color_lut_extract(lut[i].red, 16);
			g = drm_color_lut_extract(lut[i].green, 16);
			b = drm_color_lut_extract(lut[i].blue, 16);

			gamma->entries.red[i] = dal_fixed31_32_from_int(r);
			gamma->entries.green[i] = dal_fixed31_32_from_int(g);
			gamma->entries.blue[i] = dal_fixed31_32_from_int(b);
		}
		return;
	}

	/* else */
	for (i = 0; i < MAX_COLOR_LUT_ENTRIES; i++) {
		r = drm_color_lut_extract(lut[i].red, 16);
		g = drm_color_lut_extract(lut[i].green, 16);
		b = drm_color_lut_extract(lut[i].blue, 16);

		gamma->entries.red[i] = dal_fixed31_32_from_fraction(r, MAX_DRM_LUT_VALUE);
		gamma->entries.green[i] = dal_fixed31_32_from_fraction(g, MAX_DRM_LUT_VALUE);
		gamma->entries.blue[i] = dal_fixed31_32_from_fraction(b, MAX_DRM_LUT_VALUE);
	}
}
const uint16_t *get_filter_8tap_64p(struct fixed31_32 ratio)
{
	if (ratio.value < dal_fixed31_32_one.value)
		return filter_8tap_64p_upscale;
	else if (ratio.value < dal_fixed31_32_from_fraction(4, 3).value)
		return filter_8tap_64p_117;
	else if (ratio.value < dal_fixed31_32_from_fraction(5, 3).value)
		return filter_8tap_64p_150;
	else
		return filter_8tap_64p_183;
}
static inline struct fixed31_32 fixed31_32_clamp(
	struct fixed31_32 value,
	int32_t min_numerator,
	int32_t max_numerator,
	int32_t denominator)
{
	return dal_fixed31_32_clamp(
		value,
		dal_fixed31_32_from_fraction(
			min_numerator,
			denominator),
		dal_fixed31_32_from_fraction(
			max_numerator,
			denominator));
}
static void prepare_yuv_ideal(
	bool b601,
	struct fixed31_32 *matrix)
{
	static const int32_t matrix_1[] = {
		25578516, 50216016, 9752344, 6250000,
		-14764391, -28985609, 43750000, 50000000,
		43750000, -36635164, -7114836, 50000000
	};

	static const int32_t matrix_2[] = {
		18187266, 61183125, 6176484, 6250000,
		-10025059, -33724941, 43750000, 50000000,
		43750000, -39738379, -4011621, 50000000
	};

	const int32_t *matrix_x = b601 ? matrix_1 : matrix_2;

	uint32_t i = 0;

	do {
		matrix[i] = dal_fixed31_32_from_fraction(
			matrix_x[i],
			100000000);
		++i;
	} while (i != ARRAY_SIZE(matrix_1));
}
/**
 *****************************************************************************
 *  Function: setup_adjustments
 *  @note prepare to setup the values
 *
 *  @see
 *
 *****************************************************************************
 */
static void setup_adjustments(const struct opp_grph_csc_adjustment *adjust,
	struct dc_csc_adjustments *adjustments)
{
	if (adjust->adjust_divider != 0) {
		adjustments->brightness =
			dal_fixed31_32_from_fraction(adjust->grph_bright,
			adjust->adjust_divider);
		adjustments->contrast =
			dal_fixed31_32_from_fraction(adjust->grph_cont,
			adjust->adjust_divider);
		adjustments->saturation =
			dal_fixed31_32_from_fraction(adjust->grph_sat,
			adjust->adjust_divider);
	} else {
		adjustments->brightness =
			dal_fixed31_32_from_fraction(adjust->grph_bright, 1);
		adjustments->contrast =
			dal_fixed31_32_from_fraction(adjust->grph_cont, 1);
		adjustments->saturation =
			dal_fixed31_32_from_fraction(adjust->grph_sat, 1);
	}

	/* convert degrees into radians */
	adjustments->hue =
		dal_fixed31_32_mul(
			dal_fixed31_32_from_fraction(adjust->grph_hue, 180),
			dal_fixed31_32_pi);
}
void calculate_adjustments(
	const struct fixed31_32 *ideal_matrix,
	const struct dc_csc_adjustments *adjustments,
	struct fixed31_32 *matrix)
{
	calculate_adjustments_common(ideal_matrix, adjustments, matrix);

	matrix[3] = dal_fixed31_32_add(
		ideal_matrix[3],
		dal_fixed31_32_mul(
			adjustments->brightness,
			dal_fixed31_32_from_fraction(86, 100)));
}
/**
* convert_float_matrix
* This converts a double into HW register spec defined format S2D13.
* @param :
* @return None
*/
void convert_float_matrix(
	uint16_t *matrix,
	struct fixed31_32 *flt,
	uint32_t buffer_size)
{
	const struct fixed31_32 min_2_13 =
		dal_fixed31_32_from_fraction(S2D13_MIN, DIVIDER);
	const struct fixed31_32 max_2_13 =
		dal_fixed31_32_from_fraction(S2D13_MAX, DIVIDER);
	uint32_t i;

	for (i = 0; i < buffer_size; ++i) {
		uint32_t reg_value =
				fixed_point_to_int_frac(
					dal_fixed31_32_clamp(
						flt[i],
						min_2_13,
						max_2_13),
						2,
						13);

		matrix[i] = (uint16_t)reg_value;
	}
}
/*
 * initialize_color_float_adj_reference_values
 * This initialize display color adjust input from API to HW range for later
 * calculation use. This is shared by all the display color adjustment.
 * @param :
 * @return None
 */
static void initialize_color_float_adj_reference_values(
	const struct opp_grph_csc_adjustment *adjust,
	struct fixed31_32 *grph_cont,
	struct fixed31_32 *grph_sat,
	struct fixed31_32 *grph_bright,
	struct fixed31_32 *sin_grph_hue,
	struct fixed31_32 *cos_grph_hue)
{
	/* Hue adjustment could be negative. -45 ~ +45 */
	struct fixed31_32 hue =
		dal_fixed31_32_mul(
			dal_fixed31_32_from_fraction(adjust->grph_hue, 180),
			dal_fixed31_32_pi);

	*sin_grph_hue = dal_fixed31_32_sin(hue);
	*cos_grph_hue = dal_fixed31_32_cos(hue);

	if (adjust->adjust_divider) {
		*grph_cont =
			dal_fixed31_32_from_fraction(
				adjust->grph_cont,
				adjust->adjust_divider);
		*grph_sat =
			dal_fixed31_32_from_fraction(
				adjust->grph_sat,
				adjust->adjust_divider);
		*grph_bright =
			dal_fixed31_32_from_fraction(
				adjust->grph_bright,
				adjust->adjust_divider);
	} else {
		*grph_cont = dal_fixed31_32_from_int(adjust->grph_cont);
		*grph_sat = dal_fixed31_32_from_int(adjust->grph_sat);
		*grph_bright = dal_fixed31_32_from_int(adjust->grph_bright);
	}
}
static void prepare_tv_rgb_ideal(
	struct fixed31_32 *matrix)
{
	static const int32_t matrix_[] = {
		85546875, 0, 0, 6250000,
		0, 85546875, 0, 6250000,
		0, 0, 85546875, 6250000
	};

	uint32_t i = 0;

	do {
		matrix[i] = dal_fixed31_32_from_fraction(
			matrix_[i],
			100000000);
		++i;
	} while (i != ARRAY_SIZE(matrix_));
}
/**
 *****************************************************************************
 *  Function: dal_transform_wide_gamut_set_gamut_remap
 *
 *  @param [in] const struct xfm_grph_csc_adjustment *adjust
 *
 *  @return
 *     void
 *
 *  @note calculate and apply color temperature adjustment to in Rgb color space
 *
 *  @see
 *
 *****************************************************************************
 */
void dce80_transform_set_gamut_remap(
	struct transform *xfm,
	const struct xfm_grph_csc_adjustment *adjust)
{
	struct dce80_transform *xfm80 = TO_DCE80_TRANSFORM(xfm);

	if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW ||
		adjust->temperature_divider == 0)
		program_gamut_remap(xfm80, NULL);
	else {
		struct fixed31_32 arr_matrix[GAMUT_MATRIX_SIZE];
		uint16_t arr_reg_val[GAMUT_MATRIX_SIZE];

		arr_matrix[0] =
			dal_fixed31_32_from_fraction(
				adjust->temperature_matrix[0],
				adjust->temperature_divider);
		arr_matrix[1] =
			dal_fixed31_32_from_fraction(
				adjust->temperature_matrix[1],
				adjust->temperature_divider);
		arr_matrix[2] =
			dal_fixed31_32_from_fraction(
				adjust->temperature_matrix[2],
				adjust->temperature_divider);
		arr_matrix[3] = dal_fixed31_32_zero;

		arr_matrix[4] =
			dal_fixed31_32_from_fraction(
				adjust->temperature_matrix[3],
				adjust->temperature_divider);
		arr_matrix[5] =
			dal_fixed31_32_from_fraction(
				adjust->temperature_matrix[4],
				adjust->temperature_divider);
		arr_matrix[6] =
			dal_fixed31_32_from_fraction(
				adjust->temperature_matrix[5],
				adjust->temperature_divider);
		arr_matrix[7] = dal_fixed31_32_zero;

		arr_matrix[8] =
			dal_fixed31_32_from_fraction(
				adjust->temperature_matrix[6],
				adjust->temperature_divider);
		arr_matrix[9] =
			dal_fixed31_32_from_fraction(
				adjust->temperature_matrix[7],
				adjust->temperature_divider);
		arr_matrix[10] =
			dal_fixed31_32_from_fraction(
				adjust->temperature_matrix[8],
				adjust->temperature_divider);
		arr_matrix[11] = dal_fixed31_32_zero;

		convert_float_matrix(
			arr_reg_val, arr_matrix, GAMUT_MATRIX_SIZE);

		program_gamut_remap(xfm80, arr_reg_val);
	}
}
/**
 *****************************************************************************
 *  Function: dal_transform_wide_gamut_set_rgb_adjustment_legacy
 *
 *  @param [in] const struct opp_grph_csc_adjustment *adjust
 *
 *  @return
 *     void
 *
 *  @note calculate and program color adjustments for sRGB color space
 *
 *  @see
 *
 *****************************************************************************
 */
static void set_rgb_adjustment_legacy(
	struct dce110_opp *opp110,
	const struct opp_grph_csc_adjustment *adjust)
{
	const struct fixed31_32 k1 =
		dal_fixed31_32_from_fraction(701000, 1000000);
	const struct fixed31_32 k2 =
		dal_fixed31_32_from_fraction(236568, 1000000);
	const struct fixed31_32 k3 =
		dal_fixed31_32_from_fraction(-587000, 1000000);
	const struct fixed31_32 k4 =
		dal_fixed31_32_from_fraction(464432, 1000000);
	const struct fixed31_32 k5 =
		dal_fixed31_32_from_fraction(-114000, 1000000);
	const struct fixed31_32 k6 =
		dal_fixed31_32_from_fraction(-701000, 1000000);
	const struct fixed31_32 k7 =
		dal_fixed31_32_from_fraction(-299000, 1000000);
	const struct fixed31_32 k8 =
		dal_fixed31_32_from_fraction(-292569, 1000000);
	const struct fixed31_32 k9 =
		dal_fixed31_32_from_fraction(413000, 1000000);
	const struct fixed31_32 k10 =
		dal_fixed31_32_from_fraction(-92482, 1000000);
	const struct fixed31_32 k11 =
		dal_fixed31_32_from_fraction(-114000, 1000000);
	const struct fixed31_32 k12 =
		dal_fixed31_32_from_fraction(385051, 1000000);
	const struct fixed31_32 k13 =
		dal_fixed31_32_from_fraction(-299000, 1000000);
	const struct fixed31_32 k14 =
		dal_fixed31_32_from_fraction(886000, 1000000);
	const struct fixed31_32 k15 =
		dal_fixed31_32_from_fraction(-587000, 1000000);
	const struct fixed31_32 k16 =
		dal_fixed31_32_from_fraction(-741914, 1000000);
	const struct fixed31_32 k17 =
		dal_fixed31_32_from_fraction(886000, 1000000);
	const struct fixed31_32 k18 =
		dal_fixed31_32_from_fraction(-144086, 1000000);

	const struct fixed31_32 luma_r =
		dal_fixed31_32_from_fraction(299, 1000);
	const struct fixed31_32 luma_g =
		dal_fixed31_32_from_fraction(587, 1000);
	const struct fixed31_32 luma_b =
		dal_fixed31_32_from_fraction(114, 1000);

	struct out_csc_color_matrix tbl_entry;
	struct fixed31_32 matrix[OUTPUT_CSC_MATRIX_SIZE];

	struct fixed31_32 grph_cont;
	struct fixed31_32 grph_sat;
	struct fixed31_32 grph_bright;
	struct fixed31_32 sin_grph_hue;
	struct fixed31_32 cos_grph_hue;

	initialize_color_float_adj_reference_values(
		adjust, &grph_cont, &grph_sat,
		&grph_bright, &sin_grph_hue, &cos_grph_hue);

	/* COEF_1_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K1 +
	 * Sin(GrphHue) * K2)) */
	/* (Cos(GrphHue) * K1 + Sin(GrphHue) * K2) */
	matrix[0] =
		dal_fixed31_32_add(
			dal_fixed31_32_mul(cos_grph_hue, k1),
			dal_fixed31_32_mul(sin_grph_hue, k2));
	/* GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue) * K2 */
	matrix[0] = dal_fixed31_32_mul(grph_sat, matrix[0]);
	/* (LumaR + GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue) * K2)) */
	matrix[0] = dal_fixed31_32_add(luma_r, matrix[0]);
	/* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue) *
	 * K2)) */
	matrix[0] = dal_fixed31_32_mul(grph_cont, matrix[0]);

	/* COEF_1_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K3 +
	 * Sin(GrphHue) * K4)) */
	/* (Cos(GrphHue) * K3 + Sin(GrphHue) * K4) */
	matrix[1] =
		dal_fixed31_32_add(
			dal_fixed31_32_mul(cos_grph_hue, k3),
			dal_fixed31_32_mul(sin_grph_hue, k4));
	/* GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue) * K4) */
	matrix[1] = dal_fixed31_32_mul(grph_sat, matrix[1]);
	/* (LumaG + GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue) * K4)) */
	matrix[1] = dal_fixed31_32_add(luma_g, matrix[1]);
	/* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue) *
	 * K4)) */
	matrix[1] = dal_fixed31_32_mul(grph_cont, matrix[1]);

	/* COEF_1_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K5 +
	 * Sin(GrphHue) * K6)) */
	/* (Cos(GrphHue) * K5 + Sin(GrphHue) * K6) */
	matrix[2] =
		dal_fixed31_32_add(
			dal_fixed31_32_mul(cos_grph_hue, k5),
			dal_fixed31_32_mul(sin_grph_hue, k6));
	/* GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue) * K6) */
	matrix[2] = dal_fixed31_32_mul(grph_sat, matrix[2]);
	/* LumaB + GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue) * K6) */
	matrix[2] = dal_fixed31_32_add(luma_b, matrix[2]);
	/* GrphCont  * (LumaB + GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue) *
	 * K6)) */
	matrix[2] = dal_fixed31_32_mul(grph_cont, matrix[2]);

	/* COEF_1_4 = GrphBright */
	matrix[3] = grph_bright;

	/* COEF_2_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K7 +
	 * Sin(GrphHue) * K8)) */
	/* (Cos(GrphHue) * K7 + Sin(GrphHue) * K8) */
	matrix[4] =
		dal_fixed31_32_add(
			dal_fixed31_32_mul(cos_grph_hue, k7),
			dal_fixed31_32_mul(sin_grph_hue, k8));
	/* GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue) * K8) */
	matrix[4] = dal_fixed31_32_mul(grph_sat, matrix[4]);
	/* (LumaR + GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue) * K8)) */
	matrix[4] = dal_fixed31_32_add(luma_r, matrix[4]);
	/* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue) *
	 * K8)) */
	matrix[4] = dal_fixed31_32_mul(grph_cont, matrix[4]);

	/* COEF_2_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K9 +
	 * Sin(GrphHue) * K10)) */
	/* (Cos(GrphHue) * K9 + Sin(GrphHue) * K10)) */
	matrix[5] =
		dal_fixed31_32_add(
			dal_fixed31_32_mul(cos_grph_hue, k9),
			dal_fixed31_32_mul(sin_grph_hue, k10));
	/* GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue) * K10)) */
	matrix[5] = dal_fixed31_32_mul(grph_sat, matrix[5]);
	/* (LumaG + GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue) * K10)) */
	matrix[5] = dal_fixed31_32_add(luma_g, matrix[5]);
	/* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue) *
	 * K10)) */
	matrix[5] = dal_fixed31_32_mul(grph_cont, matrix[5]);

	/*  COEF_2_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K11 +
	 * Sin(GrphHue) * K12)) */
	/* (Cos(GrphHue) * K11 + Sin(GrphHue) * K12)) */
	matrix[6] =
		dal_fixed31_32_add(
			dal_fixed31_32_mul(cos_grph_hue, k11),
			dal_fixed31_32_mul(sin_grph_hue, k12));
	/* GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue) * K12)) */
	matrix[6] = dal_fixed31_32_mul(grph_sat, matrix[6]);
	/*  (LumaB + GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue) * K12)) */
	matrix[6] = dal_fixed31_32_add(luma_b, matrix[6]);
	/* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue) *
	 * K12)) */
	matrix[6] = dal_fixed31_32_mul(grph_cont, matrix[6]);

	/* COEF_2_4 = GrphBright */
	matrix[7] = grph_bright;

	/* COEF_3_1 = GrphCont  * (LumaR + GrphSat * (Cos(GrphHue) * K13 +
	 * Sin(GrphHue) * K14)) */
	/* (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */
	matrix[8] =
		dal_fixed31_32_add(
			dal_fixed31_32_mul(cos_grph_hue, k13),
			dal_fixed31_32_mul(sin_grph_hue, k14));
	/* GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */
	matrix[8] = dal_fixed31_32_mul(grph_sat, matrix[8]);
	/* (LumaR + GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */
	matrix[8] = dal_fixed31_32_add(luma_r, matrix[8]);
	/* GrphCont  * (LumaR + GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue) *
	 * K14)) */
	matrix[8] = dal_fixed31_32_mul(grph_cont, matrix[8]);

	/* COEF_3_2    = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K15 +
	 * Sin(GrphHue) * K16)) */
	/* GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16) */
	matrix[9] =
		dal_fixed31_32_add(
			dal_fixed31_32_mul(cos_grph_hue, k15),
			dal_fixed31_32_mul(sin_grph_hue, k16));
	/* (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16)) */
	matrix[9] = dal_fixed31_32_mul(grph_sat, matrix[9]);
	/* (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16)) */
	matrix[9] = dal_fixed31_32_add(luma_g, matrix[9]);
	 /* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) *
	  * K16)) */
	matrix[9] = dal_fixed31_32_mul(grph_cont, matrix[9]);

	/*  COEF_3_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K17 +
	 * Sin(GrphHue) * K18)) */
	/* (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */
	matrix[10] =
		dal_fixed31_32_add(
			dal_fixed31_32_mul(cos_grph_hue, k17),
			dal_fixed31_32_mul(sin_grph_hue, k18));
	/*  GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */
	matrix[10] = dal_fixed31_32_mul(grph_sat, matrix[10]);
	/* (LumaB + GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */
	matrix[10] = dal_fixed31_32_add(luma_b, matrix[10]);
	 /* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue) *
	  * K18)) */
	matrix[10] = dal_fixed31_32_mul(grph_cont, matrix[10]);

	/*  COEF_3_4    = GrphBright */
	matrix[11] = grph_bright;

	tbl_entry.color_space = adjust->c_space;

	convert_float_matrix(tbl_entry.regval, matrix, OUTPUT_CSC_MATRIX_SIZE);

	program_color_matrix(
		opp110, &tbl_entry, adjust->color_adjust_option);
}