Compute and attach VSC SDP and HDR metadata infoframes for logical MST
stream connectors.

Update mst_stream_enable() and implement mst_stream_update_pipe() to
configure the transcoder's Video DIP registers with VSC and HDR infoframes.
This allows fastsets (such as toggling HDR ON/OFF) to update the hardware
without triggering a full modeset.

Expose the max_bpc, HDR metadata, and DP Colorspace connector properties
during MST connector initialization to enable userspace configuration.

Change-Id: I4e79ec56a0a21650f5c70e80e4fd4d46f5fefaf9
Signed-off-by: Gil Dekel <[email protected]>
---
 drivers/gpu/drm/i915/display/intel_dp.c     |  9 +++---
 drivers/gpu/drm/i915/display/intel_dp.h     |  6 ++++
 drivers/gpu/drm/i915/display/intel_dp_mst.c | 31 ++++++++++++++++++++-
 3 files changed, 41 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 1de26c4c867f..686782d9987f 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -3157,12 +3157,13 @@ static void intel_dp_compute_as_sdp(struct intel_dp 
*intel_dp,
                as_sdp->coasting_vtotal = crtc_state->vrr.vmax;
 }
 
-static void intel_dp_compute_vsc_sdp(struct intel_dp *intel_dp,
-                                    struct intel_crtc_state *crtc_state,
-                                    const struct drm_connector_state 
*conn_state)
+void intel_dp_compute_vsc_sdp(struct intel_dp *intel_dp,
+                             struct intel_crtc_state *crtc_state,
+                             const struct drm_connector_state *conn_state)
 {
        struct intel_connector *connector = 
to_intel_connector(conn_state->connector);
        struct drm_dp_vsc_sdp *vsc;
+
        if ((!connector->dp.colorimetry_support ||
             !intel_dp_needs_vsc_sdp(crtc_state, conn_state)) &&
            !crtc_state->has_psr)
@@ -3218,7 +3219,7 @@ intel_dp_in_hdr_mode(const struct drm_connector_state 
*conn_state)
        return hdr_metadata->hdmi_metadata_type1.eotf == HDMI_EOTF_SMPTE_ST2084;
 }
 
-static void
+void
 intel_dp_compute_hdr_metadata_infoframe_sdp(struct intel_dp *intel_dp,
                                            struct intel_crtc_state *crtc_state,
                                            const struct drm_connector_state 
*conn_state)
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h 
b/drivers/gpu/drm/i915/display/intel_dp.h
index 26b3a0eb354e..29282540d6ca 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -76,6 +76,12 @@ int intel_dp_compute_config(struct intel_atomic_state *state,
                            struct intel_encoder *encoder,
                            struct intel_crtc_state *pipe_config,
                            struct drm_connector_state *conn_state);
+void intel_dp_compute_vsc_sdp(struct intel_dp *intel_dp,
+                             struct intel_crtc_state *crtc_state,
+                             const struct drm_connector_state *conn_state);
+void intel_dp_compute_hdr_metadata_infoframe_sdp(struct intel_dp *intel_dp,
+                                                struct intel_crtc_state 
*crtc_state,
+                                                const struct 
drm_connector_state *conn_state);
 bool intel_dp_needs_8b10b_fec(const struct intel_crtc_state *crtc_state,
                              bool dsc_enabled_on_crtc);
 void intel_dp_dsc_reset_config(struct intel_crtc_state *crtc_state);
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 5b76d12bb00f..d438e4942d9c 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -761,6 +761,10 @@ static int mst_stream_compute_config(struct 
intel_atomic_state *state,
 
        intel_psr_compute_config(intel_dp, pipe_config, conn_state);
 
+       intel_dp_compute_vsc_sdp(intel_dp, pipe_config, conn_state);
+
+       intel_dp_compute_hdr_metadata_infoframe_sdp(intel_dp, pipe_config, 
conn_state);
+
        return intel_dp_tunnel_atomic_compute_stream_bw(state, intel_dp, 
connector,
                                                        pipe_config);
 }
@@ -1332,6 +1336,8 @@ static void mst_stream_enable(struct intel_atomic_state 
*state,
 
        intel_ddi_enable_transcoder_func(encoder, pipe_config);
 
+       intel_dp_set_infoframes(primary_encoder, true, pipe_config, conn_state);
+
        intel_vrr_transcoder_enable(pipe_config);
 
        intel_ddi_clear_act_sent(encoder, pipe_config);
@@ -1708,6 +1714,11 @@ static int mst_topology_add_connector_properties(struct 
intel_dp *intel_dp,
        if (connector->base.max_bpc_property)
                drm_connector_attach_max_bpc_property(&connector->base, 6, 12);
 
+       if (intel_dp_has_gamut_metadata_dip(&dp_to_dig_port(intel_dp)->base))
+               
drm_connector_attach_hdr_output_metadata_property(&connector->base);
+
+       intel_attach_dp_colorspace_property(&connector->base);
+
        return drm_connector_set_path_property(&connector->base, pathprop);
 }
 
@@ -1856,6 +1867,24 @@ static const struct drm_dp_mst_topology_cbs 
mst_topology_cbs = {
        .poll_hpd_irq = mst_topology_poll_hpd_irq,
 };
 
+static void mst_stream_update_pipe(struct intel_atomic_state *state,
+                                  struct intel_encoder *encoder,
+                                  const struct intel_crtc_state *crtc_state,
+                                  const struct drm_connector_state *conn_state)
+{
+       struct intel_encoder *primary_encoder = to_primary_encoder(encoder);
+
+       /* Fallback to standard DDI updates (like Audio) */
+       intel_ddi_update_pipe(state, encoder, crtc_state, conn_state);
+
+       /*
+        * intel_ddi_update_pipe historically ignores MST for InfoFrames.
+        * We must explicitly update the Transcoder's Video DIP registers here
+        * so Atomic Fastsets (e.g. toggling HDR in the UI) propagate to the 
hardware.
+        */
+       intel_dp_set_infoframes(primary_encoder, true, crtc_state, conn_state);
+}
+
 /* Create a fake encoder for an individual MST stream */
 static struct intel_dp_mst_encoder *
 mst_stream_encoder_create(struct intel_digital_port *dig_port, enum pipe pipe)
@@ -1896,7 +1925,7 @@ mst_stream_encoder_create(struct intel_digital_port 
*dig_port, enum pipe pipe)
        encoder->disable = mst_stream_disable;
        encoder->post_disable = mst_stream_post_disable;
        encoder->post_pll_disable = mst_stream_post_pll_disable;
-       encoder->update_pipe = intel_ddi_update_pipe;
+       encoder->update_pipe = mst_stream_update_pipe;
        encoder->pre_pll_enable = mst_stream_pre_pll_enable;
        encoder->pre_enable = mst_stream_pre_enable;
        encoder->enable = mst_stream_enable;
-- 
Gil Dekel, Software Engineer, Google / ChromeOS Display and Graphics

Reply via email to