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)

Bspec: 49266
Signed-off-by: Ankit Nautiyal <[email protected]>
Signed-off-by: Suraj Kandpal <[email protected]>
---
 drivers/gpu/drm/i915/display/intel_dp.c | 31 +++++++++++++++++++++----
 1 file changed, 26 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index fbfc00101886..9c327008b733 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -3373,6 +3373,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,
@@ -3397,18 +3400,35 @@ 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);
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
        int max_m_n_ratio = intel_dp_get_max_m_n_ratio(display);
        int m_n_ratio;
 
-       if (!m_n || !m_n->link_n)
+       if (!m_n)
+               return;
+
+       m_n->bypass_m_n_ratio_limit = false;
+
+       if (!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)
+       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->pipe)) 
{
+               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 void
@@ -3425,7 +3445,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)) {
-- 
2.34.1

Reply via email to