From 6f11071b4a1a305d42e61fb7d943c703cbdbd6fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Paku=C5=82a?= Date: Tue, 1 Sep 2026 15:12:49 -0400 Subject: [PATCH] drm: Add passive_vrr properties for passive/desktop VRR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backport of upstream (Tomasz Pakula) amd-gfx v4 series patches 23/27 and 24/27, squashed into the drm-core change required for passive_vrr_capable. Add the PASSIVE_VRR_DISABLED atomic CRTC property (drm_crtc_state. passive_vrr_disabled) and the immutable passive_vrr_capable connector property, together with drm_connector_attach_passive_vrr_capable_property() and drm_connector_set_passive_vrr_capable_property() helpers. Passive VRR keeps a sink in its variable-refresh state during fixed refresh (desktop) use, avoiding blanking/flicker on VRR entry/exit for HDMI sinks that lack seamless VRR transitions. The property is opt-out (default enabled where the connector advertises passive_vrr_capable); lacking hardware support is not treated as failure. Not useful for DP/eDP where seamless VRR transitions are enforced by the standard. Signed-off-by: Tomasz PakuĊ‚a Signed-off-by: Fangzhi Zuo --- drivers/gpu/drm/drm_atomic_uapi.c | 4 ++ drivers/gpu/drm/drm_connector.c | 73 +++++++++++++++++++++++++++++++ drivers/gpu/drm/drm_crtc.c | 2 + drivers/gpu/drm/drm_mode_config.c | 6 +++ include/drm/drm_connector.h | 15 +++++++ include/drm/drm_crtc.h | 9 ++++ include/drm/drm_mode_config.h | 6 +++ 7 files changed, 115 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index 68d59e17ffc2d5..6ca4b369eced6a 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -420,6 +420,8 @@ static int drm_atomic_crtc_set_property(struct drm_crtc *crtc, return ret; } else if (property == config->prop_vrr_enabled) { state->vrr_enabled = val; + } else if (property == config->prop_passive_vrr_disabled) { + state->passive_vrr_disabled = val; } else if (property == config->degamma_lut_property) { const size_t elem_size = sizeof(struct drm_color_lut); u64 lut_size; @@ -505,6 +507,8 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc, *val = (state->mode_blob) ? state->mode_blob->base.id : 0; else if (property == config->prop_vrr_enabled) *val = state->vrr_enabled; + else if (property == config->prop_passive_vrr_disabled) + *val = state->passive_vrr_disabled; else if (property == config->degamma_lut_property) *val = (state->degamma_lut) ? state->degamma_lut->base.id : 0; else if (property == config->ctm_property) diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 8b4baed060f3ae..8dd69ec4ab7ee9 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -2393,6 +2393,16 @@ EXPORT_SYMBOL(drm_mode_create_scaling_mode_property); * * Absence of the property should indicate absence of support. * + * "passive_vrr_capable": + * Optional &drm_connector boolean property that drivers should attach + * with drm_connector_attach_passive_vrr_capable_property() on + * connectors that could support keeping variable refresh rate signalling + * in fixed-refresh rate scenarios like desktop work. Drivers should update + * the property value by calling + * drm_connector_set_passive_vrr_capable_property(). + * + * Absence of the property should indicate absence of support. + * * "VRR_ENABLED": * Default &drm_crtc boolean property that notifies the driver that the * content on the CRTC is suitable for variable refresh rate presentation. @@ -2411,6 +2421,17 @@ EXPORT_SYMBOL(drm_mode_create_scaling_mode_property); * * The driver may place further restrictions within these minimum * and maximum bounds. + * + * "PASSIVE_VRR_DISABLED": + * Default &drm_crtc boolean property that notifies the driver that the + * VRR singalling should be disabled in fixed refresh rate scenarios. + * Functionally, psssive vrr works the same as VRR_ENABLED == false + * but works around displays blanking (mainly HDMI) that do not support + * seamless VRR transitions. Also helps with brightness flickering during + * VRR transitions. + * + * Passive VRR mode is not that useful for DP/eDP sinks where seamless VRR + * transitions are enforced by the standard. */ /** @@ -2444,6 +2465,37 @@ int drm_connector_attach_vrr_capable_property( } EXPORT_SYMBOL(drm_connector_attach_vrr_capable_property); +/** + * drm_connector_attach_passive_vrr_capable_property - creates the + * passive_vrr_capable property + * @connector: connector to create the passive_vrr_capable property on. + * + * This is used by atomic drivers to add support for querying + * variable refresh rate on desktop capability for a connector. + * + * Returns: + * Zero on success, negative errno on failure. + */ +int drm_connector_attach_passive_vrr_capable_property( + struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + struct drm_property *prop; + + if (!connector->passive_vrr_capable_property) { + prop = drm_property_create_bool(dev, DRM_MODE_PROP_IMMUTABLE, + "passive_vrr_capable"); + if (!prop) + return -ENOMEM; + + connector->passive_vrr_capable_property = prop; + drm_object_attach_property(&connector->base, prop, 0); + } + + return 0; +} +EXPORT_SYMBOL(drm_connector_attach_passive_vrr_capable_property); + /** * drm_connector_attach_scaling_mode_property - attach atomic scaling mode property * @connector: connector to attach scaling mode property on. @@ -3154,6 +3206,27 @@ void drm_connector_set_vrr_capable_property( } EXPORT_SYMBOL(drm_connector_set_vrr_capable_property); +/** + * drm_connector_set_passive_vrr_capable_property - sets the variable refresh + * rate on desktop capable property for a connector + * @connector: drm connector + * @capable: True if the connector is variable refresh rate on desktop capable + * + * Should be used by atomic drivers to update the indicated support for + * variable refresh rate on desktop over a connector. + */ +void drm_connector_set_passive_vrr_capable_property( + struct drm_connector *connector, bool capable) +{ + if (!connector->passive_vrr_capable_property) + return; + + drm_object_property_set_value(&connector->base, + connector->passive_vrr_capable_property, + capable); +} +EXPORT_SYMBOL(drm_connector_set_passive_vrr_capable_property); + /** * drm_connector_set_panel_orientation - sets the connector's panel_orientation * @connector: connector for which to set the panel-orientation property. diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 63ead8ba675642..bd666dbc30f290 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -322,6 +322,8 @@ static int __drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc * config->prop_out_fence_ptr, 0); drm_object_attach_property(&crtc->base, config->prop_vrr_enabled, 0); + drm_object_attach_property(&crtc->base, + config->prop_passive_vrr_disabled, 0); } return 0; diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index 366f6d8212425e..b72c3c0bed9b1f 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -528,6 +528,12 @@ static int drm_mode_create_standard_properties(struct drm_device *dev) return -ENOMEM; dev->mode_config.prop_vrr_enabled = prop; + prop = drm_property_create_bool(dev, 0, + "PASSIVE_VRR_DISABLED"); + if (!prop) + return -ENOMEM; + dev->mode_config.prop_passive_vrr_disabled = prop; + prop = drm_property_create(dev, DRM_MODE_PROP_BLOB, "DEGAMMA_LUT", 0); diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 1659a220f1244d..cfc3aadff7f6d5 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -2313,6 +2313,17 @@ struct drm_connector { */ struct drm_property *vrr_capable_property; + /** + * @passive_vrr_capable_property: Optional property to help userspace + * query hardware support for passive variable refresh rate on a + * connector. Drivers can add the property to a connector by + * calling drm_connector_attach_passive_vrr_capable_property(). + * + * This should be updated only by calling + * drm_connector_set_passive_vrr_capable_property(). + */ + struct drm_property *passive_vrr_capable_property; + /** * @colorspace_property: Connector property to set the suitable * colorspace supported by the sink. @@ -2718,6 +2729,8 @@ int drm_connector_attach_scaling_mode_property(struct drm_connector *connector, u32 scaling_mode_mask); int drm_connector_attach_vrr_capable_property( struct drm_connector *connector); +int drm_connector_attach_passive_vrr_capable_property( + struct drm_connector *connector); void drm_connector_attach_panel_type_property(struct drm_connector *connector); int drm_connector_attach_broadcast_rgb_property(struct drm_connector *connector); int drm_connector_attach_colorspace_property(struct drm_connector *connector); @@ -2741,6 +2754,8 @@ void drm_connector_set_link_status_property(struct drm_connector *connector, uint64_t link_status); void drm_connector_set_vrr_capable_property( struct drm_connector *connector, bool capable); +void drm_connector_set_passive_vrr_capable_property( + struct drm_connector *connector, bool capable); int drm_connector_set_panel_orientation( struct drm_connector *connector, enum drm_panel_orientation panel_orientation); diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 152349f973e336..89b9dade605a24 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -311,6 +311,15 @@ struct drm_crtc_state { */ bool vrr_enabled; + /** + * @passive_vrr_disabled: + * + * Indicates if variable refresh rate on desktop should be enabled for + * the CRTC. Support for the requested state will depend on driver and + * hardware capabiltiy - lacking support is not treated as failure. + */ + bool passive_vrr_disabled; + /** * @self_refresh_active: * diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h index d8f5b7e9673ee1..c3dbde4ed8c7de 100644 --- a/include/drm/drm_mode_config.h +++ b/include/drm/drm_mode_config.h @@ -701,6 +701,12 @@ struct drm_mode_config { * whether variable refresh rate should be enabled on the CRTC. */ struct drm_property *prop_vrr_enabled; + /** + * @prop_passive_vrr_disabled: Default atomic CRTC property to indicate + * whether passive variable refresh rate should be disabled + * on the CRTC. + */ + struct drm_property *prop_passive_vrr_disabled; /** * @dvi_i_subconnector_property: Optional DVI-I property to