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

Nicolin Chen nicoleotsuka at gmail.com
Sat Oct 31 02:48:45 CET 2015


On Fri, Oct 30, 2015 at 03:04:37PM -0700, Caleb Crome wrote:
 
> **********************
> ** Problem 1 *******
> **********************
> When I enable your patch in single fifo mode we get maxburst lost
> samples at the beginning of the stream.  The important bit is below.
> It doesn't matter if the SSIEN comes before or after the TDMAE, the
> samples are lost.  Surely because something in the fsl_ssi_config
> clears the fifo.  I didn't look into that yet.

The config function has gone way complicated than I realized.
But you may need to dig a little bit to make a perfect point
to insert your change as it might break other platforms: AC97
and old i.MX and MPC.

> --------------------------- snip -------------------
> 
> If instead, I do the SSIEN at the bottom of the fsl_ssi_configure
> function like this, it works perfectly (in single fifo mode)
> 
> --------------------------- snip -------------------
> +++ b/sound/soc/fsl/fsl_ssi.c
> @@ -435,8 +435,49 @@ static void fsl_ssi_config(struct fsl_ssi_private
> *ssi_private, bool enable,
> 
>  config_done:
>      /* Enabling of subunits is done after configuration */
> -    if (enable)
> +    if (enable) {
> +        /* eanble SSI */
> +        regmap_update_bits(regs, CCSR_SSI_SCR,
> +                   CCSR_SSI_SCR_SSIEN,
> +                   CCSR_SSI_SCR_SSIEN);
> +        /*
> +         * We must wait here until the DMA actually manages to
> +         * get a word into the Tx FIFO.  Only if starting a Tx
> +         * stream.
> +         * In tests on an MX6 at 1GHz clock speed, the do
> +         * loop below never iterated at all (i.e. it dropped
> +         * through without repeating ever.  which means that
> +         * the DMA has had time to get some words into the TX
> +         * buffer. In fact, the tfcnt0 was always 13, so it
> +         * was quite full by the time it reached this point,
> +         * so this do loop should never be a bottleneck.  If
> +         * max iterations is hit, then something might be
> +         * wrong.  report it in that case.
> +         */
> +        int tfcnt0 = 0;
> +        int tfcnt1 = 1;
> +        int max_iterations = 1000;
> +        if (vals->scr & CCSR_SSI_SCR_TE) {
> +            u32 sfcsr;
> +            do {
> +                regmap_read(regs, CCSR_SSI_SFCSR, &sfcsr);
> +                tfcnt0 = CCSR_SSI_SFCSR_TFCNT0(sfcsr);
> +                tfcnt1 = CCSR_SSI_SFCSR_TFCNT0(sfcsr);
> +            } while(max_iterations-- && (tfcnt0 == 0) && (tfcnt1 == 0));
> +        }
> +        if (max_iterations <= 0) {
> +            /*
> +             * The DMA definitely should have stuck at
> +             * least a word into the FIFO by now.  Report
> +             * an error, but continue on blindly anyway,
> +             * even though the SSI might not start right.
> +             */
> +            struct platform_device *pdev = ssi_private->pdev;
> +            dev_err(&pdev->dev, "max_iterations reached when"
> +                "starting SSI Tx\n");
> +        }

Looks like polling is the only way to safely kick off. It's okay.
But I would like to see how the change will be after merging the
simultaneous TE/RE work around. It may need go a long way with
other platform users.


More information about the Alsa-devel mailing list