FROMLIST: drm: edid: HDMI 2.0 HF-VSDB block parsing
authorNickey Yang <nickey.yang@rock-chips.com>
Mon, 17 Oct 2016 06:58:31 +0000 (14:58 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Mon, 27 Feb 2017 11:07:51 +0000 (19:07 +0800)
Adds parsing for HDMI 2.0 'HDMI Forum Vendor
Specific Data Block'. This block is present in
some HDMI 2.0 EDID's and gives information about
scrambling support, SCDC, 3D Views, and others.

Parsed parameters are stored in drm_connector
structure.
(am from: https://patchwork.kernel.org/patch/9273645)

Signed-off-by: Jose Abreu <joabreu@synopsys.com>
Change-Id: I5a1485b79a407fd27ac4754827de318175bb8f6a
Signed-off-by: Nickey Yang <nickey.yang@rock-chips.com>
drivers/gpu/drm/drm_edid.c
include/drm/drm_crtc.h
include/drm/drm_edid.h
include/linux/hdmi.h

index 8c9ac021608f3aee7280ff5816de1441716bff4f..5fedff1f5d5075b87aa0ed696bd9c25e5c980977 100644 (file)
@@ -3073,6 +3073,21 @@ static bool cea_db_is_hdmi_vsdb(const u8 *db)
        return hdmi_id == HDMI_IEEE_OUI;
 }
 
+static bool cea_db_is_hdmi_hf_vsdb(const u8 *db)
+{
+       int hdmi_id;
+
+       if (cea_db_tag(db) != VENDOR_BLOCK)
+               return false;
+
+       if (cea_db_payload_len(db) < 7)
+               return false;
+
+       hdmi_id = db[1] | (db[2] << 8) | (db[3] << 16);
+
+       return hdmi_id == HDMI_IEEE_OUI_HF;
+}
+
 #define for_each_cea_db(cea, i, start, end) \
        for ((i) = (start); (i) < (end) && (i) + cea_db_payload_len(&(cea)[(i)]) < (end); (i) += cea_db_payload_len(&(cea)[(i)]) + 1)
 
@@ -3195,6 +3210,36 @@ parse_hdmi_vsdb(struct drm_connector *connector, const u8 *db)
                    connector->audio_latency[1]);
 }
 
+static void
+parse_hdmi_hf_vsdb(struct drm_connector *connector, const u8 *db)
+{
+       u8 len = cea_db_payload_len(db);
+
+       if (len < 7)
+               return;
+
+       if (db[4] != 1)
+               return; /* invalid version */
+
+       connector->max_tmds_char = db[5] * 5;
+       connector->scdc_present = db[6] & (1 << 7);
+       connector->rr_capable = db[6] & (1 << 6);
+       connector->flags_3d = db[6] & 0x7;
+       connector->lte_340mcsc_scramble = db[6] & (1 << 3);
+
+       DRM_DEBUG_KMS("HDMI v2: max TMDS clock %d, "
+                       "scdc %s, "
+                       "rr %s, "
+                       "3D flags 0x%x, "
+                       "scramble %s\n",
+                       connector->max_tmds_char,
+                       connector->scdc_present ? "available" : "not available",
+                       connector->rr_capable ? "capable" : "not capable",
+                       connector->flags_3d,
+                       connector->lte_340mcsc_scramble ?
+                               "supported" : "not supported");
+}
+
 static void
 monitor_name(struct detailed_timing *t, void *data)
 {
@@ -3274,6 +3319,9 @@ void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid)
                                /* HDMI Vendor-Specific Data Block */
                                if (cea_db_is_hdmi_vsdb(db))
                                        parse_hdmi_vsdb(connector, db);
+                               /* HDMI Forum Vendor-Specific Data Block */
+                               else if (cea_db_is_hdmi_hf_vsdb(db))
+                                       parse_hdmi_hf_vsdb(connector, db);
                                break;
                        default:
                                break;
index a9e50f0cae9310227bd167722cfbbd3b6106e122..1bf21931d42f7d8be0db78cb6b6b867468857e2c 100644 (file)
@@ -725,6 +725,11 @@ struct drm_encoder {
  * @audio_latency: audio latency info from ELD, if found
  * @null_edid_counter: track sinks that give us all zeros for the EDID
  * @bad_edid_counter: track sinks that give us an EDID with invalid checksum
+ * @max_tmds_char: indicates the maximum TMDS Character Rate supported
+ * @scdc_present: when set the sink supports SCDC functionality
+ * @rr_capable: when set the sink is capable of initiating an SCDC read request
+ * @lte_340mcsc_scramble: when set the sink supports less than 340Mcsc scramble
+ * @flags_3d: 3D view(s) supported by the sink, see drm_edid.h (DRM_EDID_3D_*)
  * @edid_corrupt: indicates whether the last read EDID was corrupt
  * @debugfs_entry: debugfs directory for this connector
  * @state: current atomic state for this connector
@@ -800,6 +805,13 @@ struct drm_connector {
        int null_edid_counter; /* needed to workaround some HW bugs where we get all 0s */
        unsigned bad_edid_counter;
 
+       /* EDID bits HDMI 2.0 */
+       int max_tmds_char;      /* in Mcsc */
+       bool scdc_present;
+       bool rr_capable;
+       bool lte_340mcsc_scramble;
+       int flags_3d;
+
        /* Flag for raw EDID header corruption - used in Displayport
         * compliance testing - * Displayport Link CTS Core 1.2 rev1.1 4.2.2.6
         */
index 2af97691e8781382d3b2484d3bffc4eb5a43a247..4317ea41382fceb2258b25f5ebf5a0ca0f5c4590 100644 (file)
@@ -266,6 +266,11 @@ struct detailed_timing {
 
 #define DRM_ELD_CEA_SAD(mnl, sad)      (20 + (mnl) + 3 * (sad))
 
+/* HDMI 2.0 */
+#define DRM_EDID_3D_INDEPENDENT_VIEW   (1 << 2)
+#define DRM_EDID_3D_DUAL_VIEW          (1 << 1)
+#define DRM_EDID_3D_OSD_DISPARITY      (1 << 0)
+
 struct edid {
        u8 header[8];
        /* Vendor & product info */
index e9744202fa292c9f49e926b7534abf6235753db3..6e234093d435a286867934043f08e4c1974b42eb 100644 (file)
@@ -35,6 +35,7 @@ enum hdmi_infoframe_type {
 };
 
 #define HDMI_IEEE_OUI 0x000c03
+#define HDMI_IEEE_OUI_HF       0xc45dd8
 #define HDMI_INFOFRAME_HEADER_SIZE  4
 #define HDMI_AVI_INFOFRAME_SIZE    13
 #define HDMI_SPD_INFOFRAME_SIZE    25