From: Amy Zhang <Amy.Zhang@xxxxxxx> - Made sure dest color space is updated in stream and info frame - Optimized segment distribution algorithm for regamma mapping Change-Id: Ia9bb4e56719e23a9827080194d89f715ee5fde29 Signed-off-by: Amy Zhang <Amy.Zhang at amd.com> Acked-by: Harry Wentland <Harry.Wentland at amd.com> Reviewed-by: Aric Cyr <Aric.Cyr at amd.com> --- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 14 ++++ drivers/gpu/drm/amd/display/dc/dc_hw_types.h | 6 +- .../amd/display/dc/dce110/dce110_hw_sequencer.c | 94 ++++++++++++++++++---- drivers/gpu/drm/amd/display/dc/inc/hw/transform.h | 11 +++ 4 files changed, 107 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index fe79a2890247..8b41c7708562 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -1310,6 +1310,20 @@ static void set_avi_info_frame( info_frame.avi_info_packet.info_packet_hdmi.bits.C0_C1 = COLORIMETRY_NO_DATA; + if (color_space == COLOR_SPACE_2020_RGB_FULLRANGE || + color_space == COLOR_SPACE_2020_RGB_LIMITEDRANGE || + color_space == COLOR_SPACE_2020_YCBCR) { + info_frame.avi_info_packet.info_packet_hdmi.bits.EC0_EC2 = + COLORIMETRYEX_BT2020RGBYCBCR; + info_frame.avi_info_packet.info_packet_hdmi.bits.C0_C1 = + COLORIMETRY_EXTENDED; + } else if (color_space == COLOR_SPACE_ADOBERGB) { + info_frame.avi_info_packet.info_packet_hdmi.bits.EC0_EC2 = + COLORIMETRYEX_ADOBERGB; + info_frame.avi_info_packet.info_packet_hdmi.bits.C0_C1 = + COLORIMETRY_EXTENDED; + } + /* TODO: un-hardcode aspect ratio */ aspect = stream->public.timing.aspect_ratio; diff --git a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h index 00958bdbb417..a17e7bc96f9e 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h @@ -444,7 +444,11 @@ enum dc_color_space { COLOR_SPACE_YCBCR601, COLOR_SPACE_YCBCR709, COLOR_SPACE_YCBCR601_LIMITED, - COLOR_SPACE_YCBCR709_LIMITED + COLOR_SPACE_YCBCR709_LIMITED, + COLOR_SPACE_2020_RGB_FULLRANGE, + COLOR_SPACE_2020_RGB_LIMITEDRANGE, + COLOR_SPACE_2020_YCBCR, + COLOR_SPACE_ADOBERGB, }; enum dc_quantization_range { diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index ee393a168c84..e9fd83e9af79 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -594,39 +594,88 @@ static bool dce110_translate_regamma_to_hw_format(const struct dc_transfer_func struct fixed31_32 y3_max; int32_t segment_start, segment_end; - uint32_t hw_points, start_index; - uint32_t i, j; + uint32_t i, j, k, seg_distr[16], increment, start_index; + uint32_t hw_points = 0; memset(regamma_params, 0, sizeof(struct pwl_params)); if (output_tf->tf == TRANSFER_FUNCTION_PQ) { - /* 16 segments x 16 points + /* 16 segments * segments are from 2^-11 to 2^5 */ segment_start = -11; segment_end = 5; + seg_distr[0] = 2; + seg_distr[1] = 2; + seg_distr[2] = 2; + seg_distr[3] = 2; + seg_distr[4] = 2; + seg_distr[5] = 2; + seg_distr[6] = 3; + seg_distr[7] = 4; + seg_distr[8] = 4; + seg_distr[9] = 4; + seg_distr[10] = 4; + seg_distr[11] = 5; + seg_distr[12] = 5; + seg_distr[13] = 5; + seg_distr[14] = 5; + seg_distr[15] = 5; + } else { - /* 10 segments x 16 points + /* 10 segments * segment is from 2^-10 to 2^0 */ segment_start = -10; segment_end = 0; + + seg_distr[0] = 3; + seg_distr[1] = 4; + seg_distr[2] = 4; + seg_distr[3] = 4; + seg_distr[4] = 4; + seg_distr[5] = 4; + seg_distr[6] = 4; + seg_distr[7] = 4; + seg_distr[8] = 5; + seg_distr[9] = 5; + seg_distr[10] = -1; + seg_distr[11] = -1; + seg_distr[12] = -1; + seg_distr[13] = -1; + seg_distr[14] = -1; + seg_distr[15] = -1; + } + + for (k = 0; k < 16; k++) { + if (seg_distr[k] != -1) + hw_points += (1 << seg_distr[k]); } - hw_points = (segment_end - segment_start) * 16; j = 0; - /* (segment + 25) * 32, every 2nd point */ - start_index = (segment_start + 25) * 32; - for (i = start_index; i <= 1025; i += 2) { - if (j > hw_points) - 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++; + for (k = 0; k < (segment_end - segment_start); k++) { + increment = 32 / (1 << seg_distr[k]); + start_index = (segment_start + k + 25) * 32; + for (i = start_index; i < start_index + 32; 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 = (segment_end + 25) * 32; + 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(segment_start)); arr_points[1].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2), @@ -677,11 +726,22 @@ static bool dce110_translate_regamma_to_hw_format(const struct dc_transfer_func regamma_params->hw_points_num = hw_points; - for (i = 0; i < segment_end - segment_start; i++) { - regamma_params->arr_curve_points[i].offset = i * 16; - regamma_params->arr_curve_points[i].segments_num = 4; + i = 1; + for (k = 0; k < 16 && i < 16; k++) { + if (seg_distr[k] != -1) { + regamma_params->arr_curve_points[k].segments_num = + seg_distr[k]; + regamma_params->arr_curve_points[i].offset = + regamma_params->arr_curve_points[k]. + offset + (1 << seg_distr[k]); + } + i++; } + if (seg_distr[k] != -1) + regamma_params->arr_curve_points[k].segments_num = + seg_distr[k]; + struct pwl_result_data *rgb = rgb_resulted; struct pwl_result_data *rgb_plus_1 = rgb_resulted + 1; diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h b/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h index ef743b70b3e9..a510d3fe48ec 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h @@ -47,6 +47,17 @@ enum colorimetry { COLORIMETRY_EXTENDED = 3 }; +enum colorimetry_ext { + COLORIMETRYEX_XVYCC601 = 0, + COLORIMETRYEX_XVYCC709 = 1, + COLORIMETRYEX_SYCC601 = 2, + COLORIMETRYEX_ADOBEYCC601 = 3, + COLORIMETRYEX_ADOBERGB = 4, + COLORIMETRYEX_BT2020YCC = 5, + COLORIMETRYEX_BT2020RGBYCBCR = 6, + COLORIMETRYEX_RESERVED = 7 +}; + enum active_format_info { ACTIVE_FORMAT_NO_DATA = 0, ACTIVE_FORMAT_VALID = 1 -- 2.9.3