From: Tomasz Pakuła <[email protected]> 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 <[email protected]> Signed-off-by: Fangzhi Zuo <[email protected]> --- 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 e997917819e8..c50c83360ba2 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 9d820a2a87ce..c429105172b0 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -2368,6 +2368,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. @@ -2386,6 +2396,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. */ /** @@ -2419,6 +2440,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. @@ -2985,6 +3037,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 63ead8ba6756..bd666dbc30f2 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 66f7dc37b597..dc1ca08655ca 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -345,6 +345,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 9f8f109c2dd1..fd370ecfc6a2 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -2212,6 +2212,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. @@ -2606,6 +2617,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); @@ -2629,6 +2642,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 c6dbe8b7db9e..642a374f403e 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 e584652ddf67..e312e6ae4d7e 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 -- 2.53.0
