Blob Blame History Raw
From: Zeyu Fan <Zeyu.Fan@amd.com>
Date: Thu, 20 Jul 2017 19:04:56 -0400
Subject: drm/amd/display: Implement logic for hdmi info packet bits.
Git-commit: 50e27654d778114382093eecc1d6e5b7e9343d23
Patch-mainline: v4.15-rc1
References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166

Signed-off-by: Zeyu Fan <Zeyu.Fan@amd.com>
Reviewed-by: Charlene Liu <Charlene.Liu@amd.com>
Acked-by: Harry Wentland <Harry.Wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_resource.c |   68 ++++++++++++++++++----
 drivers/gpu/drm/amd/display/dc/dc_types.h         |   25 ++++++++
 2 files changed, 83 insertions(+), 10 deletions(-)

--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -1603,10 +1603,13 @@ static void set_avi_info_frame(
 	enum scanning_type scan_type = SCANNING_TYPE_NODATA;
 	enum dc_aspect_ratio aspect = ASPECT_RATIO_NO_DATA;
 	bool itc = false;
+	uint8_t itc_value = 0;
 	uint8_t cn0_cn1 = 0;
+	unsigned int cn0_cn1_value = 0;
 	uint8_t *check_sum = NULL;
 	uint8_t byte_index = 0;
 	union hdmi_info_packet *hdmi_info = &info_frame.avi_info_packet.info_packet_hdmi;
+	union display_content_support support = {0};
 	unsigned int vic = pipe_ctx->stream->public.timing.vic;
 	enum dc_timing_3d_format format;
 
@@ -1703,26 +1706,71 @@ static void set_avi_info_frame(
 	hdmi_info->bits.R0_R3 = ACTIVE_FORMAT_ASPECT_RATIO_SAME_AS_PICTURE;
 
 	/* TODO: un-hardcode cn0_cn1 and itc */
+
 	cn0_cn1 = 0;
-	itc = false;
+	cn0_cn1_value = 0;
+
+	itc = true;
+	itc_value = 1;
+
+	support = stream->public.sink->edid_caps.content_support;
 
 	if (itc) {
-		hdmi_info->bits.ITC     = 1;
-		hdmi_info->bits.CN0_CN1 = cn0_cn1;
+		if (!support.bits.valid_content_type) {
+			cn0_cn1_value = 0;
+		} else {
+			if (cn0_cn1 == DISPLAY_CONTENT_TYPE_GRAPHICS) {
+				if (support.bits.graphics_content == 1) {
+					cn0_cn1_value = 0;
+				}
+			} else if (cn0_cn1 == DISPLAY_CONTENT_TYPE_PHOTO) {
+				if (support.bits.photo_content == 1) {
+					cn0_cn1_value = 1;
+				} else {
+					cn0_cn1_value = 0;
+					itc_value = 0;
+				}
+			} else if (cn0_cn1 == DISPLAY_CONTENT_TYPE_CINEMA) {
+				if (support.bits.cinema_content == 1) {
+					cn0_cn1_value = 2;
+				} else {
+					cn0_cn1_value = 0;
+					itc_value = 0;
+				}
+			} else if (cn0_cn1 == DISPLAY_CONTENT_TYPE_GAME) {
+				if (support.bits.game_content == 1) {
+					cn0_cn1_value = 3;
+				} else {
+					cn0_cn1_value = 0;
+					itc_value = 0;
+				}
+			}
+		}
+		hdmi_info->bits.CN0_CN1 = cn0_cn1_value;
+		hdmi_info->bits.ITC = itc_value;
 	}
 
 	/* TODO : We should handle YCC quantization */
 	/* but we do not have matrix calculation */
-	if (color_space == COLOR_SPACE_SRGB) {
-		hdmi_info->bits.Q0_Q1   = RGB_QUANTIZATION_FULL_RANGE;
-		hdmi_info->bits.YQ0_YQ1 = YYC_QUANTIZATION_FULL_RANGE;
-	} else if (color_space == COLOR_SPACE_SRGB_LIMITED) {
-		hdmi_info->bits.Q0_Q1   = RGB_QUANTIZATION_LIMITED_RANGE;
-		hdmi_info->bits.YQ0_YQ1 = YYC_QUANTIZATION_LIMITED_RANGE;
+	if (stream->public.sink->edid_caps.qs_bit == 1 &&
+			stream->public.sink->edid_caps.qy_bit == 1) {
+		if (color_space == COLOR_SPACE_SRGB ||
+			color_space == COLOR_SPACE_2020_RGB_FULLRANGE) {
+			hdmi_info->bits.Q0_Q1   = RGB_QUANTIZATION_FULL_RANGE;
+			hdmi_info->bits.YQ0_YQ1 = YYC_QUANTIZATION_FULL_RANGE;
+		} else if (color_space == COLOR_SPACE_SRGB_LIMITED ||
+					color_space == COLOR_SPACE_2020_RGB_LIMITEDRANGE) {
+			hdmi_info->bits.Q0_Q1   = RGB_QUANTIZATION_LIMITED_RANGE;
+			hdmi_info->bits.YQ0_YQ1 = YYC_QUANTIZATION_LIMITED_RANGE;
+		} else {
+			hdmi_info->bits.Q0_Q1   = RGB_QUANTIZATION_DEFAULT_RANGE;
+			hdmi_info->bits.YQ0_YQ1 = YYC_QUANTIZATION_LIMITED_RANGE;
+		}
 	} else {
 		hdmi_info->bits.Q0_Q1   = RGB_QUANTIZATION_DEFAULT_RANGE;
-		hdmi_info->bits.YQ0_YQ1 = YYC_QUANTIZATION_LIMITED_RANGE;
+		hdmi_info->bits.YQ0_YQ1   = YYC_QUANTIZATION_LIMITED_RANGE;
 	}
+
 	///VIC
 	format = stream->public.timing.timing_3d_format;
 	/*todo, add 3DStereo support*/
--- a/drivers/gpu/drm/amd/display/dc/dc_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_types.h
@@ -177,6 +177,18 @@ struct dc_edid {
 
 #define AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS 20
 
+union display_content_support {
+	unsigned int raw;
+	struct {
+		unsigned int valid_content_type :1;
+		unsigned int game_content :1;
+		unsigned int cinema_content :1;
+		unsigned int photo_content :1;
+		unsigned int graphics_content :1;
+		unsigned int reserved :27;
+	} bits;
+};
+
 struct dc_edid_caps {
 	/* sink identification */
 	uint16_t manufacturer_id;
@@ -193,6 +205,11 @@ struct dc_edid_caps {
 	uint32_t audio_latency;
 	uint32_t video_latency;
 
+	union display_content_support content_support;
+
+	uint8_t qs_bit;
+	uint8_t qy_bit;
+
 	/*HDMI 2.0 caps*/
 	bool lte_340mcsc_scramble;
 
@@ -384,6 +401,14 @@ enum scaling_transformation {
 		SCALING_TRANSFORMATION_PRESERVE_ASPECT_RATIO_SCALE
 };
 
+enum display_content_type {
+	DISPLAY_CONTENT_TYPE_NO_DATA = 0,
+	DISPLAY_CONTENT_TYPE_GRAPHICS = 1,
+	DISPLAY_CONTENT_TYPE_PHOTO = 2,
+	DISPLAY_CONTENT_TYPE_CINEMA = 4,
+	DISPLAY_CONTENT_TYPE_GAME = 8
+};
+
 /* audio*/
 
 union audio_sample_rates {