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.vet...@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.lesp...@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@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to