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
