summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorShengjiu Wang <shengjiu.wang@nxp.com>2018-07-19 18:33:01 +0800
committerLeonard Crestez <leonard.crestez@nxp.com>2018-08-24 12:41:33 +0300
commit14aa1192f49b1d9502e22be7f7ce4db960e4667b (patch)
tree71ccc3da00138c8b3bacc03c1098cc0899170221 /sound
parente1bbf60895c9ca124b371e0dcd174e02c7ef7724 (diff)
MLK-18875: ASoC: fsl_asrc_m2m: refine the last period size
The output size of asrc for a dedicate input is uncertain. For example, if the input size is 1k, the output ratio is 2, so the output size should be 2k. but the actual output size is not 2k, is less than 2k. if we set the dma size to be 2k, the dma can't get enough data that can't finish the transmission, then there will be "output DMA task timeout" So we need to set the dma size a proper value but we don't know how many data less than expected. so we defined the last period size for assumption of reduced size. The last period size should not be too large, if it is large there will be "input DMA task timeout" The reason is the output FIFO is full, which will block the input data comsumption. In this patch, the last period size is set to the difference of configured buffer size and the expected output size, plus a fix size. Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com> Reviewed-by: Cosmin-Gabriel Samoila <cosmin.samoila@nxp.com> (cherry picked from commit e52f5e08624185919bc794106623e8defb1c4f0e)
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/fsl/fsl_asrc.h2
-rw-r--r--sound/soc/fsl/fsl_asrc_m2m.c63
2 files changed, 58 insertions, 7 deletions
diff --git a/sound/soc/fsl/fsl_asrc.h b/sound/soc/fsl/fsl_asrc.h
index 0faaadcb3bad..7e7f0e8a1c88 100644
--- a/sound/soc/fsl/fsl_asrc.h
+++ b/sound/soc/fsl/fsl_asrc.h
@@ -26,7 +26,7 @@
#define ASRC_DMA_BUFFER_SIZE (1024 * 48 * 4)
#define ASRC_MAX_BUFFER_SIZE (1024 * 48)
#define ASRC_OUTPUT_LAST_SAMPLE_MAX 32
-#define ASRC_OUTPUT_LAST_SAMPLE 16
+#define ASRC_OUTPUT_LAST_SAMPLE 4
#define IDEAL_RATIO_RATE 1000000
diff --git a/sound/soc/fsl/fsl_asrc_m2m.c b/sound/soc/fsl/fsl_asrc_m2m.c
index e1b347801688..cfe8eee8e886 100644
--- a/sound/soc/fsl/fsl_asrc_m2m.c
+++ b/sound/soc/fsl/fsl_asrc_m2m.c
@@ -552,12 +552,7 @@ 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] * 8)
- m2m->last_period_size = (m2m->rate[OUT] / m2m->rate[IN]) * 5;
- else 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;
+ m2m->last_period_size = ASRC_OUTPUT_LAST_SAMPLE;
ret = fsl_allocate_dma_buf(pair);
if (ret) {
@@ -623,6 +618,60 @@ static long fsl_asrc_ioctl_release_pair(struct fsl_asrc_pair *pair,
return 0;
}
+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;
+ 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;
+
+ switch (m2m->word_width[IN]) {
+ case ASRC_WIDTH_24_BIT:
+ in_width = 4;
+ break;
+ case ASRC_WIDTH_16_BIT:
+ in_width = 2;
+ break;
+ case ASRC_WIDTH_8_BIT:
+ in_width = 1;
+ break;
+ default:
+ in_width = 2;
+ break;
+ }
+
+ switch (m2m->word_width[OUT]) {
+ case ASRC_WIDTH_24_BIT:
+ out_width = 4;
+ break;
+ case ASRC_WIDTH_16_BIT:
+ out_width = 2;
+ break;
+ case ASRC_WIDTH_8_BIT:
+ out_width = 1;
+ break;
+ default:
+ out_width = 2;
+ break;
+ }
+
+ in_samples = pbuf->input_buffer_length / (in_width * channels);
+
+ out_samples = (m2m->rate[OUT] * in_samples / m2m->rate[IN]);
+
+ out_length = out_samples * out_width * channels;
+
+ last_period_size = pbuf->output_buffer_length / (out_width * channels)
+ - out_samples;
+
+ m2m->last_period_size = last_period_size + 1 + ASRC_OUTPUT_LAST_SAMPLE;
+
+ return 0;
+}
+
static long fsl_asrc_ioctl_convert(struct fsl_asrc_pair *pair,
void __user *user)
{
@@ -638,6 +687,8 @@ static long fsl_asrc_ioctl_convert(struct fsl_asrc_pair *pair,
return ret;
}
+ fsl_asrc_calc_last_period_size(pair, &buf);
+
ret = fsl_asrc_prepare_buffer(pair, &buf);
if (ret) {
pair_err("failed to prepare buffer: %ld\n", ret);