On Tue, Dec 03, 2024 at 04:13:22PM +0800, Xiangxu Yin wrote: > > > On 11/29/2024 9:53 PM, Dmitry Baryshkov wrote: > > On Fri, 29 Nov 2024 at 09:59, Xiangxu Yin <quic_xiang...@quicinc.com> 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:
Anything in DP 2.1? > - 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. Any other driver doing such TPS lowering? Or maybe we should be selecting TPS3 for HBR2-only devices? > > 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_xiang...@quicinc.com> > >> --- > >> 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 > >> > > > > > > > -- > linux-phy mailing list > linux-...@lists.infradead.org > https://lists.infradead.org/mailman/listinfo/linux-phy -- With best wishes Dmitry