[PATCH 4/6] drm/i915/dp: Rework pipe joiner logic in mode_valid

Ankit Nautiyal ankit.k.nautiyal at intel.com
Tue Aug 12 04:14:25 UTC 2025


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.nautiyal at 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



More information about the Intel-xe mailing list