diff mbox

[v7] drm/i915/edp: Be less aggressive about changing link config on eDP

Message ID 1503419686-9558-1-git-send-email-jim.bride@linux.intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

jim.bride@linux.intel.com Aug. 22, 2017, 4:34 p.m. UTC
This set of changes has some history to them.  There were several attempts
to add what was called "fast link training" to i915, which actually wasn't
fast link training as per the DP spec.  These changes were:

commit 5fa836a9d859 ("drm/i915: DP link training optimization")
commit 4e96c97742f4 ("drm/i915: eDP link training optimization")

which were eventually hand-reverted by:

commit 34511dce4b35 ("drm/i915: Revert DisplayPort fast link training
                     feature")

in kernel 4.7-rc4.  The eDP pieces of the above revert, however, had some
very bad side-effects on PSR functionality on Skylake. The issue at
hand is that when PSR exits i915 briefly emits TP1 followed by TP2/3
(depending on the original link configuration) in order to quickly get
the source and sink back in synchronization across the link before handing
control back to the i915.  There's an assumption that none of the link
configuration information has changed (and thus it's still valid) since the
last full link training operation.  The revert above was identified via a
bisect as the cause of some of Skylake's PSR woes.  This patch, largely
based on commit 4e96c97742f4 ("drm/i915: eDP link training optimization")
puts the eDP portions of this patch back in place.  None of the flickering
issues that spurred the revert have been seen, and I suspect the real
culprits here were addressed by some of the recent link training changes
that Manasi has implemented, and PSR on Skylake is definitely more happy
with these changes in-place.

v2 and v3: Rebase
v4: * Clean up accesses to train_set_valid a bit for easier
      reading. (Chris)
    * Rebase
v5: * Checkpatch cleanup
    * Rebase
v6: * is_edp() => intel_dp_is_edp()
    * rebase
v7: * Remove extraneous is_edp() prototype (Rodrigo)

Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Cc: Manasi D Navare <manasi.d.navare@intel.com>
Cc: Mika Kahola <mika.kahola@intel.com>
Cc: Jani Nikula <jani.nikula@intel.com>
Fixes: 34511dce4 ("drm/i915: Revert DisplayPort fast link training feature")
Signed-off-by: Jim Bride <jim.bride@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c               |  2 ++
 drivers/gpu/drm/i915/intel_dp_link_training.c | 15 ++++++++++++++-
 drivers/gpu/drm/i915/intel_drv.h              |  1 +
 3 files changed, 17 insertions(+), 1 deletion(-)

Comments

Rodrigo Vivi Sept. 19, 2017, 7:55 p.m. UTC | #1
On Fri, Sep 15, 2017 at 06:19:12PM +0000, Manasi Navare wrote:
> The patch looks good for eDP link training optimizations.
> 
> Reviewed-by: Manasi Navare <manasi.d.navare@intel.com>

I haven't merged this patch yet because I'd like an Ack from Jani.

Also I'd like to hear from Mika if he believes it is safe or not.

On his revert commit he wrote:
"It has been found out that in some HW combination the DisplayPort
 fast link training feature caused screen flickering. Let's revert
 this feature for now until we can ensure that the feature works for
 all platforms."

I don't want to merge this patch to fix a feature that is disabled
by default with the risk of bringing flickerings back.

But even if we decide to go ahead and merge I believe we need to
resend the test and collect a full round of CI that now runs
all IGT tests.

Thanks,
Rodrigo.


> 
> Manasi
> 
> On Tue, Aug 22, 2017 at 09:34:46AM -0700, Jim Bride wrote:
> > This set of changes has some history to them.  There were several attempts
> > to add what was called "fast link training" to i915, which actually wasn't
> > fast link training as per the DP spec.  These changes were:
> > 
> > commit 5fa836a9d859 ("drm/i915: DP link training optimization")
> > commit 4e96c97742f4 ("drm/i915: eDP link training optimization")
> > 
> > which were eventually hand-reverted by:
> > 
> > commit 34511dce4b35 ("drm/i915: Revert DisplayPort fast link training
> >                      feature")
> > 
> > in kernel 4.7-rc4.  The eDP pieces of the above revert, however, had some
> > very bad side-effects on PSR functionality on Skylake. The issue at
> > hand is that when PSR exits i915 briefly emits TP1 followed by TP2/3
> > (depending on the original link configuration) in order to quickly get
> > the source and sink back in synchronization across the link before handing
> > control back to the i915.  There's an assumption that none of the link
> > configuration information has changed (and thus it's still valid) since the
> > last full link training operation.  The revert above was identified via a
> > bisect as the cause of some of Skylake's PSR woes.  This patch, largely
> > based on commit 4e96c97742f4 ("drm/i915: eDP link training optimization")
> > puts the eDP portions of this patch back in place.  None of the flickering
> > issues that spurred the revert have been seen, and I suspect the real
> > culprits here were addressed by some of the recent link training changes
> > that Manasi has implemented, and PSR on Skylake is definitely more happy
> > with these changes in-place.
> > 
> > v2 and v3: Rebase
> > v4: * Clean up accesses to train_set_valid a bit for easier
> >       reading. (Chris)
> >     * Rebase
> > v5: * Checkpatch cleanup
> >     * Rebase
> > v6: * is_edp() => intel_dp_is_edp()
> >     * rebase
> > v7: * Remove extraneous is_edp() prototype (Rodrigo)
> > 
> > Cc: Chris Wilson <chris@chris-wilson.co.uk>
> > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
> > Cc: Manasi D Navare <manasi.d.navare@intel.com>
> > Cc: Mika Kahola <mika.kahola@intel.com>
> > Cc: Jani Nikula <jani.nikula@intel.com>
> > Fixes: 34511dce4 ("drm/i915: Revert DisplayPort fast link training feature")
> > Signed-off-by: Jim Bride <jim.bride@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_dp.c               |  2 ++
> >  drivers/gpu/drm/i915/intel_dp_link_training.c | 15 ++++++++++++++-
> >  drivers/gpu/drm/i915/intel_drv.h              |  1 +
> >  3 files changed, 17 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> > index e385658..38bc7e0 100644
> > --- a/drivers/gpu/drm/i915/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > @@ -4750,6 +4750,7 @@ intel_dp_long_pulse(struct intel_connector *intel_connector)
> >  		intel_dp->max_link_rate = intel_dp_max_common_rate(intel_dp);
> >  
> >  		intel_dp->reset_link_params = false;
> > +		intel_dp->train_set_valid = false;
> >  	}
> >  
> >  	intel_dp_print_rates(intel_dp);
> > @@ -6019,6 +6020,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
> >  	intel_dp_set_source_rates(intel_dp);
> >  
> >  	intel_dp->reset_link_params = true;
> > +	intel_dp->train_set_valid = false;
> >  	intel_dp->pps_pipe = INVALID_PIPE;
> >  	intel_dp->active_pipe = INVALID_PIPE;
> >  
> > diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c
> > index 05907fa..79fe369 100644
> > --- a/drivers/gpu/drm/i915/intel_dp_link_training.c
> > +++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
> > @@ -94,7 +94,8 @@ static bool
> >  intel_dp_reset_link_train(struct intel_dp *intel_dp,
> >  			uint8_t dp_train_pat)
> >  {
> > -	memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set));
> > +	if (!intel_dp->train_set_valid)
> > +		memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set));
> >  	intel_dp_set_signal_levels(intel_dp);
> >  	return intel_dp_set_link_train(intel_dp, dp_train_pat);
> >  }
> > @@ -162,9 +163,18 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
> >  				       DP_TRAINING_PATTERN_1 |
> >  				       DP_LINK_SCRAMBLING_DISABLE)) {
> >  		DRM_ERROR("failed to enable link training\n");
> > +		intel_dp->train_set_valid = false;
> >  		return false;
> >  	}
> >  
> > +	/*
> > +	 * The initial set of link parameters are set by this point, so go
> > +	 * ahead and set intel_dp->train_set_valid to false in case any of
> > +	 * the succeeding steps fail.  It will be set back to true if we were
> > +	 * able to achieve clock recovery in the specified configuration.
> > +	 */
> > +	intel_dp->train_set_valid = false;
> > +
> >  	voltage_tries = 1;
> >  	max_vswing_tries = 0;
> >  	for (;;) {
> > @@ -179,6 +189,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
> >  
> >  		if (drm_dp_clock_recovery_ok(link_status, intel_dp->lane_count)) {
> >  			DRM_DEBUG_KMS("clock recovery OK\n");
> > +			intel_dp->train_set_valid = intel_dp_is_edp(intel_dp);
> >  			return true;
> >  		}
> >  
> > @@ -256,6 +267,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
> >  				     training_pattern |
> >  				     DP_LINK_SCRAMBLING_DISABLE)) {
> >  		DRM_ERROR("failed to start channel equalization\n");
> > +		intel_dp->train_set_valid = false;
> >  		return false;
> >  	}
> >  
> > @@ -296,6 +308,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
> >  	/* Try 5 times, else fail and try at lower BW */
> >  	if (tries == 5) {
> >  		intel_dp_dump_link_status(link_status);
> > +		intel_dp->train_set_valid = false;
> >  		DRM_DEBUG_KMS("Channel equalization failed 5 times\n");
> >  	}
> >  
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > index 2940d39..f4354ec 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -995,6 +995,7 @@ struct intel_dp {
> >  	struct drm_dp_aux aux;
> >  	enum intel_display_power_domain aux_power_domain;
> >  	uint8_t train_set[4];
> > +	bool train_set_valid;
> >  	int panel_power_up_delay;
> >  	int panel_power_down_delay;
> >  	int panel_power_cycle_delay;
> > -- 
> > 2.7.4
> > 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
jim.bride@linux.intel.com Sept. 19, 2017, 9:20 p.m. UTC | #2
On Tue, Sep 19, 2017 at 12:55:24PM -0700, Rodrigo Vivi wrote:
> On Fri, Sep 15, 2017 at 06:19:12PM +0000, Manasi Navare wrote:
> > The patch looks good for eDP link training optimizations.
> > 
> > Reviewed-by: Manasi Navare <manasi.d.navare@intel.com>
> 
> I haven't merged this patch yet because I'd like an Ack from Jani.
> 
> Also I'd like to hear from Mika if he believes it is safe or not.

Mika looked at it a few months ago and thought it would be ok.  It
can't hurt to have him look at it again, though.

> On his revert commit he wrote:
> "It has been found out that in some HW combination the DisplayPort
>  fast link training feature caused screen flickering. Let's revert
>  this feature for now until we can ensure that the feature works for
>  all platforms."
> 
> I don't want to merge this patch to fix a feature that is disabled
> by default with the risk of bringing flickerings back.
> 
> But even if we decide to go ahead and merge I believe we need to
> resend the test and collect a full round of CI that now runs
> all IGT tests.

I assume you mean resend the patch here.  I'll do that.

Jim

> Thanks,
> Rodrigo.
> 
> 
> > 
> > Manasi
> > 
> > On Tue, Aug 22, 2017 at 09:34:46AM -0700, Jim Bride wrote:
> > > This set of changes has some history to them.  There were several attempts
> > > to add what was called "fast link training" to i915, which actually wasn't
> > > fast link training as per the DP spec.  These changes were:
> > > 
> > > commit 5fa836a9d859 ("drm/i915: DP link training optimization")
> > > commit 4e96c97742f4 ("drm/i915: eDP link training optimization")
> > > 
> > > which were eventually hand-reverted by:
> > > 
> > > commit 34511dce4b35 ("drm/i915: Revert DisplayPort fast link training
> > >                      feature")
> > > 
> > > in kernel 4.7-rc4.  The eDP pieces of the above revert, however, had some
> > > very bad side-effects on PSR functionality on Skylake. The issue at
> > > hand is that when PSR exits i915 briefly emits TP1 followed by TP2/3
> > > (depending on the original link configuration) in order to quickly get
> > > the source and sink back in synchronization across the link before handing
> > > control back to the i915.  There's an assumption that none of the link
> > > configuration information has changed (and thus it's still valid) since the
> > > last full link training operation.  The revert above was identified via a
> > > bisect as the cause of some of Skylake's PSR woes.  This patch, largely
> > > based on commit 4e96c97742f4 ("drm/i915: eDP link training optimization")
> > > puts the eDP portions of this patch back in place.  None of the flickering
> > > issues that spurred the revert have been seen, and I suspect the real
> > > culprits here were addressed by some of the recent link training changes
> > > that Manasi has implemented, and PSR on Skylake is definitely more happy
> > > with these changes in-place.
> > > 
> > > v2 and v3: Rebase
> > > v4: * Clean up accesses to train_set_valid a bit for easier
> > >       reading. (Chris)
> > >     * Rebase
> > > v5: * Checkpatch cleanup
> > >     * Rebase
> > > v6: * is_edp() => intel_dp_is_edp()
> > >     * rebase
> > > v7: * Remove extraneous is_edp() prototype (Rodrigo)
> > > 
> > > Cc: Chris Wilson <chris@chris-wilson.co.uk>
> > > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
> > > Cc: Manasi D Navare <manasi.d.navare@intel.com>
> > > Cc: Mika Kahola <mika.kahola@intel.com>
> > > Cc: Jani Nikula <jani.nikula@intel.com>
> > > Fixes: 34511dce4 ("drm/i915: Revert DisplayPort fast link training feature")
> > > Signed-off-by: Jim Bride <jim.bride@linux.intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/intel_dp.c               |  2 ++
> > >  drivers/gpu/drm/i915/intel_dp_link_training.c | 15 ++++++++++++++-
> > >  drivers/gpu/drm/i915/intel_drv.h              |  1 +
> > >  3 files changed, 17 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> > > index e385658..38bc7e0 100644
> > > --- a/drivers/gpu/drm/i915/intel_dp.c
> > > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > > @@ -4750,6 +4750,7 @@ intel_dp_long_pulse(struct intel_connector *intel_connector)
> > >  		intel_dp->max_link_rate = intel_dp_max_common_rate(intel_dp);
> > >  
> > >  		intel_dp->reset_link_params = false;
> > > +		intel_dp->train_set_valid = false;
> > >  	}
> > >  
> > >  	intel_dp_print_rates(intel_dp);
> > > @@ -6019,6 +6020,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
> > >  	intel_dp_set_source_rates(intel_dp);
> > >  
> > >  	intel_dp->reset_link_params = true;
> > > +	intel_dp->train_set_valid = false;
> > >  	intel_dp->pps_pipe = INVALID_PIPE;
> > >  	intel_dp->active_pipe = INVALID_PIPE;
> > >  
> > > diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c
> > > index 05907fa..79fe369 100644
> > > --- a/drivers/gpu/drm/i915/intel_dp_link_training.c
> > > +++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
> > > @@ -94,7 +94,8 @@ static bool
> > >  intel_dp_reset_link_train(struct intel_dp *intel_dp,
> > >  			uint8_t dp_train_pat)
> > >  {
> > > -	memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set));
> > > +	if (!intel_dp->train_set_valid)
> > > +		memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set));
> > >  	intel_dp_set_signal_levels(intel_dp);
> > >  	return intel_dp_set_link_train(intel_dp, dp_train_pat);
> > >  }
> > > @@ -162,9 +163,18 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
> > >  				       DP_TRAINING_PATTERN_1 |
> > >  				       DP_LINK_SCRAMBLING_DISABLE)) {
> > >  		DRM_ERROR("failed to enable link training\n");
> > > +		intel_dp->train_set_valid = false;
> > >  		return false;
> > >  	}
> > >  
> > > +	/*
> > > +	 * The initial set of link parameters are set by this point, so go
> > > +	 * ahead and set intel_dp->train_set_valid to false in case any of
> > > +	 * the succeeding steps fail.  It will be set back to true if we were
> > > +	 * able to achieve clock recovery in the specified configuration.
> > > +	 */
> > > +	intel_dp->train_set_valid = false;
> > > +
> > >  	voltage_tries = 1;
> > >  	max_vswing_tries = 0;
> > >  	for (;;) {
> > > @@ -179,6 +189,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
> > >  
> > >  		if (drm_dp_clock_recovery_ok(link_status, intel_dp->lane_count)) {
> > >  			DRM_DEBUG_KMS("clock recovery OK\n");
> > > +			intel_dp->train_set_valid = intel_dp_is_edp(intel_dp);
> > >  			return true;
> > >  		}
> > >  
> > > @@ -256,6 +267,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
> > >  				     training_pattern |
> > >  				     DP_LINK_SCRAMBLING_DISABLE)) {
> > >  		DRM_ERROR("failed to start channel equalization\n");
> > > +		intel_dp->train_set_valid = false;
> > >  		return false;
> > >  	}
> > >  
> > > @@ -296,6 +308,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
> > >  	/* Try 5 times, else fail and try at lower BW */
> > >  	if (tries == 5) {
> > >  		intel_dp_dump_link_status(link_status);
> > > +		intel_dp->train_set_valid = false;
> > >  		DRM_DEBUG_KMS("Channel equalization failed 5 times\n");
> > >  	}
> > >  
> > > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > > index 2940d39..f4354ec 100644
> > > --- a/drivers/gpu/drm/i915/intel_drv.h
> > > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > > @@ -995,6 +995,7 @@ struct intel_dp {
> > >  	struct drm_dp_aux aux;
> > >  	enum intel_display_power_domain aux_power_domain;
> > >  	uint8_t train_set[4];
> > > +	bool train_set_valid;
> > >  	int panel_power_up_delay;
> > >  	int panel_power_down_delay;
> > >  	int panel_power_cycle_delay;
> > > -- 
> > > 2.7.4
> > > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Kahola, Mika Sept. 27, 2017, 12:23 p.m. UTC | #3
On Tue, 2017-09-19 at 12:55 -0700, Rodrigo Vivi wrote:
> On Fri, Sep 15, 2017 at 06:19:12PM +0000, Manasi Navare wrote:
> > 
> > The patch looks good for eDP link training optimizations.
> > 
> > Reviewed-by: Manasi Navare <manasi.d.navare@intel.com>
> I haven't merged this patch yet because I'd like an Ack from Jani.
> 
> Also I'd like to hear from Mika if he believes it is safe or not.
> 
> On his revert commit he wrote:
> "It has been found out that in some HW combination the DisplayPort
>  fast link training feature caused screen flickering. Let's revert
>  this feature for now until we can ensure that the feature works for
>  all platforms."
At the time of this revert there were quite a few bug reports of
flickering. The community felt that this "fast link training" was to
blame for flickering issues and therefore we decided to revert that.
However, it turned out later on that this revert didn't solve the
flickering issues. Flickering was gone once watermark work landed.

Therefore, I feel that this feature is safe to re-enable.

> 
> I don't want to merge this patch to fix a feature that is disabled
> by default with the risk of bringing flickerings back.
> 
> But even if we decide to go ahead and merge I believe we need to
> resend the test and collect a full round of CI that now runs
> all IGT tests.
> 
> Thanks,
> Rodrigo.
> 
> 
> > 
> > 
> > Manasi
> > 
> > On Tue, Aug 22, 2017 at 09:34:46AM -0700, Jim Bride wrote:
> > > 
> > > This set of changes has some history to them.  There were several
> > > attempts
> > > to add what was called "fast link training" to i915, which
> > > actually wasn't
> > > fast link training as per the DP spec.  These changes were:
> > > 
> > > commit 5fa836a9d859 ("drm/i915: DP link training optimization")
> > > commit 4e96c97742f4 ("drm/i915: eDP link training optimization")
> > > 
> > > which were eventually hand-reverted by:
> > > 
> > > commit 34511dce4b35 ("drm/i915: Revert DisplayPort fast link
> > > training
> > >                      feature")
> > > 
> > > in kernel 4.7-rc4.  The eDP pieces of the above revert, however,
> > > had some
> > > very bad side-effects on PSR functionality on Skylake. The issue
> > > at
> > > hand is that when PSR exits i915 briefly emits TP1 followed by
> > > TP2/3
> > > (depending on the original link configuration) in order to
> > > quickly get
> > > the source and sink back in synchronization across the link
> > > before handing
> > > control back to the i915.  There's an assumption that none of the
> > > link
> > > configuration information has changed (and thus it's still valid)
> > > since the
> > > last full link training operation.  The revert above was
> > > identified via a
> > > bisect as the cause of some of Skylake's PSR woes.  This patch,
> > > largely
> > > based on commit 4e96c97742f4 ("drm/i915: eDP link training
> > > optimization")
> > > puts the eDP portions of this patch back in place.  None of the
> > > flickering
> > > issues that spurred the revert have been seen, and I suspect the
> > > real
> > > culprits here were addressed by some of the recent link training
> > > changes
> > > that Manasi has implemented, and PSR on Skylake is definitely
> > > more happy
> > > with these changes in-place.
> > > 
> > > v2 and v3: Rebase
> > > v4: * Clean up accesses to train_set_valid a bit for easier
> > >       reading. (Chris)
> > >     * Rebase
> > > v5: * Checkpatch cleanup
> > >     * Rebase
> > > v6: * is_edp() => intel_dp_is_edp()
> > >     * rebase
> > > v7: * Remove extraneous is_edp() prototype (Rodrigo)
> > > 
> > > Cc: Chris Wilson <chris@chris-wilson.co.uk>
> > > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
> > > Cc: Manasi D Navare <manasi.d.navare@intel.com>
> > > Cc: Mika Kahola <mika.kahola@intel.com>
> > > Cc: Jani Nikula <jani.nikula@intel.com>
> > > Fixes: 34511dce4 ("drm/i915: Revert DisplayPort fast link
> > > training feature")
> > > Signed-off-by: Jim Bride <jim.bride@linux.intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/intel_dp.c               |  2 ++
> > >  drivers/gpu/drm/i915/intel_dp_link_training.c | 15
> > > ++++++++++++++-
> > >  drivers/gpu/drm/i915/intel_drv.h              |  1 +
> > >  3 files changed, 17 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/intel_dp.c
> > > b/drivers/gpu/drm/i915/intel_dp.c
> > > index e385658..38bc7e0 100644
> > > --- a/drivers/gpu/drm/i915/intel_dp.c
> > > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > > @@ -4750,6 +4750,7 @@ intel_dp_long_pulse(struct intel_connector
> > > *intel_connector)
> > >  		intel_dp->max_link_rate =
> > > intel_dp_max_common_rate(intel_dp);
> > >  
> > >  		intel_dp->reset_link_params = false;
> > > +		intel_dp->train_set_valid = false;
> > >  	}
> > >  
> > >  	intel_dp_print_rates(intel_dp);
> > > @@ -6019,6 +6020,7 @@ intel_dp_init_connector(struct
> > > intel_digital_port *intel_dig_port,
> > >  	intel_dp_set_source_rates(intel_dp);
> > >  
> > >  	intel_dp->reset_link_params = true;
> > > +	intel_dp->train_set_valid = false;
> > >  	intel_dp->pps_pipe = INVALID_PIPE;
> > >  	intel_dp->active_pipe = INVALID_PIPE;
> > >  
> > > diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c
> > > b/drivers/gpu/drm/i915/intel_dp_link_training.c
> > > index 05907fa..79fe369 100644
> > > --- a/drivers/gpu/drm/i915/intel_dp_link_training.c
> > > +++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
> > > @@ -94,7 +94,8 @@ static bool
> > >  intel_dp_reset_link_train(struct intel_dp *intel_dp,
> > >  			uint8_t dp_train_pat)
> > >  {
> > > -	memset(intel_dp->train_set, 0, sizeof(intel_dp-
> > > >train_set));
> > > +	if (!intel_dp->train_set_valid)
> > > +		memset(intel_dp->train_set, 0, sizeof(intel_dp-
> > > >train_set));
> > >  	intel_dp_set_signal_levels(intel_dp);
> > >  	return intel_dp_set_link_train(intel_dp, dp_train_pat);
> > >  }
> > > @@ -162,9 +163,18 @@ intel_dp_link_training_clock_recovery(struct
> > > intel_dp *intel_dp)
> > >  				       DP_TRAINING_PATTERN_1 |
> > >  				       DP_LINK_SCRAMBLING_DISABL
> > > E)) {
> > >  		DRM_ERROR("failed to enable link training\n");
> > > +		intel_dp->train_set_valid = false;
> > >  		return false;
> > >  	}
> > >  
> > > +	/*
> > > +	 * The initial set of link parameters are set by this
> > > point, so go
> > > +	 * ahead and set intel_dp->train_set_valid to false in
> > > case any of
> > > +	 * the succeeding steps fail.  It will be set back to
> > > true if we were
> > > +	 * able to achieve clock recovery in the specified
> > > configuration.
> > > +	 */
> > > +	intel_dp->train_set_valid = false;
> > > +
> > >  	voltage_tries = 1;
> > >  	max_vswing_tries = 0;
> > >  	for (;;) {
> > > @@ -179,6 +189,7 @@ intel_dp_link_training_clock_recovery(struct
> > > intel_dp *intel_dp)
> > >  
> > >  		if (drm_dp_clock_recovery_ok(link_status,
> > > intel_dp->lane_count)) {
> > >  			DRM_DEBUG_KMS("clock recovery OK\n");
> > > +			intel_dp->train_set_valid =
> > > intel_dp_is_edp(intel_dp);
> > >  			return true;
> > >  		}
> > >  
> > > @@ -256,6 +267,7 @@
> > > intel_dp_link_training_channel_equalization(struct intel_dp
> > > *intel_dp)
> > >  				     training_pattern |
> > >  				     DP_LINK_SCRAMBLING_DISABLE)
> > > ) {
> > >  		DRM_ERROR("failed to start channel
> > > equalization\n");
> > > +		intel_dp->train_set_valid = false;
> > >  		return false;
> > >  	}
> > >  
> > > @@ -296,6 +308,7 @@
> > > intel_dp_link_training_channel_equalization(struct intel_dp
> > > *intel_dp)
> > >  	/* Try 5 times, else fail and try at lower BW */
> > >  	if (tries == 5) {
> > >  		intel_dp_dump_link_status(link_status);
> > > +		intel_dp->train_set_valid = false;
> > >  		DRM_DEBUG_KMS("Channel equalization failed 5
> > > times\n");
> > >  	}
> > >  
> > > diff --git a/drivers/gpu/drm/i915/intel_drv.h
> > > b/drivers/gpu/drm/i915/intel_drv.h
> > > index 2940d39..f4354ec 100644
> > > --- a/drivers/gpu/drm/i915/intel_drv.h
> > > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > > @@ -995,6 +995,7 @@ struct intel_dp {
> > >  	struct drm_dp_aux aux;
> > >  	enum intel_display_power_domain aux_power_domain;
> > >  	uint8_t train_set[4];
> > > +	bool train_set_valid;
> > >  	int panel_power_up_delay;
> > >  	int panel_power_down_delay;
> > >  	int panel_power_cycle_delay;
Rodrigo Vivi Sept. 28, 2017, 12:25 a.m. UTC | #4
On Wed, Sep 27, 2017 at 12:23:32PM +0000, Mika Kahola wrote:
> On Tue, 2017-09-19 at 12:55 -0700, Rodrigo Vivi wrote:
> > On Fri, Sep 15, 2017 at 06:19:12PM +0000, Manasi Navare wrote:
> > > 
> > > The patch looks good for eDP link training optimizations.
> > > 
> > > Reviewed-by: Manasi Navare <manasi.d.navare@intel.com>
> > I haven't merged this patch yet because I'd like an Ack from Jani.
> > 
> > Also I'd like to hear from Mika if he believes it is safe or not.
> > 
> > On his revert commit he wrote:
> > "It has been found out that in some HW combination the DisplayPort
> >  fast link training feature caused screen flickering. Let's revert
> >  this feature for now until we can ensure that the feature works for
> >  all platforms."
> At the time of this revert there were quite a few bug reports of
> flickering. The community felt that this "fast link training" was to
> blame for flickering issues and therefore we decided to revert that.
> However, it turned out later on that this revert didn't solve the
> flickering issues. Flickering was gone once watermark work landed.

I know this feeling... like PSR blamed for VGA flickers hehe

> 
> Therefore, I feel that this feature is safe to re-enable.

Jani, Ack?

> 
> > 
> > I don't want to merge this patch to fix a feature that is disabled
> > by default with the risk of bringing flickerings back.
> > 
> > But even if we decide to go ahead and merge I believe we need to
> > resend the test and collect a full round of CI that now runs
> > all IGT tests.
> > 
> > Thanks,
> > Rodrigo.
> > 
> > 
> > > 
> > > 
> > > Manasi
> > > 
> > > On Tue, Aug 22, 2017 at 09:34:46AM -0700, Jim Bride wrote:
> > > > 
> > > > This set of changes has some history to them.  There were several
> > > > attempts
> > > > to add what was called "fast link training" to i915, which
> > > > actually wasn't
> > > > fast link training as per the DP spec.  These changes were:
> > > > 
> > > > commit 5fa836a9d859 ("drm/i915: DP link training optimization")
> > > > commit 4e96c97742f4 ("drm/i915: eDP link training optimization")
> > > > 
> > > > which were eventually hand-reverted by:
> > > > 
> > > > commit 34511dce4b35 ("drm/i915: Revert DisplayPort fast link
> > > > training
> > > >                      feature")
> > > > 
> > > > in kernel 4.7-rc4.  The eDP pieces of the above revert, however,
> > > > had some
> > > > very bad side-effects on PSR functionality on Skylake. The issue
> > > > at
> > > > hand is that when PSR exits i915 briefly emits TP1 followed by
> > > > TP2/3
> > > > (depending on the original link configuration) in order to
> > > > quickly get
> > > > the source and sink back in synchronization across the link
> > > > before handing
> > > > control back to the i915.  There's an assumption that none of the
> > > > link
> > > > configuration information has changed (and thus it's still valid)
> > > > since the
> > > > last full link training operation.  The revert above was
> > > > identified via a
> > > > bisect as the cause of some of Skylake's PSR woes.  This patch,
> > > > largely
> > > > based on commit 4e96c97742f4 ("drm/i915: eDP link training
> > > > optimization")
> > > > puts the eDP portions of this patch back in place.  None of the
> > > > flickering
> > > > issues that spurred the revert have been seen, and I suspect the
> > > > real
> > > > culprits here were addressed by some of the recent link training
> > > > changes
> > > > that Manasi has implemented, and PSR on Skylake is definitely
> > > > more happy
> > > > with these changes in-place.
> > > > 
> > > > v2 and v3: Rebase
> > > > v4: * Clean up accesses to train_set_valid a bit for easier
> > > >       reading. (Chris)
> > > >     * Rebase
> > > > v5: * Checkpatch cleanup
> > > >     * Rebase
> > > > v6: * is_edp() => intel_dp_is_edp()
> > > >     * rebase
> > > > v7: * Remove extraneous is_edp() prototype (Rodrigo)
> > > > 
> > > > Cc: Chris Wilson <chris@chris-wilson.co.uk>
> > > > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > > Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
> > > > Cc: Manasi D Navare <manasi.d.navare@intel.com>
> > > > Cc: Mika Kahola <mika.kahola@intel.com>
> > > > Cc: Jani Nikula <jani.nikula@intel.com>
> > > > Fixes: 34511dce4 ("drm/i915: Revert DisplayPort fast link
> > > > training feature")
> > > > Signed-off-by: Jim Bride <jim.bride@linux.intel.com>
> > > > ---
> > > >  drivers/gpu/drm/i915/intel_dp.c               |  2 ++
> > > >  drivers/gpu/drm/i915/intel_dp_link_training.c | 15
> > > > ++++++++++++++-
> > > >  drivers/gpu/drm/i915/intel_drv.h              |  1 +
> > > >  3 files changed, 17 insertions(+), 1 deletion(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/intel_dp.c
> > > > b/drivers/gpu/drm/i915/intel_dp.c
> > > > index e385658..38bc7e0 100644
> > > > --- a/drivers/gpu/drm/i915/intel_dp.c
> > > > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > > > @@ -4750,6 +4750,7 @@ intel_dp_long_pulse(struct intel_connector
> > > > *intel_connector)
> > > >  		intel_dp->max_link_rate =
> > > > intel_dp_max_common_rate(intel_dp);
> > > >  
> > > >  		intel_dp->reset_link_params = false;
> > > > +		intel_dp->train_set_valid = false;
> > > >  	}
> > > >  
> > > >  	intel_dp_print_rates(intel_dp);
> > > > @@ -6019,6 +6020,7 @@ intel_dp_init_connector(struct
> > > > intel_digital_port *intel_dig_port,
> > > >  	intel_dp_set_source_rates(intel_dp);
> > > >  
> > > >  	intel_dp->reset_link_params = true;
> > > > +	intel_dp->train_set_valid = false;
> > > >  	intel_dp->pps_pipe = INVALID_PIPE;
> > > >  	intel_dp->active_pipe = INVALID_PIPE;
> > > >  
> > > > diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c
> > > > b/drivers/gpu/drm/i915/intel_dp_link_training.c
> > > > index 05907fa..79fe369 100644
> > > > --- a/drivers/gpu/drm/i915/intel_dp_link_training.c
> > > > +++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
> > > > @@ -94,7 +94,8 @@ static bool
> > > >  intel_dp_reset_link_train(struct intel_dp *intel_dp,
> > > >  			uint8_t dp_train_pat)
> > > >  {
> > > > -	memset(intel_dp->train_set, 0, sizeof(intel_dp-
> > > > >train_set));
> > > > +	if (!intel_dp->train_set_valid)
> > > > +		memset(intel_dp->train_set, 0, sizeof(intel_dp-
> > > > >train_set));
> > > >  	intel_dp_set_signal_levels(intel_dp);
> > > >  	return intel_dp_set_link_train(intel_dp, dp_train_pat);
> > > >  }
> > > > @@ -162,9 +163,18 @@ intel_dp_link_training_clock_recovery(struct
> > > > intel_dp *intel_dp)
> > > >  				       DP_TRAINING_PATTERN_1 |
> > > >  				       DP_LINK_SCRAMBLING_DISABL
> > > > E)) {
> > > >  		DRM_ERROR("failed to enable link training\n");
> > > > +		intel_dp->train_set_valid = false;
> > > >  		return false;
> > > >  	}
> > > >  
> > > > +	/*
> > > > +	 * The initial set of link parameters are set by this
> > > > point, so go
> > > > +	 * ahead and set intel_dp->train_set_valid to false in
> > > > case any of
> > > > +	 * the succeeding steps fail.  It will be set back to
> > > > true if we were
> > > > +	 * able to achieve clock recovery in the specified
> > > > configuration.
> > > > +	 */
> > > > +	intel_dp->train_set_valid = false;
> > > > +
> > > >  	voltage_tries = 1;
> > > >  	max_vswing_tries = 0;
> > > >  	for (;;) {
> > > > @@ -179,6 +189,7 @@ intel_dp_link_training_clock_recovery(struct
> > > > intel_dp *intel_dp)
> > > >  
> > > >  		if (drm_dp_clock_recovery_ok(link_status,
> > > > intel_dp->lane_count)) {
> > > >  			DRM_DEBUG_KMS("clock recovery OK\n");
> > > > +			intel_dp->train_set_valid =
> > > > intel_dp_is_edp(intel_dp);
> > > >  			return true;
> > > >  		}
> > > >  
> > > > @@ -256,6 +267,7 @@
> > > > intel_dp_link_training_channel_equalization(struct intel_dp
> > > > *intel_dp)
> > > >  				     training_pattern |
> > > >  				     DP_LINK_SCRAMBLING_DISABLE)
> > > > ) {
> > > >  		DRM_ERROR("failed to start channel
> > > > equalization\n");
> > > > +		intel_dp->train_set_valid = false;
> > > >  		return false;
> > > >  	}
> > > >  
> > > > @@ -296,6 +308,7 @@
> > > > intel_dp_link_training_channel_equalization(struct intel_dp
> > > > *intel_dp)
> > > >  	/* Try 5 times, else fail and try at lower BW */
> > > >  	if (tries == 5) {
> > > >  		intel_dp_dump_link_status(link_status);
> > > > +		intel_dp->train_set_valid = false;
> > > >  		DRM_DEBUG_KMS("Channel equalization failed 5
> > > > times\n");
> > > >  	}
> > > >  
> > > > diff --git a/drivers/gpu/drm/i915/intel_drv.h
> > > > b/drivers/gpu/drm/i915/intel_drv.h
> > > > index 2940d39..f4354ec 100644
> > > > --- a/drivers/gpu/drm/i915/intel_drv.h
> > > > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > > > @@ -995,6 +995,7 @@ struct intel_dp {
> > > >  	struct drm_dp_aux aux;
> > > >  	enum intel_display_power_domain aux_power_domain;
> > > >  	uint8_t train_set[4];
> > > > +	bool train_set_valid;
> > > >  	int panel_power_up_delay;
> > > >  	int panel_power_down_delay;
> > > >  	int panel_power_cycle_delay;
> -- 
> Mika Kahola - Intel OTC
>
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index e385658..38bc7e0 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -4750,6 +4750,7 @@  intel_dp_long_pulse(struct intel_connector *intel_connector)
 		intel_dp->max_link_rate = intel_dp_max_common_rate(intel_dp);
 
 		intel_dp->reset_link_params = false;
+		intel_dp->train_set_valid = false;
 	}
 
 	intel_dp_print_rates(intel_dp);
@@ -6019,6 +6020,7 @@  intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 	intel_dp_set_source_rates(intel_dp);
 
 	intel_dp->reset_link_params = true;
+	intel_dp->train_set_valid = false;
 	intel_dp->pps_pipe = INVALID_PIPE;
 	intel_dp->active_pipe = INVALID_PIPE;
 
diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c
index 05907fa..79fe369 100644
--- a/drivers/gpu/drm/i915/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
@@ -94,7 +94,8 @@  static bool
 intel_dp_reset_link_train(struct intel_dp *intel_dp,
 			uint8_t dp_train_pat)
 {
-	memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set));
+	if (!intel_dp->train_set_valid)
+		memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set));
 	intel_dp_set_signal_levels(intel_dp);
 	return intel_dp_set_link_train(intel_dp, dp_train_pat);
 }
@@ -162,9 +163,18 @@  intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 				       DP_TRAINING_PATTERN_1 |
 				       DP_LINK_SCRAMBLING_DISABLE)) {
 		DRM_ERROR("failed to enable link training\n");
+		intel_dp->train_set_valid = false;
 		return false;
 	}
 
+	/*
+	 * The initial set of link parameters are set by this point, so go
+	 * ahead and set intel_dp->train_set_valid to false in case any of
+	 * the succeeding steps fail.  It will be set back to true if we were
+	 * able to achieve clock recovery in the specified configuration.
+	 */
+	intel_dp->train_set_valid = false;
+
 	voltage_tries = 1;
 	max_vswing_tries = 0;
 	for (;;) {
@@ -179,6 +189,7 @@  intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 
 		if (drm_dp_clock_recovery_ok(link_status, intel_dp->lane_count)) {
 			DRM_DEBUG_KMS("clock recovery OK\n");
+			intel_dp->train_set_valid = intel_dp_is_edp(intel_dp);
 			return true;
 		}
 
@@ -256,6 +267,7 @@  intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 				     training_pattern |
 				     DP_LINK_SCRAMBLING_DISABLE)) {
 		DRM_ERROR("failed to start channel equalization\n");
+		intel_dp->train_set_valid = false;
 		return false;
 	}
 
@@ -296,6 +308,7 @@  intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 	/* Try 5 times, else fail and try at lower BW */
 	if (tries == 5) {
 		intel_dp_dump_link_status(link_status);
+		intel_dp->train_set_valid = false;
 		DRM_DEBUG_KMS("Channel equalization failed 5 times\n");
 	}
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 2940d39..f4354ec 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -995,6 +995,7 @@  struct intel_dp {
 	struct drm_dp_aux aux;
 	enum intel_display_power_domain aux_power_domain;
 	uint8_t train_set[4];
+	bool train_set_valid;
 	int panel_power_up_delay;
 	int panel_power_down_delay;
 	int panel_power_cycle_delay;