diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3645-drm-amd-display-Handle-HDR-use-cases.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3645-drm-amd-display-Handle-HDR-use-cases.patch | 261 |
1 files changed, 261 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3645-drm-amd-display-Handle-HDR-use-cases.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3645-drm-amd-display-Handle-HDR-use-cases.patch new file mode 100644 index 00000000..46a871b7 --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3645-drm-amd-display-Handle-HDR-use-cases.patch @@ -0,0 +1,261 @@ +From dc59c2e92be7815617cda78f56507d76ae034a52 Mon Sep 17 00:00:00 2001 +From: Vitaly Prosyak <vitaly.prosyak@amd.com> +Date: Tue, 13 Feb 2018 13:18:43 -0600 +Subject: [PATCH 3645/4131] drm/amd/display: Handle HDR use cases. + +Implementation of de-gamma, blnd-gamma, shaper and +3d lut's. +Removed memory allocations in transfer functions. +Refactor color module. + +Signed-off-by: Vitaly Prosyak <vitaly.prosyak@amd.com> +Reviewed-by: Krunoslav Kovac <Krunoslav.Kovac@amd.com> +Reviewed-by: Tony Cheng <Tony.Cheng@amd.com> +Acked-by: Harry Wentland <harry.wentland@amd.com> +Signed-off-by: Kalyan Alle <kalyan.alle@amd.com> +--- + .../gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c | 153 +++++++++++++++++++++ + .../gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h | 5 + + drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h | 2 + + .../drm/amd/display/modules/color/color_gamma.c | 25 +--- + 4 files changed, 161 insertions(+), 24 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c +index b3db639..881a1bf 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c +@@ -416,3 +416,156 @@ bool cm_helper_translate_curve_to_hw_format( + + return true; + } ++ ++#define NUM_DEGAMMA_REGIONS 12 ++ ++ ++bool cm_helper_translate_curve_to_degamma_hw_format( ++ const struct dc_transfer_func *output_tf, ++ struct pwl_params *lut_params) ++{ ++ struct curve_points *arr_points; ++ struct pwl_result_data *rgb_resulted; ++ struct pwl_result_data *rgb; ++ struct pwl_result_data *rgb_plus_1; ++ struct fixed31_32 y_r; ++ struct fixed31_32 y_g; ++ struct fixed31_32 y_b; ++ struct fixed31_32 y1_min; ++ struct fixed31_32 y3_max; ++ ++ int32_t region_start, region_end; ++ int32_t i; ++ uint32_t j, k, seg_distr[MAX_REGIONS_NUMBER], increment, start_index, hw_points; ++ ++ if (output_tf == NULL || lut_params == NULL || output_tf->type == TF_TYPE_BYPASS) ++ return false; ++ ++ PERF_TRACE(); ++ ++ arr_points = lut_params->arr_points; ++ rgb_resulted = lut_params->rgb_resulted; ++ hw_points = 0; ++ ++ memset(lut_params, 0, sizeof(struct pwl_params)); ++ memset(seg_distr, 0, sizeof(seg_distr)); ++ ++ region_start = -NUM_DEGAMMA_REGIONS; ++ region_end = 0; ++ ++ ++ for (i = region_end - region_start; i < MAX_REGIONS_NUMBER ; i++) ++ seg_distr[i] = -1; ++ /* 12 segments ++ * segments are from 2^-12 to 0 ++ */ ++ for (i = 0; i < NUM_DEGAMMA_REGIONS ; i++) ++ seg_distr[i] = 4; ++ ++ for (k = 0; k < MAX_REGIONS_NUMBER; k++) { ++ if (seg_distr[k] != -1) ++ hw_points += (1 << seg_distr[k]); ++ } ++ ++ j = 0; ++ for (k = 0; k < (region_end - region_start); k++) { ++ increment = NUMBER_SW_SEGMENTS / (1 << seg_distr[k]); ++ start_index = (region_start + k + MAX_LOW_POINT) * ++ NUMBER_SW_SEGMENTS; ++ for (i = start_index; i < start_index + NUMBER_SW_SEGMENTS; ++ i += increment) { ++ if (j == hw_points - 1) ++ break; ++ rgb_resulted[j].red = output_tf->tf_pts.red[i]; ++ rgb_resulted[j].green = output_tf->tf_pts.green[i]; ++ rgb_resulted[j].blue = output_tf->tf_pts.blue[i]; ++ j++; ++ } ++ } ++ ++ /* last point */ ++ start_index = (region_end + MAX_LOW_POINT) * NUMBER_SW_SEGMENTS; ++ rgb_resulted[hw_points - 1].red = output_tf->tf_pts.red[start_index]; ++ rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index]; ++ rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index]; ++ ++ arr_points[0].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2), ++ dal_fixed31_32_from_int(region_start)); ++ arr_points[1].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2), ++ dal_fixed31_32_from_int(region_end)); ++ ++ y_r = rgb_resulted[0].red; ++ y_g = rgb_resulted[0].green; ++ y_b = rgb_resulted[0].blue; ++ ++ y1_min = dal_fixed31_32_min(y_r, dal_fixed31_32_min(y_g, y_b)); ++ ++ arr_points[0].y = y1_min; ++ arr_points[0].slope = dal_fixed31_32_div(arr_points[0].y, arr_points[0].x); ++ y_r = rgb_resulted[hw_points - 1].red; ++ y_g = rgb_resulted[hw_points - 1].green; ++ y_b = rgb_resulted[hw_points - 1].blue; ++ ++ /* see comment above, m_arrPoints[1].y should be the Y value for the ++ * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1) ++ */ ++ y3_max = dal_fixed31_32_max(y_r, dal_fixed31_32_max(y_g, y_b)); ++ ++ arr_points[1].y = y3_max; ++ ++ arr_points[1].slope = dal_fixed31_32_zero; ++ ++ if (output_tf->tf == TRANSFER_FUNCTION_PQ) { ++ /* for PQ, we want to have a straight line from last HW X point, ++ * and the slope to be such that we hit 1.0 at 10000 nits. ++ */ ++ const struct fixed31_32 end_value = ++ dal_fixed31_32_from_int(125); ++ ++ arr_points[1].slope = dal_fixed31_32_div( ++ dal_fixed31_32_sub(dal_fixed31_32_one, arr_points[1].y), ++ dal_fixed31_32_sub(end_value, arr_points[1].x)); ++ } ++ ++ lut_params->hw_points_num = hw_points; ++ ++ i = 1; ++ for (k = 0; k < MAX_REGIONS_NUMBER && i < MAX_REGIONS_NUMBER; k++) { ++ if (seg_distr[k] != -1) { ++ lut_params->arr_curve_points[k].segments_num = ++ seg_distr[k]; ++ lut_params->arr_curve_points[i].offset = ++ lut_params->arr_curve_points[k].offset + (1 << seg_distr[k]); ++ } ++ i++; ++ } ++ ++ if (seg_distr[k] != -1) ++ lut_params->arr_curve_points[k].segments_num = seg_distr[k]; ++ ++ rgb = rgb_resulted; ++ rgb_plus_1 = rgb_resulted + 1; ++ ++ i = 1; ++ while (i != hw_points + 1) { ++ if (dal_fixed31_32_lt(rgb_plus_1->red, rgb->red)) ++ rgb_plus_1->red = rgb->red; ++ if (dal_fixed31_32_lt(rgb_plus_1->green, rgb->green)) ++ rgb_plus_1->green = rgb->green; ++ if (dal_fixed31_32_lt(rgb_plus_1->blue, rgb->blue)) ++ rgb_plus_1->blue = rgb->blue; ++ ++ rgb->delta_red = dal_fixed31_32_sub(rgb_plus_1->red, rgb->red); ++ rgb->delta_green = dal_fixed31_32_sub(rgb_plus_1->green, rgb->green); ++ rgb->delta_blue = dal_fixed31_32_sub(rgb_plus_1->blue, rgb->blue); ++ ++ ++rgb_plus_1; ++ ++rgb; ++ ++i; ++ } ++ cm_helper_convert_to_custom_float(rgb_resulted, ++ lut_params->arr_points, ++ hw_points, false); ++ ++ return true; ++} +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h +index 64e476b8..7a531b0 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h +@@ -106,4 +106,9 @@ bool cm_helper_translate_curve_to_hw_format( + const struct dc_transfer_func *output_tf, + struct pwl_params *lut_params, bool fixpoint); + ++bool cm_helper_translate_curve_to_degamma_hw_format( ++ const struct dc_transfer_func *output_tf, ++ struct pwl_params *lut_params); ++ ++ + #endif +diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h +index 78abc16..c5aae2d 100644 +--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h ++++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h +@@ -35,6 +35,8 @@ struct dpp { + int inst; + struct dpp_caps *caps; + struct pwl_params regamma_params; ++ struct pwl_params degamma_params; ++ + }; + + struct dpp_grph_csc_adjustment { +diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c +index a5fd14a..bf629fa 100644 +--- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c ++++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c +@@ -30,15 +30,12 @@ + + #define NUM_PTS_IN_REGION 16 + #define NUM_REGIONS 32 +-#define NUM_DEGAMMA_REGIONS 12 + #define MAX_HW_POINTS (NUM_PTS_IN_REGION*NUM_REGIONS) +-#define MAX_HW_DEGAMMA_POINTS (NUM_PTS_IN_REGION*NUM_DEGAMMA_REGIONS) + + static struct hw_x_point coordinates_x[MAX_HW_POINTS + 2]; +-static struct hw_x_point degamma_coordinates_x[MAX_HW_DEGAMMA_POINTS + 2]; + + static struct fixed31_32 pq_table[MAX_HW_POINTS + 2]; +-static struct fixed31_32 de_pq_table[MAX_HW_DEGAMMA_POINTS + 2]; ++static struct fixed31_32 de_pq_table[MAX_HW_POINTS + 2]; + + static bool pq_initialized; /* = false; */ + static bool de_pq_initialized; /* = false; */ +@@ -69,26 +66,6 @@ void setup_x_points_distribution(void) + (coordinates_x[index-1].x, increment); + } + } +- +- region_size = dal_fixed31_32_from_int(1); +- degamma_coordinates_x[MAX_HW_DEGAMMA_POINTS].x = region_size; +- degamma_coordinates_x[MAX_HW_DEGAMMA_POINTS + 1].x = region_size; +- +- for (segment = -1; segment > -(NUM_DEGAMMA_REGIONS + 1); segment--) { +- region_size = dal_fixed31_32_div_int(region_size, 2); +- increment = dal_fixed31_32_div_int(region_size, +- NUM_PTS_IN_REGION); +- seg_offset = (segment + NUM_DEGAMMA_REGIONS) * NUM_PTS_IN_REGION; +- degamma_coordinates_x[seg_offset].x = region_size; +- +- for (index = seg_offset + 1; +- index < seg_offset + NUM_PTS_IN_REGION; +- index++) { +- degamma_coordinates_x[index].x = dal_fixed31_32_add +- (degamma_coordinates_x[index-1].x, increment); +- } +- } +- + } + + static void compute_pq(struct fixed31_32 in_x, struct fixed31_32 *out_y) +-- +2.7.4 + |