dmaengine: omap-dma: consolidate setup of CCR
authorRussell King <rmk+kernel@arm.linux.org.uk>
Sat, 2 Nov 2013 19:16:09 +0000 (19:16 +0000)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Thu, 3 Apr 2014 23:27:59 +0000 (00:27 +0100)
Consolidate the setup of the channel control register.  Prepare the
basic value in the preparation of the DMA descriptor, and write it into
the register upon descriptor execution.

Acked-by: Tony Lindgren <tony@atomide.com>
Acked-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
drivers/dma/omap-dma.c

index ec7cc10d45949e4ee738435618328ce454c41b1e..9a9e81907475c83f901238e103f2400f10c3a164 100644 (file)
@@ -58,8 +58,7 @@ struct omap_desc {
 
        int16_t fi;             /* for OMAP_DMA_SYNC_PACKET */
        uint8_t es;             /* OMAP_DMA_DATA_TYPE_xxx */
-       uint8_t sync_mode;      /* OMAP_DMA_SYNC_xxx */
-       uint8_t sync_type;      /* OMAP_DMA_xxx_SYNC* */
+       uint32_t ccr;           /* CCR value */
        uint16_t cicr;          /* CICR value */
        uint32_t csdp;          /* CSDP value */
 
@@ -227,7 +226,6 @@ static void omap_dma_start_desc(struct omap_chan *c)
 {
        struct virt_dma_desc *vd = vchan_next_desc(&c->vc);
        struct omap_desc *d;
-       uint32_t val;
 
        if (!vd) {
                c->desc = NULL;
@@ -239,23 +237,15 @@ static void omap_dma_start_desc(struct omap_chan *c)
        c->desc = d = to_omap_dma_desc(&vd->tx);
        c->sgidx = 0;
 
-       if (d->dir == DMA_DEV_TO_MEM) {
-               val = c->plat->dma_read(CCR, c->dma_ch);
-               val &= ~(0x03 << 14 | 0x03 << 12);
-               val |= OMAP_DMA_AMODE_POST_INC << 14;
-               val |= OMAP_DMA_AMODE_CONSTANT << 12;
-               c->plat->dma_write(val, CCR, c->dma_ch);
+       c->plat->dma_write(d->ccr, CCR, c->dma_ch);
+       if (dma_omap1())
+               c->plat->dma_write(d->ccr >> 16, CCR2, c->dma_ch);
 
+       if (d->dir == DMA_DEV_TO_MEM) {
                c->plat->dma_write(d->dev_addr, CSSA, c->dma_ch);
                c->plat->dma_write(0, CSEI, c->dma_ch);
                c->plat->dma_write(d->fi, CSFI, c->dma_ch);
        } else {
-               val = c->plat->dma_read(CCR, c->dma_ch);
-               val &= ~(0x03 << 12 | 0x03 << 14);
-               val |= OMAP_DMA_AMODE_CONSTANT << 14;
-               val |= OMAP_DMA_AMODE_POST_INC << 12;
-               c->plat->dma_write(val, CCR, c->dma_ch);
-
                c->plat->dma_write(d->dev_addr, CDSA, c->dma_ch);
                c->plat->dma_write(0, CDEI, c->dma_ch);
                c->plat->dma_write(d->fi, CDFI, c->dma_ch);
@@ -263,45 +253,6 @@ static void omap_dma_start_desc(struct omap_chan *c)
 
        c->plat->dma_write(d->csdp, CSDP, c->dma_ch);
 
-       if (dma_omap1()) {
-               val = c->plat->dma_read(CCR, c->dma_ch);
-               val &= ~(1 << 5);
-               if (d->sync_mode == OMAP_DMA_SYNC_FRAME)
-                       val |= 1 << 5;
-               c->plat->dma_write(val, CCR, c->dma_ch);
-
-               val = c->plat->dma_read(CCR2, c->dma_ch);
-               val &= ~(1 << 2);
-               if (d->sync_mode == OMAP_DMA_SYNC_BLOCK)
-                       val |= 1 << 2;
-               c->plat->dma_write(val, CCR2, c->dma_ch);
-       } else if (c->dma_sig) {
-               val = c->plat->dma_read(CCR, c->dma_ch);
-
-               /* DMA_SYNCHRO_CONTROL_UPPER depends on the channel number */
-               val &= ~(1 << 24 | 1 << 23 | 3 << 19 | 1 << 18 | 1 << 5 | 0x1f);
-               val |= (c->dma_sig & ~0x1f) << 14;
-               val |= c->dma_sig & 0x1f;
-
-               if (d->sync_mode & OMAP_DMA_SYNC_FRAME)
-                       val |= 1 << 5;
-
-               if (d->sync_mode & OMAP_DMA_SYNC_BLOCK)
-                       val |= 1 << 18;
-
-               switch (d->sync_type) {
-               case OMAP_DMA_DST_SYNC_PREFETCH:/* dest synch */
-                       val |= 1 << 23;         /* Prefetch */
-                       break;
-               case 0:
-                       break;
-               default:
-                       val |= 1 << 24;         /* source synch */
-                       break;
-               }
-               c->plat->dma_write(val, CCR, c->dma_ch);
-       }
-
        omap_dma_start_sg(c, d, 0);
 }
 
@@ -540,19 +491,17 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
        struct scatterlist *sgent;
        struct omap_desc *d;
        dma_addr_t dev_addr;
-       unsigned i, j = 0, es, en, frame_bytes, sync_type;
+       unsigned i, j = 0, es, en, frame_bytes;
        u32 burst;
 
        if (dir == DMA_DEV_TO_MEM) {
                dev_addr = c->cfg.src_addr;
                dev_width = c->cfg.src_addr_width;
                burst = c->cfg.src_maxburst;
-               sync_type = OMAP_DMA_SRC_SYNC;
        } else if (dir == DMA_MEM_TO_DEV) {
                dev_addr = c->cfg.dst_addr;
                dev_width = c->cfg.dst_addr_width;
                burst = c->cfg.dst_maxburst;
-               sync_type = OMAP_DMA_DST_SYNC;
        } else {
                dev_err(chan->device->dev, "%s: bad direction?\n", __func__);
                return NULL;
@@ -581,12 +530,28 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
        d->dir = dir;
        d->dev_addr = dev_addr;
        d->es = es;
-       d->sync_mode = OMAP_DMA_SYNC_FRAME;
-       d->sync_type = sync_type;
+
+       d->ccr = 0;
+       if (dir == DMA_DEV_TO_MEM)
+               d->ccr |= OMAP_DMA_AMODE_POST_INC << 14 |
+                         OMAP_DMA_AMODE_CONSTANT << 12;
+       else
+               d->ccr |= OMAP_DMA_AMODE_CONSTANT << 14 |
+                         OMAP_DMA_AMODE_POST_INC << 12;
+
        d->cicr = OMAP_DMA_DROP_IRQ | OMAP_DMA_BLOCK_IRQ;
        d->csdp = es;
 
        if (dma_omap1()) {
+               d->ccr |= 1 << 5; /* frame sync */
+               if (__dma_omap16xx(od->plat->dma_attr)) {
+                       d->ccr |= 1 << 10; /* disable 3.0/3.1 compatibility mode */
+                       /* Duplicate what plat-omap/dma.c does */
+                       d->ccr |= c->dma_ch + 1;
+               } else {
+                       d->ccr |= c->dma_sig & 0x1f;
+               }
+
                d->cicr |= OMAP1_DMA_TOUT_IRQ;
 
                if (dir == DMA_DEV_TO_MEM)
@@ -596,6 +561,13 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
                        d->csdp |= OMAP_DMA_PORT_TIPB << 9 |
                                   OMAP_DMA_PORT_EMIFF << 2;
        } else {
+               d->ccr |= (c->dma_sig & ~0x1f) << 14;
+               d->ccr |= c->dma_sig & 0x1f;
+               d->ccr |= 1 << 5; /* frame sync */
+
+               if (dir == DMA_DEV_TO_MEM)
+                       d->ccr |= 1 << 24; /* source synch */
+
                d->cicr |= OMAP2_DMA_MISALIGNED_ERR_IRQ | OMAP2_DMA_TRANS_ERR_IRQ;
        }
 
@@ -632,19 +604,17 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
        enum dma_slave_buswidth dev_width;
        struct omap_desc *d;
        dma_addr_t dev_addr;
-       unsigned es, sync_type;
+       unsigned es;
        u32 burst;
 
        if (dir == DMA_DEV_TO_MEM) {
                dev_addr = c->cfg.src_addr;
                dev_width = c->cfg.src_addr_width;
                burst = c->cfg.src_maxburst;
-               sync_type = OMAP_DMA_SRC_SYNC;
        } else if (dir == DMA_MEM_TO_DEV) {
                dev_addr = c->cfg.dst_addr;
                dev_width = c->cfg.dst_addr_width;
                burst = c->cfg.dst_maxburst;
-               sync_type = OMAP_DMA_DST_SYNC;
        } else {
                dev_err(chan->device->dev, "%s: bad direction?\n", __func__);
                return NULL;
@@ -674,15 +644,21 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
        d->dev_addr = dev_addr;
        d->fi = burst;
        d->es = es;
-       if (burst)
-               d->sync_mode = OMAP_DMA_SYNC_PACKET;
-       else
-               d->sync_mode = OMAP_DMA_SYNC_ELEMENT;
-       d->sync_type = sync_type;
        d->sg[0].addr = buf_addr;
        d->sg[0].en = period_len / es_bytes[es];
        d->sg[0].fn = buf_len / period_len;
        d->sglen = 1;
+
+       d->ccr = 0;
+       if (__dma_omap15xx(od->plat->dma_attr))
+               d->ccr = 3 << 8;
+       if (dir == DMA_DEV_TO_MEM)
+               d->ccr |= OMAP_DMA_AMODE_POST_INC << 14 |
+                         OMAP_DMA_AMODE_CONSTANT << 12;
+       else
+               d->ccr |= OMAP_DMA_AMODE_CONSTANT << 14 |
+                         OMAP_DMA_AMODE_POST_INC << 12;
+
        d->cicr = OMAP_DMA_DROP_IRQ;
        if (flags & DMA_PREP_INTERRUPT)
                d->cicr |= OMAP_DMA_FRAME_IRQ;
@@ -690,6 +666,14 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
        d->csdp = es;
 
        if (dma_omap1()) {
+               if (__dma_omap16xx(od->plat->dma_attr)) {
+                       d->ccr |= 1 << 10; /* disable 3.0/3.1 compatibility mode */
+                       /* Duplicate what plat-omap/dma.c does */
+                       d->ccr |= c->dma_ch + 1;
+               } else {
+                       d->ccr |= c->dma_sig & 0x1f;
+               }
+
                d->cicr |= OMAP1_DMA_TOUT_IRQ;
 
                if (dir == DMA_DEV_TO_MEM)
@@ -699,23 +683,22 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
                        d->csdp |= OMAP_DMA_PORT_MPUI << 9 |
                                   OMAP_DMA_PORT_EMIFF << 2;
        } else {
+               d->ccr |= (c->dma_sig & ~0x1f) << 14;
+               d->ccr |= c->dma_sig & 0x1f;
+
+               if (burst)
+                       d->ccr |= 1 << 18 | 1 << 5; /* packet */
+
+               if (dir == DMA_DEV_TO_MEM)
+                       d->ccr |= 1 << 24; /* source synch */
+
                d->cicr |= OMAP2_DMA_MISALIGNED_ERR_IRQ | OMAP2_DMA_TRANS_ERR_IRQ;
 
                /* src and dst burst mode 16 */
                d->csdp |= 3 << 14 | 3 << 7;
        }
 
-       if (!c->cyclic) {
-               c->cyclic = true;
-
-               if (__dma_omap15xx(od->plat->dma_attr)) {
-                       uint32_t val;
-
-                       val = c->plat->dma_read(CCR, c->dma_ch);
-                       val |= 3 << 8;
-                       c->plat->dma_write(val, CCR, c->dma_ch);
-               }
-       }
+       c->cyclic = true;
 
        return vchan_tx_prep(&c->vc, &d->vd, flags);
 }
@@ -759,14 +742,6 @@ static int omap_dma_terminate_all(struct omap_chan *c)
        if (c->cyclic) {
                c->cyclic = false;
                c->paused = false;
-
-               if (__dma_omap15xx(od->plat->dma_attr)) {
-                       uint32_t val;
-
-                       val = c->plat->dma_read(CCR, c->dma_ch);
-                       val &= ~(3 << 8);
-                       c->plat->dma_write(val, CCR, c->dma_ch);
-               }
        }
 
        vchan_get_all_descriptors(&c->vc, &head);