From ccffa3870a7ec2b59cf051b745220c56f423d182 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 14 Sep 2012 15:05:44 +0300 Subject: dmaengine: omap: Support for element mode in cyclic DMA When src_maxburst/dst_maxburst is set to 0 by the users of cyclic DMA (mostly audio) indicates that we should configure the omap DMA to element sync mode instead of packet mode. Signed-off-by: Peter Ujfalusi Acked-by: Vinod Koul Tested-by: Janusz Krzysztofik Signed-off-by: Mark Brown --- drivers/dma/omap-dma.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/dma/omap-dma.c') diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c index ae0561826137..b77a40db2856 100644 --- a/drivers/dma/omap-dma.c +++ b/drivers/dma/omap-dma.c @@ -413,7 +413,10 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic( d->dev_addr = dev_addr; d->fi = burst; d->es = es; - d->sync_mode = OMAP_DMA_SYNC_PACKET; + if (burst) + d->sync_mode = OMAP_DMA_SYNC_PACKET; + else + d->sync_mode = OMAP_DMA_SYNC_ELEMENT; d->sync_type = sync_type; d->periph_port = OMAP_DMA_PORT_MPUI; d->sg[0].addr = buf_addr; -- cgit v1.2.1 From 2dcdf570936168d488acf90be9b04a3d32dafce7 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 14 Sep 2012 15:05:45 +0300 Subject: dmaengine: omap: Add support for pause/resume in cyclic dma mode The audio stack used omap_stop_dma/omap_start_dma to pause/resume the DMA. This method has been used for years on OMAP based products. We only allow pause/resume when the DMA has been configured in cyclic mode which is used by the audio stack. Signed-off-by: Peter Ujfalusi Acked-by: Vinod Koul Tested-by: Janusz Krzysztofik Signed-off-by: Mark Brown --- drivers/dma/omap-dma.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) (limited to 'drivers/dma/omap-dma.c') diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c index b77a40db2856..71d786973dfd 100644 --- a/drivers/dma/omap-dma.c +++ b/drivers/dma/omap-dma.c @@ -34,6 +34,7 @@ struct omap_chan { struct dma_slave_config cfg; unsigned dma_sig; bool cyclic; + bool paused; int dma_ch; struct omap_desc *desc; @@ -470,11 +471,14 @@ static int omap_dma_terminate_all(struct omap_chan *c) */ if (c->desc) { c->desc = NULL; - omap_stop_dma(c->dma_ch); + /* Avoid stopping the dma twice */ + if (!c->paused) + omap_stop_dma(c->dma_ch); } if (c->cyclic) { c->cyclic = false; + c->paused = false; omap_dma_unlink_lch(c->dma_ch, c->dma_ch); } @@ -487,14 +491,30 @@ static int omap_dma_terminate_all(struct omap_chan *c) static int omap_dma_pause(struct omap_chan *c) { - /* FIXME: not supported by platform private API */ - return -EINVAL; + /* Pause/Resume only allowed with cyclic mode */ + if (!c->cyclic) + return -EINVAL; + + if (!c->paused) { + omap_stop_dma(c->dma_ch); + c->paused = true; + } + + return 0; } static int omap_dma_resume(struct omap_chan *c) { - /* FIXME: not supported by platform private API */ - return -EINVAL; + /* Pause/Resume only allowed with cyclic mode */ + if (!c->cyclic) + return -EINVAL; + + if (c->paused) { + omap_start_dma(c->dma_ch); + c->paused = false; + } + + return 0; } static int omap_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, -- cgit v1.2.1 From ec8b5e48c03790a68cb875fe5064007a9cbdfdd0 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 14 Sep 2012 15:05:47 +0300 Subject: dmaengine: Pass flags via device_prep_dma_cyclic() callback Change the parameter list of device_prep_dma_cyclic() so the DMA drivers can receive the flags coming from clients. This feature can be used during audio operation to disable all audio related interrupts when the DMA_PREP_INTERRUPT is cleared from the flags. Signed-off-by: Peter Ujfalusi Acked-by: Nicolas Ferre Acked-by: Shawn Guo Acked-by: Vinod Koul Signed-off-by: Mark Brown --- drivers/dma/omap-dma.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/dma/omap-dma.c') diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c index 71d786973dfd..4d2650f4202c 100644 --- a/drivers/dma/omap-dma.c +++ b/drivers/dma/omap-dma.c @@ -366,7 +366,8 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg( static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic( struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len, - size_t period_len, enum dma_transfer_direction dir, void *context) + size_t period_len, enum dma_transfer_direction dir, unsigned long flags, + void *context) { struct omap_chan *c = to_omap_dma_chan(chan); enum dma_slave_buswidth dev_width; -- cgit v1.2.1 From 2dde5b909e117cc95a5e31604f9bfd043e78ad9d Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 14 Sep 2012 15:05:48 +0300 Subject: dmaengine: omap-dma: Add support to suppress interrupts in cyclic mode When requested (DMA_PREP_INTERRUPT is cleared in flags) disable all DMA interrupts for the channel. In this mode user space does not expect periodic reports from kernel about the progress of the audio stream. PulseAudio for example support this type of mode. Signed-off-by: Peter Ujfalusi Acked-by: Vinod Koul Tested-by: Janusz Krzysztofik Signed-off-by: Mark Brown --- drivers/dma/omap-dma.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/dma/omap-dma.c') diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c index 4d2650f4202c..f59f244f60fc 100644 --- a/drivers/dma/omap-dma.c +++ b/drivers/dma/omap-dma.c @@ -429,7 +429,10 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic( if (!c->cyclic) { c->cyclic = true; omap_dma_link_lch(c->dma_ch, c->dma_ch); - omap_enable_dma_irq(c->dma_ch, OMAP_DMA_FRAME_IRQ); + + if (flags & DMA_PREP_INTERRUPT) + omap_enable_dma_irq(c->dma_ch, OMAP_DMA_FRAME_IRQ); + omap_disable_dma_irq(c->dma_ch, OMAP_DMA_BLOCK_IRQ); } @@ -438,7 +441,7 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic( omap_set_dma_dest_burst_mode(c->dma_ch, OMAP_DMA_DATA_BURST_16); } - return vchan_tx_prep(&c->vc, &d->vd, DMA_CTRL_ACK | DMA_PREP_INTERRUPT); + return vchan_tx_prep(&c->vc, &d->vd, flags); } static int omap_dma_slave_config(struct omap_chan *c, struct dma_slave_config *cfg) -- cgit v1.2.1