On Wed, 2026-07-01 at 18:31 +0300, Imre Deak wrote:
> Use the link caps helper to select the maximum DP MST link configuration
> for DSC computation, instead of using the separate max rate and lane
> count limits, which may not form a valid configuration after individual
> configs are disabled by fallback.
> 
> Also look up the maximum rate for state computation via the configuration
> mask when checking the DSC hblank expansion quirk.
> 
> This is a step towards unifying configuration selection and iteration
> across connector types and between compute and fallback paths.
> 
> The state computation should likely consider all allowed configurations,
> as noted in the code comment; for now keep the existing DP MST DSC
> behavior of selecting the maximum BW configuration determined by the MST
> connector BW config iteration order.
> 
> Signed-off-by: Imre Deak <[email protected]>
> ---
>  drivers/gpu/drm/i915/display/intel_dp_mst.c | 40 +++++++++++++++++----
>  1 file changed, 33 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
> b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index 47b8563f85e4d..df6e54508e5d4 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -477,6 +477,7 @@ 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 intel_dp_link_config max_link_config;
>  
>       crtc_state->pipe_bpp = limits->pipe.max_bpp;
>  
> @@ -484,8 +485,17 @@ static int mst_stream_dsc_compute_link_config(struct 
> intel_dp *intel_dp,
>                   "DSC Sink supported compressed min bpp " FXP_Q4_FMT " 
> compressed max bpp " FXP_Q4_FMT "\n",
>                   FXP_Q4_ARGS(limits->link.min_bpp_x16), 
> FXP_Q4_ARGS(limits->link.max_bpp_x16));
>  
> -     crtc_state->lane_count = limits->max_lane_count;
> -     crtc_state->port_clock = limits->max_rate;
> +     /*
> +      * FIXME: Use a proper iteration over the link configurations, instead
> +      * of using only the max BW config. For instance UHBR rate configs may
> +      * have additional limitations over non-UHBR ones, due to the DSC DPT
> +      * bpp maximum limit.
> +      */
> +     if (!intel_dp_get_connector_max_link_config(connector, limits, 
> &max_link_config))
> +             return -EINVAL;
> +
> +     crtc_state->port_clock = max_link_config.rate;
> +     crtc_state->lane_count = max_link_config.lane_count;
>  
>       return intel_dp_mtp_tu_compute_config(intel_dp, crtc_state, conn_state,
>                                             limits->link.min_bpp_x16,
> @@ -501,6 +511,20 @@ static int mode_hblank_period_ns(const struct 
> drm_display_mode *mode)
>                                    mode->crtc_clock);
>  }
>  
> +static int get_connector_max_rate(const struct intel_connector *connector,
> +                               const struct link_config_limits *limits)
> +{
> +     struct intel_dp *intel_dp = intel_attached_dp((struct intel_connector 
> *)connector);
> +     struct intel_dp_link_caps *link_caps = intel_dp->link.caps;
> +     struct intel_dp_link_config max_link_config;
> +
> +     intel_dp_link_caps_get_max_config(link_caps,
> +                                       
> INTEL_DP_LINK_CAPS_ORDER_KEY_RATE_LANE,
> +                                       limits->link_config_filter, 
> &max_link_config);
> +
> +     return max_link_config.rate;
> +}
> +
>  static bool
>  hblank_expansion_quirk_needs_dsc(const struct intel_connector *connector,
>                                const struct intel_crtc_state *crtc_state,
> @@ -511,11 +535,13 @@ hblank_expansion_quirk_needs_dsc(const struct 
> intel_connector *connector,
>       bool is_uhbr_sink = connector->mst.dp &&
>                           drm_dp_128b132b_supported(connector->mst.dp->dpcd);
>       int hblank_limit = is_uhbr_sink ? 500 : 300;
> +     int max_rate;
>  
>       if (!connector->dp.dsc_hblank_expansion_quirk)
>               return false;
>  
> -     if (is_uhbr_sink && !drm_dp_is_uhbr_rate(limits->max_rate))
> +     max_rate = get_connector_max_rate(connector, limits);
> +     if (is_uhbr_sink && !drm_dp_is_uhbr_rate(max_rate))
>               return false;
>  
>       if (mode_hblank_period_ns(adjusted_mode) > hblank_limit)
> @@ -537,6 +563,7 @@ adjust_limits_for_dsc_hblank_expansion_quirk(struct 
> intel_dp *intel_dp,
>       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;
> +     int max_rate;
>  
>       if (!hblank_expansion_quirk_needs_dsc(connector, crtc_state, limits))
>               return true;
> @@ -563,11 +590,10 @@ adjust_limits_for_dsc_hblank_expansion_quirk(struct 
> intel_dp *intel_dp,
>               return true;
>       }
>  
> -     drm_WARN_ON(display->drm, limits->min_rate != limits->max_rate);
> -
> -     if (limits->max_rate < 540000)
> +     max_rate = get_connector_max_rate(connector, limits);
> +     if (max_rate < 540000)
>               min_bpp_x16 = fxp_q4_from_int(13);
> -     else if (limits->max_rate < 810000)
> +     else if (max_rate < 810000)
>               min_bpp_x16 = fxp_q4_from_int(10);
>  
>       if (limits->link.min_bpp_x16 >= min_bpp_x16)


Reviewed-by: Luca Coelho <[email protected]>

--
Cheers,
Luca.

Reply via email to