aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2016-05-13 16:41:29 -0400
committerVille Syrjälä <ville.syrjala@linux.intel.com>2016-05-23 14:11:14 -0400
commit9f7eb31af2968a194b29f67ec10776685a81afc9 (patch)
tree7fb5e8f62a6328c0dbe5d44f348f93047bec844a
parent09492498ee631041bfc60f2dc1960e246b8a7120 (diff)
drm/i915: Unify SKL cdclk init paths
Currently we initialize cdclk on SKL from two different places, depending on whether it's during driver init or resume. Let's unify it to happen from the same place always, and that place will be the display core init function. To do this we first run through the cdclk sanitation code, which will first verify that the PLL is programmed correctly, after which we can read out the current cdclk frequency, and once the cdclk is known we verify that the cdclk "decimal" frequency is programmed correctly. If any of these fail we will force a cdclk change, and to be safe we also force the PLL to be turned off and on again. If the sanitation step didn't notice anything amiss, we'll skip the cdclk programming which will prevent cdclk reprogramming when the displays might be active. We can also toss in a few WARNs about the register values into skl_update_dpll0() since we now know that the PLL state should always be sane when that function is called. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1463172100-24715-11-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak <imre.deak@intel.com>
-rw-r--r--drivers/gpu/drm/i915/intel_display.c40
-rw-r--r--drivers/gpu/drm/i915/intel_dpll_mgr.c11
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h1
-rw-r--r--drivers/gpu/drm/i915/intel_runtime_pm.c5
4 files changed, 34 insertions, 23 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index b2adb01671be..58b8d759eaaa 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5497,8 +5497,15 @@ skl_dpll0_update(struct drm_i915_private *dev_priv)
5497 return; 5497 return;
5498 } 5498 }
5499 5499
5500 WARN_ON((val & LCPLL_PLL_LOCK) == 0);
5501
5500 val = I915_READ(DPLL_CTRL1); 5502 val = I915_READ(DPLL_CTRL1);
5501 5503
5504 WARN_ON((val & (DPLL_CTRL1_HDMI_MODE(SKL_DPLL0) |
5505 DPLL_CTRL1_SSC(SKL_DPLL0) |
5506 DPLL_CTRL1_OVERRIDE(SKL_DPLL0))) !=
5507 DPLL_CTRL1_OVERRIDE(SKL_DPLL0));
5508
5502 switch (val & DPLL_CTRL1_LINK_RATE_MASK(SKL_DPLL0)) { 5509 switch (val & DPLL_CTRL1_LINK_RATE_MASK(SKL_DPLL0)) {
5503 case DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, SKL_DPLL0): 5510 case DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, SKL_DPLL0):
5504 case DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, SKL_DPLL0): 5511 case DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, SKL_DPLL0):
@@ -5668,6 +5675,8 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv, int cdclk, int vco)
5668 intel_update_cdclk(dev); 5675 intel_update_cdclk(dev);
5669} 5676}
5670 5677
5678static void skl_sanitize_cdclk(struct drm_i915_private *dev_priv);
5679
5671void skl_uninit_cdclk(struct drm_i915_private *dev_priv) 5680void skl_uninit_cdclk(struct drm_i915_private *dev_priv)
5672{ 5681{
5673 /* disable DBUF power */ 5682 /* disable DBUF power */
@@ -5684,10 +5693,19 @@ void skl_uninit_cdclk(struct drm_i915_private *dev_priv)
5684 5693
5685void skl_init_cdclk(struct drm_i915_private *dev_priv) 5694void skl_init_cdclk(struct drm_i915_private *dev_priv)
5686{ 5695{
5687 /* DPLL0 not enabled (happens on early BIOS versions) */ 5696 int cdclk, vco;
5688 if (dev_priv->skl_vco_freq == 0) { 5697
5689 int cdclk, vco; 5698 skl_sanitize_cdclk(dev_priv);
5690 5699
5700 if (dev_priv->cdclk_freq != 0 && dev_priv->skl_vco_freq != 0) {
5701 /*
5702 * Use the current vco as our initial
5703 * guess as to what the preferred vco is.
5704 */
5705 if (dev_priv->skl_preferred_vco_freq == 0)
5706 skl_set_preferred_cdclk_vco(dev_priv,
5707 dev_priv->skl_vco_freq);
5708 } else {
5691 /* set CDCLK to the lowest frequency, Modeset follows */ 5709 /* set CDCLK to the lowest frequency, Modeset follows */
5692 vco = dev_priv->skl_preferred_vco_freq; 5710 vco = dev_priv->skl_preferred_vco_freq;
5693 if (vco == 0) 5711 if (vco == 0)
@@ -5707,7 +5725,7 @@ void skl_init_cdclk(struct drm_i915_private *dev_priv)
5707 DRM_ERROR("DBuf power enable timeout\n"); 5725 DRM_ERROR("DBuf power enable timeout\n");
5708} 5726}
5709 5727
5710int skl_sanitize_cdclk(struct drm_i915_private *dev_priv) 5728static void skl_sanitize_cdclk(struct drm_i915_private *dev_priv)
5711{ 5729{
5712 uint32_t cdctl, expected; 5730 uint32_t cdctl, expected;
5713 5731
@@ -5730,6 +5748,8 @@ int skl_sanitize_cdclk(struct drm_i915_private *dev_priv)
5730 DPLL_CTRL1_OVERRIDE(SKL_DPLL0)) 5748 DPLL_CTRL1_OVERRIDE(SKL_DPLL0))
5731 goto sanitize; 5749 goto sanitize;
5732 5750
5751 intel_update_cdclk(dev_priv->dev);
5752
5733 /* DPLL okay; verify the cdclock 5753 /* DPLL okay; verify the cdclock
5734 * 5754 *
5735 * Noticed in some instances that the freq selection is correct but 5755 * Noticed in some instances that the freq selection is correct but
@@ -5741,13 +5761,15 @@ int skl_sanitize_cdclk(struct drm_i915_private *dev_priv)
5741 skl_cdclk_decimal(dev_priv->cdclk_freq); 5761 skl_cdclk_decimal(dev_priv->cdclk_freq);
5742 if (cdctl == expected) 5762 if (cdctl == expected)
5743 /* All well; nothing to sanitize */ 5763 /* All well; nothing to sanitize */
5744 return false; 5764 return;
5745sanitize:
5746 5765
5747 skl_init_cdclk(dev_priv); 5766sanitize:
5767 DRM_DEBUG_KMS("Sanitizing cdclk programmed by pre-os\n");
5748 5768
5749 /* we did have to sanitize */ 5769 /* force cdclk programming */
5750 return true; 5770 dev_priv->cdclk_freq = 0;
5771 /* force full PLL disable + enable */
5772 dev_priv->skl_vco_freq = -1;
5751} 5773}
5752 5774
5753/* Adjust CDclk dividers to allow high res or save power if possible */ 5775/* Adjust CDclk dividers to allow high res or save power if possible */
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
index 34ec149fde85..6b70e1eccb13 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -1630,17 +1630,10 @@ static const struct intel_shared_dpll_funcs bxt_ddi_pll_funcs = {
1630static void intel_ddi_pll_init(struct drm_device *dev) 1630static void intel_ddi_pll_init(struct drm_device *dev)
1631{ 1631{
1632 struct drm_i915_private *dev_priv = dev->dev_private; 1632 struct drm_i915_private *dev_priv = dev->dev_private;
1633 uint32_t val = I915_READ(LCPLL_CTL);
1634 1633
1635 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) { 1634 if (INTEL_GEN(dev_priv) < 9) {
1636 if (skl_sanitize_cdclk(dev_priv)) 1635 uint32_t val = I915_READ(LCPLL_CTL);
1637 DRM_DEBUG_KMS("Sanitized cdclk programmed by pre-os\n");
1638 1636
1639 /* We'll want to keep using the current vco from now on */
1640 if (dev_priv->skl_vco_freq != 0)
1641 skl_set_preferred_cdclk_vco(dev_priv,
1642 dev_priv->skl_vco_freq);
1643 } else if (!IS_BROXTON(dev_priv)) {
1644 /* 1637 /*
1645 * The LCPLL register should be turned on by the BIOS. For now 1638 * The LCPLL register should be turned on by the BIOS. For now
1646 * let's just check its state and print errors in case 1639 * let's just check its state and print errors in case
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 2bee217e6ae5..3854b2ee1077 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1279,7 +1279,6 @@ void bxt_enable_dc9(struct drm_i915_private *dev_priv);
1279void bxt_disable_dc9(struct drm_i915_private *dev_priv); 1279void bxt_disable_dc9(struct drm_i915_private *dev_priv);
1280void gen9_enable_dc5(struct drm_i915_private *dev_priv); 1280void gen9_enable_dc5(struct drm_i915_private *dev_priv);
1281void skl_init_cdclk(struct drm_i915_private *dev_priv); 1281void skl_init_cdclk(struct drm_i915_private *dev_priv);
1282int skl_sanitize_cdclk(struct drm_i915_private *dev_priv);
1283void skl_uninit_cdclk(struct drm_i915_private *dev_priv); 1282void skl_uninit_cdclk(struct drm_i915_private *dev_priv);
1284unsigned int skl_cdclk_get_vco(unsigned int freq); 1283unsigned int skl_cdclk_get_vco(unsigned int freq);
1285void skl_enable_dc6(struct drm_i915_private *dev_priv); 1284void skl_enable_dc6(struct drm_i915_private *dev_priv);
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index b69b935516fb..fefe22c3c163 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -2200,12 +2200,9 @@ static void skl_display_core_init(struct drm_i915_private *dev_priv,
2200 2200
2201 mutex_unlock(&power_domains->lock); 2201 mutex_unlock(&power_domains->lock);
2202 2202
2203 if (!resume)
2204 return;
2205
2206 skl_init_cdclk(dev_priv); 2203 skl_init_cdclk(dev_priv);
2207 2204
2208 if (dev_priv->csr.dmc_payload) 2205 if (resume && dev_priv->csr.dmc_payload)
2209 intel_csr_load_program(dev_priv); 2206 intel_csr_load_program(dev_priv);
2210} 2207}
2211 2208