> -----Original Message-----
> From: Golani, Mitulkumar Ajitkumar
> <[email protected]>
> Sent: 16 October 2026 00:27
> To: Kandpal, Suraj <[email protected]>; [email protected];
> [email protected]
> Cc: Nautiyal, Ankit K <[email protected]>; Murthy, Arun R
> <[email protected]>; Kandpal, Suraj <[email protected]>
> Subject: RE: [PATCH v4 04/10] drm/i915/dp: Add M/N ratio check for DP link
> config
>
>
>
> > -----Original Message-----
> > From: Intel-gfx <[email protected]> On Behalf Of
> > Suraj Kandpal
> > Sent: 17 September 2026 10:37
> > To: [email protected]; [email protected]
> > Cc: Nautiyal, Ankit K <[email protected]>; Murthy, Arun R
> > <[email protected]>; Kandpal, Suraj <[email protected]>
> > Subject: [PATCH v4 04/10] drm/i915/dp: Add M/N ratio check for DP link
> > config
> >
> > From: Ankit Nautiyal <[email protected]>
> >
> > Introduce intel_dp_check_m_n_ratio() to validate the computed link M/N
> > ratio against the maximum allowed value, and log it if the ratio
> > exceeds the limit.
> >
> > The link config limits computed in the previous patches only restrict
> > the configurations that may be selected; this catches anything that
> > still slips through.
> >
> > Log it rather than warn about it: the link config filter already
> > excludes the configurations violating the limit, so the only way to
> > get here is with link parameters forced through debugfs, which are
> > applied after that filter. A user triggerable drm_WARN() with its
> > backtrace would be out of proportion for that.
> >
> > This check works off the M/N values as actually computed, which
> > exposes a mismatch with the prediction done while computing the
> > limits: the pixel clock there is the one before
> > intel_dp_compute_config() divides adjusted_mode-
> > >crtc_clock by the MSO link count. Divide in the prediction too, so
> > >both
> > agree. The joiner needs no such handling, as
> > intel_joiner_adjust_timings() only rewrites the pipe mode and leaves
> > the adjusted mode the link M/N is derived from untouched.
> >
> > For MST the check goes after the bpp loop rather than inside it. The
> > link M/N is computed from the pixel clock and the link symbol clock,
> > so it does not depend on the bpp being tried and the result is the same on
> every iteration.
> >
> > v2:
> > -Use the platform specific ratio limit. (Wa_14014191401) -Use the MSO
> > adjusted pixel clock when predicting the ratio, matching what the link
> > M/N is actually computed from. (Imre) -Drop the check from
> > ilk_fdi_compute_config(): it was passing dp_m_n rather than the
> > fdi_m_n it had just computed, and an FDI link cannot get anywhere near
> > the ratio limit anyway.
> > v3:
> > -Check the ratio once after the MST bpp loop instead of on every
> > iteration, the result does not depend on the bpp. (Sashiko) -Log
> > instead of warning, since the link config filter already excludes
> > these configurations and only forced link parameters can reach it.
> > (Sashiko)
> >
> > Signed-off-by: Ankit Nautiyal <[email protected]>
> > Signed-off-by: Suraj Kandpal <[email protected]>
> > ---
> > drivers/gpu/drm/i915/display/intel_dp.c | 37 +++++++++++++++++++--
> > drivers/gpu/drm/i915/display/intel_dp.h | 4 +++
> > drivers/gpu/drm/i915/display/intel_dp_mst.c | 2 ++
> > 3 files changed, 41 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c
> > b/drivers/gpu/drm/i915/display/intel_dp.c
> > index f6a2152c4432..fbfc00101886 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > @@ -1294,6 +1294,14 @@ intel_dp_can_support_m_n(struct intel_display
> > *display,
> > return 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; }
> > +
>
> These hunks fix the prediction added in "drm/i915/dp: Limit M/N ratio for DP
> SST". On its own that patch over-restricts MSO eDP by mso_link_count .
> Please squash them, together with the MSO/joiner explanation, into that
> patch so it is correct on its own, and keep this patch to the debug check.
Sure
>
> > static
> > bool intel_dp_can_join(struct intel_dp *intel_dp,
> > int num_joined_pipes)
> > @@ -1332,6 +1340,7 @@ bool intel_dp_dotclk_valid(struct intel_display
> > *display, 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,
> > @@ -1343,7 +1352,8 @@ bool intel_dp_mode_valid_m_n(struct intel_dp
> > *intel_dp, int pixel_clock)
> > 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, pixel_clock,
> > link_config.rate)) {
> > + if (intel_dp_can_support_m_n(display, m_n_pixel_clock,
> > + link_config.rate)) {
> > found = true;
> >
> > break;
> > @@ -2723,7 +2733,8 @@ intel_dp_compute_m_n_ratio_limits(struct
> > intel_dp *intel_dp,
> > 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_mode_clock(crtc_state, conn_state);
> > + 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;
> > @@ -3382,6 +3393,24 @@ static bool can_enable_drrs(struct
> > intel_connector *connector,
> > intel_panel_drrs_type(connector) == DRRS_TYPE_SEAMLESS;
> }
> >
> > +void intel_dp_check_m_n_ratio(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;
> > +
> > + if (!m_n || !m_n->link_n)
> > + return;
> > +
> > + m_n_ratio = DIV_ROUND_UP(m_n->link_m, m_n->link_n);
> > +
> > + if (m_n_ratio > max_m_n_ratio)
> > + drm_dbg_kms(display->drm,
> > + "Link M/N ratio (%d) exceeds max allowed (%d)\n",
> > + m_n_ratio, max_m_n_ratio);
> > +}
>
> Could we reuse a small helper here, since the DIV_ROUND_UP(link_m,
> link_n) <= max check appears to duplicate intel_dp_can_support_m_n?
I can do that.
> Also,
> are the !m_n and !m_n->link_n checks necessary, given that callers pass
> struct members and link_n is fixed at 0x80000?
Sure will drop the check
Could the parameters be
> const as well?
Finally, would it make sense to place this helper next to
> intel_dp_can_support_m_n ?
Can do
>
> > +
> > static void
> > intel_dp_drrs_compute_config(struct intel_connector *connector,
> > struct intel_crtc_state *pipe_config, @@ -3420,6
> > +3449,8 @@ intel_dp_drrs_compute_config(struct intel_connector
> > *connector,
> > intel_dp_bw_fec_overhead(pipe_config-
> > >fec_enable),
> > &pipe_config->dp_m2_n2);
> >
> > + intel_dp_check_m_n_ratio(pipe_config, &pipe_config->dp_m2_n2);
>
> Could we drop this check since dp_m2_n2 is computed using the same
> port_clock and its ratio should already be covered by the dp_m_n check? Or
> is this intended as a defensive check?
Sure will drop it.
>
> > +
> > /* FIXME: abstract this better */
> > if (pipe_config->splitter.enable)
> > pipe_config->dp_m2_n2.data_m *= pipe_config-
> > >splitter.link_count; @@ -3739,6 +3770,8 @@
> > intel_dp_compute_config(struct intel_atomic_state *state,
> > 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); diff --
> > git a/drivers/gpu/drm/i915/display/intel_dp.h
> > b/drivers/gpu/drm/i915/display/intel_dp.h
> > index aa58833a405b..4c975358ab96 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp.h
> > +++ b/drivers/gpu/drm/i915/display/intel_dp.h
> > @@ -26,6 +26,7 @@ struct intel_display; struct intel_dp; struct
> > intel_dp_link_config; struct intel_encoder;
> > +struct intel_link_m_n;
> >
> > struct link_config_limits {
> > struct intel_dp_link_caps_filter link_config_filter; @@ -244,4 +245,7
> > @@ bool intel_dp_mode_valid_m_n(struct intel_dp *intel_dp, int
> > pixel_clock); int intel_dp_link_init(struct intel_dp *intel_dp); void
> > intel_dp_link_cleanup(struct intel_dp *intel_dp);
> >
> > +void intel_dp_check_m_n_ratio(struct intel_crtc_state *crtc_state,
> > + struct intel_link_m_n *m_n);
> > +
> > #endif /* __INTEL_DP_H__ */
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > index 823fe99ca0a1..6d2e234a9e9b 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > @@ -429,6 +429,8 @@ int intel_dp_mtp_tu_compute_config(struct
> intel_dp
> > *intel_dp,
> > return slots;
> > }
> >
> > + intel_dp_check_m_n_ratio(crtc_state, &crtc_state->dp_m_n);
> > +
> > if (!dsc)
> > crtc_state->pipe_bpp = fxp_q4_to_int(bpp_x16);
> > else
> > --
> > 2.34.1