From e7b903d2525fe3be12b6535a27915186529a51b4 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 5 Jun 2013 13:34:14 +0200 Subject: [PATCH] drm/i915: enable/disable hooks for shared dplls MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Looks at first like a bit of overkill, but - Haswell actually wants different enable/disable functions for different plls. - And once we have full dpll hw state tracking we can move the full register setup into the ->enable hook. Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 7 ++- drivers/gpu/drm/i915/intel_display.c | 71 +++++++++++++++++----------- 2 files changed, 49 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index bb1ad20e39a1..eaa04a6808cb 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -132,6 +132,8 @@ enum hpd_pin { list_for_each_entry((intel_encoder), &(dev)->mode_config.encoder_list, base.head) \ if ((intel_encoder)->base.crtc == (__crtc)) +struct drm_i915_private; + enum intel_dpll_id { DPLL_ID_PRIVATE = -1, /* non-shared dpll in use */ /* real shared dpll ids must be >= 0 */ @@ -147,6 +149,10 @@ struct intel_shared_dpll { const char *name; /* should match the index in the dev_priv->shared_dplls array */ enum intel_dpll_id id; + void (*enable)(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll); + void (*disable)(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll); }; /* Used by dp and fdi links */ @@ -202,7 +208,6 @@ struct opregion_header; struct opregion_acpi; struct opregion_swsci; struct opregion_asle; -struct drm_i915_private; struct intel_opregion { struct opregion_header __iomem *header; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 1825ca5466e8..85f8888afce9 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1419,8 +1419,6 @@ static void ironlake_enable_shared_dpll(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc); - int reg; - u32 val; /* PCH PLLs only available on ILK, SNB and IVB */ BUG_ON(dev_priv->info->gen < 5); @@ -1434,9 +1432,6 @@ static void ironlake_enable_shared_dpll(struct intel_crtc *crtc) pll->name, pll->active, pll->on, crtc->base.base.id); - /* PCH refclock must be enabled first */ - assert_pch_refclk_enabled(dev_priv); - if (pll->active++) { WARN_ON(!pll->on); assert_shared_dpll_enabled(dev_priv, pll, NULL); @@ -1445,14 +1440,7 @@ static void ironlake_enable_shared_dpll(struct intel_crtc *crtc) WARN_ON(pll->on); DRM_DEBUG_KMS("enabling %s\n", pll->name); - - reg = PCH_DPLL(pll->id); - val = I915_READ(reg); - val |= DPLL_VCO_ENABLE; - I915_WRITE(reg, val); - POSTING_READ(reg); - udelay(200); - + pll->enable(dev_priv, pll); pll->on = true; } @@ -1460,8 +1448,6 @@ static void intel_disable_shared_dpll(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc); - int reg; - u32 val; /* PCH only available on ILK+ */ BUG_ON(dev_priv->info->gen < 5); @@ -1486,17 +1472,7 @@ static void intel_disable_shared_dpll(struct intel_crtc *crtc) return; DRM_DEBUG_KMS("disabling %s\n", pll->name); - - /* Make sure transcoder isn't still depending on us */ - assert_pch_transcoder_disabled(dev_priv, crtc->pipe); - - reg = PCH_DPLL(pll->id); - val = I915_READ(reg); - val &= ~DPLL_VCO_ENABLE; - I915_WRITE(reg, val); - POSTING_READ(reg); - udelay(200); - + pll->disable(dev_priv, pll); pll->on = false; } @@ -8729,6 +8705,43 @@ static void intel_cpu_pll_init(struct drm_device *dev) intel_ddi_pll_init(dev); } +static void ibx_pch_dpll_enable(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll) +{ + uint32_t reg, val; + + /* PCH refclock must be enabled first */ + assert_pch_refclk_enabled(dev_priv); + + reg = PCH_DPLL(pll->id); + val = I915_READ(reg); + val |= DPLL_VCO_ENABLE; + I915_WRITE(reg, val); + POSTING_READ(reg); + udelay(200); +} + +static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll) +{ + struct drm_device *dev = dev_priv->dev; + struct intel_crtc *crtc; + uint32_t reg, val; + + /* Make sure no transcoder isn't still depending on us. */ + list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) { + if (intel_crtc_to_shared_dpll(crtc) == pll) + assert_pch_transcoder_disabled(dev_priv, crtc->pipe); + } + + reg = PCH_DPLL(pll->id); + val = I915_READ(reg); + val &= ~DPLL_VCO_ENABLE; + I915_WRITE(reg, val); + POSTING_READ(reg); + udelay(200); +} + static char *ibx_pch_dpll_names[] = { "PCH DPLL A", "PCH DPLL B", @@ -8736,7 +8749,7 @@ static char *ibx_pch_dpll_names[] = { static void ibx_pch_dpll_init(struct drm_device *dev) { - drm_i915_private_t *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = dev->dev_private; int i; dev_priv->num_shared_dpll = 2; @@ -8744,12 +8757,14 @@ static void ibx_pch_dpll_init(struct drm_device *dev) for (i = 0; i < dev_priv->num_shared_dpll; i++) { dev_priv->shared_dplls[i].id = i; dev_priv->shared_dplls[i].name = ibx_pch_dpll_names[i]; + dev_priv->shared_dplls[i].enable = ibx_pch_dpll_enable; + dev_priv->shared_dplls[i].disable = ibx_pch_dpll_disable; } } static void intel_shared_dpll_init(struct drm_device *dev) { - drm_i915_private_t *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = dev->dev_private; if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) ibx_pch_dpll_init(dev); -- 2.39.5