[alsa-devel] fsl_ssi.c: Getting channel slips with fsl_ssi.c in TDM (network) mode.

arnaud.mouiche at invoxia.com arnaud.mouiche at invoxia.com
Tue Oct 20 09:36:34 CEST 2015


Hello Caleb,

I go through all [few] patchs we apply to the 4.0 linux tree (didn't 
jump to 4.2 yet).
There is one concerning the DMA firmware you can find in the freescale 
tree, available at git://git.freescale.com/imx/linux-2.6-imx.git

commit 619bfca89908b90cd6606ed894c180df0c481508
Author: Shawn Guo <shawn.guo at freescale.com>
Date:   Tue Jul 16 22:53:18 2013 +0800

     ENGR00269945: firwmare: imx: add imx6q sdma script

     Add imx6q sdma script which will be used by all i.MX6 series.

     Signed-off-by: Shawn Guo <shawn.guo at freescale.com>

  firmware/Makefile                     |   1 +
  firmware/imx/sdma/sdma-imx6q.bin.ihex | 116 
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2 files changed, 117 insertions(+)


I don't know how 4.3rcN catch some of the freescale patch. but you may 
check if you need to apply this one.
I know there are some other SDMA firmware available all around in this 
freescale tree. I didn't find proper release note or documentation. May 
be you can test them also.

Arnaud

Le 19/10/2015 17:55, Caleb Crome a écrit :
> Hello Arnaud, all,
>
> I'm trying to get the i.MX6 SSI working in 16-channel TDM mode.  FYI, 
> I'm working with the stock 4.3 kernel at 
> https://github.com/torvalds/linux.
>
> When I apply the patch below, the SSI does all configure properly and 
> even starts streaming properly with all the bits in the right place on 
> the SSI pins.  However, given a little bit of time and/or IO to the SD 
> card, the bit-stream slips by 1 slot, causing all of the channels to 
> be misaligned.
>
> My changes to the SSI driver are very minimal (shown below), and 
> amount to forcing it into network (TDM) mode, and changing the maximum 
> channels, and setting the STCCR DC mask.
>
> There is no indication from user space that anything has slipped, so 
> the data stream just continues on shifted by 1 slot.
>
> You (Arnaud) mentioned in a previous thread ("Multiple codecs on one 
> sound card for multi-channel sound card"), that I should just have to 
> set channels_max (and presumably the other changes I mentioned), and 
> it'll work mostly. However, it's very unreliable at the moment.
>
> Any thoughts to how I can diagnose this problem would be greatly 
> appreciated!
>
> So, what happens is this:
>
> The SSI Starts sending data like this:
> SLOT 0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15
> DATA 0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15
>
> But then after time, something slips and without warning it goes to:
> SLOT 0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15
> DATA 15 0  1  2  3  4  5  6  7  8  9  10 11 12 13 14
>
> diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
> index 37c5cd4..73778c2 100644
> --- a/sound/soc/fsl/fsl_ssi.c
> +++ b/sound/soc/fsl/fsl_ssi.c
> @@ -749,7 +749,10 @@ static int fsl_ssi_hw_params(struct 
> snd_pcm_substream *substream,
>                  CCSR_SSI_SCR_NET | CCSR_SSI_SCR_I2S_MODE_MASK,
>                  channels == 1 ? 0 : i2smode);
>      }
> -
> +    ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_NORMAL | 
> CCSR_SSI_SCR_NET;
> +    regmap_update_bits(regs, CCSR_SSI_SCR,
> +               CCSR_SSI_SCR_NET | CCSR_SSI_SCR_I2S_MODE_MASK,
> +               ssi_private->i2s_mode);
>      /*
>       * FIXME: The documentation says that SxCCR[WL] should not be
>       * modified while the SSI is enabled.  The only time this can
> @@ -863,6 +866,15 @@ static int _fsl_ssi_set_dai_fmt(struct device *dev,
>          return -EINVAL;
>      }
>      scr |= ssi_private->i2s_mode;
> +    // Set to 16 slots/frame
> +    regmap_update_bits(regs, CCSR_SSI_STCCR,
> +               CCSR_SSI_SxCCR_DC_MASK,
> +               CCSR_SSI_SxCCR_DC(16));
> +
> +    regmap_update_bits(regs, CCSR_SSI_SRCCR,
> +               CCSR_SSI_SxCCR_DC_MASK,
> +               CCSR_SSI_SxCCR_DC(16));
> +
>
>      /* DAI clock inversion */
>      switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
> @@ -1084,14 +1099,14 @@ static struct snd_soc_dai_driver 
> fsl_ssi_dai_template = {
>      .playback = {
>          .stream_name = "CPU-Playback",
>          .channels_min = 1,
> -        .channels_max = 2,
> +        .channels_max = 16,
>          .rates = FSLSSI_I2S_RATES,
>          .formats = FSLSSI_I2S_FORMATS,
>      },
>      .capture = {
>          .stream_name = "CPU-Capture",
>          .channels_min = 1,
> -        .channels_max = 2,
> +        .channels_max = 16,
>          .rates = FSLSSI_I2S_RATES,
>          .formats = FSLSSI_I2S_FORMATS,
>      },
>
> Another thing I have tried is changing the watermark level for the 
> fifo to give the DMA interrupt some extra time. The problem still 
> happens, but seems to be a bit better.
>
> The fifo watermark change is this:
> diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
> index 73778c2..7c2e4b0 100644
> --- a/sound/soc/fsl/fsl_ssi.c
> +++ b/sound/soc/fsl/fsl_ssi.c
> @@ -54,6 +54,8 @@
>  #include "fsl_ssi.h"
>  #include "imx-pcm.h"
>
> +#define WATERMARK 8
> +
>  /**
>   * FSLSSI_I2S_RATES: sample rates supported by the I2S
>   *
> @@ -943,7 +950,7 @@ static int _fsl_ssi_set_dai_fmt(struct device *dev,
>       * size.
>       */
>      if (ssi_private->use_dma)
> -        wm = ssi_private->fifo_depth - 2;
> +        wm = ssi_private->fifo_depth - WATERMARK;
>      else
>          wm = ssi_private->fifo_depth;
>
> @@ -1260,8 +1267,8 @@ static int fsl_ssi_imx_probe(struct 
> platform_device *pdev,
>       * We have burstsize be "fifo_depth - 2" to match the SSI
>       * watermark setting in fsl_ssi_startup().
>       */
> -    ssi_private->dma_params_tx.maxburst = ssi_private->fifo_depth - 2;
> -    ssi_private->dma_params_rx.maxburst = ssi_private->fifo_depth - 2;
> +    ssi_private->dma_params_tx.maxburst = ssi_private->fifo_depth - 
> WATERMARK;
> +    ssi_private->dma_params_rx.maxburst = ssi_private->fifo_depth - 
> WATERMARK;
>      ssi_private->dma_params_tx.addr = ssi_private->ssi_phys + 
> CCSR_SSI_STX0;
>      ssi_private->dma_params_rx.addr = ssi_private->ssi_phys + 
> CCSR_SSI_SRX0;
>
>
> Thanks,
>   -Caleb
>



More information about the Alsa-devel mailing list