drm/amd/display: Fix wrong resolution with DP/VGA adapter
authorIlya <Ilya.Bakoulin@amd.com>
Thu, 10 Feb 2022 16:09:33 +0000 (11:09 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 23 Feb 2022 19:22:03 +0000 (14:22 -0500)
[Why]
Hotplugging the VGA side of some DP/VGA adapters caused the display to
light up with the wrong (non-native) resolution.

This is caused by the adapter misbehaving by reporting the wrong number
of downstream ports when the VGA side is unplugged (reports 1 instead of
0), but only if the SINK_COUNT DPCD register is read more than once.

[How]
To work around the adapter behavior, remove the sink if link is
detected, but EDID cannot be read.

Reviewed-by: Wenjing Liu <Wenjing.Liu@amd.com>
Acked-by: Solomon Chiu <solomon.chiu@amd.com>
Signed-off-by: Ilya <Ilya.Bakoulin@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/core/dc_link.c
drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c

index 4179764..80c04ff 100644 (file)
@@ -1197,6 +1197,22 @@ static bool detect_link_and_local_sink(struct dc_link *link,
 
                                return false;
                        }
+
+                       if (link->type == dc_connection_sst_branch &&
+                                       link->dpcd_caps.dongle_type ==
+                                               DISPLAY_DONGLE_DP_VGA_CONVERTER &&
+                                       reason == DETECT_REASON_HPDRX) {
+                               /* Abort detection for DP-VGA adapters when EDID
+                                * can't be read and detection reason is VGA-side
+                                * hotplug
+                                */
+                               if (prev_sink)
+                                       dc_sink_release(prev_sink);
+                               link_disconnect_sink(link);
+
+                               return true;
+                       }
+
                        break;
                default:
                        break;
index 24dc662..f1bbd91 100644 (file)
@@ -298,6 +298,9 @@ static uint32_t defer_delay_converter_wa(
 
        if (link->dpcd_caps.dongle_type == DISPLAY_DONGLE_DP_VGA_CONVERTER &&
                link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_0080E1 &&
+               (link->dpcd_caps.branch_fw_revision[0] < 0x01 ||
+                               (link->dpcd_caps.branch_fw_revision[0] == 0x01 &&
+                               link->dpcd_caps.branch_fw_revision[1] < 0x40)) &&
                !memcmp(link->dpcd_caps.branch_dev_name,
                    DP_VGA_DONGLE_BRANCH_DEV_NAME,
                        sizeof(link->dpcd_caps.branch_dev_name)))