aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Jarzmik <robert.jarzmik@free.fr>2016-02-16 16:54:02 -0500
committerVinod Koul <vinod.koul@intel.com>2016-03-03 10:36:45 -0500
commitf16921275cc3c2442d0b95225785a601603b990f (patch)
tree712526e22bfe1e38ce5615f5c0530a47c03ccd68
parent81f70ba233d5f660e1ea5fe23260ee323af5d53a (diff)
dmaengine: pxa_dma: fix cyclic transfers
While testing audio with pxa2xx-ac97, underrun were happening while the user application was correctly feeding the music. Debug proved that the cyclic transfer is not cyclic, ie. the last descriptor did not loop on the first. Another issue is that the descriptor length was always set to 8192, because of an trivial operator issue. This was tested on a pxa27x platform. Fixes: a57e16cf0333 ("dmaengine: pxa: add pxa dmaengine driver") Reported-by: Vasily Khoruzhick <anarsoul@gmail.com> Tested-by: Vasily Khoruzhick <anarsoul@gmail.com> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
-rw-r--r--drivers/dma/pxa_dma.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/drivers/dma/pxa_dma.c b/drivers/dma/pxa_dma.c
index f2a0310ae771..debca824bed6 100644
--- a/drivers/dma/pxa_dma.c
+++ b/drivers/dma/pxa_dma.c
@@ -583,6 +583,8 @@ static void set_updater_desc(struct pxad_desc_sw *sw_desc,
583 (PXA_DCMD_LENGTH & sizeof(u32)); 583 (PXA_DCMD_LENGTH & sizeof(u32));
584 if (flags & DMA_PREP_INTERRUPT) 584 if (flags & DMA_PREP_INTERRUPT)
585 updater->dcmd |= PXA_DCMD_ENDIRQEN; 585 updater->dcmd |= PXA_DCMD_ENDIRQEN;
586 if (sw_desc->cyclic)
587 sw_desc->hw_desc[sw_desc->nb_desc - 2]->ddadr = sw_desc->first;
586} 588}
587 589
588static bool is_desc_completed(struct virt_dma_desc *vd) 590static bool is_desc_completed(struct virt_dma_desc *vd)
@@ -673,6 +675,10 @@ static irqreturn_t pxad_chan_handler(int irq, void *dev_id)
673 dev_dbg(&chan->vc.chan.dev->device, 675 dev_dbg(&chan->vc.chan.dev->device,
674 "%s(): checking txd %p[%x]: completed=%d\n", 676 "%s(): checking txd %p[%x]: completed=%d\n",
675 __func__, vd, vd->tx.cookie, is_desc_completed(vd)); 677 __func__, vd, vd->tx.cookie, is_desc_completed(vd));
678 if (to_pxad_sw_desc(vd)->cyclic) {
679 vchan_cyclic_callback(vd);
680 break;
681 }
676 if (is_desc_completed(vd)) { 682 if (is_desc_completed(vd)) {
677 list_del(&vd->node); 683 list_del(&vd->node);
678 vchan_cookie_complete(vd); 684 vchan_cookie_complete(vd);
@@ -1080,7 +1086,7 @@ pxad_prep_dma_cyclic(struct dma_chan *dchan,
1080 return NULL; 1086 return NULL;
1081 1087
1082 pxad_get_config(chan, dir, &dcmd, &dsadr, &dtadr); 1088 pxad_get_config(chan, dir, &dcmd, &dsadr, &dtadr);
1083 dcmd |= PXA_DCMD_ENDIRQEN | (PXA_DCMD_LENGTH | period_len); 1089 dcmd |= PXA_DCMD_ENDIRQEN | (PXA_DCMD_LENGTH & period_len);
1084 dev_dbg(&chan->vc.chan.dev->device, 1090 dev_dbg(&chan->vc.chan.dev->device,
1085 "%s(): buf_addr=0x%lx len=%zu period=%zu dir=%d flags=%lx\n", 1091 "%s(): buf_addr=0x%lx len=%zu period=%zu dir=%d flags=%lx\n",
1086 __func__, (unsigned long)buf_addr, len, period_len, dir, flags); 1092 __func__, (unsigned long)buf_addr, len, period_len, dir, flags);