Commit 534db198 authored by Amy Zhang's avatar Amy Zhang Committed by Alex Deucher

drm/amd/display: HDR Enablement For Applications

- Made sure dest color space is updated in stream and info frame
- Optimized segment distribution algorithm for regamma mapping
Signed-off-by: default avatarAmy Zhang <Amy.Zhang@amd.com>
Acked-by: default avatarHarry Wentland <Harry.Wentland@amd.com>
Reviewed-by: default avatarAric Cyr <Aric.Cyr@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 306dadf0
...@@ -1310,6 +1310,20 @@ static void set_avi_info_frame( ...@@ -1310,6 +1310,20 @@ static void set_avi_info_frame(
info_frame.avi_info_packet.info_packet_hdmi.bits.C0_C1 = info_frame.avi_info_packet.info_packet_hdmi.bits.C0_C1 =
COLORIMETRY_NO_DATA; 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 */ /* TODO: un-hardcode aspect ratio */
aspect = stream->public.timing.aspect_ratio; aspect = stream->public.timing.aspect_ratio;
......
...@@ -444,7 +444,11 @@ enum dc_color_space { ...@@ -444,7 +444,11 @@ enum dc_color_space {
COLOR_SPACE_YCBCR601, COLOR_SPACE_YCBCR601,
COLOR_SPACE_YCBCR709, COLOR_SPACE_YCBCR709,
COLOR_SPACE_YCBCR601_LIMITED, 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 { enum dc_quantization_range {
......
...@@ -594,38 +594,87 @@ static bool dce110_translate_regamma_to_hw_format(const struct dc_transfer_func ...@@ -594,38 +594,87 @@ static bool dce110_translate_regamma_to_hw_format(const struct dc_transfer_func
struct fixed31_32 y3_max; struct fixed31_32 y3_max;
int32_t segment_start, segment_end; int32_t segment_start, segment_end;
uint32_t hw_points, start_index; uint32_t i, j, k, seg_distr[16], increment, start_index;
uint32_t i, j; uint32_t hw_points = 0;
memset(regamma_params, 0, sizeof(struct pwl_params)); memset(regamma_params, 0, sizeof(struct pwl_params));
if (output_tf->tf == TRANSFER_FUNCTION_PQ) { if (output_tf->tf == TRANSFER_FUNCTION_PQ) {
/* 16 segments x 16 points /* 16 segments
* segments are from 2^-11 to 2^5 * segments are from 2^-11 to 2^5
*/ */
segment_start = -11; segment_start = -11;
segment_end = 5; 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 { } else {
/* 10 segments x 16 points /* 10 segments
* segment is from 2^-10 to 2^0 * segment is from 2^-10 to 2^0
*/ */
segment_start = -10; segment_start = -10;
segment_end = 0; 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; j = 0;
/* (segment + 25) * 32, every 2nd point */ for (k = 0; k < (segment_end - segment_start); k++) {
start_index = (segment_start + 25) * 32; increment = 32 / (1 << seg_distr[k]);
for (i = start_index; i <= 1025; i += 2) { start_index = (segment_start + k + 25) * 32;
if (j > hw_points) for (i = start_index; i < start_index + 32; i += increment) {
if (j == hw_points - 1)
break; break;
rgb_resulted[j].red = output_tf->tf_pts.red[i]; rgb_resulted[j].red = output_tf->tf_pts.red[i];
rgb_resulted[j].green = output_tf->tf_pts.green[i]; rgb_resulted[j].green = output_tf->tf_pts.green[i];
rgb_resulted[j].blue = output_tf->tf_pts.blue[i]; rgb_resulted[j].blue = output_tf->tf_pts.blue[i];
j++; 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), arr_points[0].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2),
dal_fixed31_32_from_int(segment_start)); dal_fixed31_32_from_int(segment_start));
...@@ -677,11 +726,22 @@ static bool dce110_translate_regamma_to_hw_format(const struct dc_transfer_func ...@@ -677,11 +726,22 @@ static bool dce110_translate_regamma_to_hw_format(const struct dc_transfer_func
regamma_params->hw_points_num = hw_points; regamma_params->hw_points_num = hw_points;
for (i = 0; i < segment_end - segment_start; i++) { i = 1;
regamma_params->arr_curve_points[i].offset = i * 16; for (k = 0; k < 16 && i < 16; k++) {
regamma_params->arr_curve_points[i].segments_num = 4; 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 = rgb_resulted;
struct pwl_result_data *rgb_plus_1 = rgb_resulted + 1; struct pwl_result_data *rgb_plus_1 = rgb_resulted + 1;
......
...@@ -47,6 +47,17 @@ enum colorimetry { ...@@ -47,6 +47,17 @@ enum colorimetry {
COLORIMETRY_EXTENDED = 3 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 { enum active_format_info {
ACTIVE_FORMAT_NO_DATA = 0, ACTIVE_FORMAT_NO_DATA = 0,
ACTIVE_FORMAT_VALID = 1 ACTIVE_FORMAT_VALID = 1
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment