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;
+}
+
 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);
+}
+
 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);
+
        /* 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

Reply via email to