Currently in intel_dp_mode_valid(), we compute the number of joined pipes
required before deciding whether DSC is needed. This ordering prevents us
from accounting for DSC-related overhead when determining pipe
requirements.

Refactor the logic to 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 a follow-up
changes.

Additionally, if a forced joiner configuration is present, we first check
whether it satisfies the bandwidth and timing constraints. If it does not,
we fall back to evaluating configurations with 1, 2, or 4 pipes joined
and prune or keep the mode accordingly.

Signed-off-by: Ankit Nautiyal <ankit.k.nauti...@intel.com>
---
 drivers/gpu/drm/i915/display/intel_dp.c | 79 +++++++++++++++++--------
 1 file changed, 55 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 0884826de1fd..0acd86c7d1c2 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1461,12 +1461,12 @@ intel_dp_mode_valid(struct drm_connector *_connector,
 {
        struct intel_display *display = to_intel_display(_connector->dev);
        struct intel_connector *connector = to_intel_connector(_connector);
+       int hdisplay_limit = DISPLAY_VER(display) >= 30 ? 6144 : 5120;
        struct intel_dp *intel_dp = intel_attached_dp(connector);
        enum intel_output_format sink_format, output_format;
        const struct drm_display_mode *fixed_mode;
        int target_clock = mode->clock;
        int max_rate, mode_rate, max_lanes, max_link_clock;
-       int max_dotclk = display->cdclk.max_dotclk_freq;
        u16 dsc_max_compressed_bpp = 0;
        u8 dsc_slice_count = 0;
        enum drm_mode_status status;
@@ -1506,31 +1506,62 @@ intel_dp_mode_valid(struct drm_connector *_connector,
        mode_rate = intel_dp_link_required(target_clock,
                                           
intel_dp_mode_min_output_bpp(connector, mode));
 
-       num_joined_pipes = intel_dp_num_joined_pipes(intel_dp, connector,
-                                                    mode->hdisplay, 
target_clock);
-       max_dotclk *= num_joined_pipes;
-
-       status = intel_pfit_mode_valid(display, mode, output_format, 
num_joined_pipes);
-       if (status != MODE_OK)
-               return status;
-
-       if (target_clock > max_dotclk)
-               return MODE_CLOCK_HIGH;
-
-       if (intel_dp_has_dsc(connector)) {
-               get_dsc_slice_and_bpp(connector, mode, target_clock,
-                                     num_joined_pipes,
-                                     output_format,
-                                     max_link_clock,
-                                     max_lanes,
-                                     &dsc_max_compressed_bpp,
-                                     &dsc_slice_count);
-
-               dsc = dsc_max_compressed_bpp && dsc_slice_count;
+       for (int joiner = -1; joiner <= 2; joiner++) {
+               int max_dotclk = display->cdclk.max_dotclk_freq;
+
+               if (joiner == -1 && connector->force_joined_pipes)
+                       num_joined_pipes = connector->force_joined_pipes;
+               else if (joiner == -1)
+                       continue;
+               else
+                       num_joined_pipes = 1 << joiner;
+
+               if (joiner >= 0 && mode->hdisplay > num_joined_pipes * 
hdisplay_limit) {
+                       status = MODE_CLOCK_HIGH;
+                       continue;
+               }
+
+               if ((num_joined_pipes == 4 && !HAS_ULTRAJOINER(display)) ||
+                   (num_joined_pipes == 2 && !HAS_BIGJOINER(display) &&
+                    !HAS_UNCOMPRESSED_JOINER(display))) {
+                       status = MODE_CLOCK_HIGH;
+                       continue;
+               }
+
+               status = intel_pfit_mode_valid(display, mode, output_format, 
num_joined_pipes);
+               if (status != MODE_OK)
+                       continue;
+
+               if (intel_dp_has_dsc(connector)) {
+                       get_dsc_slice_and_bpp(connector, mode, target_clock,
+                                             num_joined_pipes,
+                                             output_format,
+                                             max_link_clock,
+                                             max_lanes,
+                                             &dsc_max_compressed_bpp,
+                                             &dsc_slice_count);
+
+                       dsc = dsc_max_compressed_bpp && dsc_slice_count;
+               }
+
+               if (intel_dp_joiner_needs_dsc(display, num_joined_pipes) && 
!dsc) {
+                       status = MODE_CLOCK_HIGH;
+                       continue;
+               }
+
+               max_dotclk *= num_joined_pipes;
+
+               if (target_clock > max_dotclk) {
+                       status = MODE_CLOCK_HIGH;
+                       continue;
+               }
+
+               status = MODE_OK;
+               break;
        }
 
-       if (intel_dp_joiner_needs_dsc(display, num_joined_pipes) && !dsc)
-               return MODE_CLOCK_HIGH;
+       if (status != MODE_OK || num_joined_pipes > 4)
+               return status;
 
        if (mode_rate > max_rate && !dsc)
                return MODE_CLOCK_HIGH;
-- 
2.45.2

Reply via email to