[Intel-gfx] [PATCH] drm/i915: Init LCPLL on HSW/BDW if the BIOS did not
Ville Syrjala
ville.syrjala at linux.intel.com
Tue Mar 3 17:18:08 UTC 2020
From: Ville Syrjälä <ville.syrjala at linux.intel.com>
There are some rare BDW machines where the BIOS apparently does
not enable LCPLL/CDLCK. Let's try to do that ourselves.
Or maybe we should treat this case as "don't use the display engine!"
kind of knob?
Cc: Chris Wilson <chris at chris-wilson.co.uk>
Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
---
.../drm/i915/display/intel_display_power.c | 58 ++++++++++++-------
1 file changed, 36 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c
index 246e406bb385..e7641e57cebd 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power.c
@@ -4538,24 +4538,14 @@ static void icl_mbus_init(struct drm_i915_private *dev_priv)
}
}
-static void hsw_assert_cdclk(struct drm_i915_private *dev_priv)
+static bool hsw_lcpll_ok(u32 lcpll_ctl)
{
- u32 val = intel_de_read(dev_priv, LCPLL_CTL);
-
- /*
- * The LCPLL register should be turned on by the BIOS. For now
- * let's just check its state and print errors in case
- * something is wrong. Don't even try to turn it on.
- */
-
- if (val & LCPLL_CD_SOURCE_FCLK)
- drm_err(&dev_priv->drm, "CDCLK source is not LCPLL\n");
-
- if (val & LCPLL_PLL_DISABLE)
- drm_err(&dev_priv->drm, "LCPLL is disabled\n");
-
- if ((val & LCPLL_REF_MASK) != LCPLL_REF_NON_SSC)
- drm_err(&dev_priv->drm, "LCPLL not using non-SSC reference\n");
+ return (lcpll_ctl & (LCPLL_PLL_DISABLE | LCPLL_PLL_LOCK |
+ LCPLL_CD_CLOCK_DISABLE |
+ LCPLL_ROOT_CD_CLOCK_DISABLE |
+ LCPLL_CD2X_CLOCK_DISABLE |
+ LCPLL_POWER_DOWN_ALLOW |
+ LCPLL_CD_SOURCE_FCLK)) == LCPLL_PLL_LOCK;
}
static void assert_can_disable_lcpll(struct drm_i915_private *dev_priv)
@@ -4632,8 +4622,6 @@ static void hsw_disable_lcpll(struct drm_i915_private *dev_priv,
{
u32 val;
- assert_can_disable_lcpll(dev_priv);
-
val = intel_de_read(dev_priv, LCPLL_CTL);
if (switch_to_fclk) {
@@ -4681,8 +4669,7 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv)
val = intel_de_read(dev_priv, LCPLL_CTL);
- if ((val & (LCPLL_PLL_LOCK | LCPLL_PLL_DISABLE | LCPLL_CD_SOURCE_FCLK |
- LCPLL_POWER_DOWN_ALLOW)) == LCPLL_PLL_LOCK)
+ if (hsw_lcpll_ok(val))
return;
/*
@@ -4720,6 +4707,11 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv)
"Switching back to LCPLL failed\n");
}
+ val &= ~(LCPLL_CD_CLOCK_DISABLE |
+ LCPLL_ROOT_CD_CLOCK_DISABLE |
+ LCPLL_CD2X_CLOCK_DISABLE);
+ intel_de_write(dev_priv, LCPLL_CTL, val);
+
intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
intel_update_cdclk(dev_priv);
@@ -4762,6 +4754,7 @@ static void hsw_enable_pc8(struct drm_i915_private *dev_priv)
}
lpt_disable_clkout_dp(dev_priv);
+ assert_can_disable_lcpll(dev_priv);
hsw_disable_lcpll(dev_priv, true, true);
}
@@ -4781,6 +4774,27 @@ static void hsw_disable_pc8(struct drm_i915_private *dev_priv)
}
}
+static void hsw_lcpll_init(struct drm_i915_private *dev_priv)
+{
+ u32 val;
+
+ /*
+ * The LCPLL register should be turned on by the BIOS.
+ * Some machines apparently don't, so we're going to
+ * try to fix it if somehting is not correct.
+ */
+ val = intel_de_read(dev_priv, LCPLL_CTL);
+ if (hsw_lcpll_ok(val))
+ return;
+
+ drm_dbg(&dev_priv->drm,
+ "Reinitializing misconfigured LCPLL/CDCLK (LCPLL_CTL=0x%08x)\n",
+ val);
+
+ hsw_disable_lcpll(dev_priv, true, true);
+ hsw_restore_lcpll(dev_priv);
+}
+
static void intel_pch_reset_handshake(struct drm_i915_private *dev_priv,
bool enable)
{
@@ -5307,8 +5321,8 @@ void intel_power_domains_init_hw(struct drm_i915_private *i915, bool resume)
assert_ved_power_gated(i915);
assert_isp_power_gated(i915);
} else if (IS_BROADWELL(i915) || IS_HASWELL(i915)) {
- hsw_assert_cdclk(i915);
intel_pch_reset_handshake(i915, !HAS_PCH_NOP(i915));
+ hsw_lcpll_init(i915);
} else if (IS_IVYBRIDGE(i915)) {
intel_pch_reset_handshake(i915, !HAS_PCH_NOP(i915));
}
--
2.24.1
More information about the Intel-gfx
mailing list