diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.c b/drivers/gpu/drm/i915/display/intel_cx0_phy.c index 3b56d25c8db8..ce4b7582b737 100644 --- a/drivers/gpu/drm/i915/display/intel_cx0_phy.c +++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.c @@ -3838,3 +3838,124 @@ void intel_cx0_pll_power_save_wa(struct intel_display *display) intel_cx0pll_disable(encoder); } } + +static void intel_c10pll_verify_clock(struct intel_display *display, + int precomputed_clock, + const char *pll_state_name, + const struct intel_c10pll_state *pll_state, + bool is_precomputed_state) +{ + struct drm_printer p; + int clock; + + clock = intel_c10pll_calc_port_clock(pll_state); + + if (intel_dpll_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_c10pll_dump_hw_state(&p, pll_state); +} + +static void intel_c10pll_verify_params(struct intel_display *display, + const struct intel_cx0pll_params *pll_params) +{ + struct intel_c10pll_state pll_state; + + intel_c10pll_verify_clock(display, pll_params->clock_rate, pll_params->name, pll_params->c10, true); + + if (!pll_params->is_hdmi) + return; + + intel_snps_hdmi_pll_compute_c10pll(&pll_state, pll_params->clock_rate); + + intel_c10pll_verify_clock(display, pll_params->clock_rate, pll_params->name, &pll_state, false); +} + +static void intel_c20pll_verify_clock(struct intel_display *display, + int precomputed_clock, + const char *pll_state_name, + const struct intel_c20pll_state *pll_state, + bool is_precomputed_state) +{ + struct drm_printer p; + int clock; + + clock = intel_c20pll_calc_port_clock(pll_state); + + if (intel_dpll_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_c20pll_dump_hw_state(&p, pll_state); +} + +static void intel_c20pll_verify_params(struct intel_display *display, + const struct intel_cx0pll_params *pll_params) +{ + struct intel_c20pll_state pll_state; + + intel_c20pll_verify_clock(display, pll_params->clock_rate, pll_params->name, pll_params->c20, true); + + if (!pll_params->is_hdmi) + return; + + if (intel_c20_compute_hdmi_tmds_pll(display, pll_params->clock_rate, &pll_state) != 0) + return; + + intel_c20pll_verify_clock(display, pll_params->clock_rate, pll_params->name, &pll_state, false); +} + +static void intel_cx0pll_verify_tables(struct intel_display *display, + const struct intel_cx0pll_params *tables) +{ + int i; + + for (i = 0; tables[i].name; i++) { + if (tables[i].is_c10) + intel_c10pll_verify_params(display, &tables[i]); + else + intel_c20pll_verify_params(display, &tables[i]); + } +} + +void intel_cx0pll_verify_plls(struct intel_display *display) +{ + /* C10 */ + intel_cx0pll_verify_tables(display, mtl_c10_edp_tables); + intel_cx0pll_verify_tables(display, mtl_c10_dp_tables); + intel_cx0pll_verify_tables(display, mtl_c10_hdmi_tables); + + /* C20 */ + intel_cx0pll_verify_tables(display, xe2hpd_c20_edp_tables); + intel_cx0pll_verify_tables(display, mtl_c20_dp_tables); + intel_cx0pll_verify_tables(display, xe2hpd_c20_dp_tables); + intel_cx0pll_verify_tables(display, xe3lpd_c20_dp_edp_tables); + intel_cx0pll_verify_tables(display, mtl_c20_hdmi_tables); +} diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.h b/drivers/gpu/drm/i915/display/intel_cx0_phy.h index ae98ac23ea22..347fdbc0af73 100644 --- a/drivers/gpu/drm/i915/display/intel_cx0_phy.h +++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.h @@ -77,6 +77,7 @@ bool intel_mtl_tbt_pll_readout_hw_state(struct intel_display *display, struct intel_dpll_hw_state *hw_state); int intel_mtl_tbt_calc_port_clock(struct intel_encoder *encoder); +void intel_cx0pll_verify_plls(struct intel_display *display); void intel_cx0_pll_power_save_wa(struct intel_display *display); void intel_lnl_mac_transmit_lfps(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state); diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c index 9aa84a430f09..7127bc2a0898 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c @@ -4613,7 +4613,7 @@ void intel_dpll_init(struct intel_display *display) dpll_mgr = &pch_pll_mgr; if (!dpll_mgr) - return; + goto out_verify; dpll_info = dpll_mgr->dpll_info; @@ -4632,6 +4632,13 @@ void intel_dpll_init(struct intel_display *display) display->dpll.mgr = dpll_mgr; display->dpll.num_dpll = i; + +out_verify: + /* + * TODO: Convert these to a KUnit test or dependent on a kconfig + * debug option. + */ + intel_cx0pll_verify_plls(display); } /**