HDMI includes a feature called "Quick Media Switching", or QMS for short, which builds upon the existing VRR to allow for quick switching between a select few common frame rates.
Add a DRM property to the connector to allow userspace to request the kernel to use QMS. Only connectors of sources which do support QMS should register this property, though whether a specific sink supports QMS is orthogonal to this. Signed-off-by: Nicolas Frattaroli <[email protected]> --- drivers/gpu/drm/drm_atomic_helper.c | 3 +++ drivers/gpu/drm/drm_atomic_uapi.c | 4 ++++ drivers/gpu/drm/drm_connector.c | 48 +++++++++++++++++++++++++++++++++++++ include/drm/drm_connector.h | 23 ++++++++++++++++++ 4 files changed, 78 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 0664d5779282..a2919e3975a8 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -749,6 +749,9 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, new_connector_state->color_format) new_crtc_state->connectors_changed = true; + if (old_connector_state->hdmi.qms_enabled != + new_connector_state->hdmi.qms_enabled) + new_crtc_state->connectors_changed = true; } if (funcs->atomic_check) diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index c9eb01d740b3..fe9516475451 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -993,6 +993,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector, state->hdmi.broadcast_rgb = val; } else if (property == connector->color_format_property) { state->color_format = val; + } else if (property == connector->qms_enabled_property) { + state->hdmi.qms_enabled = val; } else if (connector->funcs->atomic_set_property) { return connector->funcs->atomic_set_property(connector, state, property, val); @@ -1080,6 +1082,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector, *val = state->hdmi.broadcast_rgb; } else if (property == connector->color_format_property) { *val = state->color_format; + } else if (property == connector->qms_enabled_property) { + *val = state->hdmi.qms_enabled; } else if (connector->funcs->atomic_get_property) { return connector->funcs->atomic_get_property(connector, state, property, val); diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 5c07bd221977..7ea235a58781 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -2605,6 +2605,8 @@ EXPORT_SYMBOL(drm_mode_create_scaling_mode_property); * numerator/denominator pair of a frame rate to set as the minimum VRR * target rate. Set to 0 to disable. * + * .. _VRR-MIN-DENOMINATOR: + * * "VRR_MIN_DENOMINATOR": * Default &drm_crtc integer property forming the denominator of a * numerator/denominator pair of a frame rate to set as the minimum VRR @@ -2619,11 +2621,30 @@ EXPORT_SYMBOL(drm_mode_create_scaling_mode_property); * numerator/denominator pair of a frame rate to set as the maximum VRR * target rate. Set to 0 to disable. * + * .. _VRR-MAX-DENOMINATOR: + * * "VRR_MAX_DENOMINATOR": * Default &drm_crtc integer property forming the denominator of a * numerator/denominator pair of a frame rate to set as the maximum VRR * target rate. If :ref:`VRR_MAX_NUMERATOR <VRR-MAX-NUMERATOR>` is not * zero, it must be non-zero. Otherwise, must also be zero. + * + * "qms_enabled": + * Optional &drm_connector boolean property that drivers should attach with + * drm_connector_attach_qms_enabled_property() on connectors that support + * HDMI Quick Media Switching (QMS). Present only depending on source + * capability, with no regards to sink capability. Userspace may set it to + * true if the variable refresh target rate that's expressed through + * :ref:`VRR_MIN_NUMERATOR <VRR-MIN-NUMERATOR>` divided by + * :ref:`VRR_MIN_DENOMINATOR <VRR-MIN-DENOMINATOR>` (which, in this case, + * should be equal to :ref:`VRR_MAX_NUMERATOR <VRR-MAX-NUMERATOR>` divided + * by :ref:`VRR_MAX_DENOMINATOR <VRR-MAX-DENOMINATOR>` to signal a fixed + * rate) should be achieved with signaling for HDMI Quick Media Switching. + * + * Attempting to enable QMS when the attached display is not QMS capable, + * or when the set fixed target rate is not possible with QMS, will result + * in an error during the atomic check phase that will be passed up to + * userspace to handle. */ /** @@ -3318,6 +3339,33 @@ int drm_connector_attach_color_format_property(struct drm_connector *connector, } EXPORT_SYMBOL(drm_connector_attach_color_format_property); +/** + * drm_connector_attach_qms_enabled_property - attach "qms_enabled" property + * @connector: pointer to &struct drm_connector to attach this property on. + * + * Create and attach the "qms_enabled" property to the given @connector, which + * can be used by userspace to signal that it would like to achieve the CRTC's + * desired VRR target frame rate with HDMI "Quick Media Switching". + * + * Should only be called if the source actually supports generating the packets + * needed for QMS, but is present regardless of sink support for QMS. + * + * Returns: + * Zero on success, negative errno on failure. + */ +int drm_connector_attach_qms_enabled_property(struct drm_connector *connector) +{ + connector->qms_enabled_property = + drm_property_create_bool(connector->dev, 0, "qms_enabled"); + if (!connector->qms_enabled_property) + return -ENOMEM; + + drm_object_attach_property(&connector->base, connector->qms_enabled_property, 0); + + return 0; +} +EXPORT_SYMBOL(drm_connector_attach_qms_enabled_property); + /** * drm_connector_atomic_hdr_metadata_equal - checks if the hdr metadata changed * @old_state: old connector state to compare diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 8439c82db905..a5631bebb4df 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1238,6 +1238,18 @@ struct drm_connector_hdmi_state { * deliberately not requested by the helper. */ bool scrambler_needed; + + /** + * @qms_tfr_byte: Target frame rate byte for HDMI QMS, or 0 if QMS is + * not in use. + */ + u8 qms_tfr_byte; + + /** + * @qms_enabled: Whether or not userspace requests to use HDMI Quick + * Media Switching to achieve the target frame rate. + */ + bool qms_enabled; }; /** @@ -2490,6 +2502,16 @@ struct drm_connector { */ struct drm_property *vrr_capable_property; + /** + * @qms_enabled_property: Optional atomic boolean property through which + * userspace can indicate that HDMI "Quick Media Switching" should be + * used to achieve the CRTC's target frame rate. + * + * Only HDMI connectors of sources capable of generating the right HDMI + * signalling packets should register this property. + */ + struct drm_property *qms_enabled_property; + /** * @colorspace_property: Connector property to set the suitable * colorspace supported by the sink. @@ -3016,6 +3038,7 @@ const char *drm_get_colorspace_name(enum drm_colorspace colorspace); int drm_connector_attach_color_format_property(struct drm_connector *connector, unsigned long supported_color_formats); +int drm_connector_attach_qms_enabled_property(struct drm_connector *connector); /** * drm_for_each_connector_iter - connector_list iterator macro -- 2.55.0
