[PATCH v2 1/2] drm/i915/dp: Enable SST LT fallback between UHBR and non-UHBR link rates
Imre Deak
imre.deak at intel.com
Mon Apr 7 21:41:27 UTC 2025
On Mon, Apr 07, 2025 at 11:41:38PM +0300, Almahallawy, Khaled wrote:
> On Mon, 2025-04-07 at 10:04 +0300, Imre Deak wrote:
> > On Fri, Apr 04, 2025 at 05:34:33PM -0700, Khaled Almahallawy wrote:
> > > With all the pieces for UHBR SST LT implemented, we can now enable
> > > LT
> > > fallback switching between SST UHBR and non-UHBR link rates.
> > >
> > > [...]
> > >
> > > @@ -1303,7 +1233,7 @@ static int
> > > intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
> > > return 0;
> > > }
> > >
> > > - if (!reduce_link_params(intel_dp, crtc_state,
> > > &new_link_rate, &new_lane_count))
> > > + if (!reduce_link_params_in_bw_order(intel_dp, crtc_state,
> > > &new_link_rate, &new_lane_count))
> >
> > On SST - during state computation - a minimum link configuration
> > required for the mode was selected to beging with. Simply reducing
> > that
> > link config further in BW order as for MST (which selected the
> > maximum
> > link config to begin with) doesn't work.
> >
>
> Thank you for the review.
>
> Just to clarify what we're seeing, we used the following hack to
> simulate a faulty cable that can only carry 1 lane RBR:
>
>
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
> b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
> @@ -1026,7 +1026,11 @@
> intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp,
> - training_pattern = intel_dp_training_pattern(intel_dp,
> crtc_state, dp_phy);
> + if(intel_dp_is_edp(intel_dp) || (crtc_state->lane_count == 1 &&
> crtc_state->port_clock == 162000))
> + training_pattern = intel_dp_training_pattern(intel_dp,
> crtc_state, dp_phy);
> + else
> + training_pattern = DP_TRAINING_PATTERN_1;
> +
> @@ -1419,7 +1423,7 @@ intel_dp_128b132b_lane_eq(struct intel_dp
> *intel_dp,
> /* Start transmitting 128b/132b TPS2. */
> if (!intel_dp_set_link_train(intel_dp, crtc_state, DP_PHY_DPRX,
> - DP_TRAINING_PATTERN_2)) {
> + DP_TRAINING_PATTERN_1)) {
> }
>
>
> Below is the default behavior without these changes:
>
> adjusted mode: "3840x2160": 60 533250 3840 3888 3920 4000 2160 2163
> 2168 2222 0x48 0x9
> Link Training failed at link rate = 540000, lane count = 4
> adjusted mode: "3840x2160": 60 533250 3840 3888 3920 4000 2160 2163
> 2168 2222 0x48 0x9
> Link Training failed at link rate = 540000, lane count = 4
> generating connector hotplug event
> adjusted mode: "3840x2160": 60 533250 3840 3888 3920 4000 2160 2163
> 2168 2222 0x48 0x9
> Link Training failed at link rate = 270000, lane count = 4
> generating connector hotplug event
> adjusted mode: "3840x2160": 60 533250 3840 3888 3920 4000 2160 2163
> 2168 2222 0x48 0x9
> Link Training failed at link rate = 162000, lane count = 4
> generating connector hotplug event
> adjusted mode: "3840x2160": 60 533250 3840 3888 3920 4000 2160 2163
> 2168 2222 0x48 0x9
> 128b/132b Link Training failed at link rate = 1000000, lane count = 2
> generating connector hotplug event
> adjusted mode: "3840x2160": 60 533250 3840 3888 3920 4000 2160 2163
> 2168 2222 0x48 0x9
> pica hotplug event received, stat 0x00020000, pins 0x00000400, long
> 0x00000000
> 128b/132b Link Training failed at link rate = 1000000, lane count = 1
> Can't reduce link training parameters after failure
>
> It uses the fallback code we propose to delete. It is holding the lane
> count and dropping the link rate starting from 4xHBR2, which was
> computed to the minimum required for 4k at 60. In the next loop, for 2
> lanes, it went up to the maximum common rate, UHBR10. Because of the
> condition in reduce_link_rate, it refuses to drop to non-UHBR rates and
> fails to train the monitor.
The following enables the fallback between UHBR and non-UHBR rates:
@@ -1223,7 +1223,6 @@ static bool reduce_link_params_in_bw_order(struct intel_dp *intel_dp,
static int reduce_link_rate(struct intel_dp *intel_dp, int current_rate)
{
int rate_index;
- int new_rate;
if (intel_dp->link.force_rate)
return -1;
@ -1235,13 +1234,7 @@ static int reduce_link_rate(struct intel_dp *intel_dp, int current_rate)
if (rate_index <= 0)
return -1;
- new_rate = intel_dp_common_rate(intel_dp, rate_index - 1);
-
- /* TODO: Make switching from UHBR to non-UHBR rates work. */
- if (drm_dp_is_uhbr_rate(current_rate) != drm_dp_is_uhbr_rate(new_rate))
- return -1;
-
- return new_rate;
+ return intel_dp_common_rate(intel_dp, rate_index - 1);
}
> However, with the proposed changes, we get the following:
The problem with that as I described above is that an SST link doesn't
get initially trained using the maximum link capabilities as opposed to
an MST link. For instance, in the example below 1000000x2 will not be
used at all and also get disabled for future modesets on the same link,
because the minimal link config (540000x4) initially used for the given
mode has a lower BW than that of 1000000x2. However 1000000x2 could work
fine (for instance because the limitation is due to the number of lanes
- as in a faulty cable, not due to the link rate).
> adjusted mode: "3840x2160": 60 533250 3840 3888 3920 4000 2160 2163
> 2168 2222 0x48 0x9
> Link Training passed at link rate = 810000, lane count = 4
> Link Training failed at link rate = 540000, lane count = 4
> adjusted mode: "3840x2160": 60 533250 3840 3888 3920 4000 2160 2163
> 2168 2222 0x48 0x9
> Link Training failed at link rate = 540000, lane count = 4
> generating connector hotplug event
> adjusted mode: "3840x2160": 60 533250 3840 3888 3920 4000 2160 2163
> 2168 2222 0x48 0x9
> Link Training failed at link rate = 810000, lane count = 2
> generating connector hotplug event
> adjusted mode: "3840x2160": 60 533250 3840 3888 3920 4000 2160 2163
> 2168 2222 0x48 0x9
> 128b/132b Link Training failed at link rate = 1000000, lane count = 1
> generating connector hotplug event
> adjusted mode: "3840x2160": 60 533250 3840 3888 3920 4000 2160 2163
> 2168 2222 0x48 0x9
> Link Training failed at link rate = 540000, lane count = 2
> generating connector hotplug event
> adjusted mode: "3840x2160": 60 533250 3840 3888 3920 4000 2160 2163
> 2168 2222 0x48 0x9
> Link Training failed at link rate = 270000, lane count = 4
> generating connector hotplug event
> adjusted mode: "3840x2160": 60 533250 3840 3888 3920 4000 2160 2163
> 2168 2222 0x48 0x9
> Link Training failed at link rate = 810000, lane count = 1
> generating connector hotplug event
> adjusted mode: "3840x2160": 60 533250 3840 3888 3920 4000 2160 2163
> 2168 2222 0x48 0x9
> Link Training failed at link rate = 162000, lane count = 4
> generating connector hotplug event
> adjusted mode: "3840x2160": 30 297000 3840 4016 4104 4400 2160 2168
> 2178 2250 0x40 0x5
> Link Training failed at link rate = 540000, lane count = 1
> generating connector hotplug event
> adjusted mode: "3840x2160": 30 297000 3840 4016 4104 4400 2160 2168
> 2178 2250 0x40 0x5
> Link Training failed at link rate = 270000, lane count = 2
> generating connector hotplug event
> adjusted mode: "3840x2160": 30 297000 3840 4016 4104 4400 2160 2168
> 2178 2250 0x40 0x5
> Link Training failed at link rate = 162000, lane count = 2
> generating connector hotplug event
> adjusted mode: "2560x1440": 60 241500 2560 2608 2640 2720 1440 1443
> 1448 1481 0x40 0x9
> Link Training failed at link rate = 270000, lane count = 1
> generating connector hotplug event
> adjusted mode: "1920x1080": 60 148500 1920 2008 2052 2200 1080 1084
> 1089 1125 0x40 0xa
> Link Training passed at link rate = 162000, lane count = 1
>
>
> We can see that it follows the DP2.1 specs, page 973:
>
> 1 If 128b132b_DP_Supported?
> a If support 4 lanes?
> 4 With supported bit rate configuration UHBR10, fallback as
> follows:
> 4L UHBR10 -> 4L HBR3 -> 2L UHBR10 -> 4L HBR2 -> 2L HBR3 ->
> 1L UHBR10 -> 2L HBR2 -> 4L HBR -> 1L HBR3 -> 4L RBR -> 1L
> HBR2 ->
> 2L HBR -> 2L RBR -> 1L HBR -> 1L RBR
>
>
> So, are we missing something?
>
> Thank You
> Khaled
>
>
>
> > > return -1;
> > >
> > > if (intel_dp_is_edp(intel_dp) &&
> > > --
> > > 2.43.0
> > >
>
More information about the Intel-gfx
mailing list