Skip to content

Commit

Permalink
drm/i915: Fix PCH reference clock for FDI on HSW/BDW
Browse files Browse the repository at this point in the history
The change to skip the PCH reference initialization during fastboot
did end up breaking FDI. To fix that let's try to do the PCH reference
init whenever we're disabling a DPLL that was using said reference
previously.

Cc: stable@vger.kernel.org
Tested-by: Andrija <akijo97@gmail.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=112084
Fixes: b16c7ed ("drm/i915: Do not touch the PCH SSC reference if a PLL is using it")
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191022185643.1483-1-ville.syrjala@linux.intel.com
Reviewed-by: Imre Deak <imre.deak@intel.com>
  • Loading branch information
Ville Syrjälä committed Oct 25, 2019
1 parent 2728200 commit dd5279c
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 5 deletions.
11 changes: 6 additions & 5 deletions drivers/gpu/drm/i915/display/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -9432,7 +9432,6 @@ static bool wrpll_uses_pch_ssc(struct drm_i915_private *dev_priv,
static void lpt_init_pch_refclk(struct drm_i915_private *dev_priv)
{
struct intel_encoder *encoder;
bool pch_ssc_in_use = false;
bool has_fdi = false;

for_each_intel_encoder(&dev_priv->drm, encoder) {
Expand Down Expand Up @@ -9460,22 +9459,24 @@ static void lpt_init_pch_refclk(struct drm_i915_private *dev_priv)
* clock hierarchy. That would also allow us to do
* clock bending finally.
*/
dev_priv->pch_ssc_use = 0;

if (spll_uses_pch_ssc(dev_priv)) {
DRM_DEBUG_KMS("SPLL using PCH SSC\n");
pch_ssc_in_use = true;
dev_priv->pch_ssc_use |= BIT(DPLL_ID_SPLL);
}

if (wrpll_uses_pch_ssc(dev_priv, DPLL_ID_WRPLL1)) {
DRM_DEBUG_KMS("WRPLL1 using PCH SSC\n");
pch_ssc_in_use = true;
dev_priv->pch_ssc_use |= BIT(DPLL_ID_WRPLL1);
}

if (wrpll_uses_pch_ssc(dev_priv, DPLL_ID_WRPLL2)) {
DRM_DEBUG_KMS("WRPLL2 using PCH SSC\n");
pch_ssc_in_use = true;
dev_priv->pch_ssc_use |= BIT(DPLL_ID_WRPLL2);
}

if (pch_ssc_in_use)
if (dev_priv->pch_ssc_use)
return;

if (has_fdi) {
Expand Down
15 changes: 15 additions & 0 deletions drivers/gpu/drm/i915/display/intel_dpll_mgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -526,16 +526,31 @@ static void hsw_ddi_wrpll_disable(struct drm_i915_private *dev_priv,
val = I915_READ(WRPLL_CTL(id));
I915_WRITE(WRPLL_CTL(id), val & ~WRPLL_PLL_ENABLE);
POSTING_READ(WRPLL_CTL(id));

/*
* Try to set up the PCH reference clock once all DPLLs
* that depend on it have been shut down.
*/
if (dev_priv->pch_ssc_use & BIT(id))
intel_init_pch_refclk(dev_priv);
}

static void hsw_ddi_spll_disable(struct drm_i915_private *dev_priv,
struct intel_shared_dpll *pll)
{
enum intel_dpll_id id = pll->info->id;
u32 val;

val = I915_READ(SPLL_CTL);
I915_WRITE(SPLL_CTL, val & ~SPLL_PLL_ENABLE);
POSTING_READ(SPLL_CTL);

/*
* Try to set up the PCH reference clock once all DPLLs
* that depend on it have been shut down.
*/
if (dev_priv->pch_ssc_use & BIT(id))
intel_init_pch_refclk(dev_priv);
}

static bool hsw_ddi_wrpll_get_hw_state(struct drm_i915_private *dev_priv,
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1353,6 +1353,8 @@ struct drm_i915_private {
} contexts;
} gem;

u8 pch_ssc_use;

/* For i915gm/i945gm vblank irq workaround */
u8 vblank_enabled;

Expand Down

0 comments on commit dd5279c

Please sign in to comment.