/** * 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); }