drm/msm: check HDMI HFVSDB block before adding formats

Currently, the EDID parser adds the formats based on the
parsing of the Video data blocks and other CTA blocks.

However, there is no input validation based on the
HDMI HFVSDB block to check whether the mode advertised
by the sink actually falls in the TMDS char rate limits.

Add this check in the EDID parser to make sure invalid
formats are not added to the list.

Change-Id: I9a8e8f023924421710cf27402be98150554d0271
Signed-off-by: Abhinav Kumar <abhinavk@codeaurora.org>
Signed-off-by: Narender Ankam <nankam@codeaurora.org>
diff --git a/drivers/gpu/drm/msm/sde_edid_parser.c b/drivers/gpu/drm/msm/sde_edid_parser.c
index cf0ba7e..216bb5b 100644
--- a/drivers/gpu/drm/msm/sde_edid_parser.c
+++ b/drivers/gpu/drm/msm/sde_edid_parser.c
@@ -365,6 +365,33 @@
 	else
 		SDE_EDID_DEBUG("YCbCr420 CMDB is not present\n");
 
+	/*
+	 * As per HDMI 2.0 spec, a sink supporting any modes
+	 * requiring more than 340Mhz clock rate should support
+	 * SCDC as well. This is required because we need the SCDC
+	 * channel to set the TMDS clock ratio. However in cases
+	 * where the TV publishes such a mode in its list of modes
+	 * but does not have SCDC support as per HDMI HFVSDB block
+	 * remove RGB mode support from the flags. Currently, in
+	 * the list of modes not having deep color support only RGB
+	 * modes shall requre a clock of 340Mhz and above such as the
+	 * 4K@60fps case. All other modes shall be YUV.
+	 * Deep color case is handled separately while choosing the
+	 * best mode in the _sde_hdmi_choose_best_format API where
+	 * we enable deep color only if it satisfies both source and
+	 * sink requirements. However, that API assumes that at least
+	 * RGB mode is supported on the mode. Hence, it would be better
+	 * to remove the format support flags while parsing the EDID
+	 * itself if it doesn't satisfy the HDMI spec requirement.
+	 */
+
+	list_for_each_entry(mode, &connector->probed_modes, head) {
+		if ((mode->clock > MIN_SCRAMBLER_REQ_RATE) &&
+			!connector->scdc_present) {
+			mode->flags &= ~DRM_MODE_FLAG_SUPPORTS_RGB;
+		}
+	}
+
 	SDE_EDID_DEBUG("%s -\n", __func__);
 }
 
diff --git a/drivers/gpu/drm/msm/sde_edid_parser.h b/drivers/gpu/drm/msm/sde_edid_parser.h
index fd56116..07b2ea3 100644
--- a/drivers/gpu/drm/msm/sde_edid_parser.h
+++ b/drivers/gpu/drm/msm/sde_edid_parser.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -33,6 +33,8 @@
 #define SDE_CEA_EXT    0x02
 #define SDE_EXTENDED_TAG 0x07
 
+#define MIN_SCRAMBLER_REQ_RATE 340000
+
 #define SDE_DRM_MODE_FLAG_FMT_MASK (0x3 << 20)
 
 enum extended_data_block_types {