diff --git a/drivers/video/msm/mipi_dsi_host.c b/drivers/video/msm/mipi_dsi_host.c index 527b0c84c876..02d28d7396df 100644 --- a/drivers/video/msm/mipi_dsi_host.c +++ b/drivers/video/msm/mipi_dsi_host.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -1488,6 +1489,23 @@ int mipi_dsi_cmd_dma_rx(struct dsi_buf *rp, int rlen) return rlen; } +static void mipi_dsi_wait_for_video_eng_busy(void) +{ + u32 status; + int sleep_us = 4000; + + /* + * if video mode engine was not busy (in BLLP) + * wait to pass BLLP + */ + + /* check for VIDEO_MODE_ENGINE_BUSY */ + readl_poll((MIPI_DSI_BASE + 0x0004), /* DSI_STATUS */ + status, + (status & 0x08), + sleep_us); +} + void mipi_dsi_cmd_mdp_busy(void) { u32 status; @@ -1563,6 +1581,7 @@ void mipi_dsi_cmdlist_commit(int from_mdp) { struct dcs_cmd_req *req; int video; + u32 dsi_ctrl; mutex_lock(&cmd_mutex); req = mipi_dsi_cmdlist_get(); @@ -1579,9 +1598,18 @@ void mipi_dsi_cmdlist_commit(int from_mdp) pr_debug("%s: from_mdp=%d pid=%d\n", __func__, from_mdp, current->pid); - if (!from_mdp) { /* from put */ - /* make sure dsi_cmd_mdp is idle */ - mipi_dsi_cmd_mdp_busy(); + dsi_ctrl = MIPI_INP(MIPI_DSI_BASE + 0x0000); + if (dsi_ctrl & 0x02) { + /* video mode, make sure dsi_cmd_mdp is busy + * sodcs command will be txed at start of BLLP + */ + mipi_dsi_wait_for_video_eng_busy(); + } else { + /* command mode */ + if (!from_mdp) { /* cmdlist_put */ + /* make sure dsi_cmd_mdp is idle */ + mipi_dsi_cmd_mdp_busy(); + } } if (req->flags & CMD_REQ_RX)