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;