On Tue, 2024-02-06 at 16:17 +0530, Arun R Murthy wrote:
> Fallback mandates on DP link training failure. This patch just covers
> the DP2.0 fallback sequence.
> 
> TODO: Need to implement the DP1.4 fallback.
> 
> Signed-off-by: Arun R Murthy <arun.r.mur...@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_dp.c | 92 ++++++++++++++++++++++-
> --
>  1 file changed, 82 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index 10ec231acd98..82d354a6b0cd 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -104,6 +104,50 @@ static const u8 valid_dsc_bpp[] = {6, 8, 10, 12,
> 15};
>   */
>  static const u8 valid_dsc_slicecount[] = {1, 2, 4};
>  
> +/* DL Link Rates */
> +#define UHBR20               2000000
> +#define UHBR13P5     1350000

Do we have 13.5G support?
Plz check Specs:55726 Note 6

Thanks
Khaled

> +#define UHBR10               1000000
> +#define HBR3         810000
> +#define HBR2         540000
> +#define HBR          270000
> +#define RBR          162000
> +
> +/* DP Lane Count */
> +#define LANE_COUNT_4 4
> +#define LANE_COUNT_2 2
> +#define LANE_COUNT_1 1
> +
> +/* DP2.0 fallback values */
> +struct dp_fallback {
> +     u32 link_rate;
> +     u8 lane_count;
> +};
> +
> +struct dp_fallback dp2dot0_fallback[] = {
> +     {UHBR20, LANE_COUNT_4},
> +     {UHBR13P5, LANE_COUNT_4},
> +     {UHBR20, LANE_COUNT_2},
> +     {UHBR10, LANE_COUNT_4},
> +     {UHBR13P5, LANE_COUNT_2},
> +     {HBR3, LANE_COUNT_4},
> +     {UHBR20, LANE_COUNT_1},
> +     {UHBR10, LANE_COUNT_2},
> +     {HBR2, LANE_COUNT_4},
> +     {UHBR13P5, LANE_COUNT_1},
> +     {HBR3, LANE_COUNT_2},
> +     {UHBR10, LANE_COUNT_1},
> +     {HBR2, LANE_COUNT_2},
> +     {HBR, LANE_COUNT_4},
> +     {HBR3, LANE_COUNT_1},
> +     {RBR, LANE_COUNT_4},
> +     {HBR2, LANE_COUNT_1},
> +     {HBR, LANE_COUNT_2},
> +     {RBR, LANE_COUNT_2},
> +     {HBR, LANE_COUNT_1},
> +     {RBR, LANE_COUNT_1},
> +};
> +
>  /**
>   * intel_dp_is_edp - is the given port attached to an eDP panel
> (either CPU or PCH)
>   * @intel_dp: DP struct
> @@ -299,6 +343,19 @@ static int intel_dp_common_len_rate_limit(const
> struct intel_dp *intel_dp,
>                                      intel_dp->num_common_rates,
> max_rate);
>  }
>  
> +static bool intel_dp_link_rate_supported(struct intel_dp *intel_dp,
> u32 link_rate)
> +{
> +     u8 i;
> +
> +     for (i = 0; i < ARRAY_SIZE(intel_dp->common_rates); i++) {
> +             if (intel_dp->common_rates[i] == link_rate)
> +                     return true;
> +             else
> +                     continue;
> +     }
> +     return false;
> +}
> +
>  static int intel_dp_common_rate(struct intel_dp *intel_dp, int
> index)
>  {
>       if (drm_WARN_ON(&dp_to_i915(intel_dp)->drm,
> @@ -671,15 +728,6 @@ int
> intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
>       struct drm_i915_private *i915 = dp_to_i915(intel_dp);
>       int index;
>  
> -     /*
> -      * TODO: Enable fallback on MST links once MST link compute can
> handle
> -      * the fallback params.
> -      */
> -     if (intel_dp->is_mst) {
> -             drm_err(&i915->drm, "Link Training Unsuccessful\n");
> -             return -1;
> -     }
> -
>       if (intel_dp_is_edp(intel_dp) && !intel_dp->use_max_params) {
>               drm_dbg_kms(&i915->drm,
>                           "Retrying Link training for eDP with max
> parameters\n");
> @@ -687,6 +735,31 @@ int
> intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
>               return 0;
>       }
>  
> +     /* DP fallback values */
> +     if (intel_dp->dpcd[DP_MAIN_LINK_CHANNEL_CODING] &
> DP_CAP_ANSI_128B132B) {
> +             for(index = 0; index < ARRAY_SIZE(dp2dot0_fallback);
> index++) {
> +                     if (link_rate ==
> dp2dot0_fallback[index].link_rate &&
> +                             lane_count ==
> dp2dot0_fallback[index].lane_count) {
> +                             for(index += 1; index <
> ARRAY_SIZE(dp2dot0_fallback); index++) {
> +                                     if
> (intel_dp_link_rate_supported(intel_dp,
> +                                                     dp2dot0_fallbac
> k[index].link_rate)) {
> +                                             intel_dp_set_link_param
> s(intel_dp,
> +                                                                   d
> p2dot0_fallback[index].link_rate,
> +                                                                   d
> p2dot0_fallback[index].lane_count);
> +                                             drm_dbg_kms(&i915->drm,
> +                                                         "Retrying
> Link training with link rate %d and lane count %d\n",
> +                                                         dp2dot0_fal
> lback[index].link_rate,
> +                                                         dp2dot0_fal
> lback[index].lane_count);
> +                                             return 0;
> +                                     }
> +                             }
> +                     }
> +             }
> +             /* Report failure and fail link training */
> +             drm_err(&i915->drm, "Link Training Unsuccessful\n");
> +             return -1;
> +     }
> +
>       index = intel_dp_rate_index(intel_dp->common_rates,
>                                   intel_dp->num_common_rates,
>                                   link_rate);
> @@ -716,7 +789,6 @@ int
> intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
>               drm_err(&i915->drm, "Link Training Unsuccessful\n");
>               return -1;
>       }
> -
>       return 0;
>  }
>  

Reply via email to