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
