From 121643c2c9f8d424d1e66ca635828361b687e903 Mon Sep 17 00:00:00 2001 From: Satheeshakrishna M Date: Thu, 13 Nov 2014 14:55:15 +0000 Subject: [PATCH] drm/i915/skl: CD clock back calculation for SKL Determine programmed cd clock for SKL. v2: Fix the LCPLL1 enable warning logic v3: Rebase over the hsw pll rework. v4: Rebase on top of the per-platform split (Damien) v5: Modified as per review comments from Paulo Reviewed-by: Paulo Zanoni Signed-off-by: Satheeshakrishna M Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ddi.c | 75 ++++++++++++++++++++++++++++---- 1 file changed, 66 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 68703cecdefc..01c4f70c545b 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1259,6 +1259,54 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder) } } +static int skl_get_cdclk_freq(struct drm_i915_private *dev_priv) +{ + uint32_t lcpll1 = I915_READ(LCPLL1_CTL); + uint32_t cdctl = I915_READ(CDCLK_CTL); + uint32_t linkrate; + + if (!(lcpll1 & LCPLL_PLL_ENABLE)) { + WARN(1, "LCPLL1 not enabled\n"); + return 24000; /* 24MHz is the cd freq with NSSC ref */ + } + + if ((cdctl & CDCLK_FREQ_SEL_MASK) == CDCLK_FREQ_540) + return 540000; + + linkrate = (I915_READ(DPLL_CTRL1) & + DPLL_CRTL1_LINK_RATE_MASK(SKL_DPLL0)) >> 1; + + if (linkrate == DPLL_CRTL1_LINK_RATE_2160 || + linkrate == DPLL_CRTL1_LINK_RATE_1080) { + /* vco 8640 */ + switch (cdctl & CDCLK_FREQ_SEL_MASK) { + case CDCLK_FREQ_450_432: + return 432000; + case CDCLK_FREQ_337_308: + return 308570; + case CDCLK_FREQ_675_617: + return 617140; + default: + WARN(1, "Unknown cd freq selection\n"); + } + } else { + /* vco 8100 */ + switch (cdctl & CDCLK_FREQ_SEL_MASK) { + case CDCLK_FREQ_450_432: + return 450000; + case CDCLK_FREQ_337_308: + return 337500; + case CDCLK_FREQ_675_617: + return 675000; + default: + WARN(1, "Unknown cd freq selection\n"); + } + } + + /* error case, do as if DPLL0 isn't enabled */ + return 24000; +} + static int bdw_get_cdclk_freq(struct drm_i915_private *dev_priv) { uint32_t lcpll = I915_READ(LCPLL_CTL); @@ -1300,6 +1348,9 @@ int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv) { struct drm_device *dev = dev_priv->dev; + if (IS_SKYLAKE(dev)) + return skl_get_cdclk_freq(dev_priv); + if (IS_BROADWELL(dev)) return bdw_get_cdclk_freq(dev_priv); @@ -1368,19 +1419,25 @@ void intel_ddi_pll_init(struct drm_device *dev) hsw_shared_dplls_init(dev_priv); - /* 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. - */ - DRM_DEBUG_KMS("CDCLK running at %dKHz\n", intel_ddi_get_cdclk_freq(dev_priv)); - if (val & LCPLL_CD_SOURCE_FCLK) - DRM_ERROR("CDCLK source is not LCPLL\n"); + if (IS_SKYLAKE(dev)) { + if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE)) + DRM_ERROR("LCPLL1 is disabled\n"); + } else { + /* + * 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_ERROR("CDCLK source is not LCPLL\n"); - if (val & LCPLL_PLL_DISABLE) - DRM_ERROR("LCPLL is disabled\n"); + if (val & LCPLL_PLL_DISABLE) + DRM_ERROR("LCPLL is disabled\n"); + } } void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder) -- 2.30.2