On 11/29/2024 9:53 PM, Dmitry Baryshkov wrote: > On Fri, 29 Nov 2024 at 09:59, Xiangxu Yin <quic_xiangxuy@xxxxxxxxxxx> wrote: >> >> Add a mechanism to retry Link Training 2 by lowering the pattern level >> when the link training #2 first attempt fails. This approach enhances >> compatibility, particularly addressing issues caused by certain hub >> configurations. > > Please reference corresponding part of the standard, describing this lowering. > Per DisplayPort 1.4a specification Section 3.5.1.2 and Table 3-10, while the standard doesn't explicitly define a TPS downgrade mechanism, it does specify: - All devices shall support TPS1 and TPS2 - HDR2-capable devices shall support TPS3 - HDR3-capable devices shall support TPS4 While these capabilities are explicitly defined DPCD for sink devices, source device capabilities are less strictly defined, with the minimum requirement being support for TPS1 and TPS2. In QCS615 DP phy is only supporting to HBR2, we observed a critical interoperability scenario with a DP->HDMI bridge. When link training at TPS4 consistently failed, downgrading to the next lower training pattern successfully established the link and display output successfully. This experience suggests that implementing a flexible link training pattern downgrade mechanism can significantly improve compatibility with third-party, non-standard hubs and displays, especially in scenarios where strict adherence to the highest training pattern might prevent successful connection. >> >> Signed-off-by: Xiangxu Yin <quic_xiangxuy@xxxxxxxxxxx> >> --- >> drivers/gpu/drm/msm/dp/dp_ctrl.c | 34 ++++++++++++++++++++++++++++++---- >> 1 file changed, 30 insertions(+), 4 deletions(-) >> >> diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c >> index 49c8ce9b2d0e57a613e50865be3fe98e814d425a..b1862294cb98c9f756b0108b7670cb42de37bae4 100644 >> --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c >> +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c >> @@ -1220,7 +1220,7 @@ static void msm_dp_ctrl_clear_training_pattern(struct msm_dp_ctrl_private *ctrl) >> } >> >> static int msm_dp_ctrl_link_train_2(struct msm_dp_ctrl_private *ctrl, >> - int *training_step) >> + int *training_step, bool downgrade) >> { >> int tries = 0, ret = 0; >> u8 pattern; >> @@ -1243,6 +1243,28 @@ static int msm_dp_ctrl_link_train_2(struct msm_dp_ctrl_private *ctrl, >> state_ctrl_bit = 2; >> } >> >> + /* >> + * DP link training uses the highest allowed pattern by default. >> + * If it fails, the pattern is downgraded to improve cable and monitor compatibility. >> + */ >> + if (downgrade) { >> + switch (pattern) { >> + case DP_TRAINING_PATTERN_4: >> + pattern = DP_TRAINING_PATTERN_3; >> + state_ctrl_bit = 3; >> + break; >> + case DP_TRAINING_PATTERN_3: >> + pattern = DP_TRAINING_PATTERN_2; >> + state_ctrl_bit = 2; >> + break; >> + default: >> + break; >> + } >> + } >> + >> + drm_dbg_dp(ctrl->drm_dev, "pattern(%d) state_ctrl_bit(%d) downgrade(%d)\n", >> + pattern, state_ctrl_bit, downgrade); >> + >> ret = msm_dp_catalog_ctrl_set_pattern_state_bit(ctrl->catalog, state_ctrl_bit); >> if (ret) >> return ret; >> @@ -1311,10 +1333,14 @@ static int msm_dp_ctrl_link_train(struct msm_dp_ctrl_private *ctrl, >> /* print success info as this is a result of user initiated action */ >> drm_dbg_dp(ctrl->drm_dev, "link training #1 successful\n"); >> >> - ret = msm_dp_ctrl_link_train_2(ctrl, training_step); >> + ret = msm_dp_ctrl_link_train_2(ctrl, training_step, false); >> if (ret) { >> - DRM_ERROR("link training #2 failed. ret=%d\n", ret); >> - goto end; >> + drm_dbg_dp(ctrl->drm_dev, "link training #2 failed, retry downgrade.\n"); >> + ret = msm_dp_ctrl_link_train_2(ctrl, training_step, true); >> + if (ret) { >> + DRM_ERROR("link training #2 failed. ret=%d\n", ret); >> + goto end; >> + } >> } >> >> /* print success info as this is a result of user initiated action */ >> >> -- >> 2.25.1 >> > >