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)
-- 
2.49.1

Reply via email to