[Sound-open-firmware] [PATCH] dma: dw-dma: release spinlock in error path
Currently not released on any configuration errors.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/drivers/dw-dma.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/src/drivers/dw-dma.c b/src/drivers/dw-dma.c index 7b97fb8..4a4a14a 100644 --- a/src/drivers/dw-dma.c +++ b/src/drivers/dw-dma.c @@ -438,6 +438,7 @@ static int dw_dma_set_config(struct dma *dma, int channel, struct dw_lli2 *lli_desc_tail; uint32_t desc_count = 0; uint32_t flags; + int ret = 0;
spin_lock_irq(&dma->lock, flags);
@@ -453,8 +454,9 @@ static int dw_dma_set_config(struct dma *dma, int channel, desc_count++;
if (desc_count == 0) { - trace_dma_error("eDC"); - return -EINVAL; + trace_dma_error("eD0"); + ret = -EINVAL; + goto out; }
/* do we need to realloc descriptors */ @@ -468,8 +470,9 @@ static int dw_dma_set_config(struct dma *dma, int channel, p->chan[channel].lli = rzalloc(RZONE_RUNTIME, RFLAGS_NONE, sizeof(struct dw_lli2) * p->chan[channel].desc_count); if (p->chan[channel].lli == NULL) { - trace_dma_error("eDm"); - return -ENOMEM; + trace_dma_error("eD1"); + ret = -ENOMEM; + goto out; } }
@@ -539,14 +542,17 @@ static int dw_dma_set_config(struct dma *dma, int channel, lli_desc->dar = (uint32_t)sg_elem->dest; break; default: - trace_dma_error("eDD"); - break; + trace_dma_error("eD4"); + ret = -EINVAL; + goto out; }
if (sg_elem->size > DW_CTLH_BLOCK_TS_MASK) { - trace_dma_error("eDS"); - return -EINVAL; + trace_dma_error("eD5"); + ret = -EINVAL; + goto out; } + /* set transfer size of element */ #if defined CONFIG_BAYTRAIL || defined CONFIG_CHERRYTRAIL lli_desc->ctrl_hi = DW_CTLH_CLASS(p->class) | @@ -578,9 +584,9 @@ static int dw_dma_set_config(struct dma *dma, int channel, }
p->chan[channel].status = COMP_STATE_PREPARE; +out: spin_unlock_irq(&dma->lock, flags); - - return 0; + return ret; }
/* restore DMA conext after leaving D3 */
Add an API to get the size of an individual sample in bytes.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/include/reef/audio/component.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/src/include/reef/audio/component.h b/src/include/reef/audio/component.h index 5d15fdb..f25ad3d 100644 --- a/src/include/reef/audio/component.h +++ b/src/include/reef/audio/component.h @@ -335,6 +335,21 @@ static inline uint32_t comp_frame_bytes(struct comp_dev *dev) } }
+static inline uint32_t comp_sample_bytes(struct comp_dev *dev) +{ + /* calculate period size based on params */ + switch (dev->params.frame_fmt) { + case SOF_IPC_FRAME_S16_LE: + return 2; + case SOF_IPC_FRAME_S24_4LE: + case SOF_IPC_FRAME_S32_LE: + case SOF_IPC_FRAME_FLOAT: + return 4; + default: + return 0; + } +} + /* XRUN handling */ static inline void comp_underrun(struct comp_dev *dev, struct comp_buffer *source, uint32_t copy_bytes, uint32_t min_bytes)
Use comp_sample_bytes() to set DMA transfer size in DAI component and comment why host always copies using word size transfers.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/audio/dai.c | 8 ++++---- src/audio/host.c | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/src/audio/dai.c b/src/audio/dai.c index 13f7e10..cc61e83 100644 --- a/src/audio/dai.c +++ b/src/audio/dai.c @@ -264,8 +264,8 @@ static int dai_playback_params(struct comp_dev *dev)
/* set up DMA configuration */ config->direction = DMA_DIR_MEM_TO_DEV; - config->src_width = sizeof(uint32_t); - config->dest_width = sizeof(uint32_t); + config->src_width = comp_sample_bytes(dev); + config->dest_width = comp_sample_bytes(dev); config->cyclic = 1; config->dest_dev = dd->dai->plat_data.fifo[0].handshake;
@@ -331,8 +331,8 @@ static int dai_capture_params(struct comp_dev *dev)
/* set up DMA configuration */ config->direction = DMA_DIR_DEV_TO_MEM; - config->src_width = sizeof(uint32_t); - config->dest_width = sizeof(uint32_t); + config->src_width = comp_sample_bytes(dev); + config->dest_width = comp_sample_bytes(dev); config->cyclic = 1; config->src_dev = dd->dai->plat_data.fifo[1].handshake;
diff --git a/src/audio/host.c b/src/audio/host.c index 88d45e4..b731dd6 100644 --- a/src/audio/host.c +++ b/src/audio/host.c @@ -441,7 +441,8 @@ static int host_params(struct comp_dev *dev) if (err < 0) return err;
- /* set up DMA configuration */ + /* set up DMA configuration - copy in words for all formats as + this is most optimal for memory <-> memory copies. */ config->src_width = sizeof(uint32_t); config->dest_width = sizeof(uint32_t); config->cyclic = 0;
Use transfer size in SG config structure instead of hard coded values.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/drivers/dw-dma.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-)
diff --git a/src/drivers/dw-dma.c b/src/drivers/dw-dma.c index 4a4a14a..b288049 100644 --- a/src/drivers/dw-dma.c +++ b/src/drivers/dw-dma.c @@ -488,8 +488,36 @@ static int dw_dma_set_config(struct dma *dma, int channel, sg_elem = container_of(plist, struct dma_sg_elem, list);
/* write CTL_LOn for each lli */ - lli_desc->ctrl_lo |= DW_CTLL_SRC_WIDTH(2); /* config the src tr width */ - lli_desc->ctrl_lo |= DW_CTLL_DST_WIDTH(2); /* config the dest tr width */ + switch (config->src_width) { + case 2: + /* config the src tr width for 16 bit samples */ + lli_desc->ctrl_lo |= DW_CTLL_SRC_WIDTH(1); + break; + case 4: + /* config the src tr width for 24, 32 bit samples */ + lli_desc->ctrl_lo |= DW_CTLL_SRC_WIDTH(2); + break; + default: + trace_dma_error("eD2"); + ret = -EINVAL; + goto out; + } + + switch (config->dest_width) { + case 2: + /* config the dest tr width for 16 bit samples */ + lli_desc->ctrl_lo |= DW_CTLL_DST_WIDTH(1); + break; + case 4: + /* config the dest tr width for 24, 32 bit samples */ + lli_desc->ctrl_lo |= DW_CTLL_DST_WIDTH(2); + break; + default: + trace_dma_error("eD3"); + ret = -EINVAL; + goto out; + } + lli_desc->ctrl_lo |= DW_CTLL_SRC_MSIZE(3); /* config the src msize length 2^2 */ lli_desc->ctrl_lo |= DW_CTLL_DST_MSIZE(3); /* config the dest msize length 2^2 */ lli_desc->ctrl_lo |= DW_CTLL_INT_EN; /* enable interrupt */
participants (1)
-
Liam Girdwood