aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap/dma.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-omap/dma.c')
-rw-r--r--arch/arm/plat-omap/dma.c95
1 files changed, 74 insertions, 21 deletions
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index 9eddc9507147..1bbb431843ce 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -119,32 +119,41 @@ static void clear_lch_regs(int lch)
119 omap_writew(0, lch_base + i); 119 omap_writew(0, lch_base + i);
120} 120}
121 121
122void omap_set_dma_priority(int dst_port, int priority) 122void omap_set_dma_priority(int lch, int dst_port, int priority)
123{ 123{
124 unsigned long reg; 124 unsigned long reg;
125 u32 l; 125 u32 l;
126 126
127 switch (dst_port) { 127 if (cpu_class_is_omap1()) {
128 case OMAP_DMA_PORT_OCP_T1: /* FFFECC00 */ 128 switch (dst_port) {
129 reg = OMAP_TC_OCPT1_PRIOR; 129 case OMAP_DMA_PORT_OCP_T1: /* FFFECC00 */
130 break; 130 reg = OMAP_TC_OCPT1_PRIOR;
131 case OMAP_DMA_PORT_OCP_T2: /* FFFECCD0 */ 131 break;
132 reg = OMAP_TC_OCPT2_PRIOR; 132 case OMAP_DMA_PORT_OCP_T2: /* FFFECCD0 */
133 break; 133 reg = OMAP_TC_OCPT2_PRIOR;
134 case OMAP_DMA_PORT_EMIFF: /* FFFECC08 */ 134 break;
135 reg = OMAP_TC_EMIFF_PRIOR; 135 case OMAP_DMA_PORT_EMIFF: /* FFFECC08 */
136 break; 136 reg = OMAP_TC_EMIFF_PRIOR;
137 case OMAP_DMA_PORT_EMIFS: /* FFFECC04 */ 137 break;
138 reg = OMAP_TC_EMIFS_PRIOR; 138 case OMAP_DMA_PORT_EMIFS: /* FFFECC04 */
139 break; 139 reg = OMAP_TC_EMIFS_PRIOR;
140 default: 140 break;
141 BUG(); 141 default:
142 return; 142 BUG();
143 return;
144 }
145 l = omap_readl(reg);
146 l &= ~(0xf << 8);
147 l |= (priority & 0xf) << 8;
148 omap_writel(l, reg);
149 }
150
151 if (cpu_is_omap24xx()) {
152 if (priority)
153 OMAP_DMA_CCR_REG(lch) |= (1 << 6);
154 else
155 OMAP_DMA_CCR_REG(lch) &= ~(1 << 6);
143 } 156 }
144 l = omap_readl(reg);
145 l &= ~(0xf << 8);
146 l |= (priority & 0xf) << 8;
147 omap_writel(l, reg);
148} 157}
149 158
150void omap_set_dma_transfer_params(int lch, int data_type, int elem_count, 159void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
@@ -234,6 +243,14 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
234 OMAP1_DMA_LCH_CTRL_REG(lch) = w; 243 OMAP1_DMA_LCH_CTRL_REG(lch) = w;
235} 244}
236 245
246void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode)
247{
248 if (cpu_is_omap24xx()) {
249 OMAP_DMA_CSDP_REG(lch) &= ~(0x3 << 16);
250 OMAP_DMA_CSDP_REG(lch) |= (mode << 16);
251 }
252}
253
237/* Note that src_port is only for omap1 */ 254/* Note that src_port is only for omap1 */
238void omap_set_dma_src_params(int lch, int src_port, int src_amode, 255void omap_set_dma_src_params(int lch, int src_port, int src_amode,
239 unsigned long src_start, 256 unsigned long src_start,
@@ -698,6 +715,32 @@ void omap_stop_dma(int lch)
698} 715}
699 716
700/* 717/*
718 * Allows changing the DMA callback function or data. This may be needed if
719 * the driver shares a single DMA channel for multiple dma triggers.
720 */
721int omap_set_dma_callback(int lch,
722 void (* callback)(int lch, u16 ch_status, void *data),
723 void *data)
724{
725 unsigned long flags;
726
727 if (lch < 0)
728 return -ENODEV;
729
730 spin_lock_irqsave(&dma_chan_lock, flags);
731 if (dma_chan[lch].dev_id == -1) {
732 printk(KERN_ERR "DMA callback for not set for free channel\n");
733 spin_unlock_irqrestore(&dma_chan_lock, flags);
734 return -EINVAL;
735 }
736 dma_chan[lch].callback = callback;
737 dma_chan[lch].data = data;
738 spin_unlock_irqrestore(&dma_chan_lock, flags);
739
740 return 0;
741}
742
743/*
701 * Returns current physical source address for the given DMA channel. 744 * Returns current physical source address for the given DMA channel.
702 * If the channel is running the caller must disable interrupts prior calling 745 * If the channel is running the caller must disable interrupts prior calling
703 * this function and process the returned value before re-enabling interrupt to 746 * this function and process the returned value before re-enabling interrupt to
@@ -1339,6 +1382,14 @@ static int __init omap_init_dma(void)
1339 dma_chan_count = 16; 1382 dma_chan_count = 16;
1340 } else 1383 } else
1341 dma_chan_count = 9; 1384 dma_chan_count = 9;
1385 if (cpu_is_omap16xx()) {
1386 u16 w;
1387
1388 /* this would prevent OMAP sleep */
1389 w = omap_readw(OMAP1610_DMA_LCD_CTRL);
1390 w &= ~(1 << 8);
1391 omap_writew(w, OMAP1610_DMA_LCD_CTRL);
1392 }
1342 } else if (cpu_is_omap24xx()) { 1393 } else if (cpu_is_omap24xx()) {
1343 u8 revision = omap_readb(OMAP_DMA4_REVISION); 1394 u8 revision = omap_readb(OMAP_DMA4_REVISION);
1344 printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n", 1395 printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n",
@@ -1414,11 +1465,13 @@ EXPORT_SYMBOL(omap_request_dma);
1414EXPORT_SYMBOL(omap_free_dma); 1465EXPORT_SYMBOL(omap_free_dma);
1415EXPORT_SYMBOL(omap_start_dma); 1466EXPORT_SYMBOL(omap_start_dma);
1416EXPORT_SYMBOL(omap_stop_dma); 1467EXPORT_SYMBOL(omap_stop_dma);
1468EXPORT_SYMBOL(omap_set_dma_callback);
1417EXPORT_SYMBOL(omap_enable_dma_irq); 1469EXPORT_SYMBOL(omap_enable_dma_irq);
1418EXPORT_SYMBOL(omap_disable_dma_irq); 1470EXPORT_SYMBOL(omap_disable_dma_irq);
1419 1471
1420EXPORT_SYMBOL(omap_set_dma_transfer_params); 1472EXPORT_SYMBOL(omap_set_dma_transfer_params);
1421EXPORT_SYMBOL(omap_set_dma_color_mode); 1473EXPORT_SYMBOL(omap_set_dma_color_mode);
1474EXPORT_SYMBOL(omap_set_dma_write_mode);
1422 1475
1423EXPORT_SYMBOL(omap_set_dma_src_params); 1476EXPORT_SYMBOL(omap_set_dma_src_params);
1424EXPORT_SYMBOL(omap_set_dma_src_index); 1477EXPORT_SYMBOL(omap_set_dma_src_index);