aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2016-05-13 16:41:38 -0400
committerVille Syrjälä <ville.syrjala@linux.intel.com>2016-05-23 14:11:17 -0400
commit5f199dfa8dda965d1b2fc83bd8f8e205d2b8f9f1 (patch)
tree40b537f43dfe04e1dffd02b186309fd372667521
parentf59862422d6cf4980a6bad23a2e53c25273b9c63 (diff)
drm/i915: Make bxt_set_cdclk() operate in terms of the current vs target DE PLL vco
Make bxt_set_cdclk() more readable by looking at current vs. target DE PLL vco to determine if the DE PLL needs disabling and/or enabling. We can also calculate the CD2X divider simply as (vco/cdclk) instead of depending on magic numbers. The magic numbers are still needed though, but only to map the supported cdclk frequencies to corresponding DE PLL frequencies. Note that w'll now program CDCLK_CTL correctly even for the bypass case. Actually the CD2X divider should not matter in that case since the hardware will bypass it too, but the "decimal" part should matter (if we want to do gmbus/aux with the bypass enabled). Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1463172100-24715-20-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.c128
1 files changed, 63 insertions, 65 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 4a1f659e45af..a0b46b5b17b2 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5278,6 +5278,30 @@ static int skl_cdclk_decimal(int cdclk)
5278 return DIV_ROUND_CLOSEST(cdclk - 1000, 500); 5278 return DIV_ROUND_CLOSEST(cdclk - 1000, 500);
5279} 5279}
5280 5280
5281static int bxt_de_pll_vco(struct drm_i915_private *dev_priv, int cdclk)
5282{
5283 int ratio;
5284
5285 if (cdclk == dev_priv->cdclk_pll.ref)
5286 return 0;
5287
5288 switch (cdclk) {
5289 default:
5290 MISSING_CASE(cdclk);
5291 case 144000:
5292 case 288000:
5293 case 384000:
5294 case 576000:
5295 ratio = 60;
5296 break;
5297 case 624000:
5298 ratio = 65;
5299 break;
5300 }
5301
5302 return dev_priv->cdclk_pll.ref * ratio;
5303}
5304
5281static void bxt_de_pll_disable(struct drm_i915_private *dev_priv) 5305static void bxt_de_pll_disable(struct drm_i915_private *dev_priv)
5282{ 5306{
5283 I915_WRITE(BXT_DE_PLL_ENABLE, 0); 5307 I915_WRITE(BXT_DE_PLL_ENABLE, 0);
@@ -5289,13 +5313,14 @@ static void bxt_de_pll_disable(struct drm_i915_private *dev_priv)
5289 dev_priv->cdclk_pll.vco = 0; 5313 dev_priv->cdclk_pll.vco = 0;
5290} 5314}
5291 5315
5292static void bxt_de_pll_enable(struct drm_i915_private *dev_priv, u32 ratio) 5316static void bxt_de_pll_enable(struct drm_i915_private *dev_priv, int vco)
5293{ 5317{
5318 int ratio = DIV_ROUND_CLOSEST(vco, dev_priv->cdclk_pll.ref);
5294 u32 val; 5319 u32 val;
5295 5320
5296 val = I915_READ(BXT_DE_PLL_CTL); 5321 val = I915_READ(BXT_DE_PLL_CTL);
5297 val &= ~BXT_DE_PLL_RATIO_MASK; 5322 val &= ~BXT_DE_PLL_RATIO_MASK;
5298 val |= ratio; 5323 val |= BXT_DE_PLL_RATIO(ratio);
5299 I915_WRITE(BXT_DE_PLL_CTL, val); 5324 I915_WRITE(BXT_DE_PLL_CTL, val);
5300 5325
5301 I915_WRITE(BXT_DE_PLL_ENABLE, BXT_DE_PLL_PLL_ENABLE); 5326 I915_WRITE(BXT_DE_PLL_ENABLE, BXT_DE_PLL_PLL_ENABLE);
@@ -5304,54 +5329,42 @@ static void bxt_de_pll_enable(struct drm_i915_private *dev_priv, u32 ratio)
5304 if (wait_for((I915_READ(BXT_DE_PLL_ENABLE) & BXT_DE_PLL_LOCK) != 0, 1)) 5329 if (wait_for((I915_READ(BXT_DE_PLL_ENABLE) & BXT_DE_PLL_LOCK) != 0, 1))
5305 DRM_ERROR("timeout waiting for DE PLL lock\n"); 5330 DRM_ERROR("timeout waiting for DE PLL lock\n");
5306 5331
5307 dev_priv->cdclk_pll.vco = ratio * dev_priv->cdclk_pll.ref; 5332 dev_priv->cdclk_pll.vco = vco;
5308} 5333}
5309 5334
5310static void broxton_set_cdclk(struct drm_i915_private *dev_priv, int cdclk) 5335static void broxton_set_cdclk(struct drm_i915_private *dev_priv, int cdclk)
5311{ 5336{
5312 uint32_t divider; 5337 u32 val, divider;
5313 uint32_t ratio; 5338 int vco, ret;
5314 uint32_t current_cdclk;
5315 int ret;
5316 5339
5317 /* frequency = 19.2MHz * ratio / 2 / div{1,1.5,2,4} */ 5340 vco = bxt_de_pll_vco(dev_priv, cdclk);
5318 switch (cdclk) { 5341
5319 case 144000: 5342 DRM_DEBUG_DRIVER("Changing CDCLK to %d kHz (VCO %d kHz)\n", cdclk, vco);
5343
5344 /* cdclk = vco / 2 / div{1,1.5,2,4} */
5345 switch (DIV_ROUND_CLOSEST(vco, cdclk)) {
5346 case 8:
5320 divider = BXT_CDCLK_CD2X_DIV_SEL_4; 5347 divider = BXT_CDCLK_CD2X_DIV_SEL_4;
5321 ratio = BXT_DE_PLL_RATIO(60);
5322 break; 5348 break;
5323 case 288000: 5349 case 4:
5324 divider = BXT_CDCLK_CD2X_DIV_SEL_2; 5350 divider = BXT_CDCLK_CD2X_DIV_SEL_2;
5325 ratio = BXT_DE_PLL_RATIO(60);
5326 break; 5351 break;
5327 case 384000: 5352 case 3:
5328 divider = BXT_CDCLK_CD2X_DIV_SEL_1_5; 5353 divider = BXT_CDCLK_CD2X_DIV_SEL_1_5;
5329 ratio = BXT_DE_PLL_RATIO(60);
5330 break; 5354 break;
5331 case 576000: 5355 case 2:
5332 divider = BXT_CDCLK_CD2X_DIV_SEL_1; 5356 divider = BXT_CDCLK_CD2X_DIV_SEL_1;
5333 ratio = BXT_DE_PLL_RATIO(60);
5334 break;
5335 case 624000:
5336 divider = BXT_CDCLK_CD2X_DIV_SEL_1;
5337 ratio = BXT_DE_PLL_RATIO(65);
5338 break;
5339 case 19200:
5340 /*
5341 * Bypass frequency with DE PLL disabled. Init ratio, divider
5342 * to suppress GCC warning.
5343 */
5344 ratio = 0;
5345 divider = 0;
5346 break; 5357 break;
5347 default: 5358 default:
5348 DRM_ERROR("unsupported CDCLK freq %d", cdclk); 5359 WARN_ON(cdclk != dev_priv->cdclk_pll.ref);
5360 WARN_ON(vco != 0);
5349 5361
5350 return; 5362 divider = BXT_CDCLK_CD2X_DIV_SEL_1;
5363 break;
5351 } 5364 }
5352 5365
5353 mutex_lock(&dev_priv->rps.hw_lock);
5354 /* Inform power controller of upcoming frequency change */ 5366 /* Inform power controller of upcoming frequency change */
5367 mutex_lock(&dev_priv->rps.hw_lock);
5355 ret = sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ, 5368 ret = sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ,
5356 0x80000000); 5369 0x80000000);
5357 mutex_unlock(&dev_priv->rps.hw_lock); 5370 mutex_unlock(&dev_priv->rps.hw_lock);
@@ -5362,40 +5375,26 @@ static void broxton_set_cdclk(struct drm_i915_private *dev_priv, int cdclk)
5362 return; 5375 return;
5363 } 5376 }
5364 5377
5365 current_cdclk = I915_READ(CDCLK_CTL) & CDCLK_FREQ_DECIMAL_MASK; 5378 if (dev_priv->cdclk_pll.vco != 0 &&
5366 /* convert from .1 fixpoint MHz with -1MHz offset to kHz */ 5379 dev_priv->cdclk_pll.vco != vco)
5367 current_cdclk = current_cdclk * 500 + 1000;
5368
5369 /*
5370 * DE PLL has to be disabled when
5371 * - setting to 19.2MHz (bypass, PLL isn't used)
5372 * - before setting to 624MHz (PLL needs toggling)
5373 * - before setting to any frequency from 624MHz (PLL needs toggling)
5374 */
5375 if (cdclk == 19200 || cdclk == 624000 ||
5376 current_cdclk == 624000) {
5377 bxt_de_pll_disable(dev_priv); 5380 bxt_de_pll_disable(dev_priv);
5378 }
5379 5381
5380 if (cdclk != 19200) { 5382 if (dev_priv->cdclk_pll.vco != vco)
5381 uint32_t val; 5383 bxt_de_pll_enable(dev_priv, vco);
5382
5383 bxt_de_pll_enable(dev_priv, ratio);
5384 5384
5385 val = divider | skl_cdclk_decimal(cdclk); 5385 val = divider | skl_cdclk_decimal(cdclk);
5386 /* 5386 /*
5387 * FIXME if only the cd2x divider needs changing, it could be done 5387 * FIXME if only the cd2x divider needs changing, it could be done
5388 * without shutting off the pipe (if only one pipe is active). 5388 * without shutting off the pipe (if only one pipe is active).
5389 */ 5389 */
5390 val |= BXT_CDCLK_CD2X_PIPE_NONE; 5390 val |= BXT_CDCLK_CD2X_PIPE_NONE;
5391 /* 5391 /*
5392 * Disable SSA Precharge when CD clock frequency < 500 MHz, 5392 * Disable SSA Precharge when CD clock frequency < 500 MHz,
5393 * enable otherwise. 5393 * enable otherwise.
5394 */ 5394 */
5395 if (cdclk >= 500000) 5395 if (cdclk >= 500000)
5396 val |= BXT_CDCLK_SSA_PRECHARGE_ENABLE; 5396 val |= BXT_CDCLK_SSA_PRECHARGE_ENABLE;
5397 I915_WRITE(CDCLK_CTL, val); 5397 I915_WRITE(CDCLK_CTL, val);
5398 }
5399 5398
5400 mutex_lock(&dev_priv->rps.hw_lock); 5399 mutex_lock(&dev_priv->rps.hw_lock);
5401 ret = sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ, 5400 ret = sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ,
@@ -5445,8 +5444,7 @@ void broxton_init_cdclk(struct drm_i915_private *dev_priv)
5445 5444
5446void broxton_uninit_cdclk(struct drm_i915_private *dev_priv) 5445void broxton_uninit_cdclk(struct drm_i915_private *dev_priv)
5447{ 5446{
5448 /* Set minimum (bypass) frequency, in effect turning off the DE PLL */ 5447 broxton_set_cdclk(dev_priv, dev_priv->cdclk_pll.ref);
5449 broxton_set_cdclk(dev_priv, 19200);
5450} 5448}
5451 5449
5452static int skl_calc_cdclk(int max_pixclk, int vco) 5450static int skl_calc_cdclk(int max_pixclk, int vco)