aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/davinci
diff options
context:
space:
mode:
authorPeter Ujfalusi <peter.ujfalusi@ti.com>2014-04-01 08:55:11 -0400
committerMark Brown <broonie@linaro.org>2014-04-14 12:24:11 -0400
commitdd093a0f1962fb71e8852411f03fec7290027a90 (patch)
tree7f19f76689ca699d663a2eee1913d1d2ea921ef4 /sound/soc/davinci
parent5f04c603a52d4951e6f6b2f059049e7c5ee93db7 (diff)
ASoC: davinic-mcasp: Adopt the AFIFO/DMA configuration to the stream (dynamic depth)
Configure the AFIFO numevt parameter based on the requested tx/rx_numevt, active serializers and period size in words. In this way McASP can adopt it's (and the DMA) configuration runtime and can pick the most optimal setup which satisfy the parameters. This way we do not need to place any constraint on the stream itself, allowing application greater freedom on how they want to set up ALSA. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com> Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound/soc/davinci')
-rw-r--r--sound/soc/davinci/davinci-mcasp.c30
1 files changed, 23 insertions, 7 deletions
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index ab4fa1291795..9454d123f4bb 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -466,7 +466,7 @@ static int davinci_config_channel_size(struct davinci_mcasp *mcasp,
466} 466}
467 467
468static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, 468static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream,
469 int channels) 469 int period_words, int channels)
470{ 470{
471 struct davinci_pcm_dma_params *dma_params = &mcasp->dma_params[stream]; 471 struct davinci_pcm_dma_params *dma_params = &mcasp->dma_params[stream];
472 struct snd_dmaengine_dai_dma_data *dma_data = &mcasp->dma_data[stream]; 472 struct snd_dmaengine_dai_dma_data *dma_data = &mcasp->dma_data[stream];
@@ -475,7 +475,7 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream,
475 u8 rx_ser = 0; 475 u8 rx_ser = 0;
476 u8 slots = mcasp->tdm_slots; 476 u8 slots = mcasp->tdm_slots;
477 u8 max_active_serializers = (channels + slots - 1) / slots; 477 u8 max_active_serializers = (channels + slots - 1) / slots;
478 u8 active_serializers, numevt; 478 int active_serializers, numevt, n;
479 u32 reg; 479 u32 reg;
480 /* Default configuration */ 480 /* Default configuration */
481 if (mcasp->version != MCASP_VERSION_4) 481 if (mcasp->version != MCASP_VERSION_4)
@@ -526,7 +526,6 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream,
526 return -EINVAL; 526 return -EINVAL;
527 } 527 }
528 528
529
530 /* AFIFO is not in use */ 529 /* AFIFO is not in use */
531 if (!numevt) { 530 if (!numevt) {
532 /* Configure the burst size for platform drivers */ 531 /* Configure the burst size for platform drivers */
@@ -535,11 +534,26 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream,
535 return 0; 534 return 0;
536 } 535 }
537 536
538 if (numevt * active_serializers > MCASP_MAX_AFIFO_DEPTH) 537 if (period_words % active_serializers) {
538 dev_err(mcasp->dev, "Invalid combination of period words and "
539 "active serializers: %d, %d\n", period_words,
540 active_serializers);
541 return -EINVAL;
542 }
543
544 /*
545 * Calculate the optimal AFIFO depth for platform side:
546 * The number of words for numevt need to be in steps of active
547 * serializers.
548 */
549 n = numevt % active_serializers;
550 if (n)
551 numevt += (active_serializers - n);
552 while (period_words % numevt && numevt > 0)
553 numevt -= active_serializers;
554 if (numevt <= 0)
539 numevt = active_serializers; 555 numevt = active_serializers;
540 556
541 /* Configure the AFIFO */
542 numevt *= active_serializers;
543 mcasp_mod_bits(mcasp, reg, active_serializers, NUMDMA_MASK); 557 mcasp_mod_bits(mcasp, reg, active_serializers, NUMDMA_MASK);
544 mcasp_mod_bits(mcasp, reg, NUMEVT(numevt), NUMEVT_MASK); 558 mcasp_mod_bits(mcasp, reg, NUMEVT(numevt), NUMEVT_MASK);
545 559
@@ -620,6 +634,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
620 &mcasp->dma_params[substream->stream]; 634 &mcasp->dma_params[substream->stream];
621 int word_length; 635 int word_length;
622 int channels = params_channels(params); 636 int channels = params_channels(params);
637 int period_size = params_period_size(params);
623 int ret; 638 int ret;
624 639
625 /* If mcasp is BCLK master we need to set BCLK divider */ 640 /* If mcasp is BCLK master we need to set BCLK divider */
@@ -633,7 +648,8 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
633 cpu_dai, 1, mcasp->sysclk_freq / bclk_freq); 648 cpu_dai, 1, mcasp->sysclk_freq / bclk_freq);
634 } 649 }
635 650
636 ret = mcasp_common_hw_param(mcasp, substream->stream, channels); 651 ret = mcasp_common_hw_param(mcasp, substream->stream,
652 period_size * channels, channels);
637 if (ret) 653 if (ret)
638 return ret; 654 return ret;
639 655