[Intel-gfx] [PATCH 37/40] drm/i915: Fix eDP link training when switching pipes

Daniel Vetter daniel at ffwll.ch
Tue Jul 29 20:06:57 CEST 2014


On Mon, Jun 30, 2014 at 02:52:12PM -0700, Jesse Barnes wrote:
> On Sat, 28 Jun 2014 02:04:28 +0300
> ville.syrjala at linux.intel.com wrote:
> 
> > From: Ville Syrjälä <ville.syrjala at linux.intel.com>
> > 
> > When switching from one pipe to another, the power sequencer of the new
> > pipe seems to need a bit of kicking to lock into the port. Even the vdd
> > force bit doesn't work before the power sequencer has been sufficiently
> > kicked, so this must be done even before any AUX transactions.
> > 
> > This sequence has been found to do the trick:
> > 1) enable port with idle pattern
> > 2) enable the power sequencer
> > 3) proceed with link training
> > 
> > Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_dp.c | 34 ++++++++++++++++++++++++++++++++--
> >  1 file changed, 32 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> > index 65ab54c..07b0320 100644
> > --- a/drivers/gpu/drm/i915/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > @@ -2010,6 +2010,37 @@ static void chv_post_disable_dp(struct intel_encoder *encoder)
> >  	mutex_unlock(&dev_priv->dpio_lock);
> >  }
> >  
> > +static void intel_edp_init_train(struct intel_dp *intel_dp)
> > +{
> > +	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
> > +	struct drm_device *dev = intel_dig_port->base.base.dev;
> > +	struct drm_i915_private *dev_priv = dev->dev_private;
> > +
> > +	if (!is_edp(intel_dp))
> > +		return;

This changes the order of events as observed by the sink, so I really
wonder why this is edp specific?

We do have bug reports about external DP monitors not waking up from the
sink_dpms call properly ...
-Daniel

> > +
> > +	/*
> > +	 * Need to enable the port with idle pattern to allow the power
> > +	 * sequencer to lock into the port. Otherwise the power sequencer
> > +	 * (including vdd force bit!) doesn't work on this port.
> > +	 */
> > +	if (IS_VALLEYVIEW(dev)) {
> > +		intel_dp->DP |= DP_PORT_EN;
> > +
> > +		if (IS_CHERRYVIEW(dev))
> > +			intel_dp->DP &= ~DP_LINK_TRAIN_MASK_CHV;
> > +		else
> > +			intel_dp->DP &= ~DP_LINK_TRAIN_MASK;
> > +		intel_dp->DP |= DP_LINK_TRAIN_PAT_IDLE;
> > +
> > +		I915_WRITE(intel_dp->output_reg, intel_dp->DP);
> > +		POSTING_READ(intel_dp->output_reg);
> > +	}
> > +
> > +	intel_edp_panel_on(intel_dp);
> > +	edp_panel_vdd_off(intel_dp, true);
> > +}
> > +
> >  static void intel_enable_dp(struct intel_encoder *encoder)
> >  {
> >  	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
> > @@ -2021,10 +2052,9 @@ static void intel_enable_dp(struct intel_encoder *encoder)
> >  		return;
> >  
> >  	intel_edp_panel_vdd_on(intel_dp);
> > +	intel_edp_init_train(intel_dp);
> >  	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
> >  	intel_dp_start_link_train(intel_dp);
> > -	intel_edp_panel_on(intel_dp);
> > -	edp_panel_vdd_off(intel_dp, true);
> >  	intel_dp_complete_link_train(intel_dp);
> >  	intel_dp_stop_link_train(intel_dp);
> >  }
> 
> Yeah I think this matches the doc too.  I never pushed this change
> because I could never find anything that it actually fixed.
> 
> I guess you have something now though!
> 
> Reviewed-by: Jesse Barnes <jbarnes at virtuousgeek.org>
> 
> -- 
> Jesse Barnes, Intel Open Source Technology Center
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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



More information about the Intel-gfx mailing list