[Intel-gfx] [PATCH 3/7] drm/i915: Simplify the link training functions

Ville Syrjälä ville.syrjala at linux.intel.com
Tue Sep 22 13:27:05 UTC 2020


On Tue, Sep 22, 2020 at 03:51:02PM +0300, Imre Deak wrote:
> Split the prepare, link training, fallback-handling steps into their own
> functions for clarity and as a preparation for the upcoming LTTPR changes.
> 
> While at it also add some documentation to exported functions.
> 
> Signed-off-by: Imre Deak <imre.deak at intel.com>
> ---
>  .../drm/i915/display/intel_dp_link_training.c | 80 ++++++++++++++-----
>  1 file changed, 62 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
> index 6d13d00db5e6..0c3809891bd2 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
> @@ -162,14 +162,13 @@ static bool intel_dp_link_max_vswing_reached(struct intel_dp *intel_dp)
>  	return true;
>  }
>  
> -/* Enable corresponding port and start training pattern 1 */
> -static bool
> -intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
> +/*
> + * Prepare link training by configuring the link parameters and enabling the
> + * corresponding port.
> + */
> +static void intel_dp_prepare_link_train(struct intel_dp *intel_dp)
>  {
>  	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
> -	u8 voltage;
> -	int voltage_tries, cr_tries, max_cr_tries;
> -	bool max_vswing_reached = false;
>  	u8 link_config[2];
>  	u8 link_bw, rate_select;
>  
> @@ -203,6 +202,16 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
>  	drm_dp_dpcd_write(&intel_dp->aux, DP_DOWNSPREAD_CTRL, link_config, 2);
>  
>  	intel_dp->DP |= DP_PORT_EN;

I guess we no longer actually enable the port here? The comment ^ still says
we do.

Hmm. Seems we do enable the port on ddi platforms, but not on older
platforms. I guess the docs could still use a tweak to reflect
reality a bit better.

> +}
> +
> +/* Perform the link training clock recovery phase using training pattern 1. */
> +static bool
> +intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
> +{
> +	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
> +	u8 voltage;
> +	int voltage_tries, cr_tries, max_cr_tries;
> +	bool max_vswing_reached = false;
>  
>  	/* clock recovery */
>  	if (!intel_dp_reset_link_train(intel_dp,
> @@ -325,6 +334,10 @@ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp)
>  	return DP_TRAINING_PATTERN_2;
>  }
>  
> +/*
> + * Perform the link training channel equalization phase using one of training
> + * pattern 2, 3 or 4 depending on the the source and sink capabilities.
> + */
>  static bool
>  intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
>  {
> @@ -395,6 +408,15 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
>  
>  }
>  
> +/**
> + * intel_dp_stop_link_train - stop link training
> + * @intel_dp: DP struct
> + *
> + * Stop the link training of the @intel_dp port, programming the port to
> + * output an idle pattern 

I don't think we use the idle pattern on all platforms.

BTW intel_dp_set_idle_link_train() looks pretty pointless. Could just
inline it into its only caller, or at least move it into
intel_dp_link_training.c.

Reviewed-by: Ville Syrjälä <ville.syrjala at linux.intel.com>

> on the link and  disabling the training pattern in
> + * the sink's DPCD.
> + * This function must be called after intel_dp_start_link_train().
> + */
>  void intel_dp_stop_link_train(struct intel_dp *intel_dp)
>  {
>  	intel_dp->link_trained = true;
> @@ -403,30 +425,37 @@ void intel_dp_stop_link_train(struct intel_dp *intel_dp)
>  				DP_TRAINING_PATTERN_DISABLE);
>  }
>  
> -void
> -intel_dp_start_link_train(struct intel_dp *intel_dp)
> +static bool
> +intel_dp_link_train(struct intel_dp *intel_dp)
>  {
>  	struct intel_connector *intel_connector = intel_dp->attached_connector;
> +	bool ret = false;
> +
> +	intel_dp_prepare_link_train(intel_dp);
>  
>  	if (!intel_dp_link_training_clock_recovery(intel_dp))
> -		goto failure_handling;
> +		goto out;
> +
>  	if (!intel_dp_link_training_channel_equalization(intel_dp))
> -		goto failure_handling;
> +		goto out;
>  
> -	drm_dbg_kms(&dp_to_i915(intel_dp)->drm,
> -		    "[CONNECTOR:%d:%s] Link Training Passed at Link Rate = %d, Lane count = %d",
> -		    intel_connector->base.base.id,
> -		    intel_connector->base.name,
> -		    intel_dp->link_rate, intel_dp->lane_count);
> -	return;
> +	ret = true;
>  
> - failure_handling:
> +out:
>  	drm_dbg_kms(&dp_to_i915(intel_dp)->drm,
> -		    "[CONNECTOR:%d:%s] Link Training failed at link rate = %d, lane count = %d",
> +		    "[CONNECTOR:%d:%s] Link Training %s at Link Rate = %d, Lane count = %d",
>  		    intel_connector->base.base.id,
>  		    intel_connector->base.name,
> +		    ret ? "passed" : "failed",
>  		    intel_dp->link_rate, intel_dp->lane_count);
>  
> +	return ret;
> +}
> +
> +static void intel_dp_schedule_fallback_link_training(struct intel_dp *intel_dp)
> +{
> +	struct intel_connector *intel_connector = intel_dp->attached_connector;
> +
>  	if (intel_dp->hobl_active) {
>  		drm_dbg_kms(&dp_to_i915(intel_dp)->drm,
>  			    "Link Training failed with HOBL active, not enabling it from now on");
> @@ -440,3 +469,18 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
>  	/* Schedule a Hotplug Uevent to userspace to start modeset */
>  	schedule_work(&intel_connector->modeset_retry_work);
>  }
> +
> +/**
> + * intel_dp_start_link_train - start link training
> + * @intel_dp: DP struct
> + *
> + * Start the link training of the @intel_dp port, scheduling a fallback
> + * retraining with reduced link rate/lane parameters if the link training
> + * fails.
> + * After calling this function intel_dp_stop_link_train() must be called.
> + */
> +void intel_dp_start_link_train(struct intel_dp *intel_dp)
> +{
> +	if (!intel_dp_link_train(intel_dp))
> +		intel_dp_schedule_fallback_link_training(intel_dp);
> +}
> -- 
> 2.17.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel


More information about the Intel-gfx mailing list