linux-next: manual merge of the drm-intel tree with the drm-intel-fixes tree
From: Mark Brown
Date: Mon Nov 02 2026 - 10:37:38 EST
Hi all,
Today's linux-next merge of the drm-intel tree got a conflict in:
drivers/gpu/drm/i915/display/intel_dp.c
between commit:
b42b656db1384 ("drm/i915/display: Disable pipe joiner on WCL")
from the drm-intel-fixes tree and commits:
917676a55a690 ("drm/i915/display: Disable pipe joiner on WCL")
355ce9db5fcff ("drm/i915/display: Allow forcing the joiner on eDP")
a1cce75d66ad1 ("drm/i915/dp: Bump the max Link M/N ratio to 22 for DISPLAY_VER >= 35")
cfbcf0a546bdb ("drm/i915/dp: Extend intel_dp_can_support_m_n() for BMG M/N bypass")
244cae26882a9 ("drm/i915/display: Implement Wa_14021768792 for BMG DP for link_m/n ratio > 10")
3f96e57cda40f ("drm/i915/dp: Add M/N ratio check for DP link config")
be3b2c9a29aef ("drm/i915/dp_mst: Limit M/N ratio for MST")
6af30a4f3668d ("drm/i915/display_wa: Add support for Wa_14014191401")
7a75b5717409c ("drm/i915/dp: Limit M/N ratio for DP")
from the drm-intel tree.
I fixed it up (see below) and can carry the fix as necessary. This
is now fixed as far as linux-next is concerned, but any non trivial
conflicts should be mentioned to your upstream maintainer when your tree
is submitted for merging. You may also want to consider cooperating
with the maintainer of the conflicting tree to minimise any particularly
complex conflicts.
diff --combined drivers/gpu/drm/i915/display/intel_dp.c
index 47741957935ae,ef164a7976187..0000000000000
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@@ -63,12 -63,14 +63,14 @@@
#include "intel_de.h"
#include "intel_dip.h"
#include "intel_dip_regs.h"
+ #include "intel_display.h"
#include "intel_display_driver.h"
#include "intel_display_jiffies.h"
#include "intel_display_utils.h"
#include "intel_display_regs.h"
#include "intel_display_rpm.h"
#include "intel_display_types.h"
+ #include "intel_display_wa.h"
#include "intel_dp.h"
#include "intel_dp_aux.h"
#include "intel_dp_hdcp.h"
@@@ -473,9 -475,15 +475,15 @@@ bool intel_dp_has_joiner(struct intel_d
if (intel_dp->mso_link_count)
return false;
- if (intel_dp_is_edp(intel_dp) &&
- !connector->panel.vbt.edp.pipe_joiner_enable)
- return false;
+ if (intel_dp_is_edp(intel_dp)) {
+ bool pipe_joiner_enable = connector->panel.vbt.edp.pipe_joiner_enable;
+
+ if (connector->force_joined_pipes > 1)
+ pipe_joiner_enable = true;
+
+ if (!pipe_joiner_enable)
+ return false;
+ }
return ((DISPLAY_VER(display) >= 12 && DISPLAY_VERx100(display) != 3002) ||
(DISPLAY_VER(display) == 11 &&
@@@ -1267,6 -1275,93 +1275,93 @@@ bool intel_dp_has_dsc(const struct inte
return true;
}
+ static int
+ intel_dp_get_max_m_n_ratio(struct intel_display *display)
+ {
+ if (DISPLAY_VER(display) >= 35)
+ return 22;
+
+ if (intel_display_wa(display, INTEL_DISPLAY_WA_14014191401))
+ return 4;
+
+ return 10;
+ }
+
+ static int intel_dp_link_m_n_ratio(u32 link_m, u32 link_n)
+ {
+ if (!link_n)
+ return 0;
+
+ return DIV_ROUND_UP(link_m, link_n);
+ }
+
+ static bool
+ intel_dp_can_bypass_m_n_limit(struct intel_display *display, int link_rate,
+ int m_n_ratio, enum transcoder cpu_transcoder)
+ {
+ return drm_dp_is_uhbr_rate(link_rate) &&
+ intel_display_can_bypass_m_n_limit(display, m_n_ratio, cpu_transcoder);
+ }
+
+ bool intel_dp_can_support_m_n(struct intel_display *display,
+ const struct intel_crtc_state *crtc_state,
+ int pixel_clock, int link_rate)
+ {
+ int max_m_n_ratio = intel_dp_get_max_m_n_ratio(display);
+ enum transcoder cpu_transcoder = TRANSCODER_A;
+ u32 link_m, link_n;
+ int m_n_ratio;
+
+ intel_display_compute_link_m_n(&link_m, &link_n, pixel_clock,
+ intel_dp_link_symbol_clock(link_rate));
+
+ m_n_ratio = intel_dp_link_m_n_ratio(link_m, link_n);
+
+ if (m_n_ratio <= max_m_n_ratio)
+ return true;
+
+ if (crtc_state)
+ cpu_transcoder = crtc_state->cpu_transcoder;
+
+ return intel_dp_can_bypass_m_n_limit(display, link_rate, m_n_ratio, cpu_transcoder);
+ }
+
+ void intel_dp_check_m_n_ratio(const struct intel_crtc_state *crtc_state,
+ struct intel_link_m_n *m_n)
+ {
+ struct intel_display *display = to_intel_display(crtc_state);
+ int max_m_n_ratio = intel_dp_get_max_m_n_ratio(display);
+ int m_n_ratio;
+
+ m_n->bypass_m_n_ratio_limit = false;
+
+ m_n_ratio = intel_dp_link_m_n_ratio(m_n->link_m, m_n->link_n);
+
+ if (m_n_ratio <= max_m_n_ratio)
+ return;
+
+ if (intel_dp_can_bypass_m_n_limit(display, crtc_state->port_clock, m_n_ratio,
+ crtc_state->cpu_transcoder)) {
+ m_n->bypass_m_n_ratio_limit = true;
+ drm_dbg_kms(display->drm,
+ "Bypassing Link_m/Link_n ratio limit (ratio %d)\n",
+ m_n_ratio);
+ return;
+ }
+
+ drm_dbg_kms(display->drm,
+ "Link M/N ratio (%d) exceeds max allowed (%d)\n",
+ m_n_ratio, max_m_n_ratio);
+ }
+
+ static int intel_dp_mso_pixel_clock(struct intel_dp *intel_dp, int pixel_clock)
+ {
+ if (!intel_dp->mso_link_count)
+ return pixel_clock;
+
+ return pixel_clock / intel_dp->mso_link_count;
+ }
+
static
bool intel_dp_can_join(struct intel_dp *intel_dp,
int num_joined_pipes)
@@@ -1302,6 -1397,33 +1397,33 @@@ bool intel_dp_dotclk_valid(struct intel
return target_clock <= effective_dotclk_limit;
}
+ static bool intel_dp_mode_valid_m_n(struct intel_dp *intel_dp, int pixel_clock)
+ {
+ struct intel_display *display = to_intel_display(intel_dp);
+ int m_n_pixel_clock = intel_dp_mso_pixel_clock(intel_dp, pixel_clock);
+ struct intel_dp_link_caps_order order = {
+ .key = INTEL_DP_LINK_CAPS_ORDER_KEY_RATE_LANE,
+ .dir = INTEL_DP_LINK_CAPS_ORDER_DIR_DESC,
+ };
+ struct intel_dp_link_config link_config;
+ struct intel_dp_link_caps_iter iter;
+ bool found = false;
+
+ intel_dp_link_caps_iter_start(&iter, intel_dp->link.caps, order,
+ INTEL_DP_LINK_CAPS_FILTER_ALL);
+ for_each_dp_link_config(&iter, &link_config) {
+ if (intel_dp_can_support_m_n(display, NULL, m_n_pixel_clock,
+ link_config.rate)) {
+ found = true;
+
+ break;
+ }
+ }
+ intel_dp_link_caps_iter_end(&iter);
+
+ return found;
+ }
+
static enum drm_mode_status
intel_dp_mode_valid_format(struct intel_connector *connector,
const struct drm_display_mode *mode,
@@@ -1456,6 -1578,9 +1578,9 @@@ intel_dp_mode_valid(struct drm_connecto
return status;
}
+ if (!intel_dp_mode_valid_m_n(intel_dp, target_clock))
+ return MODE_CLOCK_HIGH;
+
/*
* TODO: Even when using a 4:2:0 sink_format intel_dp_output_format()
* will always choose a 4:4:4 output_format if the DFP can do the
@@@ -2656,6 -2781,49 +2781,49 @@@ intel_dp_dsc_compute_pipe_bpp_limits(st
return true;
}
+ static bool
+ intel_dp_compute_m_n_ratio_limits(struct intel_dp *intel_dp,
+ struct drm_connector_state *conn_state,
+ const struct intel_crtc_state *crtc_state,
+ struct link_config_limits *limits)
+ {
+ struct intel_display *display = to_intel_display(intel_dp);
+ struct intel_connector *connector = to_intel_connector(conn_state->connector);
+ struct intel_dp_link_caps *link_caps = intel_dp->link.caps;
+ struct intel_dp_link_caps_order order =
+ intel_dp_link_caps_connector_compute_order(connector);
+ struct intel_dp_link_caps_filter new_filter = INTEL_DP_LINK_CAPS_FILTER_NONE;
+ int pixel_clock = intel_dp_mso_pixel_clock(intel_dp,
+ intel_dp_mode_clock(crtc_state, conn_state));
+ struct intel_dp_link_config link_config;
+ struct intel_dp_link_caps_iter iter;
+ bool found = false;
+
+ intel_dp_link_caps_iter_start(&iter, link_caps, order, limits->link_config_filter);
+ for_each_dp_link_config(&iter, &link_config) {
+ if (!intel_dp_can_support_m_n(display, crtc_state, pixel_clock,
+ link_config.rate))
+ continue;
+
+ intel_dp_link_caps_filter_add(link_caps, &new_filter, &link_config);
+ found = true;
+ }
+ intel_dp_link_caps_iter_end(&iter);
+
+ if (!found) {
+ drm_dbg_kms(display->drm,
+ "[CONNECTOR:%d:%s] No link config with a Link M/N ratio <= %d\n",
+ connector->base.base.id, connector->base.name,
+ intel_dp_get_max_m_n_ratio(display));
+
+ return false;
+ }
+
+ limits->link_config_filter = new_filter;
+
+ return true;
+ }
+
bool
intel_dp_compute_config_limits(struct intel_dp *intel_dp,
struct drm_connector_state *conn_state,
@@@ -2772,6 -2940,9 +2940,9 @@@
limits->link_config_filter = new_filter;
}
+ if (!intel_dp_compute_m_n_ratio_limits(intel_dp, conn_state, crtc_state, limits))
+ return false;
+
if (!intel_dp_test_compute_config(connector, crtc_state, limits))
return false;
@@@ -3263,6 -3434,9 +3434,9 @@@ static bool can_enable_drrs(struct inte
if (pipe_config->vrr.enable)
return false;
+ if (pipe_config->dp_m_n.bypass_m_n_ratio_limit)
+ return false;
+
/*
* DRRS and PSR can't be enable together, so giving preference to PSR
* as it allows more power-savings by complete shutting down display,
@@@ -3297,7 -3471,8 +3471,8 @@@ intel_dp_drrs_compute_config(struct int
* FIXME all joined pipes share the same transcoder.
* Need to account for that when updating M/N live.
*/
- if (has_seamless_m_n(connector) && !pipe_config->joiner_pipes)
+ if (has_seamless_m_n(connector) && !pipe_config->joiner_pipes &&
+ !pipe_config->dp_m_n.bypass_m_n_ratio_limit)
pipe_config->update_m_n = true;
if (!can_enable_drrs(connector, pipe_config, downclock_mode)) {
@@@ -3640,6 -3815,8 +3815,8 @@@ intel_dp_compute_config(struct intel_at
pipe_config->port_clock,
intel_dp_bw_fec_overhead(pipe_config->fec_enable),
&pipe_config->dp_m_n);
+
+ intel_dp_check_m_n_ratio(pipe_config, &pipe_config->dp_m_n);
}
ret = intel_dp_compute_min_hblank(pipe_config, conn_state);
Attachment:
signature.asc
Description: PGP signature