From: Ankit Nautiyal <[email protected]>

Handle the bypass logic for the M/N ratio limit for DP.
Calculate the M/N ratio, check if it can bypass the limit, and set the
appropriate flags for the workaround.

v2:
-Restrict the workaround to 128b/132b links.
-Clear bypass_m_n_ratio_limit on entry, so a rejected link rate cannot
leave it set for the rate that gets used. (Sashiko)
v3:
-Rebase on the reworked M/N ratio check, which no longer checks m_n and
link_n. m_n is no longer const, as the flag is set through it. (Mitul)
-Pass the cpu transcoder to intel_display_can_bypass_m_n_limit() instead
of the pipe. (Mitul)

Bspec: 49266
Signed-off-by: Ankit Nautiyal <[email protected]>
Co-developed-by: Suraj Kandpal <[email protected]>
Signed-off-by: Suraj Kandpal <[email protected]>
---
 drivers/gpu/drm/i915/display/intel_dp.c | 28 ++++++++++++++++++++-----
 drivers/gpu/drm/i915/display/intel_dp.h |  2 +-
 2 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 8ef6b4c4fc8e..8e6ba5b9fde6 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1300,18 +1300,32 @@ intel_dp_can_support_m_n(struct intel_display *display,
 }
 
 void intel_dp_check_m_n_ratio(const struct intel_crtc_state *crtc_state,
-                             const struct intel_link_m_n *m_n)
+                             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)
+       if (m_n_ratio <= max_m_n_ratio)
+               return;
+
+       if (intel_dp_is_uhbr(crtc_state) &&
+           intel_display_can_bypass_m_n_limit(display, m_n_ratio,
+                                              crtc_state->cpu_transcoder)) {
+               m_n->bypass_m_n_ratio_limit = true;
                drm_dbg_kms(display->drm,
-                           "Link M/N ratio (%d) exceeds max allowed (%d)\n",
-                           m_n_ratio, max_m_n_ratio);
+                           "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)
@@ -3393,6 +3407,9 @@ static bool can_enable_drrs(struct intel_connector 
*connector,
        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,
@@ -3427,7 +3444,8 @@ intel_dp_drrs_compute_config(struct intel_connector 
*connector,
         * 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)) {
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h 
b/drivers/gpu/drm/i915/display/intel_dp.h
index 1e3da678c9b6..c834d90a1f81 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -246,6 +246,6 @@ 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(const struct intel_crtc_state *crtc_state,
-                             const struct intel_link_m_n *m_n);
+                             struct intel_link_m_n *m_n);
 
 #endif /* __INTEL_DP_H__ */
-- 
2.34.1

Reply via email to