|
@@ -119,32 +119,41 @@ static void clear_lch_regs(int lch)
|
|
|
omap_writew(0, lch_base + i);
|
|
|
}
|
|
|
|
|
|
-void omap_set_dma_priority(int dst_port, int priority)
|
|
|
+void omap_set_dma_priority(int lch, int dst_port, int priority)
|
|
|
{
|
|
|
unsigned long reg;
|
|
|
u32 l;
|
|
|
|
|
|
- switch (dst_port) {
|
|
|
- case OMAP_DMA_PORT_OCP_T1: /* FFFECC00 */
|
|
|
- reg = OMAP_TC_OCPT1_PRIOR;
|
|
|
- break;
|
|
|
- case OMAP_DMA_PORT_OCP_T2: /* FFFECCD0 */
|
|
|
- reg = OMAP_TC_OCPT2_PRIOR;
|
|
|
- break;
|
|
|
- case OMAP_DMA_PORT_EMIFF: /* FFFECC08 */
|
|
|
- reg = OMAP_TC_EMIFF_PRIOR;
|
|
|
- break;
|
|
|
- case OMAP_DMA_PORT_EMIFS: /* FFFECC04 */
|
|
|
- reg = OMAP_TC_EMIFS_PRIOR;
|
|
|
- break;
|
|
|
- default:
|
|
|
- BUG();
|
|
|
- return;
|
|
|
+ if (cpu_class_is_omap1()) {
|
|
|
+ switch (dst_port) {
|
|
|
+ case OMAP_DMA_PORT_OCP_T1: /* FFFECC00 */
|
|
|
+ reg = OMAP_TC_OCPT1_PRIOR;
|
|
|
+ break;
|
|
|
+ case OMAP_DMA_PORT_OCP_T2: /* FFFECCD0 */
|
|
|
+ reg = OMAP_TC_OCPT2_PRIOR;
|
|
|
+ break;
|
|
|
+ case OMAP_DMA_PORT_EMIFF: /* FFFECC08 */
|
|
|
+ reg = OMAP_TC_EMIFF_PRIOR;
|
|
|
+ break;
|
|
|
+ case OMAP_DMA_PORT_EMIFS: /* FFFECC04 */
|
|
|
+ reg = OMAP_TC_EMIFS_PRIOR;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ BUG();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ l = omap_readl(reg);
|
|
|
+ l &= ~(0xf << 8);
|
|
|
+ l |= (priority & 0xf) << 8;
|
|
|
+ omap_writel(l, reg);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (cpu_is_omap24xx()) {
|
|
|
+ if (priority)
|
|
|
+ OMAP_DMA_CCR_REG(lch) |= (1 << 6);
|
|
|
+ else
|
|
|
+ OMAP_DMA_CCR_REG(lch) &= ~(1 << 6);
|
|
|
}
|
|
|
- l = omap_readl(reg);
|
|
|
- l &= ~(0xf << 8);
|
|
|
- l |= (priority & 0xf) << 8;
|
|
|
- omap_writel(l, reg);
|
|
|
}
|
|
|
|
|
|
void 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)
|
|
|
OMAP1_DMA_LCH_CTRL_REG(lch) = w;
|
|
|
}
|
|
|
|
|
|
+void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode)
|
|
|
+{
|
|
|
+ if (cpu_is_omap24xx()) {
|
|
|
+ OMAP_DMA_CSDP_REG(lch) &= ~(0x3 << 16);
|
|
|
+ OMAP_DMA_CSDP_REG(lch) |= (mode << 16);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/* Note that src_port is only for omap1 */
|
|
|
void omap_set_dma_src_params(int lch, int src_port, int src_amode,
|
|
|
unsigned long src_start,
|
|
@@ -697,6 +714,32 @@ void omap_stop_dma(int lch)
|
|
|
dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Allows changing the DMA callback function or data. This may be needed if
|
|
|
+ * the driver shares a single DMA channel for multiple dma triggers.
|
|
|
+ */
|
|
|
+int omap_set_dma_callback(int lch,
|
|
|
+ void (* callback)(int lch, u16 ch_status, void *data),
|
|
|
+ void *data)
|
|
|
+{
|
|
|
+ unsigned long flags;
|
|
|
+
|
|
|
+ if (lch < 0)
|
|
|
+ return -ENODEV;
|
|
|
+
|
|
|
+ spin_lock_irqsave(&dma_chan_lock, flags);
|
|
|
+ if (dma_chan[lch].dev_id == -1) {
|
|
|
+ printk(KERN_ERR "DMA callback for not set for free channel\n");
|
|
|
+ spin_unlock_irqrestore(&dma_chan_lock, flags);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+ dma_chan[lch].callback = callback;
|
|
|
+ dma_chan[lch].data = data;
|
|
|
+ spin_unlock_irqrestore(&dma_chan_lock, flags);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Returns current physical source address for the given DMA channel.
|
|
|
* If the channel is running the caller must disable interrupts prior calling
|