Преглед на файлове

disp: msm: dsi: add new function to cleanup post command transfer

Currently we are always doing command transfer cleanup which includes
disabling command engine, clocks, gdsc and unmasking overflow interrupt
as part of post command transfer function only after CMD DMA wait is
done. Cleanup should also be done if an ESD failure happens before
kickoff of a batch command. Organize code so that command transfer
cleanup can be done irrespective of whether command kickoff is done
or not.

Change-Id: Ieb92daa7f5da62c16c71f1b23ceff20adfbf3621
Signed-off-by: Srihitha Tangudu <[email protected]>
Srihitha Tangudu преди 2 години
родител
ревизия
ddb854d52d
променени са 3 файла, в които са добавени 52 реда и са изтрити 24 реда
  1. 34 23
      msm/dsi/dsi_ctrl.c
  2. 6 0
      msm/dsi/dsi_ctrl.h
  3. 12 1
      msm/dsi/dsi_display.c

+ 34 - 23
msm/dsi/dsi_ctrl.c

@@ -429,10 +429,7 @@ static void dsi_ctrl_clear_dma_status(struct dsi_ctrl *dsi_ctrl)
 
 static void dsi_ctrl_post_cmd_transfer(struct dsi_ctrl *dsi_ctrl)
 {
-	int rc = 0;
 	struct dsi_ctrl_hw_ops dsi_hw_ops = dsi_ctrl->hw.ops;
-	struct dsi_clk_ctrl_info clk_info;
-	u32 mask = BIT(DSI_FIFO_OVERFLOW);
 
 	mutex_lock(&dsi_ctrl->ctrl_lock);
 
@@ -451,26 +448,9 @@ static void dsi_ctrl_post_cmd_transfer(struct dsi_ctrl *dsi_ctrl)
 		dsi_hw_ops.reset_trig_ctrl(&dsi_ctrl->hw,
 				&dsi_ctrl->host_config.common_config);
 
-	/* Command engine disable, unmask overflow, remove vote on clocks and gdsc */
-	rc = dsi_ctrl_set_cmd_engine_state(dsi_ctrl, DSI_CTRL_ENGINE_OFF, false);
-	if (rc)
-		DSI_CTRL_ERR(dsi_ctrl, "failed to disable command engine\n");
-
-	if (!(dsi_ctrl->pending_cmd_flags & DSI_CTRL_CMD_READ))
-		dsi_ctrl_mask_error_status_interrupts(dsi_ctrl, mask, false);
-
 	mutex_unlock(&dsi_ctrl->ctrl_lock);
 
-	clk_info.client = DSI_CLK_REQ_DSI_CLIENT;
-	clk_info.clk_type = DSI_ALL_CLKS;
-	clk_info.clk_state = DSI_CLK_OFF;
-
-	rc = dsi_ctrl->clk_cb.dsi_clk_cb(dsi_ctrl->clk_cb.priv, clk_info);
-	if (rc)
-		DSI_CTRL_ERR(dsi_ctrl, "failed to disable clocks\n");
-
-	(void)pm_runtime_put_sync(dsi_ctrl->drm_dev->dev);
-
+	dsi_ctrl_transfer_cleanup(dsi_ctrl);
 }
 
 static void dsi_ctrl_post_cmd_transfer_work(struct work_struct *work)
@@ -3524,6 +3504,37 @@ int dsi_ctrl_cmd_transfer(struct dsi_ctrl *dsi_ctrl, struct dsi_cmd_desc *cmd)
 	return rc;
 }
 
+void dsi_ctrl_transfer_cleanup(struct dsi_ctrl *dsi_ctrl)
+{
+	int rc = 0;
+	struct dsi_clk_ctrl_info clk_info;
+	u32 mask = BIT(DSI_FIFO_OVERFLOW);
+
+	mutex_lock(&dsi_ctrl->ctrl_lock);
+
+	SDE_EVT32(SDE_EVTLOG_FUNC_ENTRY, dsi_ctrl->cell_index, dsi_ctrl->pending_cmd_flags);
+
+	/* Command engine disable, unmask overflow, remove vote on clocks and gdsc */
+	rc = dsi_ctrl_set_cmd_engine_state(dsi_ctrl, DSI_CTRL_ENGINE_OFF, false);
+	if (rc)
+		DSI_CTRL_ERR(dsi_ctrl, "failed to disable command engine\n");
+
+	if (!(dsi_ctrl->pending_cmd_flags & DSI_CTRL_CMD_READ))
+		dsi_ctrl_mask_error_status_interrupts(dsi_ctrl, mask, false);
+
+	mutex_unlock(&dsi_ctrl->ctrl_lock);
+
+	clk_info.client = DSI_CLK_REQ_DSI_CLIENT;
+	clk_info.clk_type = DSI_ALL_CLKS;
+	clk_info.clk_state = DSI_CLK_OFF;
+
+	rc = dsi_ctrl->clk_cb.dsi_clk_cb(dsi_ctrl->clk_cb.priv, clk_info);
+	if (rc)
+		DSI_CTRL_ERR(dsi_ctrl, "failed to disable clocks\n");
+
+	(void)pm_runtime_put_sync(dsi_ctrl->drm_dev->dev);
+}
+
 /**
  * dsi_ctrl_transfer_unprepare() - Clean up post a command transfer
  * @dsi_ctrl:                 DSI controller handle.
@@ -3540,13 +3551,13 @@ void dsi_ctrl_transfer_unprepare(struct dsi_ctrl *dsi_ctrl, u32 flags)
 	if (!dsi_ctrl)
 		return;
 
+	dsi_ctrl->pending_cmd_flags = flags;
+
 	if (!(flags & DSI_CTRL_CMD_LAST_COMMAND))
 		return;
 
 	SDE_EVT32(SDE_EVTLOG_FUNC_ENTRY, dsi_ctrl->cell_index, flags);
 
-	dsi_ctrl->pending_cmd_flags = flags;
-
 	if (flags & DSI_CTRL_CMD_ASYNC_WAIT) {
 		dsi_ctrl->post_tx_queued = true;
 		queue_work(dsi_ctrl->post_cmd_tx_workq, &dsi_ctrl->post_cmd_tx_work);

+ 6 - 0
msm/dsi/dsi_ctrl.h

@@ -946,4 +946,10 @@ int dsi_ctrl_get_io_resources(struct msm_io_res *io_res);
  * dsi_ctrl_toggle_error_interrupt_status() - Toggles error interrupt status
  */
 void dsi_ctrl_toggle_error_interrupt_status(struct dsi_ctrl *dsi_ctrl, bool enable);
+
+/**
+ * dsi_ctrl_transfer_cleanup() - Clean up post command transfer
+ * @dsi_ctrl:                 DSI controller handle.
+ */
+void dsi_ctrl_transfer_cleanup(struct dsi_ctrl *dsi_ctrl);
 #endif /* _DSI_CTRL_H_ */

+ 12 - 1
msm/dsi/dsi_display.c

@@ -3399,7 +3399,8 @@ static int dsi_host_detach(struct mipi_dsi_host *host,
 int dsi_host_transfer_sub(struct mipi_dsi_host *host, struct dsi_cmd_desc *cmd)
 {
 	struct dsi_display *display;
-	int rc = 0;
+	struct dsi_display_ctrl *ctrl;
+	int i, rc = 0;
 
 	if (!host || !cmd) {
 		DSI_ERR("Invalid params\n");
@@ -3414,6 +3415,16 @@ int dsi_host_transfer_sub(struct mipi_dsi_host *host, struct dsi_cmd_desc *cmd)
 	/* Avoid sending DCS commands when ESD recovery is pending */
 	if (atomic_read(&display->panel->esd_recovery_pending)) {
 		DSI_DEBUG("ESD recovery pending\n");
+		display_for_each_ctrl(i, display) {
+			ctrl = &display->ctrl[i];
+			if ((!ctrl) || (!ctrl->ctrl))
+				continue;
+			if ((ctrl->ctrl->pending_cmd_flags & DSI_CTRL_CMD_FETCH_MEMORY) &&
+				ctrl->ctrl->cmd_len != 0) {
+				dsi_ctrl_transfer_cleanup(ctrl->ctrl);
+				ctrl->ctrl->cmd_len = 0;
+			}
+		}
 		return 0;
 	}