]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/i915/lt_phy: Add verification for lt phy pll dividers
authorMika Kahola <mika.kahola@intel.com>
Mon, 19 Jan 2026 09:37:53 +0000 (09:37 +0000)
committerMika Kahola <mika.kahola@intel.com>
Tue, 20 Jan 2026 08:52:59 +0000 (10:52 +0200)
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 <mika.kahola@intel.com>
Reviewed-by: Suraj Kandpal <suraj.kandpal@intel.com>
Link: https://patch.msgid.link/20260119093757.2850233-13-mika.kahola@intel.com
drivers/gpu/drm/i915/display/intel_dpll_mgr.c
drivers/gpu/drm/i915/display/intel_lt_phy.c
drivers/gpu/drm/i915/display/intel_lt_phy.h

index 7127bc2a0898269a2ffcc0a903b2f1d0c78493bf..f35a9252f4e1097ac3680dd67630b61ef3db9c81 100644 (file)
@@ -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 @@ out_verify:
         * debug option.
         */
        intel_cx0pll_verify_plls(display);
+       intel_lt_phy_verify_plls(display);
 }
 
 /**
index 2790caba545793e16cb26bfec5c7e559eb3dfba4..dbe2b2dc9887d7b36f22622b6fd1929d9c385c4e 100644 (file)
@@ -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);
+}
index 22b12d2d5bb16055b4fa5b393ea75dc7887fa20a..db905668f86d1698c38396ce211b2e79fd8f4acd 100644 (file)
@@ -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__ */