[PATCH 4/4] drm/msm/dp: continue link training downgrade when cable is still plugged
Saurabh Anand <[email protected]>
| Newsgroups | org.freedesktop.lists.dri-devel,org.infradead.lists.linux-phy,org.kernel.vger.linux-arm-msm,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <20260824-qcom-dp-typec-reconnect-fixes-v1-4-2825e5bf8a96@oss.qualcomm.com> |
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. 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) 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; } rc = msm_dp_ctrl_on_link(dp->ctrl, dp->panel); -- 2.34.1