From ddb854d52dd1bf380a80495378396fa5d2acf72e Mon Sep 17 00:00:00 2001 From: Srihitha Tangudu Date: Tue, 6 Dec 2022 14:29:02 +0530 Subject: [PATCH] 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 --- msm/dsi/dsi_ctrl.c | 57 ++++++++++++++++++++++++++----------------- msm/dsi/dsi_ctrl.h | 6 +++++ msm/dsi/dsi_display.c | 13 +++++++++- 3 files changed, 52 insertions(+), 24 deletions(-) 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 65ea7e52f1..e6917b3878 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; }