On Mon, Aug 24, 2026 at 04:58:07PM +0530, Saurabh Anand wrote:
> During a Type-C reconnect the AUX channel may report link-disconnected
> transiently while the physical cable is still present. The link training
> retry loop in msm_dp_ctrl_on_link() was aborting immediately on any
> msm_dp_aux_is_link_connected() failure, preventing the rate/lane downgrade
> path from running.
> 
> When the display is known to be plugged (msm_dp_ctrl->plugged), an AUX
> link-disconnected status is likely a transient glitch rather than a true
> unplug. Allow the downgrade loop to continue in that case by requiring both
> conditions before breaking out of the retry loop: AUX reports disconnected
> and the display is not plugged.

A cable reconnect should follow the full procedure. DPRX may use long
HPD pulses to signal that DPTX should reconfigure the link according to
the changed status registers.

> 
> The plugged state is snapshotted from dp_display into msm_dp_ctrl just
> before msm_dp_ctrl_on_link() is called, so the retry loop has an accurate
> view of cable presence at the time link training started.
> 
> Signed-off-by: Saurabh Anand <[email protected]>
> ---
>  drivers/gpu/drm/msm/dp/dp_ctrl.c    | 4 ++--
>  drivers/gpu/drm/msm/dp/dp_ctrl.h    | 1 +
>  drivers/gpu/drm/msm/dp/dp_display.c | 1 +
>  3 files changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c 
> b/drivers/gpu/drm/msm/dp/dp_ctrl.c
> index 59070f399e2d..e8fd8f4c75fe 100644
> --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
> +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
> @@ -2379,7 +2379,7 @@ int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl,
>                       break;
>               } else if (training_step == DP_TRAINING_1) {
>                       /* link train_1 failed */
> -                     if (!msm_dp_aux_is_link_connected(ctrl->aux))
> +                     if (!msm_dp_aux_is_link_connected(ctrl->aux) && 
> !msm_dp_ctrl->plugged)

Locking?

>                               break;
>  
>                       drm_dp_dpcd_read_link_status(ctrl->aux, link_status);
> @@ -2404,7 +2404,7 @@ int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl,
>                       }
>               } else if (training_step == DP_TRAINING_2) {
>                       /* link train_2 failed */
> -                     if (!msm_dp_aux_is_link_connected(ctrl->aux))
> +                     if (!msm_dp_aux_is_link_connected(ctrl->aux) && 
> !msm_dp_ctrl->plugged)
>                               break;
>  
>                       drm_dp_dpcd_read_link_status(ctrl->aux, link_status);
> diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.h 
> b/drivers/gpu/drm/msm/dp/dp_ctrl.h
> index 5902cf7e746a..95533b0b6297 100644
> --- a/drivers/gpu/drm/msm/dp/dp_ctrl.h
> +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.h
> @@ -12,6 +12,7 @@
>  
>  struct msm_dp_ctrl {
>       bool wide_bus_en;
> +     bool plugged;
>  };
>  
>  struct phy;
> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
> b/drivers/gpu/drm/msm/dp/dp_display.c
> index 1f60c78a463d..93a37a44273f 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.c
> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> @@ -644,6 +644,7 @@ static int msm_dp_display_prepare_link(struct 
> msm_dp_display_private *dp)
>       if (!msm_dp_display->power_on) {
>               msm_dp_display_host_phy_init(dp);
>               force_link_train = true;
> +             dp->ctrl->plugged = dp->plugged;

No, don't create copies of the fiels. They easily get out of sync.

>       }
>  
>       rc = msm_dp_ctrl_on_link(dp->ctrl, dp->panel);
> 
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry

Reply via email to