aboutsummaryrefslogtreecommitdiff
path: root/drivers/mxc/ipu3/ipu_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mxc/ipu3/ipu_common.c')
-rw-r--r--drivers/mxc/ipu3/ipu_common.c90
1 files changed, 51 insertions, 39 deletions
diff --git a/drivers/mxc/ipu3/ipu_common.c b/drivers/mxc/ipu3/ipu_common.c
index 8065145f712..5b51fe2942e 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;
}