drm/connector: Allow clearing HDMI infoframes
authorDerek Foreman <derek.foreman@collabora.com>
Mon, 2 Dec 2024 18:19:39 +0000 (12:19 -0600)
committerMaxime Ripard <mripard@kernel.org>
Tue, 17 Dec 2024 15:20:54 +0000 (16:20 +0100)
Our infoframe setting code currently lacks the ability to clear
infoframes. For some of the infoframes, we only need to replace them,
so if an error occurred when generating a new infoframe we would leave
a stale frame instead of clearing the frame.

However, the Dynamic Range and Mastering (DRM) infoframe should only
be present when displaying HDR content (ie: the HDR_OUTPUT_METADATA blob
is set). If we can't clear infoframes, the stale DRM infoframe will
remain and we can never set the display back to SDR mode.

With this change, we clear infoframes when they can not, or should not,
be generated. This fixes switching to an SDR mode from an HDR one.

Fixes: f378b77227bc ("drm/connector: hdmi: Add Infoframes generation")
Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20241202181939.724011-1-derek.foreman@collabora.com
Signed-off-by: Maxime Ripard <mripard@kernel.org>
drivers/gpu/drm/display/drm_hdmi_state_helper.c

index 80bf2829ba89b5f84fed4fa9eb1d6302e10a4f9e..d678c635a6935050ca9c1ccafbb0865f21df5d4e 100644 (file)
@@ -347,6 +347,8 @@ static int hdmi_generate_avi_infoframe(const struct drm_connector *connector,
                is_limited_range ? HDMI_QUANTIZATION_RANGE_LIMITED : HDMI_QUANTIZATION_RANGE_FULL;
        int ret;
 
+       infoframe->set = false;
+
        ret = drm_hdmi_avi_infoframe_from_display_mode(frame, connector, mode);
        if (ret)
                return ret;
@@ -376,6 +378,8 @@ static int hdmi_generate_spd_infoframe(const struct drm_connector *connector,
                &infoframe->data.spd;
        int ret;
 
+       infoframe->set = false;
+
        ret = hdmi_spd_infoframe_init(frame,
                                      connector->hdmi.vendor,
                                      connector->hdmi.product);
@@ -398,6 +402,8 @@ static int hdmi_generate_hdr_infoframe(const struct drm_connector *connector,
                &infoframe->data.drm;
        int ret;
 
+       infoframe->set = false;
+
        if (connector->max_bpc < 10)
                return 0;
 
@@ -425,6 +431,8 @@ static int hdmi_generate_hdmi_vendor_infoframe(const struct drm_connector *conne
                &infoframe->data.vendor.hdmi;
        int ret;
 
+       infoframe->set = false;
+
        if (!info->has_hdmi_infoframe)
                return 0;