summaryrefslogtreecommitdiff
path: root/sound/soc/fsl/fsl_asrc_m2m.c
diff options
context:
space:
mode:
authorShengjiu Wang <shengjiu.wang@nxp.com>2018-08-07 15:02:34 +0800
committerDong Aisheng <aisheng.dong@nxp.com>2019-11-25 15:48:33 +0800
commit9d607a7189bad77c8357a0646a353e5ee74d9d4c (patch)
treee24bdc403091198c954692a8e3dc495ac866bde9 /sound/soc/fsl/fsl_asrc_m2m.c
parent6e7c69f03b0d932d247dc88746b3c6d794f3d640 (diff)
MLK-19151: ASoC: fsl_asrc: fix dma timeout issue for imx8qxp
In the imx8qxp, the DMA is EDMA, which require the buffer size should be divided by burst size with no remainder, otherwise the remainder is not transferred by EDMA, so the input buffer is not consumed by ASRC, then there will be dma output timeout issue. This behavior is different with SDMA. This patch is to change the input burst size to be 1 to avoid the issue, and refine the last_period_size for output buffer. Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Diffstat (limited to 'sound/soc/fsl/fsl_asrc_m2m.c')
-rw-r--r--sound/soc/fsl/fsl_asrc_m2m.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/sound/soc/fsl/fsl_asrc_m2m.c b/sound/soc/fsl/fsl_asrc_m2m.c
index 9f0314970cbb..2684518d26ee 100644
--- a/sound/soc/fsl/fsl_asrc_m2m.c
+++ b/sound/soc/fsl/fsl_asrc_m2m.c
@@ -174,8 +174,11 @@ static int fsl_asrc_dmaconfig(struct fsl_asrc_pair *pair, struct dma_chan *chan,
slave_config.direction = DMA_MEM_TO_DEV;
slave_config.dst_addr = dma_addr;
slave_config.dst_addr_width = buswidth;
- slave_config.dst_maxburst =
- m2m->watermark[IN] * pair->channels;
+ if (asrc_priv->dma_type == DMA_SDMA)
+ slave_config.dst_maxburst =
+ m2m->watermark[IN] * pair->channels;
+ else
+ slave_config.dst_maxburst = 1;
} else {
slave_config.direction = DMA_DEV_TO_MEM;
slave_config.src_addr = dma_addr;
@@ -283,6 +286,9 @@ static int fsl_asrc_prepare_io_buffer(struct fsl_asrc_pair *pair,
*dma_len -= last_period_size * word_size * pair->channels;
*dma_len = *dma_len / (word_size * pair->channels) *
(word_size * pair->channels);
+ if (asrc_priv->dma_type == DMA_EDMA)
+ *dma_len = *dma_len / (word_size * pair->channels * m2m->watermark[OUT])
+ * (word_size * pair->channels * m2m->watermark[OUT]);
}
*sg_nodes = *dma_len / ASRC_MAX_BUFFER_SIZE + 1;
@@ -625,11 +631,13 @@ static long fsl_asrc_calc_last_period_size(struct fsl_asrc_pair *pair,
struct asrc_convert_buffer *pbuf)
{
struct fsl_asrc_m2m *m2m = pair->private;
+ struct fsl_asrc *asrc_priv = pair->asrc_priv;
unsigned int out_length;
unsigned int in_width, out_width;
unsigned int channels = pair->channels;
unsigned int in_samples, out_samples;
unsigned int last_period_size;
+ unsigned int remain;
switch (m2m->word_width[IN]) {
case ASRC_WIDTH_24_BIT:
@@ -672,6 +680,12 @@ static long fsl_asrc_calc_last_period_size(struct fsl_asrc_pair *pair,
m2m->last_period_size = last_period_size + 1 + ASRC_OUTPUT_LAST_SAMPLE;
+ if (asrc_priv->dma_type == DMA_EDMA) {
+ remain = pbuf->output_buffer_length % (out_width * channels * m2m->watermark[OUT]);
+ if (remain)
+ m2m->last_period_size += remain / (out_width * channels);
+ }
+
return 0;
}