On BMG platforms, the standard M/N ratio limit of 10 can be bypassed
under specific conditions, as permitted by hardware capabilities.

Modify the helper intel_dp_can_support_m_n() to account for this by
checking whether the platform supports bypassing the limit.

During mode_valid phase, the check assumes that PIPE_A will be used to
allow the mode, where M/N ratio is with int the limits for the workaround.

Signed-off-by: Ankit Nautiyal <ankit.k.nauti...@intel.com>
---
 drivers/gpu/drm/i915/display/intel_dp.c     | 31 +++++++++++++++++----
 drivers/gpu/drm/i915/display/intel_dp.h     |  4 ++-
 drivers/gpu/drm/i915/display/intel_dp_mst.c |  6 ++--
 3 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index a5ab7d694dbe..fde373a3606a 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1414,10 +1414,13 @@ intel_dp_get_max_m_n_ratio(void)
 }
 
 bool
-intel_dp_can_support_m_n(int pixel_clock,
-                        int link_rate)
+intel_dp_can_support_m_n(struct intel_display *display,
+                        struct intel_crtc_state *crtc_state,
+                        int pixel_clock, int link_rate)
 {
+       struct intel_crtc *crtc;
        int max_m_n_ratio = intel_dp_get_max_m_n_ratio();
+       enum pipe pipe;
        u32 link_m, link_n;
        int m_n_ratio;
 
@@ -1426,7 +1429,20 @@ intel_dp_can_support_m_n(int pixel_clock,
 
        m_n_ratio = DIV_ROUND_UP(link_m, link_n);
 
-       return m_n_ratio <= max_m_n_ratio;
+       if (m_n_ratio <= max_m_n_ratio)
+               return true;
+
+       if (crtc_state) {
+               crtc = to_intel_crtc(crtc_state->uapi.crtc);
+               pipe = crtc->pipe;
+       } else {
+               pipe = PIPE_A;
+       }
+
+       if (intel_display_can_bypass_m_n_limit(display, m_n_ratio, pipe))
+               return true;
+
+       return false;
 }
 
 static enum drm_mode_status
@@ -1540,7 +1556,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,
        if (status != MODE_OK)
                return status;
 
-       if (!intel_dp_can_support_m_n(target_clock, max_rate))
+       if (!intel_dp_can_support_m_n(display, NULL, target_clock, max_rate))
                return MODE_CLOCK_HIGH;
 
        return intel_mode_valid_max_plane_size(display, mode, num_joined_pipes);
@@ -1798,6 +1814,7 @@ intel_dp_compute_link_config_wide(struct intel_dp 
*intel_dp,
                                  const struct drm_connector_state *conn_state,
                                  const struct link_config_limits *limits)
 {
+       struct intel_display *display = to_intel_display(pipe_config);
        int bpp, i, lane_count, clock = intel_dp_mode_clock(pipe_config, 
conn_state);
        int mode_rate, link_rate, link_avail;
 
@@ -1814,7 +1831,7 @@ intel_dp_compute_link_config_wide(struct intel_dp 
*intel_dp,
                            link_rate > limits->max_rate)
                                continue;
 
-                       if (!intel_dp_can_support_m_n(clock, link_rate))
+                       if (!intel_dp_can_support_m_n(display, pipe_config, 
clock, link_rate))
                                continue;
 
                        for (lane_count = limits->min_lane_count;
@@ -2001,6 +2018,7 @@ static int dsc_compute_link_config(struct intel_dp 
*intel_dp,
                                   int dsc_bpp_x16,
                                   int timeslots)
 {
+       struct intel_display *display = to_intel_display(pipe_config);
        const struct drm_display_mode *adjusted_mode = 
&pipe_config->hw.adjusted_mode;
        int link_rate, lane_count;
        int i;
@@ -2010,7 +2028,8 @@ static int dsc_compute_link_config(struct intel_dp 
*intel_dp,
                if (link_rate < limits->min_rate || link_rate > 
limits->max_rate)
                        continue;
 
-               if (!intel_dp_can_support_m_n(adjusted_mode->clock,
+               if (!intel_dp_can_support_m_n(display, pipe_config,
+                                             adjusted_mode->clock,
                                              link_rate))
                        continue;
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h 
b/drivers/gpu/drm/i915/display/intel_dp.h
index a197eb0a7fc6..7b7b950aeb61 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -215,7 +215,9 @@ int intel_dp_compute_min_hblank(struct intel_crtc_state 
*crtc_state,
 
 int intel_dp_dsc_bpp_step_x16(const struct intel_connector *connector);
 void intel_dp_dpcd_set_probe(struct intel_dp *intel_dp, bool 
force_on_external);
-bool intel_dp_can_support_m_n(int pixel_clock, int link_rate);
+bool intel_dp_can_support_m_n(struct intel_display *display,
+                             struct intel_crtc_state *crtc_state,
+                             int pixel_clock, int link_rate);
 void intel_dp_check_m_n_ratio(struct intel_crtc_state *crtc_state,
                              struct intel_link_m_n *m_n);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 45b72a2c8588..a06901ad7a9f 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -447,12 +447,14 @@ static int mst_stream_compute_link_config(struct intel_dp 
*intel_dp,
                                          struct drm_connector_state 
*conn_state,
                                          const struct link_config_limits 
*limits)
 {
+       struct intel_display *display = to_intel_display(crtc_state);
        crtc_state->lane_count = limits->max_lane_count;
        crtc_state->port_clock = limits->max_rate;
        const struct drm_display_mode *adjusted_mode =
                &crtc_state->hw.adjusted_mode;
 
-       if (!intel_dp_can_support_m_n(adjusted_mode->clock, 
crtc_state->port_clock))
+       if (!intel_dp_can_support_m_n(display, crtc_state, adjusted_mode->clock,
+                                     crtc_state->port_clock))
                return -EINVAL;
 
        /*
@@ -1560,7 +1562,7 @@ mst_connector_mode_valid_ctx(struct drm_connector 
*_connector,
                return 0;
        }
 
-       if (!intel_dp_can_support_m_n(mode->clock, max_rate)) {
+       if (!intel_dp_can_support_m_n(display, NULL, mode->clock, max_rate)) {
                *status = MODE_CLOCK_HIGH;
                return 0;
        }
-- 
2.45.2

Reply via email to