Эх сурвалжийг харах

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 <[email protected]>
Ritesh Kumar 4 жил өмнө
parent
commit
97dcdc695a

+ 1 - 0
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:

+ 1 - 0
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);
 

+ 11 - 2
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);
 	}
 

+ 7 - 0
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.

+ 15 - 0
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;
+}