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

Signed-off-by: Abhinav Kumar <[email protected]>
Signed-off-by: Yongxing Mou <[email protected]>
---
 drivers/gpu/drm/msm/dp/dp_display.c | 33 +++++++++++++++++++++++++--------
 drivers/gpu/drm/msm/dp/dp_display.h |  1 +
 2 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index 49a718f4e464..487c76e0f990 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -638,6 +638,10 @@ int msm_dp_display_prepare_link(struct msm_dp 
*msm_dp_display)
        if (msm_dp_display->is_edp)
                msm_dp_hpd_plug_handle(dp);
 
+       /* Serialized by modeset lock or mst_lock. */
+       if (msm_dp_display->link_ready)
+               return 0;
+
        rc = pm_runtime_resume_and_get(&msm_dp_display->pdev->dev);
        if (rc) {
                DRM_ERROR("failed to pm_runtime_resume\n");
@@ -659,7 +663,11 @@ int msm_dp_display_prepare_link(struct msm_dp 
*msm_dp_display)
                }
        }
 
-       return msm_dp_ctrl_prepare_stream_on(dp->ctrl, dp->panel, 
force_link_train);
+       rc = msm_dp_ctrl_prepare_stream_on(dp->ctrl, dp->panel, 
force_link_train);
+       if (!rc)
+               msm_dp_display->link_ready = true;
+
+       return rc;
 }
 
 static int msm_dp_display_enable(struct msm_dp_display_private *dp,
@@ -1501,14 +1509,16 @@ void msm_dp_display_enable_helper(struct msm_dp 
*msm_dp_display,
 
        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->link_ready) {
+               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);
@@ -1565,6 +1575,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->link_ready) {
+               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;
@@ -1583,6 +1598,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->link_ready = 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 9ecd5025fe4a..51eace1d1346 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.h
+++ b/drivers/gpu/drm/msm/dp/dp_display.h
@@ -20,6 +20,7 @@ struct msm_dp {
        bool audio_enabled;
        u32 active_stream_cnt;
        bool mst_active;
+       bool link_ready;
        unsigned int connector_type;
        bool is_edp;
 

-- 
2.43.0

Reply via email to