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
