diff --git a/drivers/video/msm/mipi_dsi.h b/drivers/video/msm/mipi_dsi.h index 02ffe9203365..2945f0f41da5 100644 --- a/drivers/video/msm/mipi_dsi.h +++ b/drivers/video/msm/mipi_dsi.h @@ -117,6 +117,7 @@ enum dsi_trigger_type { #define DSI_INTR_CMD_DMA_DONE_MASK BIT(1) #define DSI_INTR_CMD_DMA_DONE BIT(0) +#define DSI_VIDEO_TERM BIT(16) #define DSI_MDP_TERM BIT(8) #define DSI_CMD_TERM BIT(0) diff --git a/drivers/video/msm/mipi_dsi_host.c b/drivers/video/msm/mipi_dsi_host.c index 2392fe577c64..a75675a40140 100644 --- a/drivers/video/msm/mipi_dsi_host.c +++ b/drivers/video/msm/mipi_dsi_host.c @@ -43,6 +43,7 @@ static struct completion dsi_dma_comp; static struct completion dsi_mdp_comp; +static struct completion dsi_video_comp; static struct dsi_buf dsi_tx_buf; static struct dsi_buf dsi_rx_buf; static spinlock_t dsi_irq_lock; @@ -95,6 +96,7 @@ void mipi_dsi_init(void) { init_completion(&dsi_dma_comp); init_completion(&dsi_mdp_comp); + init_completion(&dsi_video_comp); mipi_dsi_buf_alloc(&dsi_tx_buf, DSI_BUF_SIZE); mipi_dsi_buf_alloc(&dsi_rx_buf, DSI_BUF_SIZE); spin_lock_init(&dsi_irq_lock); @@ -1014,7 +1016,8 @@ void mipi_dsi_op_mode_config(int mode) dsi_ctrl &= ~0x07; if (mode == DSI_VIDEO_MODE) { dsi_ctrl |= 0x03; - intr_ctrl = DSI_INTR_CMD_DMA_DONE_MASK; + intr_ctrl = (DSI_INTR_CMD_DMA_DONE_MASK | + DSI_INTR_VIDEO_DONE_MASK); } else { /* command mode */ dsi_ctrl |= 0x05; intr_ctrl = DSI_INTR_CMD_DMA_DONE_MASK | DSI_INTR_ERROR_MASK | @@ -1028,6 +1031,19 @@ void mipi_dsi_op_mode_config(int mode) wmb(); } + +static void mipi_dsi_wait4video_done(void) +{ + unsigned long flag; + + spin_lock_irqsave(&dsi_mdp_lock, flag); + INIT_COMPLETION(dsi_video_comp); + mipi_dsi_enable_irq(DSI_VIDEO_TERM); + spin_unlock_irqrestore(&dsi_mdp_lock, flag); + + wait_for_completion(&dsi_video_comp); +} + void mipi_dsi_mdp_busy_wait(void) { mutex_lock(&cmd_mutex); @@ -1490,21 +1506,11 @@ int mipi_dsi_cmd_dma_rx(struct dsi_buf *rp, int rlen) return rlen; } -static void mipi_dsi_wait_for_video_eng_busy(void) +static void mipi_dsi_wait4video_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); + mipi_dsi_wait4video_done(); + /* delay 4 ms to skip BLLP */ + usleep(4000); } void mipi_dsi_cmd_mdp_busy(void) @@ -1605,10 +1611,10 @@ void mipi_dsi_cmdlist_commit(int from_mdp) dsi_ctrl = MIPI_INP(MIPI_DSI_BASE + 0x0000); if (dsi_ctrl & 0x02) { - /* video mode, make sure dsi_cmd_mdp is busy - * so dcs command will be txed at start of BLLP + /* video mode, make sure video engine is busy + * so dcs command will be sent at start of BLLP */ - mipi_dsi_wait_for_video_eng_busy(); + mipi_dsi_wait4video_eng_busy(); } else { /* command mode */ if (!from_mdp) { /* cmdlist_put */ @@ -1763,9 +1769,10 @@ irqreturn_t mipi_dsi_isr(int irq, void *ptr) } if (isr & DSI_INTR_VIDEO_DONE) { - /* - * do something here - */ + spin_lock(&dsi_mdp_lock); + mipi_dsi_disable_irq_nosync(DSI_VIDEO_TERM); + complete(&dsi_video_comp); + spin_unlock(&dsi_mdp_lock); } if (isr & DSI_INTR_CMD_DMA_DONE) {