[PATCH v4 31/39] drm/msm/dp: add prepared to manage link-level operations

Yongxing Mou
2026-04-10T09:36:31Z

In MST mode, multiple streams share the same DP link. Track a prepared
state so msm_dp_display_prepare() runs only once per link and repeated
calls are skipped.

Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
---
drivers/gpu/drm/msm/dp/dp_display.c | 34 ++++++++++++++++++++++++++--------
drivers/gpu/drm/msm/dp/dp_display.h | 1 +
2 files changed, 27 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index 1f26283b2dee..9eaf6994a350 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -715,6 +715,11 @@ int msm_dp_display_prepare(struct msm_dp *msm_dp_display)
if (msm_dp_display->is_edp)
msm_dp_hpd_plug_handle(dp);

+ if (msm_dp_display->prepared) {
+ drm_dbg_dp(dp->drm_dev, "Link already setup, return\n");
+ return 0;
+ }
+
rc = pm_runtime_resume_and_get(&msm_dp_display->pdev->dev);
if (rc) {
DRM_ERROR("failed to pm_runtime_resume\n");
@@ -734,7 +739,11 @@ int msm_dp_display_prepare(struct msm_dp *msm_dp_display)
// TODO: schedule drm_connector_set_link_status_property()
}

- return msm_dp_ctrl_prepare_stream_on(dp->ctrl, force_link_train);
+ rc = msm_dp_ctrl_prepare_stream_on(dp->ctrl, force_link_train);
+ if (!rc)
+ msm_dp_display->prepared = true;
+
+ return rc;
}

static int msm_dp_display_enable(struct msm_dp_display_private *dp,
@@ -1590,14 +1599,16 @@ void msm_dp_display_enable_helper(struct msm_dp *msm_dp_display, struct msm_dp_p

dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);

- rc = msm_dp_display_enable(dp, msm_dp_panel);
- if (rc)
- DRM_ERROR("DP display enable failed, rc=%d\n", rc);
+ if (msm_dp_display->prepared) {
+ rc = msm_dp_display_enable(dp, msm_dp_panel);
+ if (rc)
+ DRM_ERROR("DP display enable failed, rc=%d\n", rc);

- rc = msm_dp_display_post_enable(msm_dp_display);
- if (rc) {
- DRM_ERROR("DP display post enable failed, rc=%d\n", rc);
- msm_dp_display_disable(dp, msm_dp_panel);
+ rc = msm_dp_display_post_enable(msm_dp_display);
+ if (rc) {
+ DRM_ERROR("DP display post enable failed, rc=%d\n", rc);
+ msm_dp_display_disable(dp, msm_dp_panel);
+ }
}

drm_dbg_dp(msm_dp_display->drm_dev, "type=%d Done\n", msm_dp_display->connector_type);
@@ -1646,6 +1657,11 @@ void msm_dp_display_unprepare(struct msm_dp *msm_dp_display)

dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);

+ if (!msm_dp_display->prepared) {
+ drm_dbg_dp(dp->drm_dev, "Link already setup, return\n");
+ return;
+ }
+
if (msm_dp_display->active_stream_cnt) {
drm_dbg_dp(dp->drm_dev, "stream still active, return\n");
return;
@@ -1664,6 +1680,8 @@ void msm_dp_display_unprepare(struct msm_dp *msm_dp_display)
msm_dp_display_host_phy_exit(dp);

pm_runtime_put_sync(&msm_dp_display->pdev->dev);
+
+ msm_dp_display->prepared = false;
}

void msm_dp_display_atomic_post_disable_helper(struct msm_dp *dp, struct msm_dp_panel *msm_dp_panel)
diff --git a/drivers/gpu/drm/msm/dp/dp_display.h b/drivers/gpu/drm/msm/dp/dp_display.h
index 5f3ef295d710..bda76319c459 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.h
+++ b/drivers/gpu/drm/msm/dp/dp_display.h
@@ -22,6 +22,7 @@ struct msm_dp {
bool mst_active;
unsigned int connector_type;
bool is_edp;
+ bool prepared;

struct msm_dp_audio *msm_dp_audio;
bool psr_supported;

--
2.43.0