Commit 10d187b3 authored by Mika Kahola's avatar Mika Kahola
Browse files

drm/i915/lt_phy: Add verification for lt phy pll dividers



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: default avatarMika Kahola <mika.kahola@intel.com>
Reviewed-by: default avatarSuraj Kandpal <suraj.kandpal@intel.com>
Link: https://patch.msgid.link/20260119093757.2850233-13-mika.kahola@intel.com
parent 58213c1d
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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);
}

/**
+63 −0
Original line number Diff line number Diff line
@@ -2337,3 +2337,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_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_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);
}
+1 −0
Original line number Diff line number Diff line
@@ -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__ */