drivers/gpu/drm/i915/display/intel_display.c | 33 +++++++++++++++++++-
drivers/gpu/drm/i915/display/intel_lt_phy.c | 30 ++++++++++++++++++
drivers/gpu/drm/i915/display/intel_lt_phy.h | 6 ++++
3 files changed, 68 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/display/intel_display.c
b/drivers/gpu/drm/i915/display/intel_display.c
index d5b2612d4ec2..b05f70582788 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -99,6 +99,7 @@
#include "intel_hdmi.h"
#include "intel_hotplug.h"
#include "intel_link_bw.h"
+#include "intel_lt_phy.h"
#include "intel_lvds.h"
#include "intel_lvds_regs.h"
#include "intel_modeset_setup.h"
@@ -4963,6 +4964,24 @@ static bool allow_vblank_delay_fastset(const struct
intel_crtc_state *old_crtc_s
!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DSI);
}
+static void
+pipe_config_lt_phy_pll_mismatch(struct drm_printer *p, bool fastset,
+ const struct intel_crtc *crtc,
+ const char *name,
+ const struct intel_lt_phy_pll_state *a,
+ const struct intel_lt_phy_pll_state *b)
+{
+ struct intel_display *display = to_intel_display(crtc);
+ char *chipname = "LTPHY";
+
+ pipe_config_mismatch(p, fastset, crtc, name, chipname);
+
+ drm_printf(p, "expected:\n");
+ intel_lt_phy_dump_hw_state(display, a);
+ drm_printf(p, "found:\n");
+ intel_lt_phy_dump_hw_state(display, b);
+}
+
bool
intel_pipe_config_compare(const struct intel_crtc_state *current_config,
const struct intel_crtc_state *pipe_config,
@@ -5087,6 +5106,16 @@ intel_pipe_config_compare(const struct intel_crtc_state
*current_config,
} \
} while (0)
+#define PIPE_CONF_CHECK_PLL_LT(name) do { \
+ if (!intel_lt_phy_pll_compare_hw_state(¤t_config->name, \
+ &pipe_config->name)) { \
+ pipe_config_lt_phy_pll_mismatch(&p, fastset, crtc,
__stringify(name), \
+ ¤t_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); \
@@ -5311,7 +5340,9 @@ intel_pipe_config_compare(const struct intel_crtc_state
*current_config,
PIPE_CONF_CHECK_PLL(dpll_hw_state);
/* FIXME convert MTL+ platforms over to dpll_mgr */
- if (DISPLAY_VER(display) >= 14)
+ if (HAS_LT_PHY(display))
+ PIPE_CONF_CHECK_PLL_LT(dpll_hw_state.ltpll);
+ else if (DISPLAY_VER(display) >= 14)
PIPE_CONF_CHECK_PLL_CX0(dpll_hw_state.cx0pll);
PIPE_CONF_CHECK_X(dsi_pll.ctrl);
diff --git a/drivers/gpu/drm/i915/display/intel_lt_phy.c
b/drivers/gpu/drm/i915/display/intel_lt_phy.c
index f1e41f009bb5..0be4aad0efcc 100644
--- a/drivers/gpu/drm/i915/display/intel_lt_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_lt_phy.c
@@ -1843,6 +1843,36 @@ void intel_lt_phy_set_signal_levels(struct intel_encoder
*encoder,
intel_lt_phy_transaction_end(encoder, wakeref);
}
+void intel_lt_phy_dump_hw_state(struct intel_display *display,
+ const struct intel_lt_phy_pll_state *hw_state)
+{
+ int i, j;
+
+ drm_dbg_kms(display->drm, "lt_phy_pll_hw_state:\n");
+ for (i = 0; i < 3; i++) {
+ drm_dbg_kms(display->drm, "config[%d] = 0x%.4x,\n",
+ i, hw_state->config[i]);
+ }
+
+ for (i = 0; i <= 12; i++)
+ for (j = 3; j >= 0; j--)
+ drm_dbg_kms(display->drm, "vdr_data[%d][%d] =
0x%.4x,\n",
+ i, j, hw_state->data[i][j]);
+}
+
+bool
+intel_lt_phy_pll_compare_hw_state(const struct intel_lt_phy_pll_state *a,
+ const struct intel_lt_phy_pll_state *b)
+{
+ if (memcmp(&a->config, &b->config, sizeof(a->config)) != 0)
+ return false;
+
+ if (memcmp(&a->data, &b->data, sizeof(a->data)) != 0)
+ return false;
+
+ return true;
+}
+
void intel_xe3plpd_pll_enable(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state)
{
diff --git a/drivers/gpu/drm/i915/display/intel_lt_phy.h
b/drivers/gpu/drm/i915/display/intel_lt_phy.h
index 6e67ae78801c..e93e5becc316 100644
--- a/drivers/gpu/drm/i915/display/intel_lt_phy.h
+++ b/drivers/gpu/drm/i915/display/intel_lt_phy.h
@@ -8,6 +8,7 @@
#include <linux/types.h>
+struct intel_display;
struct intel_encoder;
struct intel_crtc_state;
struct intel_lt_phy_pll_state;
@@ -22,6 +23,11 @@ int intel_lt_phy_calc_port_clock(struct intel_encoder
*encoder,
const struct intel_crtc_state *crtc_state);
void intel_lt_phy_set_signal_levels(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state);
+void intel_lt_phy_dump_hw_state(struct intel_display *display,
+ const struct intel_lt_phy_pll_state *hw_state);
+bool
+intel_lt_phy_pll_compare_hw_state(const struct intel_lt_phy_pll_state *a,
+ const struct intel_lt_phy_pll_state *b);
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);