[Intel-gfx] [PATCH 21/31] drm/i915: consolidate pch pll enable sequence
Damien Lespiau
damien.lespiau at intel.com
Mon Jun 24 16:30:58 CEST 2013
On Wed, Jun 05, 2013 at 01:34:23PM +0200, Daniel Vetter wrote:
> It's been splattered over 3 different places all doing random things.
> Now we have (mostly) the same sequence as i8xx/i9xx, but all called
> from the crtc_enable hook (through the pll->enable function):
> - write new dividers
> - enable vco and wait for stable clocks
> - write again for the pixel mutliplier
>
> I've left the seemingly random 200 usec delay in there, just in case.
>
> Also move the encoder->pre_pll_enable hook into the crtc_enable
> function, at the same spot we currently have a hack to enable the lvds
> port. Since that hack is now redundant, kill it.
>
> While doing this patch I've learned the hard way that we can only fire
> up the LVDS port if both the pch dpll _and_ the fdi rc pll are not yet
> enabled. Otherwise things go haywire, at least on cpt.
>
> v2: It is paramount to write the FPx divisors before we enable the
> the vco by writing to the DPLL registers, for otherwise the divisors
> won't get updated. This is in line with the i8xx/i9xx dpll.
>
> v3: To keep the nice abstraction add a ->mode_set callback to set the
> divisors. Also streamline the enabling/disabling code a bit by
> removing some cargo-cult duplication and clearing registers where
> possible in the ->disable hook.
>
> v4: Remove now unused local variable.
>
> Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
For some reason my brain refuses to work on this patch. I say, let's
test it in the wild instead.
Acked-by: Damien Lespiau <damien.lespiau at intel.com>
--
Damien
> ---
> drivers/gpu/drm/i915/i915_drv.h | 2 +
> drivers/gpu/drm/i915/intel_display.c | 75 +++++++++++++-----------------------
> 2 files changed, 29 insertions(+), 48 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 4dc94ed..9fc1ea4 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -157,6 +157,8 @@ struct intel_shared_dpll {
> /* should match the index in the dev_priv->shared_dplls array */
> enum intel_dpll_id id;
> struct intel_dpll_hw_state hw_state;
> + void (*mode_set)(struct drm_i915_private *dev_priv,
> + struct intel_shared_dpll *pll);
> void (*enable)(struct drm_i915_private *dev_priv,
> struct intel_shared_dpll *pll);
> void (*disable)(struct drm_i915_private *dev_priv,
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index fc1b5f7..334f86a 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -3064,13 +3064,7 @@ found:
> WARN_ON(pll->on);
> assert_shared_dpll_disabled(dev_priv, pll);
>
> - /* Wait for the clocks to stabilize before rewriting the regs */
> - I915_WRITE(PCH_DPLL(pll->id), dpll & ~DPLL_VCO_ENABLE);
> - POSTING_READ(PCH_DPLL(pll->id));
> - udelay(150);
> -
> - I915_WRITE(PCH_FP0(pll->id), fp);
> - I915_WRITE(PCH_DPLL(pll->id), dpll & ~DPLL_VCO_ENABLE);
> + pll->mode_set(dev_priv, pll);
> }
> pll->refcount++;
>
> @@ -3120,7 +3114,6 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
> struct intel_encoder *encoder;
> int pipe = intel_crtc->pipe;
> int plane = intel_crtc->plane;
> - u32 temp;
>
> WARN_ON(!crtc->enabled);
>
> @@ -3134,12 +3127,9 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
>
> intel_update_watermarks(dev);
>
> - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
> - temp = I915_READ(PCH_LVDS);
> - if ((temp & LVDS_PORT_EN) == 0)
> - I915_WRITE(PCH_LVDS, temp | LVDS_PORT_EN);
> - }
> -
> + for_each_encoder_on_crtc(dev, crtc, encoder)
> + if (encoder->pre_pll_enable)
> + encoder->pre_pll_enable(encoder);
>
> if (intel_crtc->config.has_pch_encoder) {
> /* Note: FDI PLL enabling _must_ be done before we enable the
> @@ -5682,10 +5672,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
> if (intel_crtc->config.has_dp_encoder)
> intel_dp_set_m_n(intel_crtc);
>
> - for_each_encoder_on_crtc(dev, crtc, encoder)
> - if (encoder->pre_pll_enable)
> - encoder->pre_pll_enable(encoder);
> -
> if (is_lvds && has_reduced_clock && i915_powersave)
> intel_crtc->lowfreq_avail = true;
> else
> @@ -5694,23 +5680,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
> if (intel_crtc->config.has_pch_encoder) {
> pll = intel_crtc_to_shared_dpll(intel_crtc);
>
> - I915_WRITE(PCH_DPLL(pll->id), dpll);
> -
> - /* Wait for the clocks to stabilize. */
> - POSTING_READ(PCH_DPLL(pll->id));
> - udelay(150);
> -
> - /* The pixel multiplier can only be updated once the
> - * DPLL is enabled and the clocks are stable.
> - *
> - * So write it again.
> - */
> - I915_WRITE(PCH_DPLL(pll->id), dpll);
> -
> - if (has_reduced_clock)
> - I915_WRITE(PCH_FP1(pll->id), fp2);
> - else
> - I915_WRITE(PCH_FP1(pll->id), fp);
> }
>
> intel_set_pipe_timings(intel_crtc);
> @@ -8735,19 +8704,32 @@ static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *dev_priv,
> return val & DPLL_VCO_ENABLE;
> }
>
> +static void ibx_pch_dpll_mode_set(struct drm_i915_private *dev_priv,
> + struct intel_shared_dpll *pll)
> +{
> + I915_WRITE(PCH_FP0(pll->id), pll->hw_state.fp0);
> + I915_WRITE(PCH_FP1(pll->id), pll->hw_state.fp1);
> +}
> +
> 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);
> + I915_WRITE(PCH_DPLL(pll->id), pll->hw_state.dpll);
> +
> + /* Wait for the clocks to stabilize. */
> + POSTING_READ(PCH_DPLL(pll->id));
> + udelay(150);
> +
> + /* The pixel multiplier can only be updated once the
> + * DPLL is enabled and the clocks are stable.
> + *
> + * So write it again.
> + */
> + I915_WRITE(PCH_DPLL(pll->id), pll->hw_state.dpll);
> + POSTING_READ(PCH_DPLL(pll->id));
> udelay(200);
> }
>
> @@ -8756,7 +8738,6 @@ static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv,
> {
> 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) {
> @@ -8764,11 +8745,8 @@ static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv,
> 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);
> + I915_WRITE(PCH_DPLL(pll->id), 0);
> + POSTING_READ(PCH_DPLL(pll->id));
> udelay(200);
> }
>
> @@ -8787,6 +8765,7 @@ 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].mode_set = ibx_pch_dpll_mode_set;
> dev_priv->shared_dplls[i].enable = ibx_pch_dpll_enable;
> dev_priv->shared_dplls[i].disable = ibx_pch_dpll_disable;
> dev_priv->shared_dplls[i].get_hw_state =
> --
> 1.7.11.7
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
More information about the Intel-gfx
mailing list