Re: [PATCH 3/4] drm/amd/display: Add HDMI 2.1 VRR support from HF-VSDB

Harry Wentland <[email protected]> Fri, 31 Jul 2026 15:57:12 -0400
Newsgroups org.freedesktop.lists.amd-gfx
Message-ID <[email protected]>

On 2026-07-30 13:17, Fangzhi Zuo wrote:
> why:
> HDMI 2.1 sinks advertise their VRR range in the HDMI Forum VSDB
> (HF-VSDB), but amdgpu derived FreeSync capability only from the AMD
> VSDB. Sinks that expose just the HDMI Forum VRR capability (e.g. HDMI
> compliance EDIDs) were therefore reported as not VRR capable.
> 
> how:
> - In amdgpu_dm_update_freesync_caps(), when the AMD VSDB does not
>   provide a valid FreeSync range, fall back to the HDMI 2.1 VRR range
>   parsed by DRM core from the HF-VSDB
>   (connector->display_info.hdmi.vrr_cap). VRRMAX = 0 means "up to the
>   Base Refresh Rate"; when the EDID provides no monitor range maximum
>   either, fall back to the Base Refresh Rate (the highest refresh-rate
>   mode of the preferred timing) so a valid VRR range is still reported
>   to userspace.
> - Add VRR debug logging along the FreeSync capability and config paths.
> 
> Signed-off-by: Fangzhi Zuo <[email protected]>
> ---
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  8 +++
>  .../display/amdgpu_dm/amdgpu_dm_connector.c   | 67 +++++++++++++++++++
>  2 files changed, 75 insertions(+)
> 
> 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 ccf882a22a57..223b562f7005 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -5781,6 +5781,14 @@ STATIC_IFN_KUNIT void get_freesync_config_for_crtc(
>  	}
>  out:
>  	new_crtc_state->freesync_config = config;
> +
> +	drm_dbg_driver(new_con_state->base.connector->dev,
> +		       "VRR: cfg vrr_enabled=%d vrr_supported=%d fs_capable=%d vrefresh=%d min=%d max=%d state=%d\n",
> +		       new_crtc_state->base.vrr_enabled,
> +		       new_crtc_state->vrr_supported,
> +		       new_con_state->freesync_capable, vrefresh,
> +		       aconnector->min_vfreq, aconnector->max_vfreq,
> +		       config.state);
>  }
>  EXPORT_IF_KUNIT(get_freesync_config_for_crtc);
>  
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c
> index 2deb5abae264..ebead39939a6 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c
> @@ -3605,6 +3605,15 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
>  	if (!adev->dm.freesync_module || !dc_supports_vrr(sink->ctx->dce_version))
>  		goto update;
>  
> +	drm_dbg_driver(adev_to_drm(adev),
> +		       "VRR: enter signal=%d hdmi_vrr=%d mrange[%d-%d] hdmi.vrr_cap[sup=%d min=%d max=%d]\n",
> +		       sink->sink_signal, connector->display_info.hdmi.vrr_cap.supported,
> +		       connector->display_info.monitor_range.min_vfreq,
> +		       connector->display_info.monitor_range.max_vfreq,
> +		       connector->display_info.hdmi.vrr_cap.supported,
> +		       connector->display_info.hdmi.vrr_cap.vrr_min,
> +		       connector->display_info.hdmi.vrr_cap.vrr_max);
> +
>  	/* FIXME: Get rid of drm_edid_raw() */
>  	edid = drm_edid_raw(drm_edid);
>  
> @@ -3649,6 +3658,59 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
>  				connector->display_info.monitor_range.max_vfreq = vsdb_info.max_refresh_rate_hz;
>  			}
>  		}
> +
> +		drm_dbg_driver(adev_to_drm(adev),
> +			       "VRR: amd_vsdb i=%d fs_sup=%d min=%d max=%d fs_capable=%d\n",
> +			       i, vsdb_info.freesync_supported,
> +			       vsdb_info.min_refresh_rate_hz,
> +			       vsdb_info.max_refresh_rate_hz, freesync_capable);
> +
> +		/*
> +		 * If AMD VSDB didn't provide a valid FreeSync range, fall back to
> +		 * the HDMI 2.1 VRR capability parsed from the HF-VSDB.
> +		 */
> +		if (!freesync_capable && connector->display_info.hdmi.vrr_cap.supported) {
> +			struct drm_hdmi_vrr_cap *vrr_cap =
> +				&connector->display_info.hdmi.vrr_cap;
> +
> +			drm_dbg_driver(adev_to_drm(adev),
> +				       "VRR: HF-VSDB fallback: hdmi_vrr=1 vrr_cap[sup=%d min=%d max=%d] mrange_max=%d\n",
> +				       vrr_cap->supported, vrr_cap->vrr_min, vrr_cap->vrr_max,
> +				       connector->display_info.monitor_range.max_vfreq);
> +
> +			if (vrr_cap->supported && vrr_cap->vrr_min > 0) {
> +				amdgpu_dm_connector->min_vfreq = vrr_cap->vrr_min;
> +				amdgpu_dm_connector->max_vfreq = vrr_cap->vrr_max ?
> +					vrr_cap->vrr_max :
> +					connector->display_info.monitor_range.max_vfreq;
> +
> +				/*
> +				 * VRRMAX = 0 in the HF-VSDB means "up to the Base
> +				 * Refresh Rate". If the EDID also did not provide a
> +				 * monitor range max, fall back to the Base Refresh
> +				 * Rate (the highest refresh rate of the preferred
> +				 * timing) so a valid VRR range is still reported to
> +				 * userspace.
> +				 */
> +				if (!amdgpu_dm_connector->max_vfreq) {
> +					struct drm_display_mode *brr_mode =

Should this be `vrr_mode`?

With that fixed this is
Reviewed-by: Harry Wentland <[email protected]>

Harry

> +						amdgpu_dm_get_highest_refresh_rate_mode(amdgpu_dm_connector, true);
> +
> +					if (brr_mode)
> +						amdgpu_dm_connector->max_vfreq =
> +							drm_mode_vrefresh(brr_mode);
> +				}
> +
> +				if (amdgpu_dm_connector->max_vfreq -
> +				    amdgpu_dm_connector->min_vfreq > 10)
> +					freesync_capable = true;
> +
> +				connector->display_info.monitor_range.min_vfreq =
> +					amdgpu_dm_connector->min_vfreq;
> +				connector->display_info.monitor_range.max_vfreq =
> +					amdgpu_dm_connector->max_vfreq;
> +			}
> +		}
>  	}
>  
>  	if (amdgpu_dm_connector->dc_link)
> @@ -3692,6 +3754,11 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
>  	if (dm_con_state)
>  		dm_con_state->freesync_capable = freesync_capable;
>  
> +	drm_dbg_driver(adev_to_drm(adev),
> +		       "VRR: caps result: freesync_capable=%d min_vfreq=%d max_vfreq=%d\n",
> +		       freesync_capable, amdgpu_dm_connector->min_vfreq,
> +		       amdgpu_dm_connector->max_vfreq);
> +
>  	if (connector->state && amdgpu_dm_connector->dc_link && !freesync_capable &&
>  	    amdgpu_dm_connector->dc_link->replay_settings.config.replay_supported) {
>  		amdgpu_dm_connector->dc_link->replay_settings.config.replay_supported = false;