[Sound-open-firmware] [PATCH] dw-dma: fix hardware link list mode

Pierre-Louis Bossart pierre-louis.bossart at linux.intel.com
Thu Jan 25 19:12:18 CET 2018


CHECK: Alignment should match open parenthesis
#92: FILE: src/drivers/dw-dma.c:870:
+        if (status_block & mask &&
+            p->chan[i].cb_type & DMA_IRQ_TYPE_BLOCK) {

CHECK: multiple assignments should be avoided
#93: FILE: src/drivers/dw-dma.c:871:
+            next.src = next.dest = DMA_RELOAD_LLI;


On 01/25/2018 03:25 AM, Keyon Jie wrote:
> For hardware link list mode, we also need to configure address
> and config registers for the first link list, here fix it.
>
> Signed-off-by: Keyon Jie <yang.jie at linux.intel.com>
> ---
> Tested on minnow turbot rt5651,
> SOF Master: f7beb51118e6e8463a864b9416c773a508930e06,
> SOF Tool Master: 59d81995f682876bd34f939332e8838c76f714ec,
> https://github.com/plbossart/sound/tree/topic/sof-v4.14:
> 5a91e6776d41b0e97828882294cdc00b5c0bafd6
>
> src/audio/dai.c      |  3 ++-
>   src/drivers/dw-dma.c | 43 +++++++++++++++++--------------------------
>   2 files changed, 19 insertions(+), 27 deletions(-)
>
> diff --git a/src/audio/dai.c b/src/audio/dai.c
> index d19e18a..3a6b9f7 100644
> --- a/src/audio/dai.c
> +++ b/src/audio/dai.c
> @@ -226,7 +226,8 @@ static struct comp_dev *dai_new(struct sof_ipc_comp *comp)
>   	}
>   
>   	/* set up callback */
> -	dma_set_cb(dd->dma, dd->chan, DMA_IRQ_TYPE_LLIST, dai_dma_cb, dev);
> +	dma_set_cb(dd->dma, dd->chan, DMA_IRQ_TYPE_BLOCK |
> +				DMA_IRQ_TYPE_LLIST, dai_dma_cb, dev);
>   	dev->state = COMP_STATE_READY;
>   	return dev;
>   
> diff --git a/src/drivers/dw-dma.c b/src/drivers/dw-dma.c
> index 8248461..09e441c 100644
> --- a/src/drivers/dw-dma.c
> +++ b/src/drivers/dw-dma.c
> @@ -396,22 +396,11 @@ static int dw_dma_start(struct dma *dma, int channel)
>   
>   #if DW_USE_HW_LLI
>   	/* TODO: Revisit: are we using LLP mode or single transfer ? */
> -	if (p->chan[channel].lli->llp) {
> -		/* LLP mode - only write LLP pointer */
> +	if (p->chan[channel].lli) {
> +		/* LLP mode - write LLP pointer */
>   		dw_write(dma, DW_LLP(channel), (uint32_t)p->chan[channel].lli);
> -	} else {
> -		/* single transfer */
> -		dw_write(dma, DW_LLP(channel), 0);
> -
> -		/* channel needs started from scratch, so write SARn, DARn */
> -		dw_write(dma, DW_SAR(channel), p->chan[channel].lli->sar);
> -		dw_write(dma, DW_DAR(channel), p->chan[channel].lli->dar);
> -
> -		/* program CTLn */
> -		dw_write(dma, DW_CTRL_LOW(channel), p->chan[channel].lli->ctrl_lo);
> -		dw_write(dma, DW_CTRL_HIGH(channel), p->chan[channel].lli->ctrl_hi);
>   	}
> -#else
> +#endif
>   	/* channel needs started from scratch, so write SARn, DARn */
>   	dw_write(dma, DW_SAR(channel), p->chan[channel].lli->sar);
>   	dw_write(dma, DW_DAR(channel), p->chan[channel].lli->dar);
> @@ -419,7 +408,6 @@ static int dw_dma_start(struct dma *dma, int channel)
>   	/* program CTLn */
>   	dw_write(dma, DW_CTRL_LOW(channel), p->chan[channel].lli->ctrl_lo);
>   	dw_write(dma, DW_CTRL_HIGH(channel), p->chan[channel].lli->ctrl_hi);
> -#endif
>   
>   	/* write channel config */
>   	dw_write(dma, DW_CFG_LOW(channel), p->chan[channel].cfg_lo);
> @@ -829,6 +817,7 @@ static void dw_dma_irq_handler(void *data)
>   	struct dma_sg_elem next;
>   	uint32_t status_tfr = 0;
>   	uint32_t status_block = 0;
> +	uint32_t status_block_new = 0;
>   	uint32_t status_err = 0;
>   	uint32_t status_intr;
>   	uint32_t mask;
> @@ -861,10 +850,10 @@ static void dw_dma_irq_handler(void *data)
>   	platform_interrupt_clear(dma_irq(dma), pmask);
>   
>   	/* confirm IRQ cleared */
> -	status_block = dw_read(dma, DW_STATUS_BLOCK);
> -	if (status_block) {
> +	status_block_new = dw_read(dma, DW_STATUS_BLOCK);
> +	if (status_block_new) {
>   		trace_dma_error("eI2");
> -		trace_value(status_block);
> +		trace_value(status_block_new);
>   	}
>   
>   	for (i = 0; i < DW_MAX_CHAN; i++) {
> @@ -875,6 +864,16 @@ static void dw_dma_irq_handler(void *data)
>   
>   		mask = 0x1 << i;
>   
> +#if DW_USE_HW_LLI
> +		/* end of a LLI block */
> +		if (status_block & mask &&
> +			p->chan[i].cb_type & DMA_IRQ_TYPE_BLOCK) {
> +			next.src = next.dest = DMA_RELOAD_LLI;
> +			next.size = DMA_RELOAD_LLI;
> +			p->chan[i].cb(p->chan[i].cb_data,
> +					DMA_IRQ_TYPE_BLOCK, &next);
> +		}
> +#endif
>   		/* end of a transfer */
>   		if ((status_tfr & mask) &&
>   			(p->chan[i].cb_type & DMA_IRQ_TYPE_LLIST)) {
> @@ -904,14 +903,6 @@ static void dw_dma_irq_handler(void *data)
>   				break;
>   			}
>   		}
> -#if DW_USE_HW_LLI
> -		/* end of a LLI block */
> -		if (status_block & mask &&
> -			p->chan[i].cb_type & DMA_IRQ_TYPE_BLOCK) {
> -			p->chan[i].cb(p->chan[i].cb_data,
> -					DMA_IRQ_TYPE_BLOCK);
> -		}
> -#endif
>   	}
>   }
>   



More information about the Sound-open-firmware mailing list