[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