dmaengine: at_hdmac: specialize AHB interfaces to optimize transfers
authorNicolas Ferre <nicolas.ferre@atmel.com>
Sat, 30 Apr 2011 14:57:49 +0000 (16:57 +0200)
committerVinod Koul <vinod.koul@intel.com>
Mon, 2 May 2011 10:12:09 +0000 (15:42 +0530)
DMA controller has two AHB interfaces on the SOC internal
matrix.
It is more efficient to specialize each interface as the
access to memory can introduce latencies that are not compatible
with peripheral accesses requirements.

Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
drivers/dma/at_hdmac.c
drivers/dma/at_hdmac_regs.h

index 65bd52a..f52c9e3 100644 (file)
@@ -37,8 +37,8 @@
 
 #define        ATC_DEFAULT_CFG         (ATC_FIFOCFG_HALFFIFO)
 #define        ATC_DEFAULT_CTRLA       (0)
-#define        ATC_DEFAULT_CTRLB       (ATC_SIF(0)     \
-                               |ATC_DIF(1))
+#define        ATC_DEFAULT_CTRLB       (ATC_SIF(AT_DMA_MEM_IF) \
+                               |ATC_DIF(AT_DMA_MEM_IF))
 
 /*
  * Initial number of descriptors to allocate for each channel. This could
@@ -693,14 +693,15 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
        reg_width = atslave->reg_width;
 
        ctrla = ATC_DEFAULT_CTRLA | atslave->ctrla;
-       ctrlb = ATC_DEFAULT_CTRLB | ATC_IEN;
+       ctrlb = ATC_IEN;
 
        switch (direction) {
        case DMA_TO_DEVICE:
                ctrla |=  ATC_DST_WIDTH(reg_width);
                ctrlb |=  ATC_DST_ADDR_MODE_FIXED
                        | ATC_SRC_ADDR_MODE_INCR
-                       | ATC_FC_MEM2PER;
+                       | ATC_FC_MEM2PER
+                       | ATC_SIF(AT_DMA_MEM_IF) | ATC_DIF(AT_DMA_PER_IF);
                reg = atslave->tx_reg;
                for_each_sg(sgl, sg, sg_len, i) {
                        struct at_desc  *desc;
@@ -741,7 +742,8 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
                ctrla |=  ATC_SRC_WIDTH(reg_width);
                ctrlb |=  ATC_DST_ADDR_MODE_INCR
                        | ATC_SRC_ADDR_MODE_FIXED
-                       | ATC_FC_PER2MEM;
+                       | ATC_FC_PER2MEM
+                       | ATC_SIF(AT_DMA_PER_IF) | ATC_DIF(AT_DMA_MEM_IF);
 
                reg = atslave->rx_reg;
                for_each_sg(sgl, sg, sg_len, i) {
@@ -846,20 +848,22 @@ atc_dma_cyclic_fill_desc(struct at_dma_slave *atslave, struct at_desc *desc,
                desc->lli.saddr = buf_addr + (period_len * period_index);
                desc->lli.daddr = atslave->tx_reg;
                desc->lli.ctrla = ctrla;
-               desc->lli.ctrlb = ATC_DEFAULT_CTRLB
-                               | ATC_DST_ADDR_MODE_FIXED
+               desc->lli.ctrlb = ATC_DST_ADDR_MODE_FIXED
                                | ATC_SRC_ADDR_MODE_INCR
-                               | ATC_FC_MEM2PER;
+                               | ATC_FC_MEM2PER
+                               | ATC_SIF(AT_DMA_MEM_IF)
+                               | ATC_DIF(AT_DMA_PER_IF);
                break;
 
        case DMA_FROM_DEVICE:
                desc->lli.saddr = atslave->rx_reg;
                desc->lli.daddr = buf_addr + (period_len * period_index);
                desc->lli.ctrla = ctrla;
-               desc->lli.ctrlb = ATC_DEFAULT_CTRLB
-                               | ATC_DST_ADDR_MODE_INCR
+               desc->lli.ctrlb = ATC_DST_ADDR_MODE_INCR
                                | ATC_SRC_ADDR_MODE_FIXED
-                               | ATC_FC_PER2MEM;
+                               | ATC_FC_PER2MEM
+                               | ATC_SIF(AT_DMA_PER_IF)
+                               | ATC_DIF(AT_DMA_MEM_IF);
                break;
 
        default:
index c79a9e0..ae3056d 100644 (file)
 /* Bitfields in CTRLB */
 #define        ATC_SIF(i)              (0x3 & (i))     /* Src tx done via AHB-Lite Interface i */
 #define        ATC_DIF(i)              ((0x3 & (i)) <<  4)     /* Dst tx done via AHB-Lite Interface i */
+                                 /* Specify AHB interfaces */
+#define AT_DMA_MEM_IF          0 /* interface 0 as memory interface */
+#define AT_DMA_PER_IF          1 /* interface 1 as peripheral interface */
+
 #define        ATC_SRC_PIP             (0x1 <<  8)     /* Source Picture-in-Picture enabled */
 #define        ATC_DST_PIP             (0x1 << 12)     /* Destination Picture-in-Picture enabled */
 #define        ATC_SRC_DSCR_DIS        (0x1 << 16)     /* Src Descriptor fetch disable */