diff options
Diffstat (limited to 'drivers/mxc/ipu3/ipu_common.c')
-rw-r--r-- | drivers/mxc/ipu3/ipu_common.c | 90 |
1 files changed, 51 insertions, 39 deletions
diff --git a/drivers/mxc/ipu3/ipu_common.c b/drivers/mxc/ipu3/ipu_common.c index 8065145f7125..5b51fe2942ed 100644 --- a/drivers/mxc/ipu3/ipu_common.c +++ b/drivers/mxc/ipu3/ipu_common.c @@ -1,5 +1,5 @@ /* - * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2005-2010 Freescale Semiconductor, Inc. All Rights Reserved. */ /* @@ -1751,6 +1751,44 @@ int32_t ipu_enable_channel(ipu_channel_t channel) } EXPORT_SYMBOL(ipu_enable_channel); +/*! + * This function clear buffer ready for a logical channel. + * + * @param channel Input parameter for the logical channel ID. + * + * @param type Input parameter which buffer to clear. + * + * @param bufNum Input parameter for which buffer number clear + * ready state. + * + */ +void ipu_clear_buffer_ready(ipu_channel_t channel, ipu_buffer_t type, + uint32_t bufNum) +{ + unsigned long lock_flags; + uint32_t dma_ch = channel_2_dma(channel, type); + + if (!idma_is_valid(dma_ch)) + return; + + spin_lock_irqsave(&ipu_lock, lock_flags); + + __raw_writel(0xF0000000, IPU_GPR); /* write one to clear */ + if (bufNum == 0) { + if (idma_is_set(IPU_CHA_BUF0_RDY, dma_ch)) { + __raw_writel(idma_mask(dma_ch), + IPU_CHA_BUF0_RDY(dma_ch)); + } + } else { + if (idma_is_set(IPU_CHA_BUF1_RDY, dma_ch)) { + __raw_writel(idma_mask(dma_ch), + IPU_CHA_BUF1_RDY(dma_ch)); + } + } + __raw_writel(0x0, IPU_GPR); /* write one to set */ + spin_unlock_irqrestore(&ipu_lock, lock_flags); +} + static irqreturn_t disable_chan_irq_handler(int irq, void *dev_id) { struct completion *comp = dev_id; @@ -1882,53 +1920,27 @@ int32_t ipu_disable_channel(ipu_channel_t channel, bool wait_for_stop) __raw_writel(idma_mask(thrd_dma), IPU_CHA_CUR_BUF(thrd_dma)); } + g_channel_enable_mask &= ~(1L << IPU_CHAN_ID(channel)); + + spin_unlock_irqrestore(&ipu_lock, lock_flags); + /* Set channel buffers NOT to be ready */ - __raw_writel(0xF0000000, IPU_GPR); /* write one to clear */ if (idma_is_valid(in_dma)) { - if (idma_is_set(IPU_CHA_BUF0_RDY, in_dma)) { - __raw_writel(idma_mask(in_dma), - IPU_CHA_BUF0_RDY(in_dma)); - } - if (idma_is_set(IPU_CHA_BUF1_RDY, in_dma)) { - __raw_writel(idma_mask(in_dma), - IPU_CHA_BUF1_RDY(in_dma)); - } + ipu_clear_buffer_ready(channel, IPU_VIDEO_IN_BUFFER, 0); + ipu_clear_buffer_ready(channel, IPU_VIDEO_IN_BUFFER, 1); } if (idma_is_valid(out_dma)) { - if (idma_is_set(IPU_CHA_BUF0_RDY, out_dma)) { - __raw_writel(idma_mask(out_dma), - IPU_CHA_BUF0_RDY(out_dma)); - } - if (idma_is_set(IPU_CHA_BUF1_RDY, out_dma)) { - __raw_writel(idma_mask(out_dma), - IPU_CHA_BUF1_RDY(out_dma)); - } + ipu_clear_buffer_ready(channel, IPU_OUTPUT_BUFFER, 0); + ipu_clear_buffer_ready(channel, IPU_OUTPUT_BUFFER, 1); } if (g_sec_chan_en[IPU_CHAN_ID(channel)] && idma_is_valid(sec_dma)) { - if (idma_is_set(IPU_CHA_BUF0_RDY, sec_dma)) { - __raw_writel(idma_mask(sec_dma), - IPU_CHA_BUF0_RDY(sec_dma)); - } - if (idma_is_set(IPU_CHA_BUF1_RDY, sec_dma)) { - __raw_writel(idma_mask(sec_dma), - IPU_CHA_BUF1_RDY(sec_dma)); - } + ipu_clear_buffer_ready(channel, IPU_GRAPH_IN_BUFFER, 0); + ipu_clear_buffer_ready(channel, IPU_GRAPH_IN_BUFFER, 1); } if (g_thrd_chan_en[IPU_CHAN_ID(channel)] && idma_is_valid(thrd_dma)) { - if (idma_is_set(IPU_CHA_BUF0_RDY, thrd_dma)) { - __raw_writel(idma_mask(thrd_dma), - IPU_CHA_BUF0_RDY(thrd_dma)); - } - if (idma_is_set(IPU_CHA_BUF1_RDY, thrd_dma)) { - __raw_writel(idma_mask(thrd_dma), - IPU_CHA_BUF1_RDY(thrd_dma)); - } + ipu_clear_buffer_ready(channel, IPU_ALPHA_IN_BUFFER, 0); + ipu_clear_buffer_ready(channel, IPU_ALPHA_IN_BUFFER, 1); } - __raw_writel(0x0, IPU_GPR); /* write one to set */ - - g_channel_enable_mask &= ~(1L << IPU_CHAN_ID(channel)); - - spin_unlock_irqrestore(&ipu_lock, lock_flags); return 0; } |