diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.c b/drivers/gpu/drm/i915/display/intel_cx0_phy.c
index c9e5bb6ecfd7..41f684c970dc 100644
--- a/drivers/gpu/drm/i915/display/intel_cx0_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.c
@@ -2038,6 +2038,7 @@ static int intel_c10pll_calc_state(struct intel_crtc_state *crtc_state,
 		if (crtc_state->port_clock == tables[i]->clock) {
 			crtc_state->dpll_hw_state.cx0pll.c10 = *tables[i];
 			intel_c10pll_update_pll(crtc_state, encoder);
+			crtc_state->dpll_hw_state.cx0pll.use_c10 = true;
 
 			return 0;
 		}
@@ -2105,8 +2106,8 @@ static void intel_c10_pll_program(struct drm_i915_private *i915,
 		      MB_WRITE_COMMITTED);
 }
 
-void intel_c10pll_dump_hw_state(struct drm_i915_private *i915,
-				const struct intel_c10pll_state *hw_state)
+static void intel_c10pll_dump_hw_state(struct drm_i915_private *i915,
+				       const struct intel_c10pll_state *hw_state)
 {
 	bool fracen;
 	int i;
@@ -2277,6 +2278,7 @@ static int intel_c20pll_calc_state(struct intel_crtc_state *crtc_state,
 	for (i = 0; tables[i]; i++) {
 		if (crtc_state->port_clock == tables[i]->clock) {
 			crtc_state->dpll_hw_state.cx0pll.c20 = *tables[i];
+			crtc_state->dpll_hw_state.cx0pll.use_c10 = false;
 			return 0;
 		}
 	}
@@ -2410,8 +2412,8 @@ static void intel_c20pll_readout_hw_state(struct intel_encoder *encoder,
 	intel_cx0_phy_transaction_end(encoder, wakeref);
 }
 
-void intel_c20pll_dump_hw_state(struct drm_i915_private *i915,
-				const struct intel_c20pll_state *hw_state)
+static void intel_c20pll_dump_hw_state(struct drm_i915_private *i915,
+				       const struct intel_c20pll_state *hw_state)
 {
 	int i;
 
@@ -2430,6 +2432,15 @@ void intel_c20pll_dump_hw_state(struct drm_i915_private *i915,
 	}
 }
 
+void intel_cx0pll_dump_hw_state(struct drm_i915_private *i915,
+				const struct intel_cx0pll_state *hw_state)
+{
+	if (hw_state->use_c10)
+		intel_c10pll_dump_hw_state(i915, &hw_state->c10);
+	else
+		intel_c20pll_dump_hw_state(i915, &hw_state->c20);
+}
+
 static u8 intel_c20_get_dp_rate(u32 clock)
 {
 	switch (clock) {
@@ -3266,10 +3277,64 @@ static void intel_c10pll_state_verify(const struct intel_crtc_state *state,
 void intel_cx0pll_readout_hw_state(struct intel_encoder *encoder,
 				   struct intel_cx0pll_state *pll_state)
 {
-	if (intel_encoder_is_c10phy(encoder))
+	pll_state->use_c10 = false;
+
+	if (intel_encoder_is_c10phy(encoder)) {
 		intel_c10pll_readout_hw_state(encoder, &pll_state->c10);
-	else
+		pll_state->use_c10 = true;
+	} else {
 		intel_c20pll_readout_hw_state(encoder, &pll_state->c20);
+	}
+}
+
+static bool mtl_compare_hw_state_c10(const struct intel_c10pll_state *a,
+				     const struct intel_c10pll_state *b)
+{
+	if (a->tx != b->tx)
+		return false;
+
+	if (a->cmn != b->cmn)
+		return false;
+
+	if (memcmp(&a->pll, &b->pll, sizeof(a->pll)) != 0)
+		return false;
+
+	return true;
+}
+
+static bool mtl_compare_hw_state_c20(const struct intel_c20pll_state *a,
+				     const struct intel_c20pll_state *b)
+{
+	if (memcmp(&a->tx, &b->tx, sizeof(a->tx)) != 0)
+		return false;
+
+	if (memcmp(&a->cmn, &b->cmn, sizeof(a->cmn)) != 0)
+		return false;
+
+	if (a->tx[0] & C20_PHY_USE_MPLLB) {
+		if (memcmp(&a->mpllb, &b->mpllb, sizeof(a->mpllb)) != 0)
+			return false;
+	} else {
+		if (memcmp(&a->mplla, &b->mplla, sizeof(a->mplla)) != 0)
+			return false;
+	}
+
+	return true;
+}
+
+bool intel_cx0pll_compare_hw_state(const struct intel_cx0pll_state *a,
+				   const struct intel_cx0pll_state *b)
+{
+
+	if (a->use_c10 != b->use_c10)
+		return false;
+
+	if (a->use_c10)
+		return mtl_compare_hw_state_c10(&a->c10,
+						&b->c10);
+	else
+		return mtl_compare_hw_state_c20(&a->c20,
+						&b->c20);
 }
 
 int intel_cx0pll_calc_port_clock(struct intel_encoder *encoder,
diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.h b/drivers/gpu/drm/i915/display/intel_cx0_phy.h
index 3e03af3e006c..9004b99bb51f 100644
--- a/drivers/gpu/drm/i915/display/intel_cx0_phy.h
+++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.h
@@ -35,12 +35,12 @@ void intel_cx0pll_readout_hw_state(struct intel_encoder *encoder,
 int intel_cx0pll_calc_port_clock(struct intel_encoder *encoder,
 				 const struct intel_cx0pll_state *pll_state);
 
-void intel_c10pll_dump_hw_state(struct drm_i915_private *dev_priv,
-				const struct intel_c10pll_state *hw_state);
+void intel_cx0pll_dump_hw_state(struct drm_i915_private *dev_priv,
+				const struct intel_cx0pll_state *hw_state);
 void intel_cx0pll_state_verify(struct intel_atomic_state *state,
 			       struct intel_crtc *crtc);
-void intel_c20pll_dump_hw_state(struct drm_i915_private *i915,
-				const struct intel_c20pll_state *hw_state);
+bool intel_cx0pll_compare_hw_state(const struct intel_cx0pll_state *a,
+				   const struct intel_cx0pll_state *b);
 void intel_cx0_phy_set_signal_levels(struct intel_encoder *encoder,
 				     const struct intel_crtc_state *crtc_state);
 int intel_cx0_phy_check_hdmi_link_rate(struct intel_hdmi *hdmi, int clock);
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index cce1420fb541..146208675b6e 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -66,6 +66,7 @@
 #include "intel_crtc.h"
 #include "intel_crtc_state_dump.h"
 #include "intel_cursor_regs.h"
+#include "intel_cx0_phy.h"
 #include "intel_ddi.h"
 #include "intel_de.h"
 #include "intel_display_driver.h"
@@ -5002,6 +5003,24 @@ pipe_config_pll_mismatch(struct drm_printer *p, bool fastset,
 	intel_dpll_dump_hw_state(i915, p, b);
 }
 
+static void
+pipe_config_cx0pll_mismatch(struct drm_printer *p, bool fastset,
+			    const struct intel_crtc *crtc,
+			    const char *name,
+			    const struct intel_cx0pll_state *a,
+			    const struct intel_cx0pll_state *b)
+{
+	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
+	char *chipname = a->use_c10 ? "C10" : "C20";
+
+	pipe_config_mismatch(p, fastset, crtc, name, chipname);
+
+	drm_printf(p, "expected:\n");
+	intel_cx0pll_dump_hw_state(i915, a);
+	drm_printf(p, "found:\n");
+	intel_cx0pll_dump_hw_state(i915, b);
+}
+
 bool
 intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 			  const struct intel_crtc_state *pipe_config,
@@ -5105,6 +5124,16 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 	} \
 } while (0)
 
+#define PIPE_CONF_CHECK_PLL_CX0(name) do { \
+	if (!intel_cx0pll_compare_hw_state(&current_config->name, \
+					   &pipe_config->name)) { \
+		pipe_config_cx0pll_mismatch(&p, fastset, crtc, __stringify(name), \
+					    &current_config->name, \
+					    &pipe_config->name); \
+		ret = false; \
+	} \
+} while (0)
+
 #define PIPE_CONF_CHECK_TIMINGS(name) do {     \
 	PIPE_CONF_CHECK_I(name.crtc_hdisplay); \
 	PIPE_CONF_CHECK_I(name.crtc_htotal); \
@@ -5337,6 +5366,10 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 	if (dev_priv->display.dpll.mgr || HAS_GMCH(dev_priv))
 		PIPE_CONF_CHECK_PLL(dpll_hw_state);
 
+	/* FIXME convert MTL+ platforms over to dpll_mgr */
+	if (DISPLAY_VER(dev_priv) >= 14)
+		PIPE_CONF_CHECK_PLL_CX0(dpll_hw_state.cx0pll);
+
 	PIPE_CONF_CHECK_X(dsi_pll.ctrl);
 	PIPE_CONF_CHECK_X(dsi_pll.div);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h
index f09e513ce05b..36baed75b89a 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h
+++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h
@@ -264,6 +264,7 @@ struct intel_cx0pll_state {
 		struct intel_c20pll_state c20;
 	};
 	bool ssc_enabled;
+	bool use_c10;
 };
 
 struct intel_dpll_hw_state {
