Add verification for lt phy pll dividers during boot. The port clock is calculated from pll dividers and compared against the requested port clock value. If there are a difference exceeding +-1 kHz an drm_warn() is thrown out to indicate possible pll divider mismatch.
v2: - Move the LT_PHY_PLL_PARAMS -> LT_PHY_PLL_DP/HDMI_PARAMS change earlier. - Use tables[i].name != NULL as a terminating condition. - Use state vs. params term consistently in intel_c10pll_verify_clock() and intel_c20pll_verify_clock(). Signed-off-by: Mika Kahola <[email protected]> --- drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 2 + drivers/gpu/drm/i915/display/intel_lt_phy.c | 63 +++++++++++++++++++ drivers/gpu/drm/i915/display/intel_lt_phy.h | 1 + 3 files changed, 66 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c index 7127bc2a0898..f35a9252f4e1 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c @@ -38,6 +38,7 @@ #include "intel_dpll.h" #include "intel_dpll_mgr.h" #include "intel_hti.h" +#include "intel_lt_phy.h" #include "intel_mg_phy_regs.h" #include "intel_pch_refclk.h" #include "intel_step.h" @@ -4639,6 +4640,7 @@ void intel_dpll_init(struct intel_display *display) * debug option. */ intel_cx0pll_verify_plls(display); + intel_lt_phy_verify_plls(display); } /** diff --git a/drivers/gpu/drm/i915/display/intel_lt_phy.c b/drivers/gpu/drm/i915/display/intel_lt_phy.c index e33f6f48a6ce..13acfc7c0469 100644 --- a/drivers/gpu/drm/i915/display/intel_lt_phy.c +++ b/drivers/gpu/drm/i915/display/intel_lt_phy.c @@ -2343,3 +2343,66 @@ void intel_xe3plpd_pll_disable(struct intel_encoder *encoder) intel_lt_phy_pll_disable(encoder); } + +static void intel_lt_phy_pll_verify_clock(struct intel_display *display, + int precomputed_clock, + const char *pll_state_name, + const struct intel_lt_phy_pll_state *pll_state, + bool is_precomputed_state) +{ + struct drm_printer p; + int clock; + + clock = intel_lt_phy_calc_port_clock(display, pll_state); + + if (intel_cx0pll_clock_matches(clock, precomputed_clock)) + return; + + drm_warn(display->drm, + "PLL state %s (%s): clock difference too high: computed %d, pre-computed %d\n", + pll_state_name, + is_precomputed_state ? "precomputed" : "computed", + clock, precomputed_clock); + + if (!drm_debug_enabled(DRM_UT_KMS)) + return; + + p = drm_dbg_printer(display->drm, DRM_UT_KMS, NULL); + + drm_printf(&p, "PLL state %s (%s):\n", + pll_state_name, + is_precomputed_state ? "precomputed" : "computed"); + intel_lt_phy_dump_hw_state(display, pll_state); +} + +static void intel_lt_phy_pll_verify_params(struct intel_display *display, + const struct intel_lt_phy_pll_params *pll_params) +{ + struct intel_lt_phy_pll_state pll_state; + + intel_lt_phy_pll_verify_clock(display, pll_params->clock_rate, pll_params->name, pll_params->state, true); + + if (!pll_params->is_hdmi) + return; + + if (intel_lt_phy_calculate_hdmi_state(&pll_state, pll_params->clock_rate) != 0) + return; + + intel_lt_phy_pll_verify_clock(display, pll_params->clock_rate, pll_params->name, &pll_state, false); +} + +static void intel_lt_phy_pll_verify_tables(struct intel_display *display, + const struct intel_lt_phy_pll_params *tables) +{ + int i; + + for (i = 0; tables[i].name; i++) + intel_lt_phy_pll_verify_params(display, &tables[i]); +} + +void intel_lt_phy_verify_plls(struct intel_display *display) +{ + intel_lt_phy_pll_verify_tables(display, xe3plpd_lt_dp_tables); + intel_lt_phy_pll_verify_tables(display, xe3plpd_lt_edp_tables); + intel_lt_phy_pll_verify_tables(display, xe3plpd_lt_hdmi_tables); +} diff --git a/drivers/gpu/drm/i915/display/intel_lt_phy.h b/drivers/gpu/drm/i915/display/intel_lt_phy.h index c4999a55473e..56c5a875d93b 100644 --- a/drivers/gpu/drm/i915/display/intel_lt_phy.h +++ b/drivers/gpu/drm/i915/display/intel_lt_phy.h @@ -41,5 +41,6 @@ intel_lt_phy_calculate_hdmi_state(struct intel_lt_phy_pll_state *lt_state, void intel_xe3plpd_pll_enable(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state); void intel_xe3plpd_pll_disable(struct intel_encoder *encoder); +void intel_lt_phy_verify_plls(struct intel_display *display); #endif /* __INTEL_LT_PHY_H__ */ -- 2.34.1
