[Intel-gfx] [PATCH 3/5] drm/i915: robustify edp_pll_on/off

Daniel Vetter daniel at ffwll.ch
Thu Sep 13 21:22:48 CEST 2012


On Thu, Sep 13, 2012 at 02:46:19PM -0300, Paulo Zanoni wrote:
> Hi
> 
> 2012/9/6 Daniel Vetter <daniel.vetter at ffwll.ch>:
> > With the previous patch to clean up where exactly these two functions
> > are getting called, this patch can tackle the enable/disable code
> > itself:
> 
> This is the kind of patch that's hard to proof-read. Basically, IMHO,
> the intel_dp->DP variable makes things harder to understand and
> review. Sometimes we use intel_dp->DP directly, sometimes we do "int
> DP = intel_dp->DP" and then just change the temporary DP (sometimes
> not updating the original intel_dp->DP after changing the temporary
> DP), sometimes we read/write directly from intel_dp->output_reg,
> sometimes we pass "int DP" as a function argument instead of storing
> the value inside intel_dp->DP. I have to admit that even after working
> some time with this code I'm not exactly sure why intel_dp->DP is
> really necessary. One of my plans was to try to write a patch that
> removes the variable so I could at least maybe understand why it's
> necessary (the plan was to read/write from/to intel_dp->output_reg
> directly). You can do that if you want :)
> 
> Complaints aside, here are my comments:
> 
> >
> > - WARN if the port enable bit is in the wrong state or if the edp pll
> >   bit is in the wrong state, just for paranoia's sake.
> 
> Looks good.
> 
> > - Don't disable the edp pll harder in the modeset functions just for
> >   fun.
> 
> Which part of the patch is this message about? Did you mean
> intel_dp_link_down instead of modeset? I could not find anything on
> our documentation saying that the PLL must be disabled when retraining
> the link, so your patch looks correct, but this is the kind of thing
> that we should really try to test somehow :)

See below.
> 
> > - Don't set the edp pll enable flag in intel_dp->DP in modeset, do
> >   that while changing the actual hw state. We do the same with the
> >   actual port enable bit, so this is a bit more consistent.
> 
> Looks good.
> 
> > - Track the current DP register value when setting things up and add
> >   some comments how intel_dp->DP is used in the disable code.
> >
> > v2: Be more careful with resetting intel_dp->DP - otherwise dpms
> > off->on will fail spectacularly, becuase we enable the eDP port when
> > we should only enable the eDP pll.
> >
> 
> These 2 chunks are the ones my comment above is about. I'll just trust
> our beloved maintainer on these chunks :)

Yeah, intel_dp->DP is hard to follow, and I have some more patches. After
all this has settled the rule is:
- intel_dp->DP is computed freshly in intel_dp_mode_set
- intel_dp->DP is update with the link training values in start_link_train
  so that complete_link_train writes the right registers. Same applies to
  edp_pll_on for similar reasons
- All the disable functions don't frob intel_dp->DP so that we can
  re-enable after dpms off without going through ->mode_set

So yeah, a bit a mess, but should work.
-Daniel

> Reviewed-by: Paulo Zanoni <paulo.r.zanoni at intel.com>
> 
> > Signed-Off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
> 
> 
> > ---
> >  drivers/gpu/drm/i915/intel_dp.c | 29 ++++++++++++++++++-----------
> >  1 file changed, 18 insertions(+), 11 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> > index c72d4f3..7c746d1 100644
> > --- a/drivers/gpu/drm/i915/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > @@ -887,7 +887,6 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
> >                 intel_dp->DP |= intel_crtc->pipe << 29;
> >
> >                 /* don't miss out required setting for eDP */
> > -               intel_dp->DP |= DP_PLL_ENABLE;
> >                 if (adjusted_mode->clock < 200000)
> >                         intel_dp->DP |= DP_PLL_FREQ_160MHZ;
> >                 else
> > @@ -909,7 +908,6 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
> >
> >                 if (is_cpu_edp(intel_dp)) {
> >                         /* don't miss out required setting for eDP */
> > -                       intel_dp->DP |= DP_PLL_ENABLE;
> >                         if (adjusted_mode->clock < 200000)
> >                                 intel_dp->DP |= DP_PLL_FREQ_160MHZ;
> >                         else
> > @@ -1192,8 +1190,15 @@ static void ironlake_edp_pll_on(struct intel_dp *intel_dp)
> >
> >         DRM_DEBUG_KMS("\n");
> >         dpa_ctl = I915_READ(DP_A);
> > -       dpa_ctl |= DP_PLL_ENABLE;
> > -       I915_WRITE(DP_A, dpa_ctl);
> > +       WARN(dpa_ctl & DP_PLL_ENABLE, "dp pll on, should be off\n");
> > +       WARN(dpa_ctl & DP_PORT_EN, "dp port still on, should be off\n");
> > +
> > +       /* We don't adjust intel_dp->DP while tearing down the link, to
> > +        * facilitate link retraining (e.g. after hotplug). Hence clear all
> > +        * enable bits here to ensure that we don't enable too much. */
> > +       intel_dp->DP &= ~(DP_PORT_EN | DP_AUDIO_OUTPUT_ENABLE);
> > +       intel_dp->DP |= DP_PLL_ENABLE;
> > +       I915_WRITE(DP_A, intel_dp->DP);
> >         POSTING_READ(DP_A);
> >         udelay(200);
> >  }
> > @@ -1209,6 +1214,13 @@ static void ironlake_edp_pll_off(struct intel_dp *intel_dp)
> >                              to_intel_crtc(crtc)->pipe);
> >
> >         dpa_ctl = I915_READ(DP_A);
> > +       WARN((dpa_ctl & DP_PLL_ENABLE) == 0,
> > +            "dp pll off, should be on\n");
> > +       WARN(dpa_ctl & DP_PORT_EN, "dp port still on, should be off\n");
> > +
> > +       /* We can't rely on the value tracked for the DP register in
> > +        * intel_dp->DP because link_down must not change that (otherwise link
> > +        * re-training will fail. */
> >         dpa_ctl &= ~DP_PLL_ENABLE;
> >         I915_WRITE(DP_A, dpa_ctl);
> >         POSTING_READ(DP_A);
> > @@ -1906,13 +1918,6 @@ intel_dp_link_down(struct intel_dp *intel_dp)
> >
> >         DRM_DEBUG_KMS("\n");
> >
> > -       if (is_edp(intel_dp)) {
> > -               DP &= ~DP_PLL_ENABLE;
> > -               I915_WRITE(intel_dp->output_reg, DP);
> > -               POSTING_READ(intel_dp->output_reg);
> > -               udelay(100);
> > -       }
> > -

This junk here is the "disable cpu edp pll harder" part.

> >         if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp))) {
> >                 DP &= ~DP_LINK_TRAIN_MASK_CPT;
> >                 I915_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE_CPT);
> > @@ -2456,6 +2461,8 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
> >
> >         intel_dp->output_reg = output_reg;
> >         intel_dp->port = port;
> > +       /* Preserve the current hw state. */
> > +       intel_dp->DP = I915_READ(intel_dp->output_reg);
> >
> >         intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
> >         if (!intel_connector) {
> > --
> > 1.7.11.2
> >
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx at lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> 
> 
> -- 
> Paulo Zanoni

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch



More information about the Intel-gfx mailing list