Blob Blame History Raw
From 949561eb85bcee10248e7da51d44a0325d5e0d1b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com>
Date: Fri, 4 Oct 2019 17:19:13 +0300
Subject: drm/edid: Fix HDMI VIC handling
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Git-commit: 949561eb85bcee10248e7da51d44a0325d5e0d1b
Patch-mainline: v5.5-rc1
References: bsc#1152489

Extract drm_mode_hdmi_vic() to correctly calculate the final HDMI
VIC for us. Currently this is being done a bit differently between
the AVI and HDMI infoframes. Let's get both to agree on this.

We need to allow the case where a mode is both 3D and has a HDMI
VIC. Currently we'll just refuse to generate the HDMI infoframe when
we really should be setting HDMI VIC to 0 and instead enabling 3D
stereo signalling.

If the sink doesn't even support the HDMI infoframe we should
not be picking the HDMI VIC in favor of the CEA VIC, because then
we'll end up not sending either VIC in the end.

Cc: Wayne Lin <waynelin@amd.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191004141914.20600-3-ville.syrjala@linux.intel.com
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/drm_edid.c | 37 +++++++++++++++++++++----------------
 1 file changed, 21 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 68f2c885d8ab..8f7ffc2eb82a 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -5161,11 +5161,25 @@ drm_hdmi_infoframe_set_hdr_metadata(struct hdmi_drm_infoframe *frame,
 }
 EXPORT_SYMBOL(drm_hdmi_infoframe_set_hdr_metadata);
 
+static u8 drm_mode_hdmi_vic(struct drm_connector *connector,
+			    const struct drm_display_mode *mode)
+{
+	bool has_hdmi_infoframe = connector ?
+		connector->display_info.has_hdmi_infoframe : false;
+
+	if (!has_hdmi_infoframe)
+		return 0;
+
+	/* No HDMI VIC when signalling 3D video format */
+	if (mode->flags & DRM_MODE_FLAG_3D_MASK)
+		return 0;
+
+	return drm_match_hdmi_mode(mode);
+}
+
 static u8 drm_mode_cea_vic(struct drm_connector *connector,
 			   const struct drm_display_mode *mode)
 {
-	u8 vendor_if_vic = drm_match_hdmi_mode(mode);
-	bool is_s3d = mode->flags & DRM_MODE_FLAG_3D_MASK;
 	u8 vic;
 
 	/*
@@ -5174,7 +5188,7 @@ static u8 drm_mode_cea_vic(struct drm_connector *connector,
 	 * VIC in AVI infoframes. Lets check if this mode is present in
 	 * HDMI 1.4b 4K modes
 	 */
-	if (drm_valid_hdmi_vic(vendor_if_vic) && !is_s3d)
+	if (drm_mode_hdmi_vic(connector, mode))
 		return 0;
 
 	vic = drm_match_cea_mode(mode);
@@ -5434,8 +5448,6 @@ drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame,
 	bool has_hdmi_infoframe = connector ?
 		connector->display_info.has_hdmi_infoframe : false;
 	int err;
-	u32 s3d_flags;
-	u8 vic;
 
 	if (!frame || !mode)
 		return -EINVAL;
@@ -5443,8 +5455,9 @@ drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame,
 	if (!has_hdmi_infoframe)
 		return -EINVAL;
 
-	vic = drm_match_hdmi_mode(mode);
-	s3d_flags = mode->flags & DRM_MODE_FLAG_3D_MASK;
+	err = hdmi_vendor_infoframe_init(frame);
+	if (err < 0)
+		return err;
 
 	/*
 	 * Even if it's not absolutely necessary to send the infoframe
@@ -5455,15 +5468,7 @@ drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame,
 	 * mode if the source simply stops sending the infoframe when
 	 * it wants to switch from 3D to 2D.
 	 */
-
-	if (vic && s3d_flags)
-		return -EINVAL;
-
-	err = hdmi_vendor_infoframe_init(frame);
-	if (err < 0)
-		return err;
-
-	frame->vic = vic;
+	frame->vic = drm_mode_hdmi_vic(connector, mode);
 	frame->s3d_struct = s3d_structure_from_display_mode(mode);
 
 	return 0;
-- 
2.28.0