diff --git a/msm/dsi/dsi_ctrl.c b/msm/dsi/dsi_ctrl.c index f3940b768a..6169d55cb1 100644 --- a/msm/dsi/dsi_ctrl.c +++ b/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); diff --git a/msm/dsi/dsi_ctrl.h b/msm/dsi/dsi_ctrl.h index 766501382c..cf8cb1a638 100644 --- a/msm/dsi/dsi_ctrl.h +++ b/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_ */ diff --git a/msm/dsi/dsi_display.c b/msm/dsi/dsi_display.c index 8262642be3..42b0e7cb94 100644 --- a/msm/dsi/dsi_display.c +++ b/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; }