[Why]
DP -> HDMI PCONs need a completely separate treatment but they did fall
into DP/eDP path in amdgpu_dm_update_freesync_caps() previously. This
could sometimes result in weird values assigned to the connector even
though it doesn't support VRR at all and needs a bit of HDMI-like
treatment.

[How]
Check if the connected sink is a HDMI -> DP converter earlier and
gate DP/eDP path

Signed-off-by: Tomasz Pakuła <[email protected]>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index f36059bb0324..2f31fe7265d9 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -13321,6 +13321,7 @@ void amdgpu_dm_update_freesync_caps(struct 
drm_connector *connector,
        struct dpcd_caps dpcd_caps = {0};
        const struct edid *edid;
        bool freesync_capable = false;
+       bool is_pcon = false;
        enum adaptive_sync_type as_type = ADAPTIVE_SYNC_TYPE_NONE;
 
        if (!connector->state) {
@@ -13349,14 +13350,18 @@ void amdgpu_dm_update_freesync_caps(struct 
drm_connector *connector,
        if (!adev->dm.freesync_module || 
!dc_supports_vrr(sink->ctx->dce_version))
                goto update;
 
+       /* Gather all data */
        edid = drm_edid_raw(drm_edid); // FIXME: Get rid of drm_edid_raw()
        parse_amd_vsdb_cea(amdgpu_dm_connector, edid, &vsdb_info);
 
-       if (amdgpu_dm_connector->dc_link)
+       if (amdgpu_dm_connector->dc_link) {
                dpcd_caps = amdgpu_dm_connector->dc_link->dpcd_caps;
+               is_pcon = dpcd_caps.dongle_type == 
DISPLAY_DONGLE_DP_HDMI_CONVERTER;
+       }
 
-       if (sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT ||
-           sink->sink_signal == SIGNAL_TYPE_EDP) {
+       /* DP & eDP excluding PCONs */
+       if ((sink->sink_signal == SIGNAL_TYPE_EDP ||
+            sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT) && !is_pcon) {
                /* Some eDP panels only have the refresh rate range info in 
DisplayID */
                if (is_monitor_range_invalid(connector))
                        parse_edid_displayid_vrr(connector, edid);
@@ -13381,14 +13386,16 @@ void amdgpu_dm_update_freesync_caps(struct 
drm_connector *connector,
                        amdgpu_dm_connector->as_type = ADAPTIVE_SYNC_TYPE_EDP;
                }
 
+       /* HDMI */
        } else if (sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A && 
vsdb_info.freesync_supported) {
                monitor_range_from_vsdb(&connector->display_info, &vsdb_info);
                freesync_capable = copy_range_to_amdgpu_connector(connector);
        }
 
-       if (amdgpu_dm_connector->dc_link)
+       if (amdgpu_dm_connector->dc_link && is_pcon)
                as_type = 
dm_get_adaptive_sync_support_type(amdgpu_dm_connector->dc_link);
 
+       /* DP -> HDMI PCON */
        if (as_type == FREESYNC_TYPE_PCON_IN_WHITELIST && 
vsdb_info.freesync_supported) {
                amdgpu_dm_connector->pack_sdp_v1_3 = true;
                amdgpu_dm_connector->as_type = as_type;
-- 
2.53.0

Reply via email to