[PATCH 8/8] drm/i915/dp: Extend intel_dp_can_support_m_n() for BMG M/N bypass

Ankit Nautiyal ankit.k.nautiyal at intel.com
Thu Jul 17 03:31:19 UTC 2025


On BMG platforms, the standard M/N ratio limit of 10 can be bypassed
under specific conditions, as permitted by hardware capabilities.

Modify the helper intel_dp_can_support_m_n() to account for this by
checking whether the platform supports bypassing the limit.

During mode_valid phase, the check assumes that PIPE_A will be used to
allow the mode, where M/N ratio is with int the limits for the workaround.

Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal at intel.com>
---
 drivers/gpu/drm/i915/display/intel_dp.c     | 31 +++++++++++++++++----
 drivers/gpu/drm/i915/display/intel_dp.h     |  4 ++-
 drivers/gpu/drm/i915/display/intel_dp_mst.c |  6 ++--
 3 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 561f01897d88..51174ff9ea20 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1414,10 +1414,12 @@ intel_dp_get_max_m_n_ratio(void)
 }
 
 bool
-intel_dp_can_support_m_n(int pixel_clock,
-			 int link_rate)
+intel_dp_can_support_m_n(struct intel_display *display,
+			 struct intel_crtc_state *crtc_state,
+			 int pixel_clock, int link_rate)
 {
 	int max_m_n_ratio = intel_dp_get_max_m_n_ratio();
+	enum pipe pipe;
 	u32 link_m, link_n;
 	int m_n_ratio;
 
@@ -1426,7 +1428,20 @@ intel_dp_can_support_m_n(int pixel_clock,
 
 	m_n_ratio = DIV_ROUND_UP(link_m, link_n);
 
-	return m_n_ratio <= max_m_n_ratio;
+	if (m_n_ratio <= max_m_n_ratio)
+		return true;
+
+	if (crtc_state) {
+		struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+		pipe = crtc->pipe;
+	} else {
+		pipe = PIPE_A;
+	}
+
+	if (intel_display_can_bypass_m_n_limit(display, m_n_ratio, pipe))
+		return true;
+
+	return false;
 }
 
 static enum drm_mode_status
@@ -1540,7 +1555,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,
 	if (status != MODE_OK)
 		return status;
 
-	if (!intel_dp_can_support_m_n(target_clock, max_rate))
+	if (!intel_dp_can_support_m_n(display, NULL, target_clock, max_rate))
 		return MODE_CLOCK_HIGH;
 
 	return intel_mode_valid_max_plane_size(display, mode, num_joined_pipes);
@@ -1792,6 +1807,7 @@ intel_dp_compute_link_config_wide(struct intel_dp *intel_dp,
 				  const struct drm_connector_state *conn_state,
 				  const struct link_config_limits *limits)
 {
+	struct intel_display *display = to_intel_display(pipe_config);
 	int bpp, i, lane_count, clock = intel_dp_mode_clock(pipe_config, conn_state);
 	int mode_rate, link_rate, link_avail;
 
@@ -1808,7 +1824,7 @@ intel_dp_compute_link_config_wide(struct intel_dp *intel_dp,
 			    link_rate > limits->max_rate)
 				continue;
 
-			if (!intel_dp_can_support_m_n(clock, link_rate))
+			if (!intel_dp_can_support_m_n(display, pipe_config, clock, link_rate))
 				continue;
 
 			for (lane_count = limits->min_lane_count;
@@ -1995,6 +2011,7 @@ static int dsc_compute_link_config(struct intel_dp *intel_dp,
 				   int dsc_bpp_x16,
 				   int timeslots)
 {
+	struct intel_display *display = to_intel_display(pipe_config);
 	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
 	int link_rate, lane_count;
 	int i;
@@ -2004,7 +2021,9 @@ static int dsc_compute_link_config(struct intel_dp *intel_dp,
 		if (link_rate < limits->min_rate || link_rate > limits->max_rate)
 			continue;
 
-		if (!intel_dp_can_support_m_n(adjusted_mode->clock,
+
+		if (!intel_dp_can_support_m_n(display, pipe_config,
+					      adjusted_mode->clock,
 					      link_rate))
 			continue;
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index a197eb0a7fc6..7b7b950aeb61 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -215,7 +215,9 @@ int intel_dp_compute_min_hblank(struct intel_crtc_state *crtc_state,
 
 int intel_dp_dsc_bpp_step_x16(const struct intel_connector *connector);
 void intel_dp_dpcd_set_probe(struct intel_dp *intel_dp, bool force_on_external);
-bool intel_dp_can_support_m_n(int pixel_clock, int link_rate);
+bool intel_dp_can_support_m_n(struct intel_display *display,
+			      struct intel_crtc_state *crtc_state,
+			      int pixel_clock, int link_rate);
 void intel_dp_check_m_n_ratio(struct intel_crtc_state *crtc_state,
 			      struct intel_link_m_n *m_n);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 45b72a2c8588..a06901ad7a9f 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -447,12 +447,14 @@ static int mst_stream_compute_link_config(struct intel_dp *intel_dp,
 					  struct drm_connector_state *conn_state,
 					  const struct link_config_limits *limits)
 {
+	struct intel_display *display = to_intel_display(crtc_state);
 	crtc_state->lane_count = limits->max_lane_count;
 	crtc_state->port_clock = limits->max_rate;
 	const struct drm_display_mode *adjusted_mode =
 		&crtc_state->hw.adjusted_mode;
 
-	if (!intel_dp_can_support_m_n(adjusted_mode->clock, crtc_state->port_clock))
+	if (!intel_dp_can_support_m_n(display, crtc_state, adjusted_mode->clock,
+				      crtc_state->port_clock))
 		return -EINVAL;
 
 	/*
@@ -1560,7 +1562,7 @@ mst_connector_mode_valid_ctx(struct drm_connector *_connector,
 		return 0;
 	}
 
-	if (!intel_dp_can_support_m_n(mode->clock, max_rate)) {
+	if (!intel_dp_can_support_m_n(display, NULL, mode->clock, max_rate)) {
 		*status = MODE_CLOCK_HIGH;
 		return 0;
 	}
-- 
2.45.2



More information about the Intel-gfx-trybot mailing list