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
