[PATCH 16/25] drm/amd/display: HDR Enablement For Applications
Harry Wentland
harry.wentland at amd.com
Mon Jan 23 14:36:04 UTC 2017
From: Amy Zhang <Amy.Zhang at amd.com>
- 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
More information about the amd-gfx
mailing list