[Intel-gfx] [PATCH] drm/i915: Fix DP clock recovery "voltage_tries" handling
Imre Deak
imre.deak at intel.com
Fri Oct 1 17:17:04 UTC 2021
On Fri, Oct 01, 2021 at 07:08:26PM +0300, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala at linux.intel.com>
>
> The DP spec says:
> "If the receiver keeps the same value in the ADJUST_REQUEST_LANEx_y
> register(s) while the LANEx_CR_DONE bits remain unset, the transmitter
> must loop four times with the same voltage swing. On the fifth time,
> the transmitter must down-shift to the lower bit rate and must repeat
> the CR-lock training sequence as described below."
>
> Lets fix the code to follow that instead of terminating after five
> times of transmitting the same signal levels. The text in spec feels
> a little bit ambiguous still, but this is my best guess at its meaning.
>
> As a bonus this also gets rid of the train_set[0] stuff which
> would not work for per-lane drive settings anyway.
>
> Cc: Imre Deak <imre.deak at intel.com>
> CC: Jani Nikula <jani.nikula at intel.com>
> Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
Reviewed-by: Imre Deak <imre.deak at intel.com>
It's likely that the receiver is still trying new settings and didn't
abort yet, if it changes anything in the request.
> ---
> .../drm/i915/display/intel_dp_link_training.c | 29 +++++++++++++++----
> 1 file changed, 24 insertions(+), 5 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 053ed9302cda..73a823f1ec22 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
> @@ -511,6 +511,25 @@ static void intel_dp_link_training_clock_recovery_delay(struct intel_dp *intel_d
> drm_dp_lttpr_link_train_clock_recovery_delay();
> }
>
> +static bool intel_dp_adjust_request_changed(int lane_count,
> + const u8 old_link_status[DP_LINK_STATUS_SIZE],
> + const u8 new_link_status[DP_LINK_STATUS_SIZE])
> +{
> + int lane;
> +
> + for (lane = 0; lane < lane_count; lane++) {
> + u8 old = drm_dp_get_adjust_request_voltage(old_link_status, lane) |
> + drm_dp_get_adjust_request_pre_emphasis(old_link_status, lane);
> + u8 new = drm_dp_get_adjust_request_voltage(new_link_status, lane) |
> + drm_dp_get_adjust_request_pre_emphasis(new_link_status, lane);
> +
> + if (old != new)
> + return true;
> + }
> +
> + return false;
> +}
> +
> /*
> * Perform the link training clock recovery phase on the given DP PHY using
> * training pattern 1.
> @@ -521,7 +540,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp,
> enum drm_dp_phy dp_phy)
> {
> struct drm_i915_private *i915 = dp_to_i915(intel_dp);
> - u8 voltage;
> + u8 old_link_status[DP_LINK_STATUS_SIZE] = {};
> int voltage_tries, cr_tries, max_cr_tries;
> bool max_vswing_reached = false;
>
> @@ -574,8 +593,6 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp,
> return false;
> }
>
> - voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
> -
> /* Update training set as requested by target */
> intel_dp_get_adjust_train(intel_dp, crtc_state, dp_phy,
> link_status);
> @@ -585,12 +602,14 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp,
> return false;
> }
>
> - if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) ==
> - voltage)
> + if (!intel_dp_adjust_request_changed(crtc_state->lane_count,
> + old_link_status, link_status))
> ++voltage_tries;
> else
> voltage_tries = 1;
>
> + memcpy(old_link_status, link_status, sizeof(link_status));
> +
> if (intel_dp_link_max_vswing_reached(intel_dp, crtc_state))
> max_vswing_reached = true;
>
> --
> 2.32.0
>
More information about the Intel-gfx
mailing list