From e203443c3a3fdfceeca161b78c93798bda83ebcc Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 30 Oct 2024 21:23:09 +0200 Subject: drm/i915/ptl/dp_mst: Fix slave transcoder enabling wrt. DDI function On PTL during modeset enabling configure the DDI function without enabling it for MST slave transcoders before programming the data and link M/N values. The DDI function gets enabled separately later in the transcoder enabling sequence. This fixes a slave transcoder getting stuck during enabling, leading to page flip timeout errors on the corresponding pipe. The spec requires the same programming step for ADLP+ platforms, that will be addressed separately (on those platforms the above transcoder getting stuck issue was not observed). Bspec: 68849 Reviewed-by: Luca Coelho Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20241030192313.4030617-2-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/gpu/drm/i915/display/intel_dp_mst.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 5bba078c00d8..bd5a5956123a 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -1224,6 +1224,9 @@ static void intel_mst_pre_enable_dp(struct intel_atomic_state *state, if (DISPLAY_VER(dev_priv) < 12 || !first_mst_stream) intel_ddi_enable_transcoder_clock(encoder, pipe_config); + if (DISPLAY_VER(dev_priv) >= 30 && !first_mst_stream) + intel_ddi_config_transcoder_func(encoder, pipe_config); + intel_dsc_dp_pps_write(&dig_port->base, pipe_config); intel_ddi_set_dp_msa(pipe_config, conn_state); } -- cgit v1.2.3 From 734148a1d8d1ff00b1f31a44f20bf013f820e8e0 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 30 Oct 2024 21:23:10 +0200 Subject: drm/i915/adlp+/dp_mst: Align slave transcoder enabling with spec wrt. DDI function On ADLP+ during modeset enabling configure the DDI function without enabling it for MST slave transcoders before programming the data and link M/N values. The DDI function gets enabled separately later in the transcoder enabling sequence. Align the code with the spec based on the above. v2: Move this patch earlier in the series, addressing the DP2 config fixes for all ADLP+ platforms later. Bspec: 55424, 54128, 65448, 68849 Reviewed-by: Luca Coelho Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20241030192313.4030617-3-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp_mst.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index bd5a5956123a..13449c85162d 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -1224,7 +1224,7 @@ static void intel_mst_pre_enable_dp(struct intel_atomic_state *state, if (DISPLAY_VER(dev_priv) < 12 || !first_mst_stream) intel_ddi_enable_transcoder_clock(encoder, pipe_config); - if (DISPLAY_VER(dev_priv) >= 30 && !first_mst_stream) + if (DISPLAY_VER(dev_priv) >= 13 && !first_mst_stream) intel_ddi_config_transcoder_func(encoder, pipe_config); intel_dsc_dp_pps_write(&dig_port->base, pipe_config); -- cgit v1.2.3 From 1a6330df069f90b94625ec77cb290d51a99f2c7a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 11 Nov 2024 12:34:02 +0200 Subject: drm/i915/display: convert display device identification to struct intel_display Convert intel_display_device.[ch] to struct intel_display, including callers, but excluding intel_display_device_probe() which will be handled in follow-up. v2: fix display->drm = display->drm goof-up Reviewed-by: Vinod Govindapillai Link: https://patchwork.freedesktop.org/patch/msgid/865b27b66f599e707081d46fca9f679e19a4e8aa.1731321183.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp_mst.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 13449c85162d..29f2f8952c39 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -1563,11 +1563,12 @@ static int intel_dp_mst_detect(struct drm_connector *connector, struct drm_modeset_acquire_ctx *ctx, bool force) { + struct intel_display *display = to_intel_display(connector->dev); struct drm_i915_private *i915 = to_i915(connector->dev); struct intel_connector *intel_connector = to_intel_connector(connector); struct intel_dp *intel_dp = intel_connector->mst_port; - if (!intel_display_device_enabled(i915)) + if (!intel_display_device_enabled(display)) return connector_status_disconnected; if (drm_connector_is_unregistered(connector)) -- cgit v1.2.3 From 612d02f9357669d9ba0a152e9782c15e6461d669 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 12 Nov 2024 13:10:37 +0200 Subject: drm/i915/mst: pass primary encoder to primary encoder hooks Pass the primary encoder to the primary encoder hooks. This is pedantically correct, but intel_ddi_post_pll_disable() also works with the fake encoder by coincidence. Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/a0151fddfdd5ec11a26345232cdd3ae59c8cf56a.1731409802.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp_mst.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 29f2f8952c39..7723f36ad256 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -1113,7 +1113,7 @@ static void intel_mst_post_pll_disable_dp(struct intel_atomic_state *state, if (intel_dp->active_mst_links == 0 && dig_port->base.post_pll_disable) - dig_port->base.post_pll_disable(state, encoder, old_crtc_state, old_conn_state); + dig_port->base.post_pll_disable(state, &dig_port->base, old_crtc_state, old_conn_state); } static void intel_mst_pre_pll_enable_dp(struct intel_atomic_state *state, -- cgit v1.2.3 From 45f9b3e8cb43bdb9c0cf430199ed19ba2fc0252d Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 12 Nov 2024 13:10:38 +0200 Subject: drm/i915/mst: rename intel_encoder to encoder Switch to the modern style in fake mst encoder creation. Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/4d29387fba64b925c6ab4c108782a7b5ac22628a.1731409802.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 46 ++++++++++++++--------------- 1 file changed, 23 insertions(+), 23 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp_mst.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 7723f36ad256..4a1c857f113f 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -1785,7 +1785,7 @@ static struct intel_dp_mst_encoder * intel_dp_create_fake_mst_encoder(struct intel_digital_port *dig_port, enum pipe pipe) { struct intel_dp_mst_encoder *intel_mst; - struct intel_encoder *intel_encoder; + struct intel_encoder *encoder; struct drm_device *dev = dig_port->base.base.dev; intel_mst = kzalloc(sizeof(*intel_mst), GFP_KERNEL); @@ -1794,16 +1794,16 @@ intel_dp_create_fake_mst_encoder(struct intel_digital_port *dig_port, enum pipe return NULL; intel_mst->pipe = pipe; - intel_encoder = &intel_mst->base; + encoder = &intel_mst->base; intel_mst->primary = dig_port; - drm_encoder_init(dev, &intel_encoder->base, &intel_dp_mst_enc_funcs, + drm_encoder_init(dev, &encoder->base, &intel_dp_mst_enc_funcs, DRM_MODE_ENCODER_DPMST, "DP-MST %c", pipe_name(pipe)); - intel_encoder->type = INTEL_OUTPUT_DP_MST; - intel_encoder->power_domain = dig_port->base.power_domain; - intel_encoder->port = dig_port->base.port; - intel_encoder->cloneable = 0; + encoder->type = INTEL_OUTPUT_DP_MST; + encoder->power_domain = dig_port->base.power_domain; + encoder->port = dig_port->base.port; + encoder->cloneable = 0; /* * This is wrong, but broken userspace uses the intersection * of possible_crtcs of all the encoders of a given connector @@ -1812,22 +1812,22 @@ intel_dp_create_fake_mst_encoder(struct intel_digital_port *dig_port, enum pipe * To keep such userspace functioning we must misconfigure * this to make sure the intersection is not empty :( */ - intel_encoder->pipe_mask = ~0; - - intel_encoder->compute_config = intel_dp_mst_compute_config; - intel_encoder->compute_config_late = intel_dp_mst_compute_config_late; - intel_encoder->disable = intel_mst_disable_dp; - intel_encoder->post_disable = intel_mst_post_disable_dp; - intel_encoder->post_pll_disable = intel_mst_post_pll_disable_dp; - intel_encoder->update_pipe = intel_ddi_update_pipe; - intel_encoder->pre_pll_enable = intel_mst_pre_pll_enable_dp; - intel_encoder->pre_enable = intel_mst_pre_enable_dp; - intel_encoder->enable = intel_mst_enable_dp; - intel_encoder->audio_enable = intel_audio_codec_enable; - intel_encoder->audio_disable = intel_audio_codec_disable; - intel_encoder->get_hw_state = intel_dp_mst_enc_get_hw_state; - intel_encoder->get_config = intel_dp_mst_enc_get_config; - intel_encoder->initial_fastset_check = intel_dp_mst_initial_fastset_check; + encoder->pipe_mask = ~0; + + encoder->compute_config = intel_dp_mst_compute_config; + encoder->compute_config_late = intel_dp_mst_compute_config_late; + encoder->disable = intel_mst_disable_dp; + encoder->post_disable = intel_mst_post_disable_dp; + encoder->post_pll_disable = intel_mst_post_pll_disable_dp; + encoder->update_pipe = intel_ddi_update_pipe; + encoder->pre_pll_enable = intel_mst_pre_pll_enable_dp; + encoder->pre_enable = intel_mst_pre_enable_dp; + encoder->enable = intel_mst_enable_dp; + encoder->audio_enable = intel_audio_codec_enable; + encoder->audio_disable = intel_audio_codec_disable; + encoder->get_hw_state = intel_dp_mst_enc_get_hw_state; + encoder->get_config = intel_dp_mst_enc_get_config; + encoder->initial_fastset_check = intel_dp_mst_initial_fastset_check; return intel_mst; -- cgit v1.2.3 From ca743f5faca00a00ba17b115db1f1cea5930f622 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 12 Nov 2024 13:10:39 +0200 Subject: drm/i915/mst: introduce to_primary_encoder() and to_primary_dp() Add helpers to_primary_encoder() and to_primary_dp() to convert fake MST encoder pointers to primary encoder and DP pointers, respectively, and use them. The main point is to highlight the primary encoder and DP usage. Very few places actually need the struct intel_dp_mst_encoder pointer, or the primary struct intel_digital_port, so ditch them where possible for clarity. Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/ff8786c04bae053055783f720f89a4d9f9815c70.1731409802.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 98 +++++++++++++++-------------- 1 file changed, 52 insertions(+), 46 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp_mst.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 4a1c857f113f..037f71eac5e8 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -53,6 +53,24 @@ #include "intel_vdsc.h" #include "skl_scaler.h" +/* From fake MST encoder to primary encoder */ +static struct intel_encoder *to_primary_encoder(struct intel_encoder *encoder) +{ + struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder); + struct intel_digital_port *dig_port = intel_mst->primary; + + return &dig_port->base; +} + +/* From fake MST encoder to primary DP */ +static struct intel_dp *to_primary_dp(struct intel_encoder *encoder) +{ + struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder); + struct intel_digital_port *dig_port = intel_mst->primary; + + return &dig_port->dp; +} + static int intel_dp_mst_max_dpt_bpp(const struct intel_crtc_state *crtc_state, bool dsc) { @@ -171,8 +189,7 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, bool dsc) { struct drm_atomic_state *state = crtc_state->uapi.state; - struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder); - struct intel_dp *intel_dp = &intel_mst->primary->dp; + struct intel_dp *intel_dp = to_primary_dp(encoder); struct drm_dp_mst_topology_state *mst_state; struct intel_connector *connector = to_intel_connector(conn_state->connector); @@ -422,8 +439,7 @@ static int intel_dp_mst_update_slots(struct intel_encoder *encoder, struct drm_connector_state *conn_state) { struct drm_i915_private *i915 = to_i915(encoder->base.dev); - struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder); - struct intel_dp *intel_dp = &intel_mst->primary->dp; + struct intel_dp *intel_dp = to_primary_dp(encoder); struct drm_dp_mst_topology_mgr *mgr = &intel_dp->mst_mgr; struct drm_dp_mst_topology_state *topology_state; u8 link_coding_cap = intel_dp_is_uhbr(crtc_state) ? @@ -581,8 +597,7 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder, struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_atomic_state *state = to_intel_atomic_state(conn_state->state); struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); - struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder); - struct intel_dp *intel_dp = &intel_mst->primary->dp; + struct intel_dp *intel_dp = to_primary_dp(encoder); struct intel_connector *connector = to_intel_connector(conn_state->connector); const struct drm_display_mode *adjusted_mode = @@ -855,8 +870,7 @@ static int intel_dp_mst_compute_config_late(struct intel_encoder *encoder, struct drm_connector_state *conn_state) { struct intel_atomic_state *state = to_intel_atomic_state(conn_state->state); - struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder); - struct intel_dp *intel_dp = &intel_mst->primary->dp; + struct intel_dp *intel_dp = to_primary_dp(encoder); /* lowest numbered transcoder will be designated master */ crtc_state->mst_master_transcoder = @@ -970,8 +984,7 @@ static void wait_for_act_sent(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { struct drm_i915_private *i915 = to_i915(encoder->base.dev); - struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder); - struct intel_dp *intel_dp = &intel_mst->primary->dp; + struct intel_dp *intel_dp = to_primary_dp(encoder); if (intel_de_wait_for_set(i915, dp_tp_status_reg(encoder, crtc_state), DP_TP_STATUS_ACT_SENT, 1)) @@ -986,8 +999,7 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state, const struct drm_connector_state *old_conn_state) { struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder); - struct intel_digital_port *dig_port = intel_mst->primary; - struct intel_dp *intel_dp = &dig_port->dp; + struct intel_dp *intel_dp = to_primary_dp(encoder); struct intel_connector *connector = to_intel_connector(old_conn_state->connector); struct drm_i915_private *i915 = to_i915(connector->base.dev); @@ -1010,8 +1022,8 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state, { struct intel_display *display = to_intel_display(encoder); struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder); - struct intel_digital_port *dig_port = intel_mst->primary; - struct intel_dp *intel_dp = &dig_port->dp; + struct intel_encoder *primary_encoder = to_primary_encoder(encoder); + struct intel_dp *intel_dp = to_primary_dp(encoder); struct intel_connector *connector = to_intel_connector(old_conn_state->connector); struct drm_dp_mst_topology_state *old_mst_state = @@ -1080,8 +1092,7 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state, * BSpec 4287: disable DIP after the transcoder is disabled and before * the transcoder clock select is set to none. */ - intel_dp_set_infoframes(&dig_port->base, false, - old_crtc_state, NULL); + intel_dp_set_infoframes(primary_encoder, false, old_crtc_state, NULL); /* * From TGL spec: "If multi-stream slave transcoder: Configure * Transcoder Clock Select to direct no clock to the transcoder" @@ -1095,8 +1106,8 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state, intel_mst->connector = NULL; if (last_mst_stream) - dig_port->base.post_disable(state, &dig_port->base, - old_crtc_state, NULL); + primary_encoder->post_disable(state, primary_encoder, + old_crtc_state, NULL); drm_dbg_kms(&dev_priv->drm, "active links %d\n", intel_dp->active_mst_links); @@ -1107,13 +1118,12 @@ static void intel_mst_post_pll_disable_dp(struct intel_atomic_state *state, const struct intel_crtc_state *old_crtc_state, const struct drm_connector_state *old_conn_state) { - struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder); - struct intel_digital_port *dig_port = intel_mst->primary; - struct intel_dp *intel_dp = &dig_port->dp; + struct intel_encoder *primary_encoder = to_primary_encoder(encoder); + struct intel_dp *intel_dp = to_primary_dp(encoder); if (intel_dp->active_mst_links == 0 && - dig_port->base.post_pll_disable) - dig_port->base.post_pll_disable(state, &dig_port->base, old_crtc_state, old_conn_state); + primary_encoder->post_pll_disable) + primary_encoder->post_pll_disable(state, primary_encoder, old_crtc_state, old_conn_state); } static void intel_mst_pre_pll_enable_dp(struct intel_atomic_state *state, @@ -1121,19 +1131,18 @@ static void intel_mst_pre_pll_enable_dp(struct intel_atomic_state *state, const struct intel_crtc_state *pipe_config, const struct drm_connector_state *conn_state) { - struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder); - struct intel_digital_port *dig_port = intel_mst->primary; - struct intel_dp *intel_dp = &dig_port->dp; + struct intel_encoder *primary_encoder = to_primary_encoder(encoder); + struct intel_dp *intel_dp = to_primary_dp(encoder); if (intel_dp->active_mst_links == 0) - dig_port->base.pre_pll_enable(state, &dig_port->base, - pipe_config, NULL); + primary_encoder->pre_pll_enable(state, primary_encoder, + pipe_config, NULL); else /* * The port PLL state needs to get updated for secondary * streams as for the primary stream. */ - intel_ddi_update_active_dpll(state, &dig_port->base, + intel_ddi_update_active_dpll(state, primary_encoder, to_intel_crtc(pipe_config->uapi.crtc)); } @@ -1170,8 +1179,8 @@ static void intel_mst_pre_enable_dp(struct intel_atomic_state *state, const struct drm_connector_state *conn_state) { struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder); - struct intel_digital_port *dig_port = intel_mst->primary; - struct intel_dp *intel_dp = &dig_port->dp; + struct intel_encoder *primary_encoder = to_primary_encoder(encoder); + struct intel_dp *intel_dp = to_primary_dp(encoder); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_connector *connector = to_intel_connector(conn_state->connector); @@ -1201,8 +1210,8 @@ static void intel_mst_pre_enable_dp(struct intel_atomic_state *state, intel_dp_sink_enable_decompression(state, connector, pipe_config); if (first_mst_stream) { - dig_port->base.pre_enable(state, &dig_port->base, - pipe_config, NULL); + primary_encoder->pre_enable(state, primary_encoder, + pipe_config, NULL); intel_mst_reprobe_topology(intel_dp, pipe_config); } @@ -1212,11 +1221,11 @@ static void intel_mst_pre_enable_dp(struct intel_atomic_state *state, ret = drm_dp_add_payload_part1(&intel_dp->mst_mgr, mst_state, drm_atomic_get_mst_payload_state(mst_state, connector->port)); if (ret < 0) - intel_dp_queue_modeset_retry_for_link(state, &dig_port->base, pipe_config); + intel_dp_queue_modeset_retry_for_link(state, primary_encoder, pipe_config); /* * Before Gen 12 this is not done as part of - * dig_port->base.pre_enable() and should be done here. For + * primary_encoder->pre_enable() and should be done here. For * Gen 12+ the step in which this should be done is different for the * first MST stream, so it's done on the DDI for the first stream and * here for the following ones. @@ -1227,7 +1236,7 @@ static void intel_mst_pre_enable_dp(struct intel_atomic_state *state, if (DISPLAY_VER(dev_priv) >= 13 && !first_mst_stream) intel_ddi_config_transcoder_func(encoder, pipe_config); - intel_dsc_dp_pps_write(&dig_port->base, pipe_config); + intel_dsc_dp_pps_write(primary_encoder, pipe_config); intel_ddi_set_dp_msa(pipe_config, conn_state); } @@ -1270,9 +1279,8 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state, const struct drm_connector_state *conn_state) { struct intel_display *display = to_intel_display(encoder); - struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder); - struct intel_digital_port *dig_port = intel_mst->primary; - struct intel_dp *intel_dp = &dig_port->dp; + struct intel_encoder *primary_encoder = to_primary_encoder(encoder); + struct intel_dp *intel_dp = to_primary_dp(encoder); struct intel_connector *connector = to_intel_connector(conn_state->connector); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_dp_mst_topology_state *mst_state = @@ -1316,7 +1324,7 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state, drm_atomic_get_mst_payload_state(mst_state, connector->port)); if (ret < 0) - intel_dp_queue_modeset_retry_for_link(state, &dig_port->base, pipe_config); + intel_dp_queue_modeset_retry_for_link(state, primary_encoder, pipe_config); if (DISPLAY_VER(dev_priv) >= 12) intel_de_rmw(dev_priv, hsw_chicken_trans_reg(dev_priv, trans), @@ -1350,19 +1358,17 @@ static bool intel_dp_mst_enc_get_hw_state(struct intel_encoder *encoder, static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { - struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder); - struct intel_digital_port *dig_port = intel_mst->primary; + struct intel_encoder *primary_encoder = to_primary_encoder(encoder); - dig_port->base.get_config(&dig_port->base, pipe_config); + primary_encoder->get_config(primary_encoder, pipe_config); } static bool intel_dp_mst_initial_fastset_check(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state) { - struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder); - struct intel_digital_port *dig_port = intel_mst->primary; + struct intel_encoder *primary_encoder = to_primary_encoder(encoder); - return intel_dp_initial_fastset_check(&dig_port->base, crtc_state); + return intel_dp_initial_fastset_check(primary_encoder, crtc_state); } static int intel_dp_mst_get_ddc_modes(struct drm_connector *connector) -- cgit v1.2.3 From 3e5c6c719967adbf9f66cc3c1a961050629805f8 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 12 Nov 2024 13:10:40 +0200 Subject: drm/i915/mst: use primary_encoder in fake mst encoder creation Use a primary_encoder local variable in intel_dp_create_fake_mst_encoder() for clarity. Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/7c9ad1db97550b7eacb1f010521704f623b0c689.1731409802.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp_mst.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 037f71eac5e8..7641ced64610 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -1790,6 +1790,7 @@ static const struct drm_dp_mst_topology_cbs mst_cbs = { static struct intel_dp_mst_encoder * intel_dp_create_fake_mst_encoder(struct intel_digital_port *dig_port, enum pipe pipe) { + struct intel_encoder *primary_encoder = &dig_port->base; struct intel_dp_mst_encoder *intel_mst; struct intel_encoder *encoder; struct drm_device *dev = dig_port->base.base.dev; @@ -1807,8 +1808,8 @@ intel_dp_create_fake_mst_encoder(struct intel_digital_port *dig_port, enum pipe DRM_MODE_ENCODER_DPMST, "DP-MST %c", pipe_name(pipe)); encoder->type = INTEL_OUTPUT_DP_MST; - encoder->power_domain = dig_port->base.power_domain; - encoder->port = dig_port->base.port; + encoder->power_domain = primary_encoder->power_domain; + encoder->port = primary_encoder->port; encoder->cloneable = 0; /* * This is wrong, but broken userspace uses the intersection -- cgit v1.2.3 From 8c6942748b35cd94a0cfa4e72f19169733cb0395 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 12 Nov 2024 13:10:41 +0200 Subject: drm/i915/display: make CHICKEN_TRANS() display version aware Making register macros platform or display version aware is not exactly something I want to promote widely, but in this case it's the lesser of two evils. hsw_chicken_trans_reg() is not pretty, and it doesn't have a suitable home. v2: Rebase Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/712c17ee22537b0628aa32695743bc017b3fe332.1731409802.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp_mst.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 7641ced64610..5afbaa5b1841 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -1326,8 +1326,8 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state, if (ret < 0) intel_dp_queue_modeset_retry_for_link(state, primary_encoder, pipe_config); - if (DISPLAY_VER(dev_priv) >= 12) - intel_de_rmw(dev_priv, hsw_chicken_trans_reg(dev_priv, trans), + if (DISPLAY_VER(display) >= 12) + intel_de_rmw(display, CHICKEN_TRANS(display, trans), FECSTALL_DIS_DPTSTREAM_DPTTG, pipe_config->fec_enable ? FECSTALL_DIS_DPTSTREAM_DPTTG : 0); -- cgit v1.2.3 From 529798bd786a83180eba8da87421ba64d8bb873a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 12 Nov 2024 13:10:42 +0200 Subject: drm/i915/mst: convert to struct intel_display struct intel_display will replace struct drm_i915_private as the main display device data structure. Convert the DP MST code to struct intel_display as much as possible. Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/84c9923fccdd779f0ca713cab1d26a0c802b140c.1731409802.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 170 ++++++++++++++-------------- 1 file changed, 85 insertions(+), 85 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp_mst.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 5afbaa5b1841..ef7f510c07a7 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -74,11 +74,11 @@ static struct intel_dp *to_primary_dp(struct intel_encoder *encoder) static int intel_dp_mst_max_dpt_bpp(const struct intel_crtc_state *crtc_state, bool dsc) { - struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; - if (!intel_dp_is_uhbr(crtc_state) || DISPLAY_VER(i915) >= 20 || !dsc) + if (!intel_dp_is_uhbr(crtc_state) || DISPLAY_VER(display) >= 20 || !dsc) return INT_MAX; /* @@ -188,12 +188,12 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, int step, bool dsc) { + struct intel_display *display = to_intel_display(encoder); struct drm_atomic_state *state = crtc_state->uapi.state; struct intel_dp *intel_dp = to_primary_dp(encoder); struct drm_dp_mst_topology_state *mst_state; struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; int bpp, slots = -EINVAL; @@ -221,18 +221,18 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, max_dpt_bpp = intel_dp_mst_max_dpt_bpp(crtc_state, dsc); if (max_bpp > max_dpt_bpp) { - drm_dbg_kms(&i915->drm, "Limiting bpp to max DPT bpp (%d -> %d)\n", + drm_dbg_kms(display->drm, "Limiting bpp to max DPT bpp (%d -> %d)\n", max_bpp, max_dpt_bpp); max_bpp = max_dpt_bpp; } - drm_dbg_kms(&i915->drm, "Looking for slots in range min bpp %d max bpp %d\n", + drm_dbg_kms(display->drm, "Looking for slots in range min bpp %d max bpp %d\n", min_bpp, max_bpp); if (dsc) { dsc_slice_count = intel_dp_mst_dsc_get_slice_count(connector, crtc_state); if (!dsc_slice_count) { - drm_dbg_kms(&i915->drm, "Can't get valid DSC slice count\n"); + drm_dbg_kms(display->drm, "Can't get valid DSC slice count\n"); return -ENOSPC; } @@ -245,7 +245,7 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, int remote_tu; fixed20_12 pbn; - drm_dbg_kms(&i915->drm, "Trying bpp %d\n", bpp); + drm_dbg_kms(display->drm, "Trying bpp %d\n", bpp); link_bpp_x16 = fxp_q4_from_int(dsc ? bpp : intel_dp_output_bpp(crtc_state->output_format, bpp)); @@ -298,7 +298,7 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, pbn.full = remote_tu * mst_state->pbn_div.full; crtc_state->pbn = dfixed_trunc(pbn); - drm_WARN_ON(&i915->drm, remote_tu < crtc_state->dp_m_n.tu); + drm_WARN_ON(display->drm, remote_tu < crtc_state->dp_m_n.tu); crtc_state->dp_m_n.tu = remote_tu; slots = drm_dp_atomic_find_time_slots(state, &intel_dp->mst_mgr, @@ -308,7 +308,7 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, return slots; if (slots >= 0) { - drm_WARN_ON(&i915->drm, slots != crtc_state->dp_m_n.tu); + drm_WARN_ON(display->drm, slots != crtc_state->dp_m_n.tu); break; } @@ -319,14 +319,15 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, slots = ret; if (slots < 0) { - drm_dbg_kms(&i915->drm, "failed finding vcpi slots:%d\n", + drm_dbg_kms(display->drm, "failed finding vcpi slots:%d\n", slots); } else { if (!dsc) crtc_state->pipe_bpp = bpp; else crtc_state->dsc.compressed_bpp_x16 = fxp_q4_from_int(bpp); - drm_dbg_kms(&i915->drm, "Got %d slots for pipe bpp %d dsc %d\n", slots, bpp, dsc); + drm_dbg_kms(display->drm, "Got %d slots for pipe bpp %d dsc %d\n", + slots, bpp, dsc); } return slots; @@ -360,8 +361,8 @@ static int intel_dp_dsc_mst_compute_link_config(struct intel_encoder *encoder, struct drm_connector_state *conn_state, struct link_config_limits *limits) { - struct intel_connector *connector = - to_intel_connector(conn_state->connector); + struct intel_display *display = to_intel_display(encoder); + struct intel_connector *connector = to_intel_connector(conn_state->connector); struct drm_i915_private *i915 = to_i915(connector->base.dev); int slots = -EINVAL; int i, num_bpc; @@ -371,7 +372,7 @@ static int intel_dp_dsc_mst_compute_link_config(struct intel_encoder *encoder, int min_compressed_bpp, max_compressed_bpp; /* Max DSC Input BPC for ICL is 10 and for TGL+ is 12 */ - if (DISPLAY_VER(i915) >= 12) + if (DISPLAY_VER(display) >= 12) dsc_max_bpc = min_t(u8, 12, conn_state->max_requested_bpc); else dsc_max_bpc = min_t(u8, 10, conn_state->max_requested_bpc); @@ -382,7 +383,7 @@ static int intel_dp_dsc_mst_compute_link_config(struct intel_encoder *encoder, num_bpc = drm_dp_dsc_sink_supported_input_bpcs(connector->dp.dsc_dpcd, dsc_bpc); - drm_dbg_kms(&i915->drm, "DSC Source supported min bpp %d max bpp %d\n", + drm_dbg_kms(display->drm, "DSC Source supported min bpp %d max bpp %d\n", min_bpp, max_bpp); sink_max_bpp = dsc_bpc[0] * 3; @@ -395,7 +396,7 @@ static int intel_dp_dsc_mst_compute_link_config(struct intel_encoder *encoder, sink_max_bpp = dsc_bpc[i] * 3; } - drm_dbg_kms(&i915->drm, "DSC Sink supported min bpp %d max bpp %d\n", + drm_dbg_kms(display->drm, "DSC Sink supported min bpp %d max bpp %d\n", sink_min_bpp, sink_max_bpp); if (min_bpp < sink_min_bpp) @@ -416,7 +417,7 @@ static int intel_dp_dsc_mst_compute_link_config(struct intel_encoder *encoder, min_compressed_bpp = max(min_compressed_bpp, fxp_q4_to_int_roundup(limits->link.min_bpp_x16)); - drm_dbg_kms(&i915->drm, "DSC Sink supported compressed min bpp %d compressed max bpp %d\n", + drm_dbg_kms(display->drm, "DSC Sink supported compressed min bpp %d compressed max bpp %d\n", min_compressed_bpp, max_compressed_bpp); /* Align compressed bpps according to our own constraints */ @@ -438,7 +439,7 @@ static int intel_dp_mst_update_slots(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state, struct drm_connector_state *conn_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_dp *intel_dp = to_primary_dp(encoder); struct drm_dp_mst_topology_mgr *mgr = &intel_dp->mst_mgr; struct drm_dp_mst_topology_state *topology_state; @@ -447,7 +448,7 @@ static int intel_dp_mst_update_slots(struct intel_encoder *encoder, topology_state = drm_atomic_get_mst_topology_state(conn_state->state, mgr); if (IS_ERR(topology_state)) { - drm_dbg_kms(&i915->drm, "slot update failed\n"); + drm_dbg_kms(display->drm, "slot update failed\n"); return PTR_ERR(topology_state); } @@ -495,7 +496,7 @@ adjust_limits_for_dsc_hblank_expansion_quirk(const struct intel_connector *conne struct link_config_limits *limits, bool dsc) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); const struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); int min_bpp_x16 = limits->link.min_bpp_x16; @@ -504,14 +505,14 @@ adjust_limits_for_dsc_hblank_expansion_quirk(const struct intel_connector *conne if (!dsc) { if (intel_dp_supports_dsc(connector, crtc_state)) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CRTC:%d:%s][CONNECTOR:%d:%s] DSC needed by hblank expansion quirk\n", crtc->base.base.id, crtc->base.name, connector->base.base.id, connector->base.name); return false; } - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CRTC:%d:%s][CONNECTOR:%d:%s] Increasing link min bpp to 24 due to hblank expansion quirk\n", crtc->base.base.id, crtc->base.name, connector->base.base.id, connector->base.name); @@ -524,7 +525,7 @@ adjust_limits_for_dsc_hblank_expansion_quirk(const struct intel_connector *conne return true; } - drm_WARN_ON(&i915->drm, limits->min_rate != limits->max_rate); + drm_WARN_ON(display->drm, limits->min_rate != limits->max_rate); if (limits->max_rate < 540000) min_bpp_x16 = fxp_q4_from_int(13); @@ -534,7 +535,7 @@ adjust_limits_for_dsc_hblank_expansion_quirk(const struct intel_connector *conne if (limits->link.min_bpp_x16 >= min_bpp_x16) return true; - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CRTC:%d:%s][CONNECTOR:%d:%s] Increasing link min bpp to " FXP_Q4_FMT " in DSC mode due to hblank expansion quirk\n", crtc->base.base.id, crtc->base.name, connector->base.base.id, connector->base.name, @@ -594,6 +595,7 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state) { + struct intel_display *display = to_intel_display(encoder); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_atomic_state *state = to_intel_atomic_state(conn_state->state); struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); @@ -646,7 +648,7 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder, /* enable compression if the mode doesn't fit available BW */ if (dsc_needed) { - drm_dbg_kms(&dev_priv->drm, "Try DSC (fallback=%s, joiner=%s, force=%s)\n", + drm_dbg_kms(display->drm, "Try DSC (fallback=%s, joiner=%s, force=%s)\n", str_yes_no(ret), str_yes_no(joiner_needs_dsc), str_yes_no(intel_dp->force_dsc_en)); @@ -664,12 +666,13 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder, * FIXME: As bpc is hardcoded to 8, as mentioned above, * WARN and ignore the debug flag force_dsc_bpc for now. */ - drm_WARN(&dev_priv->drm, intel_dp->force_dsc_bpc, "Cannot Force BPC for MST\n"); + drm_WARN(display->drm, intel_dp->force_dsc_bpc, + "Cannot Force BPC for MST\n"); /* * Try to get at least some timeslots and then see, if * we can fit there with DSC. */ - drm_dbg_kms(&dev_priv->drm, "Trying to find VCPI slots in DSC mode\n"); + drm_dbg_kms(display->drm, "Trying to find VCPI slots in DSC mode\n"); ret = intel_dp_dsc_mst_compute_link_config(encoder, pipe_config, conn_state, &limits); @@ -691,7 +694,7 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder, pipe_config->limited_color_range = intel_dp_limited_color_range(pipe_config, conn_state); - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) + if (display->platform.geminilake || display->platform.broxton) pipe_config->lane_lat_optim_mask = bxt_dpio_phy_calc_lane_lat_optim_mask(pipe_config->lane_count); @@ -713,13 +716,13 @@ static unsigned int intel_dp_mst_transcoder_mask(struct intel_atomic_state *state, struct intel_dp *mst_port) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); const struct intel_digital_connector_state *conn_state; struct intel_connector *connector; u8 transcoders = 0; int i; - if (DISPLAY_VER(dev_priv) < 12) + if (DISPLAY_VER(display) < 12) return 0; for_each_new_intel_connector_in_state(state, connector, conn_state, i) { @@ -773,7 +776,7 @@ static int intel_dp_mst_check_fec_change(struct intel_atomic_state *state, struct drm_dp_mst_topology_mgr *mst_mgr, struct intel_link_bw_limits *limits) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_crtc *crtc; u8 mst_pipe_mask; u8 fec_pipe_mask = 0; @@ -781,12 +784,12 @@ static int intel_dp_mst_check_fec_change(struct intel_atomic_state *state, mst_pipe_mask = get_pipes_downstream_of_mst_port(state, mst_mgr, NULL); - for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, mst_pipe_mask) { + for_each_intel_crtc_in_pipe_mask(display->drm, crtc, mst_pipe_mask) { struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); /* Atomic connector check should've added all the MST CRTCs. */ - if (drm_WARN_ON(&i915->drm, !crtc_state)) + if (drm_WARN_ON(display->drm, !crtc_state)) return -EINVAL; if (crtc_state->fec_enable) @@ -896,7 +899,7 @@ static int intel_dp_mst_atomic_topology_check(struct intel_connector *connector, struct intel_atomic_state *state) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(connector); struct drm_connector_list_iter connector_list_iter; struct intel_connector *connector_iter; int ret = 0; @@ -904,7 +907,7 @@ intel_dp_mst_atomic_topology_check(struct intel_connector *connector, if (!intel_connector_needs_modeset(state, &connector->base)) return 0; - drm_connector_list_iter_begin(&dev_priv->drm, &connector_list_iter); + drm_connector_list_iter_begin(display->drm, &connector_list_iter); for_each_intel_connector_iter(connector_iter, &connector_list_iter) { struct intel_digital_connector_state *conn_iter_state; struct intel_crtc_state *crtc_state; @@ -974,21 +977,21 @@ intel_dp_mst_atomic_check(struct drm_connector *connector, static void clear_act_sent(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); - intel_de_write(i915, dp_tp_status_reg(encoder, crtc_state), + intel_de_write(display, dp_tp_status_reg(encoder, crtc_state), DP_TP_STATUS_ACT_SENT); } static void wait_for_act_sent(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_dp *intel_dp = to_primary_dp(encoder); - if (intel_de_wait_for_set(i915, dp_tp_status_reg(encoder, crtc_state), + if (intel_de_wait_for_set(display, dp_tp_status_reg(encoder, crtc_state), DP_TP_STATUS_ACT_SENT, 1)) - drm_err(&i915->drm, "Timed out waiting for ACT sent\n"); + drm_err(display->drm, "Timed out waiting for ACT sent\n"); drm_dp_check_act_status(&intel_dp->mst_mgr); } @@ -998,13 +1001,13 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state, const struct intel_crtc_state *old_crtc_state, const struct drm_connector_state *old_conn_state) { + struct intel_display *display = to_intel_display(state); struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder); struct intel_dp *intel_dp = to_primary_dp(encoder); struct intel_connector *connector = to_intel_connector(old_conn_state->connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); - drm_dbg_kms(&i915->drm, "active links %d\n", + drm_dbg_kms(display->drm, "active links %d\n", intel_dp->active_mst_links); if (intel_dp->active_mst_links == 1) @@ -1034,15 +1037,13 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state, drm_atomic_get_mst_payload_state(old_mst_state, connector->port); struct drm_dp_mst_atomic_payload *new_payload = drm_atomic_get_mst_payload_state(new_mst_state, connector->port); - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct intel_crtc *pipe_crtc; bool last_mst_stream; int i; intel_dp->active_mst_links--; last_mst_stream = intel_dp->active_mst_links == 0; - drm_WARN_ON(&dev_priv->drm, - DISPLAY_VER(dev_priv) >= 12 && last_mst_stream && + drm_WARN_ON(display->drm, DISPLAY_VER(display) >= 12 && last_mst_stream && !intel_dp_mst_is_master_trans(old_crtc_state)); for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state, i) { @@ -1058,8 +1059,8 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state, clear_act_sent(encoder, old_crtc_state); - intel_de_rmw(dev_priv, - TRANS_DDI_FUNC_CTL(dev_priv, old_crtc_state->cpu_transcoder), + intel_de_rmw(display, + TRANS_DDI_FUNC_CTL(display, old_crtc_state->cpu_transcoder), TRANS_DDI_DP_VC_PAYLOAD_ALLOC, 0); wait_for_act_sent(encoder, old_crtc_state); @@ -1075,7 +1076,7 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state, intel_dsc_disable(old_pipe_crtc_state); - if (DISPLAY_VER(dev_priv) >= 9) + if (DISPLAY_VER(display) >= 9) skl_scaler_disable(old_pipe_crtc_state); else ilk_pfit_disable(old_pipe_crtc_state); @@ -1100,7 +1101,7 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state, * From older GENs spec: "Configure Transcoder Clock Select to direct * no clock to the transcoder" */ - if (DISPLAY_VER(dev_priv) < 12 || !last_mst_stream) + if (DISPLAY_VER(display) < 12 || !last_mst_stream) intel_ddi_disable_transcoder_clock(old_crtc_state); @@ -1109,7 +1110,7 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state, primary_encoder->post_disable(state, primary_encoder, old_crtc_state, NULL); - drm_dbg_kms(&dev_priv->drm, "active links %d\n", + drm_dbg_kms(display->drm, "active links %d\n", intel_dp->active_mst_links); } @@ -1178,10 +1179,10 @@ static void intel_mst_pre_enable_dp(struct intel_atomic_state *state, const struct intel_crtc_state *pipe_config, const struct drm_connector_state *conn_state) { + struct intel_display *display = to_intel_display(state); struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder); struct intel_encoder *primary_encoder = to_primary_encoder(encoder); struct intel_dp *intel_dp = to_primary_dp(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_connector *connector = to_intel_connector(conn_state->connector); struct drm_dp_mst_topology_state *mst_state = @@ -1195,11 +1196,10 @@ static void intel_mst_pre_enable_dp(struct intel_atomic_state *state, connector->encoder = encoder; intel_mst->connector = connector; first_mst_stream = intel_dp->active_mst_links == 0; - drm_WARN_ON(&dev_priv->drm, - DISPLAY_VER(dev_priv) >= 12 && first_mst_stream && + drm_WARN_ON(display->drm, DISPLAY_VER(display) >= 12 && first_mst_stream && !intel_dp_mst_is_master_trans(pipe_config)); - drm_dbg_kms(&dev_priv->drm, "active links %d\n", + drm_dbg_kms(display->drm, "active links %d\n", intel_dp->active_mst_links); if (first_mst_stream) @@ -1230,10 +1230,10 @@ static void intel_mst_pre_enable_dp(struct intel_atomic_state *state, * first MST stream, so it's done on the DDI for the first stream and * here for the following ones. */ - if (DISPLAY_VER(dev_priv) < 12 || !first_mst_stream) + if (DISPLAY_VER(display) < 12 || !first_mst_stream) intel_ddi_enable_transcoder_clock(encoder, pipe_config); - if (DISPLAY_VER(dev_priv) >= 13 && !first_mst_stream) + if (DISPLAY_VER(display) >= 13 && !first_mst_stream) intel_ddi_config_transcoder_func(encoder, pipe_config); intel_dsc_dp_pps_write(primary_encoder, pipe_config); @@ -1242,6 +1242,7 @@ static void intel_mst_pre_enable_dp(struct intel_atomic_state *state, static void enable_bs_jitter_was(const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); u32 clear = 0; u32 set = 0; @@ -1249,7 +1250,7 @@ static void enable_bs_jitter_was(const struct intel_crtc_state *crtc_state) if (!IS_ALDERLAKE_P(i915)) return; - if (!IS_DISPLAY_STEP(i915, STEP_D0, STEP_FOREVER)) + if (!IS_DISPLAY_STEP(display, STEP_D0, STEP_FOREVER)) return; /* Wa_14013163432:adlp */ @@ -1257,7 +1258,7 @@ static void enable_bs_jitter_was(const struct intel_crtc_state *crtc_state) set |= DP_MST_FEC_BS_JITTER_WA(crtc_state->cpu_transcoder); /* Wa_14014143976:adlp */ - if (IS_DISPLAY_STEP(i915, STEP_E0, STEP_FOREVER)) { + if (IS_DISPLAY_STEP(display, STEP_E0, STEP_FOREVER)) { if (intel_dp_is_uhbr(crtc_state)) set |= DP_MST_SHORT_HBLANK_WA(crtc_state->cpu_transcoder); else if (crtc_state->fec_enable) @@ -1270,7 +1271,7 @@ static void enable_bs_jitter_was(const struct intel_crtc_state *crtc_state) if (!clear && !set) return; - intel_de_rmw(i915, CHICKEN_MISC_3, clear, set); + intel_de_rmw(display, CHICKEN_MISC_3, clear, set); } static void intel_mst_enable_dp(struct intel_atomic_state *state, @@ -1282,7 +1283,6 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state, struct intel_encoder *primary_encoder = to_primary_encoder(encoder); struct intel_dp *intel_dp = to_primary_dp(encoder); struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_dp_mst_topology_state *mst_state = drm_atomic_get_new_mst_topology_state(&state->base, &intel_dp->mst_mgr); enum transcoder trans = pipe_config->cpu_transcoder; @@ -1290,16 +1290,16 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state, struct intel_crtc *pipe_crtc; int ret, i; - drm_WARN_ON(&dev_priv->drm, pipe_config->has_pch_encoder); + drm_WARN_ON(display->drm, pipe_config->has_pch_encoder); if (intel_dp_is_uhbr(pipe_config)) { const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; u64 crtc_clock_hz = KHz(adjusted_mode->crtc_clock); - intel_de_write(dev_priv, TRANS_DP2_VFREQHIGH(pipe_config->cpu_transcoder), + intel_de_write(display, TRANS_DP2_VFREQHIGH(pipe_config->cpu_transcoder), TRANS_DP2_VFREQ_PIXEL_CLOCK(crtc_clock_hz >> 24)); - intel_de_write(dev_priv, TRANS_DP2_VFREQLOW(pipe_config->cpu_transcoder), + intel_de_write(display, TRANS_DP2_VFREQLOW(pipe_config->cpu_transcoder), TRANS_DP2_VFREQ_PIXEL_CLOCK(crtc_clock_hz & 0xffffff)); } @@ -1309,10 +1309,10 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state, clear_act_sent(encoder, pipe_config); - intel_de_rmw(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, trans), 0, + intel_de_rmw(display, TRANS_DDI_FUNC_CTL(display, trans), 0, TRANS_DDI_DP_VC_PAYLOAD_ALLOC); - drm_dbg_kms(&dev_priv->drm, "active links %d\n", + drm_dbg_kms(display->drm, "active links %d\n", intel_dp->active_mst_links); wait_for_act_sent(encoder, pipe_config); @@ -1445,13 +1445,14 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector, struct drm_modeset_acquire_ctx *ctx, enum drm_mode_status *status) { + struct intel_display *display = to_intel_display(connector->dev); struct drm_i915_private *dev_priv = to_i915(connector->dev); struct intel_connector *intel_connector = to_intel_connector(connector); struct intel_dp *intel_dp = intel_connector->mst_port; struct drm_dp_mst_topology_mgr *mgr = &intel_dp->mst_mgr; struct drm_dp_mst_port *port = intel_connector->port; const int min_bpp = 18; - int max_dotclk = to_i915(connector->dev)->display.cdclk.max_dotclk_freq; + int max_dotclk = display->cdclk.max_dotclk_freq; int max_rate, mode_rate, max_lanes, max_link_clock; int ret; bool dsc = false; @@ -1624,12 +1625,12 @@ static int intel_dp_mst_add_properties(struct intel_dp *intel_dp, struct drm_connector *connector, const char *pathprop) { - struct drm_i915_private *i915 = to_i915(connector->dev); + struct intel_display *display = to_intel_display(intel_dp); drm_object_attach_property(&connector->base, - i915->drm.mode_config.path_property, 0); + display->drm->mode_config.path_property, 0); drm_object_attach_property(&connector->base, - i915->drm.mode_config.tile_property, 0); + display->drm->mode_config.tile_property, 0); intel_attach_force_audio_property(connector); intel_attach_broadcast_rgb_property(connector); @@ -1663,7 +1664,7 @@ intel_dp_mst_read_decompression_port_dsc_caps(struct intel_dp *intel_dp, static bool detect_dsc_hblank_expansion_quirk(const struct intel_connector *connector) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct drm_dp_aux *aux = connector->dp.dsc_decompression_aux; struct drm_dp_desc desc; u8 dpcd[DP_RECEIVER_CAP_SIZE]; @@ -1701,7 +1702,7 @@ static bool detect_dsc_hblank_expansion_quirk(const struct intel_connector *conn !(dpcd[DP_RECEIVE_PORT_0_CAP_0] & DP_HBLANK_EXPANSION_CAPABLE)) return false; - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] DSC HBLANK expansion quirk detected\n", connector->base.base.id, connector->base.name); @@ -1713,9 +1714,8 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo const char *pathprop) { struct intel_dp *intel_dp = container_of(mgr, struct intel_dp, mst_mgr); + struct intel_display *display = to_intel_display(intel_dp); struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); - struct drm_device *dev = dig_port->base.base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); struct intel_connector *intel_connector; struct drm_connector *connector; enum pipe pipe; @@ -1739,7 +1739,7 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo detect_dsc_hblank_expansion_quirk(intel_connector); connector = &intel_connector->base; - ret = drm_connector_init(dev, connector, &intel_dp_mst_connector_funcs, + ret = drm_connector_init(display->drm, connector, &intel_dp_mst_connector_funcs, DRM_MODE_CONNECTOR_DisplayPort); if (ret) { drm_dp_mst_put_port_malloc(port); @@ -1749,7 +1749,7 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo drm_connector_helper_add(connector, &intel_dp_mst_connector_helper_funcs); - for_each_pipe(dev_priv, pipe) { + for_each_pipe(display, pipe) { struct drm_encoder *enc = &intel_dp->mst_encoders[pipe]->base.base; @@ -1764,7 +1764,7 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo ret = intel_dp_hdcp_init(dig_port, intel_connector); if (ret) - drm_dbg_kms(&dev_priv->drm, "[%s:%d] HDCP MST init failed, skipping.\n", + drm_dbg_kms(display->drm, "[%s:%d] HDCP MST init failed, skipping.\n", connector->name, connector->base.id); return connector; @@ -1790,10 +1790,10 @@ static const struct drm_dp_mst_topology_cbs mst_cbs = { static struct intel_dp_mst_encoder * intel_dp_create_fake_mst_encoder(struct intel_digital_port *dig_port, enum pipe pipe) { + struct intel_display *display = to_intel_display(dig_port); struct intel_encoder *primary_encoder = &dig_port->base; struct intel_dp_mst_encoder *intel_mst; struct intel_encoder *encoder; - struct drm_device *dev = dig_port->base.base.dev; intel_mst = kzalloc(sizeof(*intel_mst), GFP_KERNEL); @@ -1804,7 +1804,7 @@ intel_dp_create_fake_mst_encoder(struct intel_digital_port *dig_port, enum pipe encoder = &intel_mst->base; intel_mst->primary = dig_port; - drm_encoder_init(dev, &encoder->base, &intel_dp_mst_enc_funcs, + drm_encoder_init(display->drm, &encoder->base, &intel_dp_mst_enc_funcs, DRM_MODE_ENCODER_DPMST, "DP-MST %c", pipe_name(pipe)); encoder->type = INTEL_OUTPUT_DP_MST; @@ -1843,11 +1843,11 @@ intel_dp_create_fake_mst_encoder(struct intel_digital_port *dig_port, enum pipe static bool intel_dp_create_fake_mst_encoders(struct intel_digital_port *dig_port) { + struct intel_display *display = to_intel_display(dig_port); struct intel_dp *intel_dp = &dig_port->dp; - struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); enum pipe pipe; - for_each_pipe(dev_priv, pipe) + for_each_pipe(display, pipe) intel_dp->mst_encoders[pipe] = intel_dp_create_fake_mst_encoder(dig_port, pipe); return true; } @@ -1861,25 +1861,25 @@ intel_dp_mst_encoder_active_links(struct intel_digital_port *dig_port) int intel_dp_mst_encoder_init(struct intel_digital_port *dig_port, int conn_base_id) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct intel_display *display = to_intel_display(dig_port); struct intel_dp *intel_dp = &dig_port->dp; enum port port = dig_port->base.port; int ret; - if (!HAS_DP_MST(i915) || intel_dp_is_edp(intel_dp)) + if (!HAS_DP_MST(display) || intel_dp_is_edp(intel_dp)) return 0; - if (DISPLAY_VER(i915) < 12 && port == PORT_A) + if (DISPLAY_VER(display) < 12 && port == PORT_A) return 0; - if (DISPLAY_VER(i915) < 11 && port == PORT_E) + if (DISPLAY_VER(display) < 11 && port == PORT_E) return 0; intel_dp->mst_mgr.cbs = &mst_cbs; /* create encoders */ intel_dp_create_fake_mst_encoders(dig_port); - ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, &i915->drm, + ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, display->drm, &intel_dp->aux, 16, 3, conn_base_id); if (ret) { intel_dp->mst_mgr.cbs = NULL; -- cgit v1.2.3 From 5674e700d43eb23ca30aa794262bef5a18dac708 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 12 Nov 2024 13:10:43 +0200 Subject: drm/i915/mst: change naming from fake encoders to MST stream encoders The fake encoders pretty much match individual MST streams. The encoders remain as fake as ever, but change the naming to MST stream encoders. Rename all the encoder hooks and related functions called from them to mst_stream_* to clarify what type of encoders the hooks are called on. Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/37d9572e884ca2fdd84ea6722b4b7cefde04eed9.1731409802.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 204 ++++++++++++++-------------- 1 file changed, 100 insertions(+), 104 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp_mst.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index ef7f510c07a7..df7edcfe885b 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -53,7 +53,7 @@ #include "intel_vdsc.h" #include "skl_scaler.h" -/* From fake MST encoder to primary encoder */ +/* From fake MST stream encoder to primary encoder */ static struct intel_encoder *to_primary_encoder(struct intel_encoder *encoder) { struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder); @@ -62,7 +62,7 @@ static struct intel_encoder *to_primary_encoder(struct intel_encoder *encoder) return &dig_port->base; } -/* From fake MST encoder to primary DP */ +/* From fake MST stream encoder to primary DP */ static struct intel_dp *to_primary_dp(struct intel_encoder *encoder) { struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder); @@ -179,14 +179,12 @@ static int intel_dp_mst_dsc_get_slice_count(const struct intel_connector *connec num_joined_pipes); } -static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, - struct intel_crtc_state *crtc_state, - int max_bpp, - int min_bpp, - struct link_config_limits *limits, - struct drm_connector_state *conn_state, - int step, - bool dsc) +static int mst_stream_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, + struct intel_crtc_state *crtc_state, + int max_bpp, int min_bpp, + struct link_config_limits *limits, + struct drm_connector_state *conn_state, + int step, bool dsc) { struct intel_display *display = to_intel_display(encoder); struct drm_atomic_state *state = crtc_state->uapi.state; @@ -333,10 +331,10 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, return slots; } -static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder, - struct intel_crtc_state *crtc_state, - struct drm_connector_state *conn_state, - struct link_config_limits *limits) +static int mst_stream_compute_link_config(struct intel_encoder *encoder, + struct intel_crtc_state *crtc_state, + struct drm_connector_state *conn_state, + struct link_config_limits *limits) { int slots = -EINVAL; @@ -344,11 +342,11 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder, * FIXME: allocate the BW according to link_bpp, which in the case of * YUV420 is only half of the pipe bpp value. */ - slots = intel_dp_mst_find_vcpi_slots_for_bpp(encoder, crtc_state, - fxp_q4_to_int(limits->link.max_bpp_x16), - fxp_q4_to_int(limits->link.min_bpp_x16), - limits, - conn_state, 2 * 3, false); + slots = mst_stream_find_vcpi_slots_for_bpp(encoder, crtc_state, + fxp_q4_to_int(limits->link.max_bpp_x16), + fxp_q4_to_int(limits->link.min_bpp_x16), + limits, + conn_state, 2 * 3, false); if (slots < 0) return slots; @@ -356,10 +354,10 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder, return 0; } -static int intel_dp_dsc_mst_compute_link_config(struct intel_encoder *encoder, - struct intel_crtc_state *crtc_state, - struct drm_connector_state *conn_state, - struct link_config_limits *limits) +static int mst_stream_dsc_compute_link_config(struct intel_encoder *encoder, + struct intel_crtc_state *crtc_state, + struct drm_connector_state *conn_state, + struct link_config_limits *limits) { struct intel_display *display = to_intel_display(encoder); struct intel_connector *connector = to_intel_connector(conn_state->connector); @@ -426,18 +424,19 @@ static int intel_dp_dsc_mst_compute_link_config(struct intel_encoder *encoder, min_compressed_bpp = intel_dp_dsc_nearest_valid_bpp(i915, min_compressed_bpp, crtc_state->pipe_bpp); - slots = intel_dp_mst_find_vcpi_slots_for_bpp(encoder, crtc_state, max_compressed_bpp, - min_compressed_bpp, limits, - conn_state, 1, true); + slots = mst_stream_find_vcpi_slots_for_bpp(encoder, crtc_state, max_compressed_bpp, + min_compressed_bpp, limits, + conn_state, 1, true); if (slots < 0) return slots; return 0; } -static int intel_dp_mst_update_slots(struct intel_encoder *encoder, - struct intel_crtc_state *crtc_state, - struct drm_connector_state *conn_state) + +static int mst_stream_update_slots(struct intel_encoder *encoder, + struct intel_crtc_state *crtc_state, + struct drm_connector_state *conn_state) { struct intel_display *display = to_intel_display(encoder); struct intel_dp *intel_dp = to_primary_dp(encoder); @@ -550,11 +549,11 @@ adjust_limits_for_dsc_hblank_expansion_quirk(const struct intel_connector *conne } static bool -intel_dp_mst_compute_config_limits(struct intel_dp *intel_dp, - const struct intel_connector *connector, - struct intel_crtc_state *crtc_state, - bool dsc, - struct link_config_limits *limits) +mst_stream_compute_config_limits(struct intel_dp *intel_dp, + const struct intel_connector *connector, + struct intel_crtc_state *crtc_state, + bool dsc, + struct link_config_limits *limits) { /* * for MST we always configure max link bw - the spec doesn't @@ -591,9 +590,9 @@ intel_dp_mst_compute_config_limits(struct intel_dp *intel_dp, dsc); } -static int intel_dp_mst_compute_config(struct intel_encoder *encoder, - struct intel_crtc_state *pipe_config, - struct drm_connector_state *conn_state) +static int mst_stream_compute_config(struct intel_encoder *encoder, + struct intel_crtc_state *pipe_config, + struct drm_connector_state *conn_state) { struct intel_display *display = to_intel_display(encoder); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); @@ -629,15 +628,12 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder, joiner_needs_dsc = intel_dp_joiner_needs_dsc(dev_priv, num_joined_pipes); dsc_needed = joiner_needs_dsc || intel_dp->force_dsc_en || - !intel_dp_mst_compute_config_limits(intel_dp, - connector, - pipe_config, - false, - &limits); + !mst_stream_compute_config_limits(intel_dp, connector, + pipe_config, false, &limits); if (!dsc_needed) { - ret = intel_dp_mst_compute_link_config(encoder, pipe_config, - conn_state, &limits); + ret = mst_stream_compute_link_config(encoder, pipe_config, + conn_state, &limits); if (ret == -EDEADLK) return ret; @@ -655,11 +651,9 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder, if (!intel_dp_supports_dsc(connector, pipe_config)) return -EINVAL; - if (!intel_dp_mst_compute_config_limits(intel_dp, - connector, - pipe_config, - true, - &limits)) + if (!mst_stream_compute_config_limits(intel_dp, connector, + pipe_config, true, + &limits)) return -EINVAL; /* @@ -674,8 +668,8 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder, */ drm_dbg_kms(display->drm, "Trying to find VCPI slots in DSC mode\n"); - ret = intel_dp_dsc_mst_compute_link_config(encoder, pipe_config, - conn_state, &limits); + ret = mst_stream_dsc_compute_link_config(encoder, pipe_config, + conn_state, &limits); if (ret < 0) return ret; @@ -687,7 +681,7 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder, if (ret) return ret; - ret = intel_dp_mst_update_slots(encoder, pipe_config, conn_state); + ret = mst_stream_update_slots(encoder, pipe_config, conn_state); if (ret) return ret; @@ -868,9 +862,9 @@ int intel_dp_mst_atomic_check_link(struct intel_atomic_state *state, return 0; } -static int intel_dp_mst_compute_config_late(struct intel_encoder *encoder, - struct intel_crtc_state *crtc_state, - struct drm_connector_state *conn_state) +static int mst_stream_compute_config_late(struct intel_encoder *encoder, + struct intel_crtc_state *crtc_state, + struct drm_connector_state *conn_state) { struct intel_atomic_state *state = to_intel_atomic_state(conn_state->state); struct intel_dp *intel_dp = to_primary_dp(encoder); @@ -996,10 +990,10 @@ static void wait_for_act_sent(struct intel_encoder *encoder, drm_dp_check_act_status(&intel_dp->mst_mgr); } -static void intel_mst_disable_dp(struct intel_atomic_state *state, - struct intel_encoder *encoder, - const struct intel_crtc_state *old_crtc_state, - const struct drm_connector_state *old_conn_state) +static void mst_stream_disable(struct intel_atomic_state *state, + struct intel_encoder *encoder, + const struct intel_crtc_state *old_crtc_state, + const struct drm_connector_state *old_conn_state) { struct intel_display *display = to_intel_display(state); struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder); @@ -1018,10 +1012,10 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state, intel_dp_sink_disable_decompression(state, connector, old_crtc_state); } -static void intel_mst_post_disable_dp(struct intel_atomic_state *state, - struct intel_encoder *encoder, - const struct intel_crtc_state *old_crtc_state, - const struct drm_connector_state *old_conn_state) +static void mst_stream_post_disable(struct intel_atomic_state *state, + struct intel_encoder *encoder, + const struct intel_crtc_state *old_crtc_state, + const struct drm_connector_state *old_conn_state) { struct intel_display *display = to_intel_display(encoder); struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder); @@ -1114,10 +1108,10 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state, intel_dp->active_mst_links); } -static void intel_mst_post_pll_disable_dp(struct intel_atomic_state *state, - struct intel_encoder *encoder, - const struct intel_crtc_state *old_crtc_state, - const struct drm_connector_state *old_conn_state) +static void mst_stream_post_pll_disable(struct intel_atomic_state *state, + struct intel_encoder *encoder, + const struct intel_crtc_state *old_crtc_state, + const struct drm_connector_state *old_conn_state) { struct intel_encoder *primary_encoder = to_primary_encoder(encoder); struct intel_dp *intel_dp = to_primary_dp(encoder); @@ -1127,10 +1121,10 @@ static void intel_mst_post_pll_disable_dp(struct intel_atomic_state *state, primary_encoder->post_pll_disable(state, primary_encoder, old_crtc_state, old_conn_state); } -static void intel_mst_pre_pll_enable_dp(struct intel_atomic_state *state, - struct intel_encoder *encoder, - const struct intel_crtc_state *pipe_config, - const struct drm_connector_state *conn_state) +static void mst_stream_pre_pll_enable(struct intel_atomic_state *state, + struct intel_encoder *encoder, + const struct intel_crtc_state *pipe_config, + const struct drm_connector_state *conn_state) { struct intel_encoder *primary_encoder = to_primary_encoder(encoder); struct intel_dp *intel_dp = to_primary_dp(encoder); @@ -1174,10 +1168,10 @@ static void intel_mst_reprobe_topology(struct intel_dp *intel_dp, crtc_state->port_clock, crtc_state->lane_count); } -static void intel_mst_pre_enable_dp(struct intel_atomic_state *state, - struct intel_encoder *encoder, - const struct intel_crtc_state *pipe_config, - const struct drm_connector_state *conn_state) +static void mst_stream_pre_enable(struct intel_atomic_state *state, + struct intel_encoder *encoder, + const struct intel_crtc_state *pipe_config, + const struct drm_connector_state *conn_state) { struct intel_display *display = to_intel_display(state); struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder); @@ -1274,10 +1268,10 @@ static void enable_bs_jitter_was(const struct intel_crtc_state *crtc_state) intel_de_rmw(display, CHICKEN_MISC_3, clear, set); } -static void intel_mst_enable_dp(struct intel_atomic_state *state, - struct intel_encoder *encoder, - const struct intel_crtc_state *pipe_config, - const struct drm_connector_state *conn_state) +static void mst_stream_enable(struct intel_atomic_state *state, + struct intel_encoder *encoder, + const struct intel_crtc_state *pipe_config, + const struct drm_connector_state *conn_state) { struct intel_display *display = to_intel_display(encoder); struct intel_encoder *primary_encoder = to_primary_encoder(encoder); @@ -1345,8 +1339,8 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state, intel_hdcp_enable(state, encoder, pipe_config, conn_state); } -static bool intel_dp_mst_enc_get_hw_state(struct intel_encoder *encoder, - enum pipe *pipe) +static bool mst_stream_get_hw_state(struct intel_encoder *encoder, + enum pipe *pipe) { struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder); *pipe = intel_mst->pipe; @@ -1355,16 +1349,16 @@ static bool intel_dp_mst_enc_get_hw_state(struct intel_encoder *encoder, return false; } -static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder, - struct intel_crtc_state *pipe_config) +static void mst_stream_get_config(struct intel_encoder *encoder, + struct intel_crtc_state *pipe_config) { struct intel_encoder *primary_encoder = to_primary_encoder(encoder); primary_encoder->get_config(primary_encoder, pipe_config); } -static bool intel_dp_mst_initial_fastset_check(struct intel_encoder *encoder, - struct intel_crtc_state *crtc_state) +static bool mst_stream_initial_fastset_check(struct intel_encoder *encoder, + struct intel_crtc_state *crtc_state) { struct intel_encoder *primary_encoder = to_primary_encoder(encoder); @@ -1598,7 +1592,7 @@ static const struct drm_connector_helper_funcs intel_dp_mst_connector_helper_fun .detect_ctx = intel_dp_mst_detect, }; -static void intel_dp_mst_encoder_destroy(struct drm_encoder *encoder) +static void mst_stream_encoder_destroy(struct drm_encoder *encoder) { struct intel_dp_mst_encoder *intel_mst = enc_to_mst(to_intel_encoder(encoder)); @@ -1606,8 +1600,8 @@ static void intel_dp_mst_encoder_destroy(struct drm_encoder *encoder) kfree(intel_mst); } -static const struct drm_encoder_funcs intel_dp_mst_enc_funcs = { - .destroy = intel_dp_mst_encoder_destroy, +static const struct drm_encoder_funcs mst_stream_encoder_funcs = { + .destroy = mst_stream_encoder_destroy, }; static bool intel_dp_mst_get_hw_state(struct intel_connector *connector) @@ -1787,8 +1781,9 @@ static const struct drm_dp_mst_topology_cbs mst_cbs = { .poll_hpd_irq = intel_dp_mst_poll_hpd_irq, }; +/* Create a fake encoder for an individual MST stream */ static struct intel_dp_mst_encoder * -intel_dp_create_fake_mst_encoder(struct intel_digital_port *dig_port, enum pipe pipe) +mst_stream_encoder_create(struct intel_digital_port *dig_port, enum pipe pipe) { struct intel_display *display = to_intel_display(dig_port); struct intel_encoder *primary_encoder = &dig_port->base; @@ -1804,7 +1799,7 @@ intel_dp_create_fake_mst_encoder(struct intel_digital_port *dig_port, enum pipe encoder = &intel_mst->base; intel_mst->primary = dig_port; - drm_encoder_init(display->drm, &encoder->base, &intel_dp_mst_enc_funcs, + drm_encoder_init(display->drm, &encoder->base, &mst_stream_encoder_funcs, DRM_MODE_ENCODER_DPMST, "DP-MST %c", pipe_name(pipe)); encoder->type = INTEL_OUTPUT_DP_MST; @@ -1821,34 +1816,35 @@ intel_dp_create_fake_mst_encoder(struct intel_digital_port *dig_port, enum pipe */ encoder->pipe_mask = ~0; - encoder->compute_config = intel_dp_mst_compute_config; - encoder->compute_config_late = intel_dp_mst_compute_config_late; - encoder->disable = intel_mst_disable_dp; - encoder->post_disable = intel_mst_post_disable_dp; - encoder->post_pll_disable = intel_mst_post_pll_disable_dp; + encoder->compute_config = mst_stream_compute_config; + encoder->compute_config_late = mst_stream_compute_config_late; + 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->pre_pll_enable = intel_mst_pre_pll_enable_dp; - encoder->pre_enable = intel_mst_pre_enable_dp; - encoder->enable = intel_mst_enable_dp; + encoder->pre_pll_enable = mst_stream_pre_pll_enable; + encoder->pre_enable = mst_stream_pre_enable; + encoder->enable = mst_stream_enable; encoder->audio_enable = intel_audio_codec_enable; encoder->audio_disable = intel_audio_codec_disable; - encoder->get_hw_state = intel_dp_mst_enc_get_hw_state; - encoder->get_config = intel_dp_mst_enc_get_config; - encoder->initial_fastset_check = intel_dp_mst_initial_fastset_check; + encoder->get_hw_state = mst_stream_get_hw_state; + encoder->get_config = mst_stream_get_config; + encoder->initial_fastset_check = mst_stream_initial_fastset_check; return intel_mst; } +/* Create the fake encoders for MST streams */ static bool -intel_dp_create_fake_mst_encoders(struct intel_digital_port *dig_port) +mst_stream_encoders_create(struct intel_digital_port *dig_port) { struct intel_display *display = to_intel_display(dig_port); struct intel_dp *intel_dp = &dig_port->dp; enum pipe pipe; for_each_pipe(display, pipe) - intel_dp->mst_encoders[pipe] = intel_dp_create_fake_mst_encoder(dig_port, pipe); + intel_dp->mst_encoders[pipe] = mst_stream_encoder_create(dig_port, pipe); return true; } @@ -1878,7 +1874,7 @@ intel_dp_mst_encoder_init(struct intel_digital_port *dig_port, int conn_base_id) intel_dp->mst_mgr.cbs = &mst_cbs; /* create encoders */ - intel_dp_create_fake_mst_encoders(dig_port); + mst_stream_encoders_create(dig_port); ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, display->drm, &intel_dp->aux, 16, 3, conn_base_id); if (ret) { -- cgit v1.2.3 From d58f65df2dcb59acd3965907507cfa608fe924b4 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 18 Nov 2024 15:10:44 +0200 Subject: drm/i915/dp_mst: Fix connector initialization in intel_dp_add_mst_connector() The connector initialization in intel_dp_add_mst_connector() depends on the device pointer in connector to be valid, at least by connector debug printing. The device pointer is initialized by drm_connector_init(), however that function also exposes the connector to in-kernel users, which can't be done before the connector is fully initialized. For now make sure the device pointer is valid before it's used, until a follow-up change moving this to DRM core. This issue was revealed by the commit in the Fixes: line below, before which the above debug printing checked and handled a NULL device pointer gracefully in DRM core. Cc: Jani Nikula Fixes: 529798bd786a ("drm/i915/mst: convert to struct intel_display") Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12799 Reviewed-by: Rodrigo Vivi Signed-off-by: Imre Deak Reviewed-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20241118131044.1278028-1-imre.deak@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers/gpu/drm/i915/display/intel_dp_mst.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index df7edcfe885b..f058360a2641 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -1727,6 +1727,16 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo intel_dp_init_modeset_retry_work(intel_connector); + /* + * TODO: The following drm_connector specific initialization belongs + * to DRM core, however it happens atm too late in + * drm_connector_init(). That function will also expose the connector + * to in-kernel users, so it can't be called until the connector is + * sufficiently initialized; init the device pointer used by the + * following DSC setup, until a fix moving this to DRM core. + */ + intel_connector->base.dev = mgr->dev; + intel_connector->dp.dsc_decompression_aux = drm_dp_mst_dsc_aux_for_port(port); intel_dp_mst_read_decompression_port_dsc_caps(intel_dp, intel_connector); intel_connector->dp.dsc_hblank_expansion_quirk = -- cgit v1.2.3 From 2b1245f3ec879a42394b6b3407da33a0aaaebc0c Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 20 Nov 2024 14:43:09 +0200 Subject: drm/i915/mst: pass intel_dp around in mst stream helpers All of the functions in question operate on the primary encoder, and more specifically the primary intel_dp, so pass it around instead of the encoder for less ambiguity. Suggested-by: Imre Deak Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/165ee8b723c42bcdeb3adf6a1b34ea09371e5d64.1732106557.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp_mst.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index f058360a2641..dab50a1ed15b 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -179,16 +179,15 @@ static int intel_dp_mst_dsc_get_slice_count(const struct intel_connector *connec num_joined_pipes); } -static int mst_stream_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, +static int mst_stream_find_vcpi_slots_for_bpp(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state, int max_bpp, int min_bpp, struct link_config_limits *limits, struct drm_connector_state *conn_state, int step, bool dsc) { - struct intel_display *display = to_intel_display(encoder); + struct intel_display *display = to_intel_display(intel_dp); struct drm_atomic_state *state = crtc_state->uapi.state; - struct intel_dp *intel_dp = to_primary_dp(encoder); struct drm_dp_mst_topology_state *mst_state; struct intel_connector *connector = to_intel_connector(conn_state->connector); @@ -331,7 +330,7 @@ static int mst_stream_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, return slots; } -static int mst_stream_compute_link_config(struct intel_encoder *encoder, +static int mst_stream_compute_link_config(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state, struct drm_connector_state *conn_state, struct link_config_limits *limits) @@ -342,7 +341,7 @@ static int mst_stream_compute_link_config(struct intel_encoder *encoder, * FIXME: allocate the BW according to link_bpp, which in the case of * YUV420 is only half of the pipe bpp value. */ - slots = mst_stream_find_vcpi_slots_for_bpp(encoder, crtc_state, + slots = mst_stream_find_vcpi_slots_for_bpp(intel_dp, crtc_state, fxp_q4_to_int(limits->link.max_bpp_x16), fxp_q4_to_int(limits->link.min_bpp_x16), limits, @@ -354,12 +353,12 @@ static int mst_stream_compute_link_config(struct intel_encoder *encoder, return 0; } -static int mst_stream_dsc_compute_link_config(struct intel_encoder *encoder, +static int mst_stream_dsc_compute_link_config(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state, struct drm_connector_state *conn_state, struct link_config_limits *limits) { - struct intel_display *display = to_intel_display(encoder); + struct intel_display *display = to_intel_display(intel_dp); struct intel_connector *connector = to_intel_connector(conn_state->connector); struct drm_i915_private *i915 = to_i915(connector->base.dev); int slots = -EINVAL; @@ -424,7 +423,7 @@ static int mst_stream_dsc_compute_link_config(struct intel_encoder *encoder, min_compressed_bpp = intel_dp_dsc_nearest_valid_bpp(i915, min_compressed_bpp, crtc_state->pipe_bpp); - slots = mst_stream_find_vcpi_slots_for_bpp(encoder, crtc_state, max_compressed_bpp, + slots = mst_stream_find_vcpi_slots_for_bpp(intel_dp, crtc_state, max_compressed_bpp, min_compressed_bpp, limits, conn_state, 1, true); @@ -434,12 +433,11 @@ static int mst_stream_dsc_compute_link_config(struct intel_encoder *encoder, return 0; } -static int mst_stream_update_slots(struct intel_encoder *encoder, +static int mst_stream_update_slots(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state, struct drm_connector_state *conn_state) { - struct intel_display *display = to_intel_display(encoder); - struct intel_dp *intel_dp = to_primary_dp(encoder); + struct intel_display *display = to_intel_display(intel_dp); struct drm_dp_mst_topology_mgr *mgr = &intel_dp->mst_mgr; struct drm_dp_mst_topology_state *topology_state; u8 link_coding_cap = intel_dp_is_uhbr(crtc_state) ? @@ -632,7 +630,7 @@ static int mst_stream_compute_config(struct intel_encoder *encoder, pipe_config, false, &limits); if (!dsc_needed) { - ret = mst_stream_compute_link_config(encoder, pipe_config, + ret = mst_stream_compute_link_config(intel_dp, pipe_config, conn_state, &limits); if (ret == -EDEADLK) @@ -668,7 +666,7 @@ static int mst_stream_compute_config(struct intel_encoder *encoder, */ drm_dbg_kms(display->drm, "Trying to find VCPI slots in DSC mode\n"); - ret = mst_stream_dsc_compute_link_config(encoder, pipe_config, + ret = mst_stream_dsc_compute_link_config(intel_dp, pipe_config, conn_state, &limits); if (ret < 0) return ret; @@ -681,7 +679,7 @@ static int mst_stream_compute_config(struct intel_encoder *encoder, if (ret) return ret; - ret = mst_stream_update_slots(encoder, pipe_config, conn_state); + ret = mst_stream_update_slots(intel_dp, pipe_config, conn_state); if (ret) return ret; -- cgit v1.2.3 From fdb65ede8a45240552e867d5c17186d917d29147 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 20 Nov 2024 14:43:10 +0200 Subject: drm/i915/mst: unify MST connector function naming to mst_connector_* Similar to commit 5674e700d43e ("drm/i915/mst: change naming from fake encoders to MST stream encoders"), name all MST connector related functions to mst_connector_*. Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/3d4814a94b97fcff88722e0effd2fb5893b256af.1732106557.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 63 +++++++++++++++-------------- 1 file changed, 32 insertions(+), 31 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp_mst.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index dab50a1ed15b..56b2db02893d 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -888,8 +888,8 @@ static int mst_stream_compute_config_late(struct intel_encoder *encoder, * recomputation of the corresponding CRTC states. */ static int -intel_dp_mst_atomic_topology_check(struct intel_connector *connector, - struct intel_atomic_state *state) +mst_connector_atomic_topology_check(struct intel_connector *connector, + struct intel_atomic_state *state) { struct intel_display *display = to_intel_display(connector); struct drm_connector_list_iter connector_list_iter; @@ -937,8 +937,8 @@ intel_dp_mst_atomic_topology_check(struct intel_connector *connector, } static int -intel_dp_mst_atomic_check(struct drm_connector *connector, - struct drm_atomic_state *_state) +mst_connector_atomic_check(struct drm_connector *connector, + struct drm_atomic_state *_state) { struct intel_atomic_state *state = to_intel_atomic_state(_state); struct intel_connector *intel_connector = @@ -949,7 +949,7 @@ intel_dp_mst_atomic_check(struct drm_connector *connector, if (ret) return ret; - ret = intel_dp_mst_atomic_topology_check(intel_connector, state); + ret = mst_connector_atomic_topology_check(intel_connector, state); if (ret) return ret; @@ -1363,7 +1363,7 @@ static bool mst_stream_initial_fastset_check(struct intel_encoder *encoder, return intel_dp_initial_fastset_check(primary_encoder, crtc_state); } -static int intel_dp_mst_get_ddc_modes(struct drm_connector *connector) +static int mst_connector_get_ddc_modes(struct drm_connector *connector) { struct intel_connector *intel_connector = to_intel_connector(connector); struct drm_i915_private *i915 = to_i915(intel_connector->base.dev); @@ -1387,7 +1387,7 @@ static int intel_dp_mst_get_ddc_modes(struct drm_connector *connector) } static int -intel_dp_mst_connector_late_register(struct drm_connector *connector) +mst_connector_late_register(struct drm_connector *connector) { struct intel_connector *intel_connector = to_intel_connector(connector); int ret; @@ -1406,7 +1406,7 @@ intel_dp_mst_connector_late_register(struct drm_connector *connector) } static void -intel_dp_mst_connector_early_unregister(struct drm_connector *connector) +mst_connector_early_unregister(struct drm_connector *connector) { struct intel_connector *intel_connector = to_intel_connector(connector); @@ -1415,27 +1415,27 @@ intel_dp_mst_connector_early_unregister(struct drm_connector *connector) intel_connector->port); } -static const struct drm_connector_funcs intel_dp_mst_connector_funcs = { +static const struct drm_connector_funcs mst_connector_funcs = { .fill_modes = drm_helper_probe_single_connector_modes, .atomic_get_property = intel_digital_connector_atomic_get_property, .atomic_set_property = intel_digital_connector_atomic_set_property, - .late_register = intel_dp_mst_connector_late_register, - .early_unregister = intel_dp_mst_connector_early_unregister, + .late_register = mst_connector_late_register, + .early_unregister = mst_connector_early_unregister, .destroy = intel_connector_destroy, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, .atomic_duplicate_state = intel_digital_connector_duplicate_state, }; -static int intel_dp_mst_get_modes(struct drm_connector *connector) +static int mst_connector_get_modes(struct drm_connector *connector) { - return intel_dp_mst_get_ddc_modes(connector); + return mst_connector_get_ddc_modes(connector); } static int -intel_dp_mst_mode_valid_ctx(struct drm_connector *connector, - struct drm_display_mode *mode, - struct drm_modeset_acquire_ctx *ctx, - enum drm_mode_status *status) +mst_connector_mode_valid_ctx(struct drm_connector *connector, + struct drm_display_mode *mode, + struct drm_modeset_acquire_ctx *ctx, + enum drm_mode_status *status) { struct intel_display *display = to_intel_display(connector->dev); struct drm_i915_private *dev_priv = to_i915(connector->dev); @@ -1546,8 +1546,9 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector, return 0; } -static struct drm_encoder *intel_mst_atomic_best_encoder(struct drm_connector *connector, - struct drm_atomic_state *state) +static struct drm_encoder * +mst_connector_atomic_best_encoder(struct drm_connector *connector, + struct drm_atomic_state *state) { struct drm_connector_state *connector_state = drm_atomic_get_new_connector_state(state, connector); @@ -1559,8 +1560,8 @@ static struct drm_encoder *intel_mst_atomic_best_encoder(struct drm_connector *c } static int -intel_dp_mst_detect(struct drm_connector *connector, - struct drm_modeset_acquire_ctx *ctx, bool force) +mst_connector_detect_ctx(struct drm_connector *connector, + struct drm_modeset_acquire_ctx *ctx, bool force) { struct intel_display *display = to_intel_display(connector->dev); struct drm_i915_private *i915 = to_i915(connector->dev); @@ -1582,12 +1583,12 @@ intel_dp_mst_detect(struct drm_connector *connector, intel_connector->port); } -static const struct drm_connector_helper_funcs intel_dp_mst_connector_helper_funcs = { - .get_modes = intel_dp_mst_get_modes, - .mode_valid_ctx = intel_dp_mst_mode_valid_ctx, - .atomic_best_encoder = intel_mst_atomic_best_encoder, - .atomic_check = intel_dp_mst_atomic_check, - .detect_ctx = intel_dp_mst_detect, +static const struct drm_connector_helper_funcs mst_connector_helper_funcs = { + .get_modes = mst_connector_get_modes, + .mode_valid_ctx = mst_connector_mode_valid_ctx, + .atomic_best_encoder = mst_connector_atomic_best_encoder, + .atomic_check = mst_connector_atomic_check, + .detect_ctx = mst_connector_detect_ctx, }; static void mst_stream_encoder_destroy(struct drm_encoder *encoder) @@ -1602,7 +1603,7 @@ static const struct drm_encoder_funcs mst_stream_encoder_funcs = { .destroy = mst_stream_encoder_destroy, }; -static bool intel_dp_mst_get_hw_state(struct intel_connector *connector) +static bool mst_connector_get_hw_state(struct intel_connector *connector) { if (intel_attached_encoder(connector) && connector->base.state->crtc) { enum pipe pipe; @@ -1717,7 +1718,7 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo if (!intel_connector) return NULL; - intel_connector->get_hw_state = intel_dp_mst_get_hw_state; + intel_connector->get_hw_state = mst_connector_get_hw_state; intel_connector->sync_state = intel_dp_connector_sync_state; intel_connector->mst_port = intel_dp; intel_connector->port = port; @@ -1741,7 +1742,7 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo detect_dsc_hblank_expansion_quirk(intel_connector); connector = &intel_connector->base; - ret = drm_connector_init(display->drm, connector, &intel_dp_mst_connector_funcs, + ret = drm_connector_init(display->drm, connector, &mst_connector_funcs, DRM_MODE_CONNECTOR_DisplayPort); if (ret) { drm_dp_mst_put_port_malloc(port); @@ -1749,7 +1750,7 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo return NULL; } - drm_connector_helper_add(connector, &intel_dp_mst_connector_helper_funcs); + drm_connector_helper_add(connector, &mst_connector_helper_funcs); for_each_pipe(display, pipe) { struct drm_encoder *enc = -- cgit v1.2.3 From 81c6d5d83bc794c10366cab3da0534622c137a84 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 20 Nov 2024 14:43:11 +0200 Subject: drm/i915/mst: simplify mst_connector_get_hw_state() Use a variable for the encoder to simplify. Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/eb8595ae36c6330cce1615059bd2c89a7db79668.1732106557.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp_mst.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 56b2db02893d..b5e8db579e20 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -1605,13 +1605,14 @@ static const struct drm_encoder_funcs mst_stream_encoder_funcs = { static bool mst_connector_get_hw_state(struct intel_connector *connector) { - if (intel_attached_encoder(connector) && connector->base.state->crtc) { - enum pipe pipe; - if (!intel_attached_encoder(connector)->get_hw_state(intel_attached_encoder(connector), &pipe)) - return false; - return true; - } - return false; + /* This is the MST stream encoder set in ->pre_enable, if any */ + struct intel_encoder *encoder = intel_attached_encoder(connector); + enum pipe pipe; + + if (!encoder || !connector->base.state->crtc) + return false; + + return encoder->get_hw_state(encoder, &pipe); } static int intel_dp_mst_add_properties(struct intel_dp *intel_dp, -- cgit v1.2.3 From 5503f8112e52da6d964f0d9a70d810b0eb4d4ce8 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 20 Nov 2024 14:43:12 +0200 Subject: drm/i915/mst: unify MST topology callback naming to mst_topology_* Make it easier to keep track of what belongs where. Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/e8efc8fddc3ca93e1256a1dad13bc4eca07c3382.1732106557.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp_mst.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index b5e8db579e20..9dd8d2d9048b 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -1615,9 +1615,9 @@ static bool mst_connector_get_hw_state(struct intel_connector *connector) return encoder->get_hw_state(encoder, &pipe); } -static int intel_dp_mst_add_properties(struct intel_dp *intel_dp, - struct drm_connector *connector, - const char *pathprop) +static int mst_topology_add_connector_properties(struct intel_dp *intel_dp, + struct drm_connector *connector, + const char *pathprop) { struct intel_display *display = to_intel_display(intel_dp); @@ -1703,9 +1703,10 @@ static bool detect_dsc_hblank_expansion_quirk(const struct intel_connector *conn return true; } -static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, - struct drm_dp_mst_port *port, - const char *pathprop) +static struct drm_connector * +mst_topology_add_connector(struct drm_dp_mst_topology_mgr *mgr, + struct drm_dp_mst_port *port, + const char *pathprop) { struct intel_dp *intel_dp = container_of(mgr, struct intel_dp, mst_mgr); struct intel_display *display = to_intel_display(intel_dp); @@ -1762,7 +1763,7 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo goto err; } - ret = intel_dp_mst_add_properties(intel_dp, connector, pathprop); + ret = mst_topology_add_connector_properties(intel_dp, connector, pathprop); if (ret) goto err; @@ -1779,16 +1780,16 @@ err: } static void -intel_dp_mst_poll_hpd_irq(struct drm_dp_mst_topology_mgr *mgr) +mst_topology_poll_hpd_irq(struct drm_dp_mst_topology_mgr *mgr) { struct intel_dp *intel_dp = container_of(mgr, struct intel_dp, mst_mgr); intel_hpd_trigger_irq(dp_to_dig_port(intel_dp)); } -static const struct drm_dp_mst_topology_cbs mst_cbs = { - .add_connector = intel_dp_add_mst_connector, - .poll_hpd_irq = intel_dp_mst_poll_hpd_irq, +static const struct drm_dp_mst_topology_cbs mst_topology_cbs = { + .add_connector = mst_topology_add_connector, + .poll_hpd_irq = mst_topology_poll_hpd_irq, }; /* Create a fake encoder for an individual MST stream */ @@ -1881,7 +1882,7 @@ intel_dp_mst_encoder_init(struct intel_digital_port *dig_port, int conn_base_id) if (DISPLAY_VER(display) < 11 && port == PORT_E) return 0; - intel_dp->mst_mgr.cbs = &mst_cbs; + intel_dp->mst_mgr.cbs = &mst_topology_cbs; /* create encoders */ mst_stream_encoders_create(dig_port); -- cgit v1.2.3 From c3a126818a3ec533cfc34556de9ceb75ded9cdf9 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 20 Nov 2024 14:43:15 +0200 Subject: drm/i915/dp: refactor clear/wait for act sent Move clear_act_sent() and wait_for_act_sent() to intel_ddi.[ch] and make independent of DP MST. They'll be needed for 128b/132b SST operation. Rename accordingly. Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/ef05f5bc222e8ba48d84f75a9ea5dd29667055d2.1732106557.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 32 ++++++----------------------- 1 file changed, 6 insertions(+), 26 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp_mst.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 9dd8d2d9048b..c59c2c14679c 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -966,28 +966,6 @@ mst_connector_atomic_check(struct drm_connector *connector, intel_connector->port); } -static void clear_act_sent(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state) -{ - struct intel_display *display = to_intel_display(encoder); - - intel_de_write(display, dp_tp_status_reg(encoder, crtc_state), - DP_TP_STATUS_ACT_SENT); -} - -static void wait_for_act_sent(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state) -{ - struct intel_display *display = to_intel_display(encoder); - struct intel_dp *intel_dp = to_primary_dp(encoder); - - if (intel_de_wait_for_set(display, dp_tp_status_reg(encoder, crtc_state), - DP_TP_STATUS_ACT_SENT, 1)) - drm_err(display->drm, "Timed out waiting for ACT sent\n"); - - drm_dp_check_act_status(&intel_dp->mst_mgr); -} - static void mst_stream_disable(struct intel_atomic_state *state, struct intel_encoder *encoder, const struct intel_crtc_state *old_crtc_state, @@ -1049,13 +1027,14 @@ static void mst_stream_post_disable(struct intel_atomic_state *state, drm_dp_remove_payload_part1(&intel_dp->mst_mgr, new_mst_state, new_payload); - clear_act_sent(encoder, old_crtc_state); + intel_ddi_clear_act_sent(encoder, old_crtc_state); intel_de_rmw(display, TRANS_DDI_FUNC_CTL(display, old_crtc_state->cpu_transcoder), TRANS_DDI_DP_VC_PAYLOAD_ALLOC, 0); - wait_for_act_sent(encoder, old_crtc_state); + intel_ddi_wait_for_act_sent(encoder, old_crtc_state); + drm_dp_check_act_status(&intel_dp->mst_mgr); drm_dp_remove_payload_part2(&intel_dp->mst_mgr, new_mst_state, old_payload, new_payload); @@ -1299,7 +1278,7 @@ static void mst_stream_enable(struct intel_atomic_state *state, intel_ddi_enable_transcoder_func(encoder, pipe_config); - clear_act_sent(encoder, pipe_config); + intel_ddi_clear_act_sent(encoder, pipe_config); intel_de_rmw(display, TRANS_DDI_FUNC_CTL(display, trans), 0, TRANS_DDI_DP_VC_PAYLOAD_ALLOC); @@ -1307,7 +1286,8 @@ static void mst_stream_enable(struct intel_atomic_state *state, drm_dbg_kms(display->drm, "active links %d\n", intel_dp->active_mst_links); - wait_for_act_sent(encoder, pipe_config); + intel_ddi_wait_for_act_sent(encoder, pipe_config); + drm_dp_check_act_status(&intel_dp->mst_mgr); if (first_mst_stream) intel_ddi_wait_for_fec_status(encoder, pipe_config, true); -- cgit v1.2.3 From f5d38d4fa88441bc4f96e185bce7426790e32949 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 4 Dec 2024 12:21:50 +0200 Subject: drm/i915/display: convert intel_display_driver.[ch] to struct intel_display Going forward, struct intel_display will be the main display driver structure. Convert the main display entry points to struct intel_display. Cc: Rodrigo Vivi Reviewed-by: Gustavo Sousa Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20241204102150.2223455-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp_mst.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index c59c2c14679c..34ff93f5306d 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -1345,8 +1345,8 @@ static bool mst_stream_initial_fastset_check(struct intel_encoder *encoder, static int mst_connector_get_ddc_modes(struct drm_connector *connector) { + struct intel_display *display = to_intel_display(connector->dev); struct intel_connector *intel_connector = to_intel_connector(connector); - struct drm_i915_private *i915 = to_i915(intel_connector->base.dev); struct intel_dp *intel_dp = intel_connector->mst_port; const struct drm_edid *drm_edid; int ret; @@ -1354,7 +1354,7 @@ static int mst_connector_get_ddc_modes(struct drm_connector *connector) if (drm_connector_is_unregistered(connector)) return intel_connector_update_modes(connector, NULL); - if (!intel_display_driver_check_access(i915)) + if (!intel_display_driver_check_access(display)) return drm_edid_connector_add_modes(connector); drm_edid = drm_dp_mst_edid_read(connector, &intel_dp->mst_mgr, intel_connector->port); @@ -1544,7 +1544,6 @@ mst_connector_detect_ctx(struct drm_connector *connector, struct drm_modeset_acquire_ctx *ctx, bool force) { struct intel_display *display = to_intel_display(connector->dev); - struct drm_i915_private *i915 = to_i915(connector->dev); struct intel_connector *intel_connector = to_intel_connector(connector); struct intel_dp *intel_dp = intel_connector->mst_port; @@ -1554,7 +1553,7 @@ mst_connector_detect_ctx(struct drm_connector *connector, if (drm_connector_is_unregistered(connector)) return connector_status_disconnected; - if (!intel_display_driver_check_access(i915)) + if (!intel_display_driver_check_access(display)) return connector->status; intel_dp_flush_connector_commits(intel_connector); -- cgit v1.2.3 From b031ef5ea8b16525ba7ec47c0db36393b759615c Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 25 Nov 2024 17:19:33 +0200 Subject: drm/i915/mst: add beginnings of DP MST documentation Add a little bit of documentation around DP MST. This is nowhere near complete nor does it have enough detail. But it's better than nothing, and hopefully gives people a basic grasp of what's going on. Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20241125151933.2382910-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 32 +++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'drivers/gpu/drm/i915/display/intel_dp_mst.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 34ff93f5306d..123c4ece6268 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -53,6 +53,38 @@ #include "intel_vdsc.h" #include "skl_scaler.h" +/* + * DP MST (DisplayPort Multi-Stream Transport) + * + * MST support on the source depends on the platform and port. DP initialization + * sets up MST for each MST capable encoder. This will become the primary + * encoder for the port. + * + * MST initialization of each primary encoder creates MST stream encoders, one + * per pipe, and initializes the MST topology manager. The MST stream encoders + * are sometimes called "fake encoders", because they're virtual, not + * physical. Thus there are (number of MST capable ports) x (number of pipes) + * MST stream encoders in total. + * + * Decision to use MST for a sink happens at detect on the connector attached to + * the primary encoder, and this will not change while the sink is connected. We + * always use MST when possible, including for SST sinks with sideband messaging + * support. + * + * The connectors for the MST streams are added and removed dynamically by the + * topology manager. Their connection status is also determined by the topology + * manager. + * + * On hardware, each transcoder may be associated with a single DDI + * port. Multiple transcoders may be associated with the same DDI port only if + * the port is in MST mode. + * + * On TGL+, all the transcoders streaming on the same DDI port will indicate a + * primary transcoder; the TGL_DP_TP_CTL and TGL_DP_TP_STATUS registers are + * relevant only on the primary transcoder. Prior to that, they are port + * registers. + */ + /* From fake MST stream encoder to primary encoder */ static struct intel_encoder *to_primary_encoder(struct intel_encoder *encoder) { -- cgit v1.2.3 From 805cc9fef1fa9b07ab76d59ac733b915e0c52e48 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 11 Dec 2024 16:43:10 +0200 Subject: drm/i915/mst: use intel_dp_compute_config_limits() for DP MST There's a lot of duplication between mst_stream_compute_config_limits() and intel_dp_compute_config_limits(). Adjust the latter to suit the needs of the former, and use the same function for both. This reduces duplication and highlights the differences for SST and MST and UHBR. Remove the kernel-doc for intel_dp_compute_config_link_bpp_limits() which now becomes static. Cc: Imre Deak Reviewed-by: Imre Deak Reviewed-by: Ankit Nautiyal Link: https://patchwork.freedesktop.org/patch/msgid/20241211144310.701895-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 29 ++--------------------------- 1 file changed, 2 insertions(+), 27 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp_mst.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 123c4ece6268..d77ebcb1432e 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -585,33 +585,8 @@ mst_stream_compute_config_limits(struct intel_dp *intel_dp, bool dsc, struct link_config_limits *limits) { - /* - * for MST we always configure max link bw - the spec doesn't - * seem to suggest we should do otherwise. - */ - limits->min_rate = limits->max_rate = - intel_dp_max_link_rate(intel_dp); - - limits->min_lane_count = limits->max_lane_count = - intel_dp_max_lane_count(intel_dp); - - limits->pipe.min_bpp = intel_dp_min_bpp(crtc_state->output_format); - /* - * FIXME: If all the streams can't fit into the link with - * their current pipe_bpp we should reduce pipe_bpp across - * the board until things start to fit. Until then we - * limit to <= 8bpc since that's what was hardcoded for all - * MST streams previously. This hack should be removed once - * we have the proper retry logic in place. - */ - limits->pipe.max_bpp = min(crtc_state->pipe_bpp, 24); - - intel_dp_test_compute_config(intel_dp, crtc_state, limits); - - if (!intel_dp_compute_config_link_bpp_limits(intel_dp, - crtc_state, - dsc, - limits)) + if (!intel_dp_compute_config_limits(intel_dp, crtc_state, false, dsc, + limits)) return false; return adjust_limits_for_dsc_hblank_expansion_quirk(connector, -- cgit v1.2.3 From 5d1bbfba0f39cf7a37e30e88b362a500272c9b2a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 13 Dec 2024 11:48:24 +0200 Subject: drm/i915/dp: convert interfaces to struct intel_display Convert the intel_dp.[ch] external interfaces to struct intel_display. Reviewed-by: Luca Coelho Link: https://patchwork.freedesktop.org/patch/msgid/7d55f5fd9fc0619be3113098a49259d5374013c6.1734083244.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp_mst.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index d77ebcb1432e..326ff20a5a49 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -392,7 +392,6 @@ static int mst_stream_dsc_compute_link_config(struct intel_dp *intel_dp, { struct intel_display *display = to_intel_display(intel_dp); struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); int slots = -EINVAL; int i, num_bpc; u8 dsc_bpc[3] = {}; @@ -450,9 +449,9 @@ static int mst_stream_dsc_compute_link_config(struct intel_dp *intel_dp, min_compressed_bpp, max_compressed_bpp); /* Align compressed bpps according to our own constraints */ - max_compressed_bpp = intel_dp_dsc_nearest_valid_bpp(i915, max_compressed_bpp, + max_compressed_bpp = intel_dp_dsc_nearest_valid_bpp(display, max_compressed_bpp, crtc_state->pipe_bpp); - min_compressed_bpp = intel_dp_dsc_nearest_valid_bpp(i915, min_compressed_bpp, + min_compressed_bpp = intel_dp_dsc_nearest_valid_bpp(display, min_compressed_bpp, crtc_state->pipe_bpp); slots = mst_stream_find_vcpi_slots_for_bpp(intel_dp, crtc_state, max_compressed_bpp, @@ -600,7 +599,6 @@ static int mst_stream_compute_config(struct intel_encoder *encoder, struct drm_connector_state *conn_state) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_atomic_state *state = to_intel_atomic_state(conn_state->state); struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); struct intel_dp *intel_dp = to_primary_dp(encoder); @@ -630,7 +628,7 @@ static int mst_stream_compute_config(struct intel_encoder *encoder, pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; pipe_config->has_pch_encoder = false; - joiner_needs_dsc = intel_dp_joiner_needs_dsc(dev_priv, num_joined_pipes); + joiner_needs_dsc = intel_dp_joiner_needs_dsc(display, num_joined_pipes); dsc_needed = joiner_needs_dsc || intel_dp->force_dsc_en || !mst_stream_compute_config_limits(intel_dp, connector, @@ -1501,7 +1499,7 @@ mst_connector_mode_valid_ctx(struct drm_connector *connector, if (drm_dp_sink_supports_fec(intel_connector->dp.fec_capability)) { dsc_max_compressed_bpp = - intel_dp_dsc_get_max_compressed_bpp(dev_priv, + intel_dp_dsc_get_max_compressed_bpp(display, max_link_clock, max_lanes, target_clock, @@ -1519,7 +1517,7 @@ mst_connector_mode_valid_ctx(struct drm_connector *connector, dsc = dsc_max_compressed_bpp && dsc_slice_count; } - if (intel_dp_joiner_needs_dsc(dev_priv, num_joined_pipes) && !dsc) { + if (intel_dp_joiner_needs_dsc(display, num_joined_pipes) && !dsc) { *status = MODE_CLOCK_HIGH; return 0; } -- cgit v1.2.3 From 230a14f4c586be1f6a58cd35d35d7dfa34eb071e Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Tue, 17 Dec 2024 15:02:31 +0530 Subject: drm/i915/dp: Refactor FEC support check in intel_dp_supports_dsc Forward Error Correction is required for DP if we are using DSC but is optional for eDP. Currently the helper intel_dp_supports_dsc checks if fec_enable is set for DP or not. The helper is called after fec_enable is set in crtc_state. Instead of this a better approach would be to: first, call intel_dp_supports_dsc to check for DSC support (along with FEC requirement for DP) and then set fec_enable for DP (if not already set) in crtc_state. To achieve this, remove the check for fec_enable in the helper and instead check for FEC support for DP. With this change the helper intel_dp_supports_dsc can be called earlier and return early if DSC is not supported. The structure intel_dp is added to the helper to get the FEC support for DP. v2: Pass intel_dp to adjust_limits_for_dsc_hblank_expansion_quirk instead of deriving it from connector. (Jani) Signed-off-by: Ankit Nautiyal Reviewed-by: Suraj Kandpal Reviewed-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20241217093244.3938132-2-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp_mst.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 326ff20a5a49..4217350eefb0 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -519,7 +519,8 @@ hblank_expansion_quirk_needs_dsc(const struct intel_connector *connector, } static bool -adjust_limits_for_dsc_hblank_expansion_quirk(const struct intel_connector *connector, +adjust_limits_for_dsc_hblank_expansion_quirk(struct intel_dp *intel_dp, + const struct intel_connector *connector, const struct intel_crtc_state *crtc_state, struct link_config_limits *limits, bool dsc) @@ -532,7 +533,7 @@ adjust_limits_for_dsc_hblank_expansion_quirk(const struct intel_connector *conne return true; if (!dsc) { - if (intel_dp_supports_dsc(connector, crtc_state)) { + if (intel_dp_supports_dsc(intel_dp, connector, crtc_state)) { drm_dbg_kms(display->drm, "[CRTC:%d:%s][CONNECTOR:%d:%s] DSC needed by hblank expansion quirk\n", crtc->base.base.id, crtc->base.name, @@ -588,7 +589,8 @@ mst_stream_compute_config_limits(struct intel_dp *intel_dp, limits)) return false; - return adjust_limits_for_dsc_hblank_expansion_quirk(connector, + return adjust_limits_for_dsc_hblank_expansion_quirk(intel_dp, + connector, crtc_state, limits, dsc); @@ -651,7 +653,7 @@ static int mst_stream_compute_config(struct intel_encoder *encoder, str_yes_no(ret), str_yes_no(joiner_needs_dsc), str_yes_no(intel_dp->force_dsc_en)); - if (!intel_dp_supports_dsc(connector, pipe_config)) + if (!intel_dp_supports_dsc(intel_dp, connector, pipe_config)) return -EINVAL; if (!mst_stream_compute_config_limits(intel_dp, connector, -- cgit v1.2.3 From 1db9bd98e78155fb6be94fedab1520218e7468b1 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Tue, 17 Dec 2024 15:02:37 +0530 Subject: drm/i915/dp_mst: Use helpers to get dsc min/max input bpc Use helpers for source min/max input bpc with DSC. Signed-off-by: Ankit Nautiyal Reviewed-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/20241217093244.3938132-8-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp_mst.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 4217350eefb0..c9c4c8b960f1 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -396,17 +396,14 @@ static int mst_stream_dsc_compute_link_config(struct intel_dp *intel_dp, int i, num_bpc; u8 dsc_bpc[3] = {}; int min_bpp, max_bpp, sink_min_bpp, sink_max_bpp; - u8 dsc_max_bpc; + int dsc_max_bpc, dsc_min_bpc; int min_compressed_bpp, max_compressed_bpp; - /* Max DSC Input BPC for ICL is 10 and for TGL+ is 12 */ - if (DISPLAY_VER(display) >= 12) - dsc_max_bpc = min_t(u8, 12, conn_state->max_requested_bpc); - else - dsc_max_bpc = min_t(u8, 10, conn_state->max_requested_bpc); + dsc_max_bpc = intel_dp_dsc_max_src_input_bpc(display); + dsc_min_bpc = intel_dp_dsc_min_src_input_bpc(); - max_bpp = min_t(u8, dsc_max_bpc * 3, limits->pipe.max_bpp); - min_bpp = limits->pipe.min_bpp; + max_bpp = min(dsc_max_bpc * 3, limits->pipe.max_bpp); + min_bpp = max(dsc_min_bpc * 3, limits->pipe.min_bpp); num_bpc = drm_dp_dsc_sink_supported_input_bpcs(connector->dp.dsc_dpcd, dsc_bpc); -- cgit v1.2.3 From a35dc4aee37c5f5c2052735babf59062cc19c92c Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Tue, 17 Dec 2024 15:02:40 +0530 Subject: drm/i915/dp_mst: Use pipe_bpp->limits.{max/min}_bpp for dsc The dsc limits->pipe.max/min_bpp are already set in intel_dp_compute_config_limits. Use the limits while computing the link config with DSC for MST. Signed-off-by: Ankit Nautiyal Reviewed-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/20241217093244.3938132-11-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp_mst.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index c9c4c8b960f1..689fbd6bcf9b 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -396,14 +396,10 @@ static int mst_stream_dsc_compute_link_config(struct intel_dp *intel_dp, int i, num_bpc; u8 dsc_bpc[3] = {}; int min_bpp, max_bpp, sink_min_bpp, sink_max_bpp; - int dsc_max_bpc, dsc_min_bpc; int min_compressed_bpp, max_compressed_bpp; - dsc_max_bpc = intel_dp_dsc_max_src_input_bpc(display); - dsc_min_bpc = intel_dp_dsc_min_src_input_bpc(); - - max_bpp = min(dsc_max_bpc * 3, limits->pipe.max_bpp); - min_bpp = max(dsc_min_bpc * 3, limits->pipe.min_bpp); + max_bpp = limits->pipe.max_bpp; + min_bpp = limits->pipe.min_bpp; num_bpc = drm_dp_dsc_sink_supported_input_bpcs(connector->dp.dsc_dpcd, dsc_bpc); -- cgit v1.2.3 From 5aad05463d221bb8afb11607d63eb56fc56eff82 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Tue, 17 Dec 2024 15:02:44 +0530 Subject: drm/i915/dp_mst: Use link.{min/max}_bpp_x16 The link.{min/max}_bpp_x16 is already set in crtc_state, use that while computing link config for MST. Signed-off-by: Ankit Nautiyal Reviewed-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/20241217093244.3938132-15-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp_mst.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 689fbd6bcf9b..a9d9d7694acb 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -428,15 +428,8 @@ static int mst_stream_dsc_compute_link_config(struct intel_dp *intel_dp, crtc_state->pipe_bpp = max_bpp; - max_compressed_bpp = intel_dp_dsc_sink_max_compressed_bpp(connector, - crtc_state, - max_bpp / 3); - max_compressed_bpp = min(max_compressed_bpp, - fxp_q4_to_int(limits->link.max_bpp_x16)); - - min_compressed_bpp = intel_dp_dsc_sink_min_compressed_bpp(crtc_state); - min_compressed_bpp = max(min_compressed_bpp, - fxp_q4_to_int_roundup(limits->link.min_bpp_x16)); + max_compressed_bpp = fxp_q4_to_int(limits->link.max_bpp_x16); + min_compressed_bpp = fxp_q4_to_int_roundup(limits->link.min_bpp_x16); drm_dbg_kms(display->drm, "DSC Sink supported compressed min bpp %d compressed max bpp %d\n", min_compressed_bpp, max_compressed_bpp); -- cgit v1.2.3 From 939bc3e4d996ba2eebc5a9d8a8cf785cd17b1f93 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Fri, 3 Jan 2025 08:44:24 +0530 Subject: drm/i915/dp: Return early if dsc is required but not supported Currently, when bandwidth is insufficient for a given mode, we attempt to use DSC. This is indicated by a debug print, followed by a check for DSC support. The debug message states that we are trying DSC, but DSC might not be supported, which can give an incorrect picture in the logs if we bail out later. Correct the order for both DP and DP MST to: - Check if DSC is required and supported, and return early if DSC is not supported. - Print a debug message to indicate that DSC will be tried next. Suggested-by: Jani Nikula Signed-off-by: Ankit Nautiyal Reviewed-by: Suraj Kandpal Reviewed-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20250103031424.1732774-1-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp_mst.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index a9d9d7694acb..7d9a164a7556 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -633,14 +633,17 @@ static int mst_stream_compute_config(struct intel_encoder *encoder, dsc_needed = true; } + if (dsc_needed && !intel_dp_supports_dsc(intel_dp, connector, pipe_config)) { + drm_dbg_kms(display->drm, "DSC required but not available\n"); + return -EINVAL; + } + /* enable compression if the mode doesn't fit available BW */ if (dsc_needed) { drm_dbg_kms(display->drm, "Try DSC (fallback=%s, joiner=%s, force=%s)\n", str_yes_no(ret), str_yes_no(joiner_needs_dsc), str_yes_no(intel_dp->force_dsc_en)); - if (!intel_dp_supports_dsc(intel_dp, connector, pipe_config)) - return -EINVAL; if (!mst_stream_compute_config_limits(intel_dp, connector, pipe_config, true, -- cgit v1.2.3 From 79cb1fad39fad0ace231aeb8d5e6b016d562dd83 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 3 Jan 2025 15:52:24 +0200 Subject: drm/mst: remove mgr parameter and debug logging from drm_dp_get_vc_payload_bw() The struct drm_dp_mst_topology_mgr *mgr parameter is only used for debug logging in case the passed in link rate or lane count are zero. There's no further error checking as such, and the function returns 0. There should be no case where the parameters are zero. The returned value is generally used as a divisor, and if we were hitting this, we'd be seeing division by zero. Just remove the debug logging altogether, along with the mgr parameter, so that the function can be used in non-MST contexts without the topology manager. v2: Also remove drm_dp_mst_helper_tests_init as unnecessary (Imre) Cc: Imre Deak Cc: Lyude Paul Reviewed-by: Imre Deak Acked-by: Maxime Ripard Acked-by: Thomas Zimmermann Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/72d77e7a7fe69c784e9df048b7e6f250fd7599e4.1735912293.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp_mst.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 0433f2ff77e1..10009d4003fc 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -244,8 +244,7 @@ static int mst_stream_find_vcpi_slots_for_bpp(struct intel_dp *intel_dp, crtc_state->fec_enable = !intel_dp_is_uhbr(crtc_state); } - mst_state->pbn_div = drm_dp_get_vc_payload_bw(&intel_dp->mst_mgr, - crtc_state->port_clock, + mst_state->pbn_div = drm_dp_get_vc_payload_bw(crtc_state->port_clock, crtc_state->lane_count); max_dpt_bpp = intel_dp_mst_max_dpt_bpp(crtc_state, dsc); -- cgit v1.2.3 From 2f6ba896cef8a8a138567f727467fb7edd438257 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 3 Jan 2025 15:52:25 +0200 Subject: drm/i915/mst: drop connector parameter from intel_dp_mst_bw_overhead() intel_dp_mst_bw_overhead() doesn't need the connector. Remove the parameter. Reviewed-by: Imre Deak Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/e1379aca0748e392d8a232135b823deec783e829.1735912293.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp_mst.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 10009d4003fc..e1340cff77fe 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -139,7 +139,6 @@ static int intel_dp_mst_max_dpt_bpp(const struct intel_crtc_state *crtc_state, } static int intel_dp_mst_bw_overhead(const struct intel_crtc_state *crtc_state, - const struct intel_connector *connector, bool ssc, int dsc_slice_count, int bpp_x16) { const struct drm_display_mode *adjusted_mode = @@ -278,9 +277,9 @@ static int mst_stream_find_vcpi_slots_for_bpp(struct intel_dp *intel_dp, link_bpp_x16 = fxp_q4_from_int(dsc ? bpp : intel_dp_output_bpp(crtc_state->output_format, bpp)); - local_bw_overhead = intel_dp_mst_bw_overhead(crtc_state, connector, + local_bw_overhead = intel_dp_mst_bw_overhead(crtc_state, false, dsc_slice_count, link_bpp_x16); - remote_bw_overhead = intel_dp_mst_bw_overhead(crtc_state, connector, + remote_bw_overhead = intel_dp_mst_bw_overhead(crtc_state, true, dsc_slice_count, link_bpp_x16); intel_dp_mst_compute_m_n(crtc_state, connector, -- cgit v1.2.3 From d7cde2e6bc76d724394f4bb858453c004efe9fcc Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 3 Jan 2025 15:52:26 +0200 Subject: drm/i915/mst: drop connector parameter from intel_dp_mst_compute_m_n() intel_dp_mst_compute_m_n() doesn't need the connector. Remove the parameter. Reviewed-by: Imre Deak Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/eec2e9a2e2dc3d166ac94bb9de691246a14d3945.1735912293.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp_mst.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index e1340cff77fe..927b0f05a691 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -167,7 +167,6 @@ static int intel_dp_mst_bw_overhead(const struct intel_crtc_state *crtc_state, } static void intel_dp_mst_compute_m_n(const struct intel_crtc_state *crtc_state, - const struct intel_connector *connector, int overhead, int bpp_x16, struct intel_link_m_n *m_n) @@ -282,7 +281,7 @@ static int mst_stream_find_vcpi_slots_for_bpp(struct intel_dp *intel_dp, remote_bw_overhead = intel_dp_mst_bw_overhead(crtc_state, true, dsc_slice_count, link_bpp_x16); - intel_dp_mst_compute_m_n(crtc_state, connector, + intel_dp_mst_compute_m_n(crtc_state, local_bw_overhead, link_bpp_x16, &crtc_state->dp_m_n); -- cgit v1.2.3 From 643b06e29ec00b6e32f69af5ce4aaf1220fdf5f9 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 3 Jan 2025 15:52:27 +0200 Subject: drm/i915/mst: change return value of mst_stream_find_vcpi_slots_for_bpp() The callers of mst_stream_find_vcpi_slots_for_bpp() don't need the returned slots for anything. On the contrary, they need to jump through hoops to just distinguish between success and failure. Just return 0 instead of slots from mst_stream_find_vcpi_slots_for_bpp() for success, and simplify the callers. There's a pointless ret local variable that we can drop in the process. Reviewed-by: Imre Deak Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/7b3671a548c893b1bb62151d41f90bb8ce842ccc.1735912293.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 52 ++++++++++------------------- 1 file changed, 18 insertions(+), 34 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp_mst.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 927b0f05a691..f1adb1d0ecb3 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -226,7 +226,6 @@ static int mst_stream_find_vcpi_slots_for_bpp(struct intel_dp *intel_dp, int bpp, slots = -EINVAL; int dsc_slice_count = 0; int max_dpt_bpp; - int ret = 0; mst_state = drm_atomic_get_mst_topology_state(state, &intel_dp->mst_mgr); if (IS_ERR(mst_state)) @@ -340,23 +339,21 @@ static int mst_stream_find_vcpi_slots_for_bpp(struct intel_dp *intel_dp, } } - /* We failed to find a proper bpp/timeslots, return error */ - if (ret) - slots = ret; - if (slots < 0) { drm_dbg_kms(display->drm, "failed finding vcpi slots:%d\n", slots); - } else { - if (!dsc) - crtc_state->pipe_bpp = bpp; - else - crtc_state->dsc.compressed_bpp_x16 = fxp_q4_from_int(bpp); - drm_dbg_kms(display->drm, "Got %d slots for pipe bpp %d dsc %d\n", - slots, bpp, dsc); + return slots; } - return slots; + if (!dsc) + crtc_state->pipe_bpp = bpp; + else + crtc_state->dsc.compressed_bpp_x16 = fxp_q4_from_int(bpp); + + drm_dbg_kms(display->drm, "Got %d slots for pipe bpp %d dsc %d\n", + slots, bpp, dsc); + + return 0; } static int mst_stream_compute_link_config(struct intel_dp *intel_dp, @@ -364,22 +361,15 @@ static int mst_stream_compute_link_config(struct intel_dp *intel_dp, struct drm_connector_state *conn_state, struct link_config_limits *limits) { - int slots = -EINVAL; - /* * FIXME: allocate the BW according to link_bpp, which in the case of * YUV420 is only half of the pipe bpp value. */ - slots = mst_stream_find_vcpi_slots_for_bpp(intel_dp, crtc_state, - fxp_q4_to_int(limits->link.max_bpp_x16), - fxp_q4_to_int(limits->link.min_bpp_x16), - limits, - conn_state, 2 * 3, false); - - if (slots < 0) - return slots; - - return 0; + return mst_stream_find_vcpi_slots_for_bpp(intel_dp, crtc_state, + fxp_q4_to_int(limits->link.max_bpp_x16), + fxp_q4_to_int(limits->link.min_bpp_x16), + limits, + conn_state, 2 * 3, false); } static int mst_stream_dsc_compute_link_config(struct intel_dp *intel_dp, @@ -389,7 +379,6 @@ static int mst_stream_dsc_compute_link_config(struct intel_dp *intel_dp, { struct intel_display *display = to_intel_display(intel_dp); struct intel_connector *connector = to_intel_connector(conn_state->connector); - int slots = -EINVAL; int i, num_bpc; u8 dsc_bpc[3] = {}; int min_bpp, max_bpp, sink_min_bpp, sink_max_bpp; @@ -437,14 +426,9 @@ static int mst_stream_dsc_compute_link_config(struct intel_dp *intel_dp, min_compressed_bpp = intel_dp_dsc_nearest_valid_bpp(display, min_compressed_bpp, crtc_state->pipe_bpp); - slots = mst_stream_find_vcpi_slots_for_bpp(intel_dp, crtc_state, max_compressed_bpp, - min_compressed_bpp, limits, - conn_state, 1, true); - - if (slots < 0) - return slots; - - return 0; + return mst_stream_find_vcpi_slots_for_bpp(intel_dp, crtc_state, max_compressed_bpp, + min_compressed_bpp, limits, + conn_state, 1, true); } static int mst_stream_update_slots(struct intel_dp *intel_dp, -- cgit v1.2.3 From 0dcc5c6a02abf95a918abff9a540f1618291624c Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 3 Jan 2025 15:52:28 +0200 Subject: drm/i915/mst: remove crtc_state->pbn The crtc_state->pbn member is only used as a temporary variable within mst_stream_find_vcpi_slots_for_bpp(). Remove it as unnecessary. Suggested-by: Imre Deak Reviewed-by: Imre Deak Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/726aaadbd425057dfd854e42417bcf8d69b769d3.1735912293.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp_mst.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index f1adb1d0ecb3..2ab960a8bd8e 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -321,14 +321,13 @@ static int mst_stream_find_vcpi_slots_for_bpp(struct intel_dp *intel_dp, * first branch device's link also applies here. */ pbn.full = remote_tu * mst_state->pbn_div.full; - crtc_state->pbn = dfixed_trunc(pbn); drm_WARN_ON(display->drm, remote_tu < crtc_state->dp_m_n.tu); crtc_state->dp_m_n.tu = remote_tu; slots = drm_dp_atomic_find_time_slots(state, &intel_dp->mst_mgr, connector->port, - crtc_state->pbn); + dfixed_trunc(pbn)); if (slots == -EDEADLK) return slots; -- cgit v1.2.3 From 1ed21a66ecb7005ab80132643cce99e0addea5dd Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 3 Jan 2025 15:52:29 +0200 Subject: drm/i915/mst: split out a helper for figuring out the TU Extract intel_dp_mtp_tu_compute_config() for figuring out the TU. Move the link configuration and mst state access to the callers. This will be easier to adapt to 128b/132b SST. v2: Don't add SST stuff here yet Reviewed-by: Imre Deak Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/c3ea8370c9bd3cdc579159e68a63f4ed2fadc66a.1735912293.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 53 +++++++++++++++++++---------- 1 file changed, 35 insertions(+), 18 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp_mst.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 2ab960a8bd8e..b9b64c00817e 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -209,31 +209,23 @@ static int intel_dp_mst_dsc_get_slice_count(const struct intel_connector *connec num_joined_pipes); } -static int mst_stream_find_vcpi_slots_for_bpp(struct intel_dp *intel_dp, - struct intel_crtc_state *crtc_state, - int max_bpp, int min_bpp, - struct link_config_limits *limits, - struct drm_connector_state *conn_state, - int step, bool dsc) +int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp, + struct intel_crtc_state *crtc_state, + int max_bpp, int min_bpp, + struct drm_connector_state *conn_state, + int step, bool dsc) { struct intel_display *display = to_intel_display(intel_dp); struct drm_atomic_state *state = crtc_state->uapi.state; - struct drm_dp_mst_topology_state *mst_state; struct intel_connector *connector = to_intel_connector(conn_state->connector); const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; + fixed20_12 pbn_div; int bpp, slots = -EINVAL; int dsc_slice_count = 0; int max_dpt_bpp; - mst_state = drm_atomic_get_mst_topology_state(state, &intel_dp->mst_mgr); - if (IS_ERR(mst_state)) - return PTR_ERR(mst_state); - - crtc_state->lane_count = limits->max_lane_count; - crtc_state->port_clock = limits->max_rate; - if (dsc) { if (!intel_dp_supports_fec(intel_dp, connector, crtc_state)) return -EINVAL; @@ -241,8 +233,8 @@ static int mst_stream_find_vcpi_slots_for_bpp(struct intel_dp *intel_dp, crtc_state->fec_enable = !intel_dp_is_uhbr(crtc_state); } - mst_state->pbn_div = drm_dp_get_vc_payload_bw(crtc_state->port_clock, - crtc_state->lane_count); + pbn_div = drm_dp_get_vc_payload_bw(crtc_state->port_clock, + crtc_state->lane_count); max_dpt_bpp = intel_dp_mst_max_dpt_bpp(crtc_state, dsc); if (max_bpp > max_dpt_bpp) { @@ -302,7 +294,7 @@ static int mst_stream_find_vcpi_slots_for_bpp(struct intel_dp *intel_dp, pbn.full = dfixed_const(intel_dp_mst_calc_pbn(adjusted_mode->crtc_clock, link_bpp_x16, remote_bw_overhead)); - remote_tu = DIV_ROUND_UP(pbn.full, mst_state->pbn_div.full); + remote_tu = DIV_ROUND_UP(pbn.full, pbn_div.full); /* * Aligning the TUs ensures that symbols consisting of multiple @@ -320,7 +312,7 @@ static int mst_stream_find_vcpi_slots_for_bpp(struct intel_dp *intel_dp, * allocated for the whole path and the TUs allocated for the * first branch device's link also applies here. */ - pbn.full = remote_tu * mst_state->pbn_div.full; + pbn.full = remote_tu * pbn_div.full; drm_WARN_ON(display->drm, remote_tu < crtc_state->dp_m_n.tu); crtc_state->dp_m_n.tu = remote_tu; @@ -355,6 +347,31 @@ static int mst_stream_find_vcpi_slots_for_bpp(struct intel_dp *intel_dp, return 0; } +static int mst_stream_find_vcpi_slots_for_bpp(struct intel_dp *intel_dp, + struct intel_crtc_state *crtc_state, + int max_bpp, int min_bpp, + struct link_config_limits *limits, + struct drm_connector_state *conn_state, + int step, bool dsc) +{ + struct drm_atomic_state *state = crtc_state->uapi.state; + struct drm_dp_mst_topology_state *mst_state; + + mst_state = drm_atomic_get_mst_topology_state(state, &intel_dp->mst_mgr); + if (IS_ERR(mst_state)) + return PTR_ERR(mst_state); + + crtc_state->lane_count = limits->max_lane_count; + crtc_state->port_clock = limits->max_rate; + + mst_state->pbn_div = drm_dp_get_vc_payload_bw(crtc_state->port_clock, + crtc_state->lane_count); + + return intel_dp_mtp_tu_compute_config(intel_dp, crtc_state, + max_bpp, min_bpp, + conn_state, step, dsc); +} + static int mst_stream_compute_link_config(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state, struct drm_connector_state *conn_state, -- cgit v1.2.3 From f6971d7427c2b235a2aa30d986343a3523cbe974 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 3 Jan 2025 15:52:30 +0200 Subject: drm/i915/mst: adapt intel_dp_mtp_tu_compute_config() for 128b/132b SST Handle 128b/132b SST in intel_dp_mtp_tu_compute_config(). The remote bandwidth overhead and time slot allocation are only relevant for MST; SST only needs the local bandwidth and a check that 64 slots isn't exceeded. Reviewed-by: Imre Deak Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/b59c94b0aac2c073b0306c0a0040b26330f94260.1735912293.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 109 ++++++++++++++++------------ 1 file changed, 61 insertions(+), 48 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp_mst.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index b9b64c00817e..0c44fc7dd86c 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -257,10 +257,7 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp, for (bpp = max_bpp; bpp >= min_bpp; bpp -= step) { int local_bw_overhead; - int remote_bw_overhead; int link_bpp_x16; - int remote_tu; - fixed20_12 pbn; drm_dbg_kms(display->drm, "Trying bpp %d\n", bpp); @@ -269,57 +266,73 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp, local_bw_overhead = intel_dp_mst_bw_overhead(crtc_state, false, dsc_slice_count, link_bpp_x16); - remote_bw_overhead = intel_dp_mst_bw_overhead(crtc_state, - true, dsc_slice_count, link_bpp_x16); - intel_dp_mst_compute_m_n(crtc_state, local_bw_overhead, link_bpp_x16, &crtc_state->dp_m_n); - /* - * The TU size programmed to the HW determines which slots in - * an MTP frame are used for this stream, which needs to match - * the payload size programmed to the first downstream branch - * device's payload table. - * - * Note that atm the payload's PBN value DRM core sends via - * the ALLOCATE_PAYLOAD side-band message matches the payload - * size (which it calculates from the PBN value) it programs - * to the first branch device's payload table. The allocation - * in the payload table could be reduced though (to - * crtc_state->dp_m_n.tu), provided that the driver doesn't - * enable SSC on the corresponding link. - */ - pbn.full = dfixed_const(intel_dp_mst_calc_pbn(adjusted_mode->crtc_clock, - link_bpp_x16, - remote_bw_overhead)); - remote_tu = DIV_ROUND_UP(pbn.full, pbn_div.full); - - /* - * Aligning the TUs ensures that symbols consisting of multiple - * (4) symbol cycles don't get split between two consecutive - * MTPs, as required by Bspec. - * TODO: remove the alignment restriction for 128b/132b links - * on some platforms, where Bspec allows this. - */ - remote_tu = ALIGN(remote_tu, 4 / crtc_state->lane_count); - - /* - * Also align PBNs accordingly, since MST core will derive its - * own copy of TU from the PBN in drm_dp_atomic_find_time_slots(). - * The above comment about the difference between the PBN - * allocated for the whole path and the TUs allocated for the - * first branch device's link also applies here. - */ - pbn.full = remote_tu * pbn_div.full; - - drm_WARN_ON(display->drm, remote_tu < crtc_state->dp_m_n.tu); - crtc_state->dp_m_n.tu = remote_tu; + if (intel_dp->is_mst) { + int remote_bw_overhead; + int remote_tu; + fixed20_12 pbn; + + remote_bw_overhead = intel_dp_mst_bw_overhead(crtc_state, + true, dsc_slice_count, link_bpp_x16); + + /* + * The TU size programmed to the HW determines which slots in + * an MTP frame are used for this stream, which needs to match + * the payload size programmed to the first downstream branch + * device's payload table. + * + * Note that atm the payload's PBN value DRM core sends via + * the ALLOCATE_PAYLOAD side-band message matches the payload + * size (which it calculates from the PBN value) it programs + * to the first branch device's payload table. The allocation + * in the payload table could be reduced though (to + * crtc_state->dp_m_n.tu), provided that the driver doesn't + * enable SSC on the corresponding link. + */ + pbn.full = dfixed_const(intel_dp_mst_calc_pbn(adjusted_mode->crtc_clock, + link_bpp_x16, + remote_bw_overhead)); + remote_tu = DIV_ROUND_UP(pbn.full, pbn_div.full); + + /* + * Aligning the TUs ensures that symbols consisting of multiple + * (4) symbol cycles don't get split between two consecutive + * MTPs, as required by Bspec. + * TODO: remove the alignment restriction for 128b/132b links + * on some platforms, where Bspec allows this. + */ + remote_tu = ALIGN(remote_tu, 4 / crtc_state->lane_count); + + /* + * Also align PBNs accordingly, since MST core will derive its + * own copy of TU from the PBN in drm_dp_atomic_find_time_slots(). + * The above comment about the difference between the PBN + * allocated for the whole path and the TUs allocated for the + * first branch device's link also applies here. + */ + pbn.full = remote_tu * pbn_div.full; + + drm_WARN_ON(display->drm, remote_tu < crtc_state->dp_m_n.tu); + crtc_state->dp_m_n.tu = remote_tu; + + slots = drm_dp_atomic_find_time_slots(state, &intel_dp->mst_mgr, + connector->port, + dfixed_trunc(pbn)); + } else { + /* Same as above for remote_tu */ + crtc_state->dp_m_n.tu = ALIGN(crtc_state->dp_m_n.tu, + 4 / crtc_state->lane_count); + + if (crtc_state->dp_m_n.tu <= 64) + slots = crtc_state->dp_m_n.tu; + else + slots = -EINVAL; + } - slots = drm_dp_atomic_find_time_slots(state, &intel_dp->mst_mgr, - connector->port, - dfixed_trunc(pbn)); if (slots == -EDEADLK) return slots; -- cgit v1.2.3