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

Keyon Jie yang.jie at linux.intel.com
Mon Jan 29 02:30:01 CET 2018



On 2018年01月26日 02:12, Pierre-Louis Bossart wrote:
> 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;

will fix it in v2, thanks.

Thanks,
~Keyon

> 
> 
> 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
>>       }
>>   }
> 
> _______________________________________________
> Sound-open-firmware mailing list
> Sound-open-firmware at alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/sound-open-firmware


More information about the Sound-open-firmware mailing list