[Intel-gfx] [PATCH] drm/i915: Adaptive backoff delay on link training

Ander Conselvan De Oliveira conselvan2 at gmail.com
Thu Mar 3 09:27:06 UTC 2016


(Cc'ing Sivakumar, as he might have some ideas on this)

On Fri, 2016-02-26 at 12:54 +0200, Mika Kuoppala wrote:
> If the panel don't give us the information how long to wait
> before starting a new link training phase, it is not productive
> to poke it at 100us or 400us intervals and then give up if it
> fails to respond in time. Instead gradually increase the training
> delay so that we reach the slower kind and get display up.
> 
> This was needed to reach panel:
> 
> 0000: 12 14 c4 41 00 00 01 c0 02 00 00 00 1f 0b 00
> 0070: 01 00
> 0080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 0100: 14 84 00 00 00 00 00 00 01 10 00
> 0200: 01 00 00 00 80 00 00 00
> 0600: 01
> 0700: 02
> 0701: b7 f6 00 00
> 0720: 00 04 02 00 0a 04 0a 00 1b 00 00 01 00 ff ff 03
> 0732: 04 10
> 
> on kbl (8086:591e)

I poked at the machine in question. Here's what I found out:

- having the delay fixed at 16ms with all the retries in this patch is enough to
achieve clock recovery;
- forcing different iboost levels doesn't reduce the number of tries done with
the code in this patch;
- clock recovery fails because lane 0 fails to achieve clock recovery most of
the time, while the other lanes succeed.

The log below was obtained with a patch to log the link status after each clock
recovery delay.


 [drm:intel_dp_set_signal_levels] Using signal levels 00000000
 [drm:intel_dp_set_signal_levels] Using vswing level 0
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 00 00 80 00 11 11
 [drm:intel_dp_set_signal_levels] Using signal levels 04000000
 [drm:intel_dp_set_signal_levels] Using vswing level 1
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 10 11 80 00 12 11
 [drm:intel_dp_set_signal_levels] Using signal levels 07000000
 [drm:intel_dp_set_signal_levels] Using vswing level 2
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 10 11 80 00 23 22
 [drm:intel_dp_set_signal_levels] Using signal levels 09000000
 [drm:intel_dp_set_signal_levels] Using vswing level 3
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 10 10 80 00 33 33

 [drm:intel_dp_set_signal_levels] Using signal levels 00000000
 [drm:intel_dp_set_signal_levels] Using vswing level 0
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 00 00 80 00 11 11
 [drm:intel_dp_set_signal_levels] Using signal levels 04000000
 [drm:intel_dp_set_signal_levels] Using vswing level 1
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 10 10 80 00 12 12
 [drm:intel_dp_set_signal_levels] Using signal levels 07000000
 [drm:intel_dp_set_signal_levels] Using vswing level 2
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 10 11 80 00 23 22
 [drm:intel_dp_set_signal_levels] Using signal levels 09000000
 [drm:intel_dp_set_signal_levels] Using vswing level 3
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 10 10 80 00 33 33

 [drm:intel_dp_set_signal_levels] Using signal levels 00000000
 [drm:intel_dp_set_signal_levels] Using vswing level 0
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 00 00 80 00 11 11
 [drm:intel_dp_set_signal_levels] Using signal levels 04000000
 [drm:intel_dp_set_signal_levels] Using vswing level 1
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 10 10 80 00 12 12
 [drm:intel_dp_set_signal_levels] Using signal levels 07000000
 [drm:intel_dp_set_signal_levels] Using vswing level 2
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 10 11 80 00 23 22
 [drm:intel_dp_set_signal_levels] Using signal levels 09000000
 [drm:intel_dp_set_signal_levels] Using vswing level 3
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 10 10 80 00 33 33

 [drm:intel_dp_set_signal_levels] Using signal levels 00000000
 [drm:intel_dp_set_signal_levels] Using vswing level 0
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 00 00 80 00 11 11
 [drm:intel_dp_set_signal_levels] Using signal levels 04000000
 [drm:intel_dp_set_signal_levels] Using vswing level 1
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 10 10 80 00 12 12
 [drm:intel_dp_set_signal_levels] Using signal levels 07000000
 [drm:intel_dp_set_signal_levels] Using vswing level 2
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 10 11 80 00 23 22
 [drm:intel_dp_set_signal_levels] Using signal levels 09000000
 [drm:intel_dp_set_signal_levels] Using vswing level 3
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 10 10 80 00 33 33

 [drm:intel_dp_set_signal_levels] Using signal levels 00000000
 [drm:intel_dp_set_signal_levels] Using vswing level 0
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 00 00 80 00 11 11
 [drm:intel_dp_set_signal_levels] Using signal levels 04000000
 [drm:intel_dp_set_signal_levels] Using vswing level 1
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 10 10 80 00 12 12
 [drm:intel_dp_set_signal_levels] Using signal levels 07000000
 [drm:intel_dp_set_signal_levels] Using vswing level 2
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 10 11 80 00 23 22
 [drm:intel_dp_set_signal_levels] Using signal levels 09000000
 [drm:intel_dp_set_signal_levels] Using vswing level 3
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 10 10 80 00 33 33

 [drm:intel_dp_set_signal_levels] Using signal levels 00000000
 [drm:intel_dp_set_signal_levels] Using vswing level 0
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 00 00 80 00 11 11
 [drm:intel_dp_set_signal_levels] Using signal levels 04000000
 [drm:intel_dp_set_signal_levels] Using vswing level 1
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 10 10 80 00 12 12
 [drm:intel_dp_set_signal_levels] Using signal levels 07000000
 [drm:intel_dp_set_signal_levels] Using vswing level 2
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 10 11 80 00 23 22
 [drm:intel_dp_set_signal_levels] Using signal levels 09000000
 [drm:intel_dp_set_signal_levels] Using vswing level 3
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 10 10 80 00 33 33

 [drm:intel_dp_set_signal_levels] Using signal levels 00000000
 [drm:intel_dp_set_signal_levels] Using vswing level 0
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 00 00 80 00 11 11
 [drm:intel_dp_set_signal_levels] Using signal levels 04000000
 [drm:intel_dp_set_signal_levels] Using vswing level 1
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 10 10 80 00 12 12
 [drm:intel_dp_set_signal_levels] Using signal levels 07000000
 [drm:intel_dp_set_signal_levels] Using vswing level 2
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 10 11 80 00 23 22
 [drm:intel_dp_set_signal_levels] Using signal levels 09000000
 [drm:intel_dp_set_signal_levels] Using vswing level 3
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 10 10 80 00 33 33

 [drm:intel_dp_set_signal_levels] Using signal levels 00000000
 [drm:intel_dp_set_signal_levels] Using vswing level 0
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 00 00 80 00 11 11
 [drm:intel_dp_set_signal_levels] Using signal levels 04000000
 [drm:intel_dp_set_signal_levels] Using vswing level 1
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 00 10 80 00 22 12
 [drm:intel_dp_set_signal_levels] Using signal levels 07000000
 [drm:intel_dp_set_signal_levels] Using vswing level 2
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 10 11 80 00 23 22
 [drm:intel_dp_set_signal_levels] Using signal levels 09000000
 [drm:intel_dp_set_signal_levels] Using vswing level 3
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 10 10 80 00 33 33

 [drm:intel_dp_set_signal_levels] Using signal levels 00000000
 [drm:intel_dp_set_signal_levels] Using vswing level 0
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 00 00 80 00 11 11
 [drm:intel_dp_set_signal_levels] Using signal levels 04000000
 [drm:intel_dp_set_signal_levels] Using vswing level 1
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 11 10 80 00 11 12
 [drm:intel_dp_set_signal_levels] Using signal levels 07000000
 [drm:intel_dp_set_signal_levels] Using vswing level 2
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0
 [drm:intel_dp_link_training_clock_recovery] link status: 11 11 80 00 22 22
 [drm:intel_dp_link_training_clock_recovery] clock recovery OK
 [drm:intel_dp_link_training_channel_equalization] link status: 11 11 80 00 66
66
 [drm:intel_dp_set_signal_levels] Using signal levels 08000000
 [drm:intel_dp_set_signal_levels] Using vswing level 2
 [drm:intel_dp_set_signal_levels] Using pre-emphasis level 1
 [drm:intel_dp_link_training_channel_equalization] link status: 77 77 81 01 66
66
 [drm:intel_dp_link_training_channel_equalization] Channel EQ done. DP Training
successful


Ander

> 
> Cc: Ander Conselvan de Oliveira <conselvan2 at gmail.com>
> Cc: Rodrigo Vivi <rodrigo.vivi at intel.com>
> Cc: Mika Kahola <mika.kahola at intel.com>
> Signed-off-by: Mika Kuoppala <mika.kuoppala at intel.com>
> ---
>  drivers/gpu/drm/i915/intel_dp_link_training.c | 21 ++++++++++++++++++---
>  1 file changed, 18 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c
> b/drivers/gpu/drm/i915/intel_dp_link_training.c
> index 0b8eefc2acc5..aec81e28e347 100644
> --- a/drivers/gpu/drm/i915/intel_dp_link_training.c
> +++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
> @@ -104,6 +104,19 @@ intel_dp_update_link_train(struct intel_dp *intel_dp)
>  	return ret == intel_dp->lane_count;
>  }
>  
> +static void intel_dp_link_training_delay(struct intel_dp *intel_dp,
> +					 int retry_count)
> +{
> +	if (intel_dp->dpcd[DP_TRAINING_AUX_RD_INTERVAL]) {
> +		mdelay(intel_dp->dpcd[DP_TRAINING_AUX_RD_INTERVAL] * 4);
> +	} else {
> +		if (retry_count)
> +			mdelay(retry_count * 4);
> +		else
> +			udelay(400);
> +	}
> +}
> +
>  /* Enable corresponding port and start training pattern 1 */
>  static void
>  intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
> @@ -150,7 +163,8 @@ intel_dp_link_training_clock_recovery(struct intel_dp
> *intel_dp)
>  	for (;;) {
>  		uint8_t link_status[DP_LINK_STATUS_SIZE];
>  
> -		drm_dp_link_train_clock_recovery_delay(intel_dp->dpcd);
> +		intel_dp_link_training_delay(intel_dp, loop_tries);
> +
>  		if (!intel_dp_get_link_status(intel_dp, link_status)) {
>  			DRM_ERROR("failed to get link status\n");
>  			break;
> @@ -184,7 +198,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp
> *intel_dp)
>  				break;
>  		if (i == intel_dp->lane_count) {
>  			++loop_tries;
> -			if (loop_tries == 5) {
> +			if (loop_tries == 10) {
>  				DRM_ERROR("too many full retries, give
> up\n");
>  				break;
>  			}
> @@ -275,7 +289,8 @@ intel_dp_link_training_channel_equalization(struct
> intel_dp *intel_dp)
>  			break;
>  		}
>  
> -		drm_dp_link_train_channel_eq_delay(intel_dp->dpcd);
> +		intel_dp_link_training_delay(intel_dp, cr_tries);
> +
>  		if (!intel_dp_get_link_status(intel_dp, link_status)) {
>  			DRM_ERROR("failed to get link status\n");
>  			break;


More information about the Intel-gfx mailing list