Refactor the logic to get the number of joined pipes. Start with a single
pipe and incrementally try additional pipes only if needed. While DSC
overhead is not yet computed here, this restructuring prepares the code to
support that in follow-up changes.

Signed-off-by: Ankit Nautiyal <[email protected]>
---
 drivers/gpu/drm/i915/display/intel_dp.c     |   1 -
 drivers/gpu/drm/i915/display/intel_dp.h     |   1 +
 drivers/gpu/drm/i915/display/intel_dp_mst.c | 100 ++++++++++++--------
 3 files changed, 64 insertions(+), 38 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index d96d9ac1e830..2ead783129f4 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1378,7 +1378,6 @@ intel_dp_mode_valid_downstream(struct intel_connector 
*connector,
        return MODE_OK;
 }
 
-static
 int intel_dp_hdisplay_limit(struct intel_display *display)
 {
        return DISPLAY_VER(display) >= 30 ? 6144 : 5120;
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h 
b/drivers/gpu/drm/i915/display/intel_dp.h
index a27e3b5829bd..e5913fba0143 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -232,5 +232,6 @@ int intel_dp_compute_config_late(struct intel_encoder 
*encoder,
                                 struct drm_connector_state *conn_state);
 int intel_dp_sdp_min_guardband(const struct intel_crtc_state *crtc_state,
                               bool assume_all_enabled);
+int intel_dp_hdisplay_limit(struct intel_display *display);
 
 #endif /* __INTEL_DP_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 8a42da2588eb..3b1825161d18 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -92,6 +92,13 @@
  * registers.
  */
 
+static const enum joiner_type joiner_candidates[] = {
+       FORCED_JOINER,
+       NO_JOINER,
+       BIG_JOINER,
+       ULTRA_JOINER,
+};
+
 /* From fake MST stream encoder to primary encoder */
 static struct intel_encoder *to_primary_encoder(struct intel_encoder *encoder)
 {
@@ -1420,7 +1427,6 @@ mst_connector_mode_valid_ctx(struct drm_connector 
*_connector,
        struct drm_dp_mst_topology_mgr *mgr = &intel_dp->mst.mgr;
        struct drm_dp_mst_port *port = connector->mst.port;
        const int min_bpp = 18;
-       int max_dotclk = display->cdclk.max_dotclk_freq;
        int max_rate, mode_rate, max_lanes, max_link_clock;
        unsigned long bw_overhead_flags =
                DRM_DP_BW_OVERHEAD_MST | DRM_DP_BW_OVERHEAD_SSC_REF_CLK;
@@ -1428,6 +1434,7 @@ mst_connector_mode_valid_ctx(struct drm_connector 
*_connector,
        bool dsc = false;
        int target_clock = mode->clock;
        int num_joined_pipes;
+       int i;
 
        if (drm_connector_is_unregistered(&connector->base)) {
                *status = MODE_ERROR;
@@ -1480,47 +1487,66 @@ mst_connector_mode_valid_ctx(struct drm_connector 
*_connector,
                return 0;
        }
 
-       num_joined_pipes = intel_dp_num_joined_pipes(intel_dp, connector,
-                                                    mode->hdisplay, 
target_clock);
-
-       if (intel_dp_has_dsc(connector) && 
drm_dp_sink_supports_fec(connector->dp.fec_capability)) {
-               /*
-                * TBD pass the connector BPC,
-                * for now U8_MAX so that max BPC on that platform would be 
picked
-                */
-               int pipe_bpp = intel_dp_dsc_compute_max_bpp(connector, U8_MAX);
-
-               if (!drm_dp_is_uhbr_rate(max_link_clock))
-                       bw_overhead_flags |= DRM_DP_BW_OVERHEAD_FEC;
-
-               dsc = intel_dp_mode_valid_with_dsc(connector,
-                                                  max_link_clock, max_lanes,
-                                                  target_clock, mode->hdisplay,
-                                                  num_joined_pipes,
-                                                  INTEL_OUTPUT_FORMAT_RGB, 
pipe_bpp,
-                                                  bw_overhead_flags);
-       }
+       for (i = 0; i < ARRAY_SIZE(joiner_candidates); i++) {
+               int max_dotclk = display->cdclk.max_dotclk_freq;
+               enum joiner_type joiner = joiner_candidates[i];
 
-       if (intel_dp_joiner_needs_dsc(display, num_joined_pipes) && !dsc) {
                *status = MODE_CLOCK_HIGH;
-               return 0;
-       }
 
-       if (mode_rate > max_rate && !dsc) {
-               *status = MODE_CLOCK_HIGH;
-               return 0;
+               if (joiner == FORCED_JOINER) {
+                       if (!connector->force_joined_pipes)
+                               continue;
+                       num_joined_pipes = connector->force_joined_pipes;
+               } else {
+                       num_joined_pipes = 1 << joiner;
+               }
+
+               if ((joiner >= NO_JOINER && !intel_dp_has_joiner(intel_dp)) ||
+                   (joiner == BIG_JOINER && !HAS_BIGJOINER(display)) ||
+                   (joiner == ULTRA_JOINER && !HAS_ULTRAJOINER(display)))
+                       break;
+
+               if (mode->hdisplay > num_joined_pipes * 
intel_dp_hdisplay_limit(display))
+                       continue;
+
+               if (intel_dp_has_dsc(connector) &&
+                   drm_dp_sink_supports_fec(connector->dp.fec_capability)) {
+                       /*
+                        * TBD pass the connector BPC,
+                        * for now U8_MAX so that max BPC on that platform 
would be picked
+                        */
+                       int pipe_bpp = intel_dp_dsc_compute_max_bpp(connector, 
U8_MAX);
+
+                       if (!drm_dp_is_uhbr_rate(max_link_clock))
+                               bw_overhead_flags |= DRM_DP_BW_OVERHEAD_FEC;
+
+                       dsc = intel_dp_mode_valid_with_dsc(connector,
+                                                          max_link_clock, 
max_lanes,
+                                                          target_clock, 
mode->hdisplay,
+                                                          num_joined_pipes,
+                                                          
INTEL_OUTPUT_FORMAT_RGB, pipe_bpp,
+                                                          bw_overhead_flags);
+               }
+
+               if (intel_dp_joiner_needs_dsc(display, num_joined_pipes) && 
!dsc)
+                       continue;
+
+               if (mode_rate > max_rate && !dsc)
+                       continue;
+
+               *status = intel_mode_valid_max_plane_size(display, mode, 
num_joined_pipes);
+
+               if (*status != MODE_OK)
+                       continue;
+
+               max_dotclk *= num_joined_pipes;
+
+               if (mode->clock <= max_dotclk) {
+                       *status = MODE_OK;
+                       break;
+               }
        }
 
-       *status = intel_mode_valid_max_plane_size(display, mode, 
num_joined_pipes);
-
-       if (*status != MODE_OK)
-               return 0;
-
-       max_dotclk *= num_joined_pipes;
-
-       if (mode->clock <= max_dotclk)
-               *status = MODE_OK;
-
        return 0;
 }
 
-- 
2.45.2

Reply via email to