aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/dma/cppi41.c13
-rw-r--r--drivers/dma/imx-sdma.c22
-rw-r--r--sound/soc/fsl/imx-pcm-dma.c1
3 files changed, 28 insertions, 8 deletions
diff --git a/drivers/dma/cppi41.c b/drivers/dma/cppi41.c
index d028f36ae655..8f8b0b608875 100644
--- a/drivers/dma/cppi41.c
+++ b/drivers/dma/cppi41.c
@@ -86,6 +86,9 @@
86 86
87#define USBSS_IRQ_PD_COMP (1 << 2) 87#define USBSS_IRQ_PD_COMP (1 << 2)
88 88
89/* Packet Descriptor */
90#define PD2_ZERO_LENGTH (1 << 19)
91
89struct cppi41_channel { 92struct cppi41_channel {
90 struct dma_chan chan; 93 struct dma_chan chan;
91 struct dma_async_tx_descriptor txd; 94 struct dma_async_tx_descriptor txd;
@@ -307,7 +310,7 @@ static irqreturn_t cppi41_irq(int irq, void *data)
307 __iormb(); 310 __iormb();
308 311
309 while (val) { 312 while (val) {
310 u32 desc; 313 u32 desc, len;
311 314
312 q_num = __fls(val); 315 q_num = __fls(val);
313 val &= ~(1 << q_num); 316 val &= ~(1 << q_num);
@@ -319,9 +322,13 @@ static irqreturn_t cppi41_irq(int irq, void *data)
319 q_num, desc); 322 q_num, desc);
320 continue; 323 continue;
321 } 324 }
322 c->residue = pd_trans_len(c->desc->pd6) -
323 pd_trans_len(c->desc->pd0);
324 325
326 if (c->desc->pd2 & PD2_ZERO_LENGTH)
327 len = 0;
328 else
329 len = pd_trans_len(c->desc->pd0);
330
331 c->residue = pd_trans_len(c->desc->pd6) - len;
325 dma_cookie_complete(&c->txd); 332 dma_cookie_complete(&c->txd);
326 c->txd.callback(c->txd.callback_param); 333 c->txd.callback(c->txd.callback_param);
327 } 334 }
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 128714622bf5..14867e3ac8ff 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -255,6 +255,7 @@ struct sdma_channel {
255 enum dma_slave_buswidth word_size; 255 enum dma_slave_buswidth word_size;
256 unsigned int buf_tail; 256 unsigned int buf_tail;
257 unsigned int num_bd; 257 unsigned int num_bd;
258 unsigned int period_len;
258 struct sdma_buffer_descriptor *bd; 259 struct sdma_buffer_descriptor *bd;
259 dma_addr_t bd_phys; 260 dma_addr_t bd_phys;
260 unsigned int pc_from_device, pc_to_device; 261 unsigned int pc_from_device, pc_to_device;
@@ -593,6 +594,12 @@ static void sdma_event_disable(struct sdma_channel *sdmac, unsigned int event)
593 594
594static void sdma_handle_channel_loop(struct sdma_channel *sdmac) 595static void sdma_handle_channel_loop(struct sdma_channel *sdmac)
595{ 596{
597 if (sdmac->desc.callback)
598 sdmac->desc.callback(sdmac->desc.callback_param);
599}
600
601static void sdma_update_channel_loop(struct sdma_channel *sdmac)
602{
596 struct sdma_buffer_descriptor *bd; 603 struct sdma_buffer_descriptor *bd;
597 604
598 /* 605 /*
@@ -611,9 +618,6 @@ static void sdma_handle_channel_loop(struct sdma_channel *sdmac)
611 bd->mode.status |= BD_DONE; 618 bd->mode.status |= BD_DONE;
612 sdmac->buf_tail++; 619 sdmac->buf_tail++;
613 sdmac->buf_tail %= sdmac->num_bd; 620 sdmac->buf_tail %= sdmac->num_bd;
614
615 if (sdmac->desc.callback)
616 sdmac->desc.callback(sdmac->desc.callback_param);
617 } 621 }
618} 622}
619 623
@@ -669,6 +673,9 @@ static irqreturn_t sdma_int_handler(int irq, void *dev_id)
669 int channel = fls(stat) - 1; 673 int channel = fls(stat) - 1;
670 struct sdma_channel *sdmac = &sdma->channel[channel]; 674 struct sdma_channel *sdmac = &sdma->channel[channel];
671 675
676 if (sdmac->flags & IMX_DMA_SG_LOOP)
677 sdma_update_channel_loop(sdmac);
678
672 tasklet_schedule(&sdmac->tasklet); 679 tasklet_schedule(&sdmac->tasklet);
673 680
674 __clear_bit(channel, &stat); 681 __clear_bit(channel, &stat);
@@ -1129,6 +1136,7 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic(
1129 sdmac->status = DMA_IN_PROGRESS; 1136 sdmac->status = DMA_IN_PROGRESS;
1130 1137
1131 sdmac->buf_tail = 0; 1138 sdmac->buf_tail = 0;
1139 sdmac->period_len = period_len;
1132 1140
1133 sdmac->flags |= IMX_DMA_SG_LOOP; 1141 sdmac->flags |= IMX_DMA_SG_LOOP;
1134 sdmac->direction = direction; 1142 sdmac->direction = direction;
@@ -1225,9 +1233,15 @@ static enum dma_status sdma_tx_status(struct dma_chan *chan,
1225 struct dma_tx_state *txstate) 1233 struct dma_tx_state *txstate)
1226{ 1234{
1227 struct sdma_channel *sdmac = to_sdma_chan(chan); 1235 struct sdma_channel *sdmac = to_sdma_chan(chan);
1236 u32 residue;
1237
1238 if (sdmac->flags & IMX_DMA_SG_LOOP)
1239 residue = (sdmac->num_bd - sdmac->buf_tail) * sdmac->period_len;
1240 else
1241 residue = sdmac->chn_count - sdmac->chn_real_count;
1228 1242
1229 dma_set_tx_state(txstate, chan->completed_cookie, chan->cookie, 1243 dma_set_tx_state(txstate, chan->completed_cookie, chan->cookie,
1230 sdmac->chn_count - sdmac->chn_real_count); 1244 residue);
1231 1245
1232 return sdmac->status; 1246 return sdmac->status;
1233} 1247}
diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c
index 0849b7b83f0a..0db94f492e97 100644
--- a/sound/soc/fsl/imx-pcm-dma.c
+++ b/sound/soc/fsl/imx-pcm-dma.c
@@ -59,7 +59,6 @@ int imx_pcm_dma_init(struct platform_device *pdev)
59{ 59{
60 return devm_snd_dmaengine_pcm_register(&pdev->dev, 60 return devm_snd_dmaengine_pcm_register(&pdev->dev,
61 &imx_dmaengine_pcm_config, 61 &imx_dmaengine_pcm_config,
62 SND_DMAENGINE_PCM_FLAG_NO_RESIDUE |
63 SND_DMAENGINE_PCM_FLAG_COMPAT); 62 SND_DMAENGINE_PCM_FLAG_COMPAT);
64} 63}
65EXPORT_SYMBOL_GPL(imx_pcm_dma_init); 64EXPORT_SYMBOL_GPL(imx_pcm_dma_init);