]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/i915/dp_mst: Rework pipe joiner logic in mode_valid
authorAnkit Nautiyal <ankit.k.nautiyal@intel.com>
Mon, 2 Feb 2026 10:37:22 +0000 (16:07 +0530)
committerAnkit Nautiyal <ankit.k.nautiyal@intel.com>
Tue, 3 Feb 2026 08:17:06 +0000 (13:47 +0530)
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.

v2:
 - Remove fallback in case force-joiner configuration fails. (Imre)
 - Drop redundant MODE_OK assignment (Imre)
v3:
 - Align with the changes in intel_dp_mode_valid(). (Imre)
v4:
 - Set MODE_CLOCK_HIGH on DSC/rate failures aligning with SST case. (Imre)

Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
Link: https://patch.msgid.link/20260202103731.357416-9-ankit.k.nautiyal@intel.com
drivers/gpu/drm/i915/display/intel_dp.c
drivers/gpu/drm/i915/display/intel_dp.h
drivers/gpu/drm/i915/display/intel_dp_mst.c

index 1f690b8f31d20c9ebb7f276532a4bf288ce13803..cba893cf356abb80cc583a58a38960fd121ef9ed 100644 (file)
@@ -1371,7 +1371,6 @@ intel_dp_mode_valid_downstream(struct intel_connector *connector,
        return MODE_OK;
 }
 
-static
 int intel_dp_max_hdisplay_per_pipe(struct intel_display *display)
 {
        return DISPLAY_VER(display) >= 30 ? 6144 : 5120;
@@ -1434,7 +1433,6 @@ bool intel_dp_has_dsc(const struct intel_connector *connector)
        return true;
 }
 
-static
 bool intel_dp_can_join(struct intel_display *display,
                       int num_joined_pipes)
 {
index 25bfbfd291b0a40ccbbd98f229fa3b056c51ba9b..6d409c1998c985ed54965ad4b2aeea49d9bf6610 100644 (file)
@@ -225,5 +225,8 @@ 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_max_hdisplay_per_pipe(struct intel_display *display);
+bool intel_dp_can_join(struct intel_display *display,
+                      int num_joined_pipes);
 
 #endif /* __INTEL_DP_H__ */
index fc9367cc42ec67665580af2fb8f9e76716b41f84..5209cc1843ba8a55992989a9ae9d47f268e31cdb 100644 (file)
@@ -1420,7 +1420,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;
@@ -1480,46 +1479,63 @@ 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);
+       *status = MODE_CLOCK_HIGH;
+       for (num_joined_pipes = 1; num_joined_pipes <= I915_MAX_PIPES; num_joined_pipes++) {
+               int max_dotclk = display->cdclk.max_dotclk_freq;
 
-       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 (connector->force_joined_pipes &&
+                   num_joined_pipes != connector->force_joined_pipes)
+                       continue;
 
-               if (!drm_dp_is_uhbr_rate(max_link_clock))
-                       bw_overhead_flags |= DRM_DP_BW_OVERHEAD_FEC;
+               if (!intel_dp_can_join(display, num_joined_pipes))
+                       continue;
 
-               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 (mode->hdisplay > num_joined_pipes * intel_dp_max_hdisplay_per_pipe(display))
+                       continue;
 
-       if (intel_dp_joiner_needs_dsc(display, num_joined_pipes) && !dsc) {
-               *status = MODE_CLOCK_HIGH;
-               return 0;
-       }
+               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 (mode_rate > max_rate && !dsc) {
-               *status = MODE_CLOCK_HIGH;
-               return 0;
-       }
+                       if (!drm_dp_is_uhbr_rate(max_link_clock))
+                               bw_overhead_flags |= DRM_DP_BW_OVERHEAD_FEC;
 
-       *status = intel_mode_valid_max_plane_size(display, mode, num_joined_pipes);
+                       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 (*status != MODE_OK)
-               return 0;
+               if (intel_dp_joiner_needs_dsc(display, num_joined_pipes) && !dsc) {
+                       *status = MODE_CLOCK_HIGH;
+                       continue;
+               }
 
-       max_dotclk *= num_joined_pipes;
+               if (mode_rate > max_rate && !dsc) {
+                       *status = MODE_CLOCK_HIGH;
+                       continue;
+               }
 
-       if (mode->clock > max_dotclk)
-               *status = MODE_CLOCK_HIGH;
+               *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_CLOCK_HIGH;
+                       continue;
+               }
+
+               break;
+       }
 
        return 0;
 }