summaryrefslogtreecommitdiff
path: root/sound/soc/fsl
diff options
context:
space:
mode:
authorShengjiu Wang <shengjiu.wang@freescale.com>2014-12-15 17:28:00 +0800
committerDong Aisheng <aisheng.dong@nxp.com>2019-11-25 15:48:20 +0800
commit432bae15eebb2fe0d9681c2f2ab6ade98956bfc4 (patch)
treedb023ba53df8f100f35125ad0e854f2f27d9f2e0 /sound/soc/fsl
parentb063e095e46db242817d39a3814a0e90ae5b3a1b (diff)
MLK-10048-4: ASoC: fsl_asrc: fix dma task timeout issue when use 3 instance
Merged from 49108fcf7b79ed77d34be33b53a3964b2ac27204 1. Watermark level in sdma use byte as its unit. but asrc driver use word, there is mismatch between them. Here fix this issue and sdma can work more efficiency. 2. Enlarge the larst_period_size, when use small size, for some case, the dma task will timeout, because sdma has no much data for output. Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com> (cherry picked from commit 8a96e09e265294f396bd3af29b429e4b7bdff461)
Diffstat (limited to 'sound/soc/fsl')
-rw-r--r--sound/soc/fsl/fsl_asrc.h3
-rw-r--r--sound/soc/fsl/fsl_asrc_m2m.c17
2 files changed, 14 insertions, 6 deletions
diff --git a/sound/soc/fsl/fsl_asrc.h b/sound/soc/fsl/fsl_asrc.h
index c449143a2a89..0c07304bbd89 100644
--- a/sound/soc/fsl/fsl_asrc.h
+++ b/sound/soc/fsl/fsl_asrc.h
@@ -22,7 +22,8 @@
#define ASRC_FIFO_THRESHOLD_MAX 63
#define ASRC_DMA_BUFFER_SIZE (1024 * 48 * 4)
#define ASRC_MAX_BUFFER_SIZE (1024 * 48)
-#define ASRC_OUTPUT_LAST_SAMPLE 8
+#define ASRC_OUTPUT_LAST_SAMPLE_MAX 32
+#define ASRC_OUTPUT_LAST_SAMPLE 16
#define IDEAL_RATIO_RATE 1000000
diff --git a/sound/soc/fsl/fsl_asrc_m2m.c b/sound/soc/fsl/fsl_asrc_m2m.c
index 97c9f6af17d7..1ae6aa7b739b 100644
--- a/sound/soc/fsl/fsl_asrc_m2m.c
+++ b/sound/soc/fsl/fsl_asrc_m2m.c
@@ -24,6 +24,7 @@ struct fsl_asrc_m2m {
enum asrc_word_width word_width[2];
unsigned int rate[2];
+ unsigned int last_period_size;
u32 watermark[2];
spinlock_t lock;
};
@@ -111,8 +112,8 @@ retry:
if (size)
goto retry;
- if (t_size > ASRC_OUTPUT_LAST_SAMPLE)
- t_size = ASRC_OUTPUT_LAST_SAMPLE;
+ if (t_size > m2m->last_period_size)
+ t_size = m2m->last_period_size;
if (reg24)
output->length += t_size * pair->channels * 4;
@@ -181,13 +182,13 @@ static int fsl_asrc_dmaconfig(struct fsl_asrc_pair *pair, struct dma_chan *chan,
slave_config.dst_addr = dma_addr;
slave_config.dst_addr_width = buswidth;
slave_config.dst_maxburst =
- m2m->watermark[IN] * pair->channels / buswidth;
+ m2m->watermark[IN] * pair->channels;
} else {
slave_config.direction = DMA_DEV_TO_MEM;
slave_config.src_addr = dma_addr;
slave_config.src_addr_width = buswidth;
slave_config.src_maxburst =
- m2m->watermark[OUT] * pair->channels / buswidth;
+ m2m->watermark[OUT] * pair->channels;
}
ret = dmaengine_slave_config(chan, &slave_config);
@@ -251,6 +252,7 @@ static int fsl_asrc_prepare_io_buffer(struct fsl_asrc_pair *pair,
struct dma_chan *dma_chan = pair->dma_chan[dir];
unsigned int buf_len, wm = m2m->watermark[dir];
unsigned int *sg_nodes = &m2m->sg_nodes[dir];
+ unsigned int last_period_size = m2m->last_period_size;
enum asrc_pair_index index = pair->index;
u32 word_size, fifo_addr;
void __user *buf_vaddr;
@@ -283,7 +285,7 @@ static int fsl_asrc_prepare_io_buffer(struct fsl_asrc_pair *pair,
*dma_len = buf_len;
if (dir == OUT)
- *dma_len -= ASRC_OUTPUT_LAST_SAMPLE * word_size * pair->channels;
+ *dma_len -= last_period_size * word_size * pair->channels;
*sg_nodes = *dma_len / ASRC_MAX_BUFFER_SIZE + 1;
@@ -556,6 +558,11 @@ static long fsl_asrc_ioctl_config_pair(struct fsl_asrc_pair *pair,
m2m->rate[IN] = config.input_sample_rate;
m2m->rate[OUT] = config.output_sample_rate;
+ if (m2m->rate[OUT] > m2m->rate[IN])
+ m2m->last_period_size = ASRC_OUTPUT_LAST_SAMPLE_MAX;
+ else
+ m2m->last_period_size = ASRC_OUTPUT_LAST_SAMPLE;
+
ret = fsl_allocate_dma_buf(pair);
if (ret) {
pair_err("failed to allocate DMA buffer: %ld\n", ret);