]> exis.tech > repos - linux.git/blobdiff - drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
Merge tag 'hwmon-for-v7.2-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/groec...
[linux.git] / drivers / gpu / drm / amd / display / amdgpu_dm / amdgpu_dm_helpers.c
index f257ea91a34dcc19e34e64f50a2807807ae58480..6be7f6edd0b29366b3ce906e525f058a68db8303 100644 (file)
@@ -95,8 +95,11 @@ static u32 edid_extract_panel_id(struct edid *edid)
               (u32)EDID_PRODUCT_ID(edid);
 }
 
-static void apply_edid_quirks(struct drm_device *dev, struct edid *edid, struct dc_edid_caps *edid_caps)
+static void apply_edid_quirks(struct dc_link *link, struct edid *edid,
+                             struct dc_edid_caps *edid_caps)
 {
+       struct amdgpu_dm_connector *aconnector = link->priv;
+       struct drm_device *dev = aconnector->base.dev;
        uint32_t panel_id = edid_extract_panel_id(edid);
 
        switch (panel_id) {
@@ -126,6 +129,11 @@ static void apply_edid_quirks(struct drm_device *dev, struct edid *edid, struct
                drm_dbg_driver(dev, "Disabling VSC on monitor with panel id %X\n", panel_id);
                edid_caps->panel_patch.disable_colorimetry = true;
                break;
+       /* Workaround for monitors that get corrupted by the PHY SSC reduction */
+       case drm_edid_encode_panel_id('D', 'E', 'L', 0x4147):
+               drm_dbg_driver(dev, "Skip PHY SSC reduction on panel id %X\n", panel_id);
+               link->wa_flags.skip_phy_ssc_reduction = true;
+               break;
        default:
                return;
        }
@@ -147,7 +155,6 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
 {
        struct amdgpu_dm_connector *aconnector = link->priv;
        struct drm_connector *connector = &aconnector->base;
-       struct drm_device *dev = connector->dev;
        struct edid *edid_buf = edid ? (struct edid *) edid->raw_edid : NULL;
        struct cea_sad *sads;
        int sad_count = -1;
@@ -188,7 +195,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
                                        edid_caps->frl_dsc_max_frl_rate, edid_caps->frl_dsc_total_chunk_kbytes);
        }
 
-       apply_edid_quirks(dev, edid_buf, edid_caps);
+       apply_edid_quirks(link, edid_buf, edid_caps);
 
        sad_count = drm_edid_to_sad((struct edid *) edid->raw_edid, &sads);
        if (sad_count <= 0)
@@ -1194,11 +1201,25 @@ enum dc_edid_status dm_helpers_read_local_edid(
                        continue;
 
                edid = drm_edid_raw(drm_edid); // FIXME: Get rid of drm_edid_raw()
-               if (!edid ||
-                   edid->extensions >= sizeof(sink->dc_edid.raw_edid) / EDID_LENGTH)
+               /*
+                * Use the length of the EDID property blob populated by
+                * drm_edid_connector_update() above. It reflects the true number
+                * of EDID blocks, including any HDMI Forum EDID Extension Override
+                * Data Block (HF-EEODB) count, which the raw byte 0x7e extension
+                * count can hide (e.g. HDMI 8K sinks).
+                */
+               if (!edid || !connector->edid_blob_ptr ||
+                   connector->edid_blob_ptr->length > sizeof(sink->dc_edid.raw_edid))
                        return EDID_BAD_INPUT;
 
-               sink->dc_edid.length = EDID_LENGTH * (edid->extensions + 1);
+               /*
+                * FIXME: amdgpu_dm today does not consider the HF-EEODB, which
+                * may contain additional mode info for sinks. This is a
+                * workaround until dc_edid is refactored out from DC into
+                * amdgpu_dm's ownership, allowing amdgpu_dm to use drm_edid
+                * directly
+                */
+               sink->dc_edid.length = connector->edid_blob_ptr->length;
                memmove(sink->dc_edid.raw_edid, (uint8_t *)edid, sink->dc_edid.length);
 
                /* We don't need the original edid anymore */