From: Michal Bielaga <[email protected]> Variable Refresh Rate (VRR/FreeSync) currently only works with Single-Stream Transport (SST) DisplayPort connections. Monitors connected via MST hubs cannot utilize VRR even when they support it, because the driver only enables VRR for SST connections.
This patch enables VRR for DisplayPort MST by: - Including SIGNAL_TYPE_DISPLAY_PORT_MST in VRR capability detection - Reading VRR range from display EDID instead of MST hub DPCD, since dc_link points to the hub rather than the actual display - Fixing call order to parse EDID before checking VRR capabilities, ensuring display_info.monitor_range is populated - Properly attaching VRR property to MST connectors by reusing the master connector's property Without this patch, MST displays cannot use VRR even if they support it, limiting the user experience for multi-monitor DisplayPort MST setups. Signed-off-by: Michal Bielaga <[email protected]> --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 11 +++++++++-- .../drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 9 ++++++--- 2 files changed, 15 insertions(+), 5 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 ef026143dc1c..ac5b6c22361f 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -12644,9 +12644,16 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector, parse_edid_displayid_vrr(connector, edid); if (edid && (sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT || + sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT_MST || sink->sink_signal == SIGNAL_TYPE_EDP)) { - if (amdgpu_dm_connector->dc_link && - amdgpu_dm_connector->dc_link->dpcd_caps.allow_invalid_MSA_timing_param) { + /* For MST, check monitor range from EDID directly since the dc_link + * points to the MST hub, not the actual display + */ + if ((sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT_MST || + (amdgpu_dm_connector->dc_link && + amdgpu_dm_connector->dc_link->dpcd_caps.allow_invalid_MSA_timing_param)) && + connector->display_info.monitor_range.min_vfreq && + connector->display_info.monitor_range.max_vfreq) { amdgpu_dm_connector->min_vfreq = connector->display_info.monitor_range.min_vfreq; amdgpu_dm_connector->max_vfreq = connector->display_info.monitor_range.max_vfreq; if (amdgpu_dm_connector->max_vfreq - amdgpu_dm_connector->min_vfreq > 10) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 77a9d2c7d318..062259514b3c 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -443,6 +443,9 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector) } } + /* Update connector with EDID first so display_info.monitor_range is populated */ + drm_edid_connector_update(&aconnector->base, aconnector->drm_edid); + if (aconnector->dc_sink) { amdgpu_dm_update_freesync_caps( connector, aconnector->drm_edid); @@ -459,8 +462,6 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector) } } - drm_edid_connector_update(&aconnector->base, aconnector->drm_edid); - ret = drm_edid_connector_add_modes(connector); return ret; @@ -650,9 +651,11 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, if (connector->max_bpc_property) drm_connector_attach_max_bpc_property(connector, 8, 16); + /* Reuse VRR property from master connector for MST connectors */ connector->vrr_capable_property = master->base.vrr_capable_property; if (connector->vrr_capable_property) - drm_connector_attach_vrr_capable_property(connector); + drm_object_attach_property(&connector->base, + connector->vrr_capable_property, 0); drm_object_attach_property( &connector->base, -- 2.51.1
