[alsa-devel] iMX6 ESAI TDM with underrun and overrun support

Aurelien Bouin a_bouin at yahoo.fr
Fri Dec 19 11:13:32 CET 2014


Hi Nicolin,
First thank you for your support,

>
>Le Vendredi 19 décembre 2014 10h23, Nicolin Chen <nicoleotsuka at gmail.com> a écrit :
>On Thu, Dec 18, 2014 at 09:00:43AM +0000, Aurelien Bouin wrote:
>> Yes and No.
>> It supports up to 32 words (slots) per period on each transmit line, in the limit of 128 words (FIFO limitations)
>> My reference is in the Reference Manual of the iMX6 "26.1.1 Features" in the ESAI chapter
>> 
>> FYI in the fsl_esai.c you can find how multiples lines and slots are handled : 
>> -> fsl_esai_hw_params : u32 pins = DIV_ROUND_UP(channels, esai_priv->slots);
>> Then it will enable the number of hardware pins used in transmit and receive mode with TFCR or RFCR :
>> val = ESAI_xFCR_xWA(width) | ESAI_xFCR_xFWM(esai_priv->fifo_depth) |
>> (tx ? ESAI_xFCR_TE(pins) | ESAI_xFCR_TIEN : ESAI_xFCR_RE(pins));
>
>
>> I first apply the patch on my kernel I am currently using 64 channels (32 slots of 8bits width on 2 transmits pins)
>> 
>> But for example you can use up to 6 transmits pins with a configuration of 2 slots of 16 bits width and 12 channels ask in alsa ...
>
>
>Ah, I forgot you could use several pins....
>
>
>> >http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git
>> I already tried the branches :
>> imx_3.10.31_1.1.0_alpha
>> imx_3.10.31_1.1.0_beta2
>> They implemented a fsl_reset function somewhere ... but it is never called ... and the problem persist ...
>
>
>I have a bit doubt whether your problem is the underrun or not. Because
>I remember the work around submitter did test with underrun issue.
>The reset function would be trigger by the ESAI internal ISR but be called
>through the ISR from dma callback.
>
>
>There's a fsl_esai_check_xrun() inside the ESAI. You can try to see if

>it's really underrun happened.

I get back to linux branch imx_3.10.31_1.1.0_beta2 at git://git.freescale.com/imx/linux-2.6-imx.git
I figured out that the TIE and TEIE bits in the TCR register are not set at any moment ...
So I add in the fsl_esai_set_dai_fmt


#define MAKE_TCR_INTERRUPTIBLE
#ifdef MAKE_TCR_INTERRUPTIBLE
//make it interruptible
printk(KERN_ERR"%s(%d)\n",__func__,__LINE__);
mask |= ESAI_xCR_xEIE_MASK | ESAI_xCR_xIE_MASK;
xcr |= ESAI_xCR_xEIE | ESAI_xCR_xIE;
//make it interruptible
#endif /* MAKE_TCR_INTERRUPTIBLE */


I also add a dump function that show the register at  fsl_esai_hw_params : ESAI_TCR   0x00728100
I also add debug in the function fsl_esai_check_xrun that show the saisr register
When underrun occured (when I see that with an oscilloscope)

There is no interrupt generated ...

I tried to change the transmit fifo watermak(These bits configure the threshold at which the Transmit FIFO Empty flag will set) to set it to a value of 2
Before I was using 64, since I use 64 channels in this case I get a lot of underrun interrupt ... and of course it is not working correctly .. because the dma know to late that there is not enough data in the ESAI transmit FIFO...

FYI here is my fsl_esai.c modified : http://pastebin.com/x5vnfAM8

>
>

>And besides, which pins from IOMUX are you using for ESAI?
I am using TX0, TX1 and RX0, RX1
But for the moment I am just working on the playback (transmits pins)
>

>--Nicolin

Regards,
Aurelien BOUIN


More information about the Alsa-devel mailing list