From 97dcdc695a5a5eb02de73ef5de664f922c323416 Mon Sep 17 00:00:00 2001 From: Ritesh Kumar Date: Wed, 21 Oct 2020 16:56:35 +0530 Subject: [PATCH] disp: msm: dsi: invoke DSI soft reset when video engine is stuck During ESD check failure, DSI video engine can get stuck sending data from display engine. In use cases where GDSC toggle does not happen like DP MST connected or secure video playback, display does not recover back after ESD failure. This change adds support to perform soft reset when DSI video engine gets stuck. Change-Id: I9cb31e6c71c4da171f9fe22fc3bee9175711831d Signed-off-by: Ritesh Kumar --- msm/dsi/dsi_catalog.c | 1 + msm/dsi/dsi_catalog.h | 1 + msm/dsi/dsi_ctrl.c | 13 +++++++++++-- msm/dsi/dsi_ctrl_hw.h | 7 +++++++ msm/dsi/dsi_ctrl_hw_cmn.c | 15 +++++++++++++++ 5 files changed, 35 insertions(+), 2 deletions(-) diff --git a/msm/dsi/dsi_catalog.c b/msm/dsi/dsi_catalog.c index 9e67ca5033..7e63e55fee 100644 --- a/msm/dsi/dsi_catalog.c +++ b/msm/dsi/dsi_catalog.c @@ -63,6 +63,7 @@ static void dsi_catalog_cmn_init(struct dsi_ctrl_hw *ctrl, ctrl->ops.wait4dynamic_refresh_done = dsi_ctrl_hw_cmn_wait4dynamic_refresh_done; ctrl->ops.hs_req_sel = dsi_ctrl_hw_cmn_hs_req_sel; + ctrl->ops.vid_engine_busy = dsi_ctrl_hw_cmn_vid_engine_busy; switch (version) { case DSI_CTRL_VERSION_1_4: diff --git a/msm/dsi/dsi_catalog.h b/msm/dsi/dsi_catalog.h index 15bb7846dd..e49be2f735 100644 --- a/msm/dsi/dsi_catalog.h +++ b/msm/dsi/dsi_catalog.h @@ -263,6 +263,7 @@ void dsi_phy_hw_v3_0_dyn_refresh_pipe_delay(struct dsi_phy_hw *phy, struct dsi_dyn_clk_delay *delay); int dsi_ctrl_hw_cmn_wait4dynamic_refresh_done(struct dsi_ctrl_hw *ctrl); +bool dsi_ctrl_hw_cmn_vid_engine_busy(struct dsi_ctrl_hw *ctrl); int dsi_phy_hw_v3_0_cache_phy_timings(struct dsi_phy_per_lane_cfgs *timings, u32 *dst, u32 size); diff --git a/msm/dsi/dsi_ctrl.c b/msm/dsi/dsi_ctrl.c index 8caa7fc78b..c44378bcd9 100644 --- a/msm/dsi/dsi_ctrl.c +++ b/msm/dsi/dsi_ctrl.c @@ -3683,6 +3683,7 @@ int dsi_ctrl_set_vid_engine_state(struct dsi_ctrl *dsi_ctrl, { int rc = 0; bool on; + bool vid_eng_busy; if (!dsi_ctrl || (state >= DSI_CTRL_ENGINE_MAX)) { DSI_CTRL_ERR(dsi_ctrl, "Invalid params\n"); @@ -3702,9 +3703,17 @@ int dsi_ctrl_set_vid_engine_state(struct dsi_ctrl *dsi_ctrl, if (!skip_op) { on = (state == DSI_CTRL_ENGINE_ON) ? true : false; dsi_ctrl->hw.ops.video_engine_en(&dsi_ctrl->hw, on); + vid_eng_busy = dsi_ctrl->hw.ops.vid_engine_busy(&dsi_ctrl->hw); - /* perform a reset when turning off video engine */ - if (!on && dsi_ctrl->version < DSI_CTRL_VERSION_1_3) + /* + * During ESD check failure, DSI video engine can get stuck + * sending data from display engine. In use cases where GDSC + * toggle does not happen like DP MST connected or secure video + * playback, display does not recover back after ESD failure. + * Perform a reset if video engine is stuck. + */ + if (!on && (dsi_ctrl->version < DSI_CTRL_VERSION_1_3 || + vid_eng_busy)) dsi_ctrl->hw.ops.soft_reset(&dsi_ctrl->hw); } diff --git a/msm/dsi/dsi_ctrl_hw.h b/msm/dsi/dsi_ctrl_hw.h index dd1c85a7f8..04dbaa0a5e 100644 --- a/msm/dsi/dsi_ctrl_hw.h +++ b/msm/dsi/dsi_ctrl_hw.h @@ -827,6 +827,13 @@ struct dsi_ctrl_hw_ops { * @ctrl: Pointer to the controller host hardware. */ int (*wait4dynamic_refresh_done)(struct dsi_ctrl_hw *ctrl); + + /** + * hw.ops.vid_engine_busy() - Returns true if vid engine is busy + * @ctrl: Pointer to the controller host hardware. + */ + bool (*vid_engine_busy)(struct dsi_ctrl_hw *ctrl); + /** * hw.ops.hs_req_sel() - enable continuous clk support through phy * @ctrl: Pointer to the controller host hardware. diff --git a/msm/dsi/dsi_ctrl_hw_cmn.c b/msm/dsi/dsi_ctrl_hw_cmn.c index 0b4d18b32b..1a5aaf1cca 100644 --- a/msm/dsi/dsi_ctrl_hw_cmn.c +++ b/msm/dsi/dsi_ctrl_hw_cmn.c @@ -1687,3 +1687,18 @@ int dsi_ctrl_hw_cmn_wait4dynamic_refresh_done(struct dsi_ctrl_hw *ctrl) return 0; } + +bool dsi_ctrl_hw_cmn_vid_engine_busy(struct dsi_ctrl_hw *ctrl) +{ + u32 reg = 0, video_engine_busy = BIT(3); + int rc; + u32 const sleep_us = 1000; + u32 const timeout_us = 50000; + + rc = readl_poll_timeout(ctrl->base + DSI_STATUS, reg, + !(reg & video_engine_busy), sleep_us, timeout_us); + if (rc) + return true; + + return false; +}