[Sound-open-firmware] [PATCH 24/25] dw-dma: handle different cases in irq handler

Liam Girdwood liam.r.girdwood at linux.intel.com
Wed Feb 8 13:15:48 CET 2017


On Tue, 2017-02-07 at 22:03 +0800, Keyon Jie wrote:
> After finished a transfer copy, check for reload channel:
> 1. if next.size is 0xFFFFFFFF, stop this dma copy;
> 2. if next.size > 0 but not 0xFFFFFFFF, use next element

magic numbers.

> for next copy
> 3. if we are waiting for pause, pause it;
> 4. otherwise, reload lli.
> 
> Signed-off-by: Keyon Jie <yang.jie at linux.intel.com>
> ---
>  src/audio/dai.c        |  2 +-
>  src/drivers/dw-dma.c   | 25 ++++++++++++++-----------
>  src/include/reef/dma.h |  6 ++++++
>  3 files changed, 21 insertions(+), 12 deletions(-)
> 
> diff --git a/src/audio/dai.c b/src/audio/dai.c
> index a9b46a5..e365ed9 100644
> --- a/src/audio/dai.c
> +++ b/src/audio/dai.c
> @@ -140,7 +140,7 @@ static void dai_dma_cb(void *data, uint32_t type, struct dma_sg_elem *next)
>  		if (dma_buffer->avail == 0) {
>  			dai_cmd(dev, COMP_CMD_STOP, NULL);
>  			/* stop dma immediatly */
> -			next->size = 0xFFFFFFFF;
> +			next->size = DMA_RELOAD_STOP_SIZE;
>  			/* let any waiters know we have completed */
>  			wait_completed(&dev->pipeline->complete);
>  			return;
> diff --git a/src/drivers/dw-dma.c b/src/drivers/dw-dma.c
> index c073ed5..baa773e 100644
> --- a/src/drivers/dw-dma.c
> +++ b/src/drivers/dw-dma.c
> @@ -387,7 +387,6 @@ out:
>  static int dw_dma_release(struct dma *dma, int channel)
>  {
>  	struct dma_pdata *p = dma_get_drvdata(dma);
> -	struct dma_sg_elem next;
>  	uint32_t flags;
>  
>  	spin_lock_irq(&dma->lock, flags);
> @@ -395,8 +394,6 @@ static int dw_dma_release(struct dma *dma, int channel)
>  	trace_dma("Dpr");
>  
>  	if (p->chan[channel].status == DMA_STATUS_PAUSED) {
> -		if (p->chan[channel].cb && p->chan[channel].cb_type & DMA_IRQ_TYPE_LLIST)
> -			p->chan[channel].cb(p->chan[channel].cb_data, DMA_IRQ_TYPE_LLIST, &next);
>  		dw_dma_chan_reload_lli(dma, channel);
>  	}
>  
> @@ -834,20 +831,26 @@ static void dw_dma_irq_handler(void *data)
>  		if ((status_tfr & mask) &&
>  			(p->chan[i].cb_type & DMA_IRQ_TYPE_LLIST)) {
>  
> -			if (p->chan[i].status == DMA_STATUS_PAUSING) {
> -				p->chan[i].status = DMA_STATUS_PAUSED;
> -				continue;
> -			}
> -
>  			next.size = 0;
>  			if (p->chan[i].cb)
>  				p->chan[i].cb(p->chan[i].cb_data,
>  					DMA_IRQ_TYPE_LLIST, &next);
>  
> -			/* check for reload channel */
> -			if (next.size > 0)
> +			/* check for reload channel:
> +			 * next.size is DMA_RELOAD_STOP_SIZE, stop this dma copy;
> +			 * next.size > 0 but not DMA_RELOAD_STOP_SIZE, use next
> +			 * element for next copy;
> +			 * if we are waiting for pause, pause it;
> +			 * otherwise, reload lli
> +			 */
> +			if (next.size == DMA_RELOAD_STOP_SIZE)
> +				continue;
> +			else if (next.size > 0)
>  				dw_dma_chan_reload_next(dma, i, &next);
> -			else
> +			else if (p->chan[i].status == DMA_STATUS_PAUSING) {
> +				p->chan[i].status = DMA_STATUS_PAUSED;
> +				continue;
> +			} else
>  				dw_dma_chan_reload_lli(dma, i);
>  		}
>  #if DW_USE_HW_LLI
> diff --git a/src/include/reef/dma.h b/src/include/reef/dma.h
> index 6de2ede..273371e 100644
> --- a/src/include/reef/dma.h
> +++ b/src/include/reef/dma.h
> @@ -59,6 +59,12 @@
>  #define DMA_IRQ_TYPE_BLOCK	(1 << 0)
>  #define DMA_IRQ_TYPE_LLIST	(1 << 1)
>  
> +
> +/* We will use this macro in cb handler to inform dma that
> + * we need to stop the reload for specail purpose
> + */
> +#define DMA_RELOAD_STOP_SIZE	0xFFFFFFFF

if we are using the size variable then it makes more sense to use 0 here
to indicate end of transfer.

#define DMA_RELOAD_END	0

> +
>  struct dma;
>  
>  struct dma_sg_elem {




More information about the Sound-open-firmware mailing list