ESAI peripheral generating incorrect I2S frequencies

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

ESAI peripheral generating incorrect I2S frequencies

387 Views
remingtonfurman
Contributor II

I'm having trouble getting my ESAI peripheral to generate the right I2S clock frequencies on the SCK, BCK, and LRCK pins going to my codec.  The codec is a TI PCM1753 and it can only be a clock slave, so the ESAI has to be the master and generate SCK.

I think I have the clocks configured correctly in the device tree and my drivers, but when I scope the pins they are wildly different from the target frequencies.

As an example, to play stereo audio at a 8kHz sample rate I need:

LRCK =    8000 Hz
BCK  =  512000 Hz (LRCK * 2 channels * 32 bits per channel)
SCK  = 1024000 Hz (LRCK * 128)

When I probe the pins I currently get these frequencies (with a lot of jitter):
LRCK =   ~220 Hz

BCK = ~670000 Hz

SCK = 0 Hz (stuck high)

My main question is why are these values so different, and what would cause a LRCK to be so low?

I suppose the answer might be found in the actual register values in the ESAI, but so far I've only tackled the problem through the Linux 4.9.9 source code and my board's device tree config.  I've been using a JTAG debugger to learn help sort this out.

I have a .dts file that configures the ESAI_EXTAL clock to use PLL4 and OSC as the source clock.   The target frequency for EXTAL is 983040000Hz (~983MHz) so that the ESAI can divide down to the I2S SCK values I would like (128 times 8kHz, 16kHz, or 48kHz).

&esai {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_esai>;
    fsl,fifo-depth = <128>;

    assigned-clocks = <&clks IMX6QDL_CLK_ESAI_SEL>,
                      <&clks IMX6QDL_CLK_PLL4_POST_DIV>,
                      <&clks IMX6QDL_CLK_ESAI_EXTAL>;
    assigned-clock-parents = <&clks IMX6QDL_CLK_PLL4_AUDIO_DIV>;
    assigned-clock-rates = <983040000>, <983040000>, <983040000>;

    status = "okay";
};

&clks {
    assigned-clocks = <&clks IMX6QDL_CLK_PLL4>,
                      <&clks IMX6QDL_PLL4_BYPASS>;
    assigned-clock-parents = <&clks IMX6QDL_CLK_OSC>,
                             <&clks IMX6QDL_CLK_PLL4>;
    assigned-clock-rates = <983040000>, <983040000>;
};

        pinctrl_esai: esaigrp {
            fsl,pins = <
                MX6QDL_PAD_GPIO_4__ESAI_TX_HF_CLK   0x1b030
                MX6QDL_PAD_GPIO_17__ESAI_TX0        0x1b030
                MX6QDL_PAD_GPIO_6__ESAI_TX_CLK      0x1b030
                MX6QDL_PAD_GPIO_2__ESAI_TX_FS       0x1b030
            >;
        };

At runtime, cat /sys/kernel/debug/clk/clk_summary shows that the EXTAL clock is indeed set to 983MHz:

    pll4                                  0            0   983040000          0 0  
       pll4_bypass                        0            0   983040000          0 0  
          pll4_audio                      0            0   983040000          0 0  
             pll4_post_div                0            0   983040000          0 0  
                pll4_audio_div            0            0   983040000          0 0  
                   esai_sel               0            0   983040000          0 0  
                      esai_pred           0            0   983040000          0 0  
                         esai_podf           0            0   983040000          0 0  
                            esai_extal           0            0   983040000          0 0

I believe 938MHz is allowed for the ESAI EXTAL clock frequency, but I can't find documentation on the allowed frequencies in the reference manual.  It does say that PLL4 can go from 650 MHz to 1300 MHz, but is that whole range valid for the ESAI?

I am using the simple-card.c ASoC driver instead of writing my own ASoC machine driver.  I don't think I need the ASRC peripheral, since all the audio sample rates I need can be divided from a 983040000Hz.  (I have a spreadsheet to double check that math.)  The function fsl_esai_set_dai_sysclk() in fsl_esai.c does not return an error with this EXTAL frequency, so I believe that it is able to set the dividers to generate SCK correctly.

This is the device tree config I am using for that driver:

    sound {

        compatible = "simple-audio-card";

        simple-audio-card,name = "Texas Instruments PCM1753 Audio";

        simple-audio-card,format = "i2s";

        simple-audio-card,widgets = "Speaker", "Internal Speaker"; /* template, widget name */

        simple-audio-card,routing = "Internal Speaker", "VOUTL",   /* sink, source */

                                    "Internal Speaker", "VOUTR";

        simple-audio-card,bitclock-master = <&dailink0_master>;

        simple-audio-card,frame-master = <&dailink0_master>;

        simple-audio-card,mclk-fs = <128>; /* 128, 192, 256, 384, 512, 768, 1152 */

        status = "okay";

        dailink0_master: simple-audio-card,cpu {

            sound-dai = <&esai>;

            dai-tdm-slot-num = <2>;    /* stereo, left and right channels */

            dai-tdm-slot-width = <32>; /* 32 bit clocks per channel */

        };

        simple-audio-card,codec {

            sound-dai = <&pcm1753>;

        };

    };

I'm setting the slot-num and slot-width parameters above so that the BCK is 64*LRCK, as required by my codec.

Please let me know if you have any suggestions or see anything incorrect in what I've shared so far.

Thank you,

Remington Furman

Board details:

Custom board

NXP iMX6 Solo
TI PCM1753 Codec
Linux kernel version 4.9.9
Built with Yocto

Labels (4)
4 Replies

22 Views
remingtonfurman
Contributor II

Thanks for the reference links, Igor.

Are you able to answer this particular question?

I believe 938MHz is allowed for the ESAI EXTAL clock frequency, but I can't find documentation on the allowed frequencies in the reference manual.  It does say that PLL4 can go from 650 MHz to 1300 MHz, but is that whole range valid for the ESAI?

The other option for clocking the ESAI is the fsys clock which is only 132MHz, but I can't use that to generate the I2S clocks I want.

I've been comparing the actual ESAI register values (TCR, TCCR, and ECR) with what I expect to see based on the reference manual, but have not found anything wrong there yet.  Obviously I'm still learning how this works, so I might have missed something.

I think I am close to finding the source of the problem with my current driver setup, but if I can't figure it out soon I'll look into using the ASRC driver.  Switching kernel versions is not an option for my team, since we have many patches on our current version.

0 Kudos
Reply

22 Views
igorpadykov
NXP Employee
NXP Employee

>I believe 938MHz is allowed for the ESAI EXTAL clock frequency

I do not think so, sorry.

Best regards
igor

0 Kudos
Reply

22 Views
igorpadykov
NXP Employee
NXP Employee

Hi Remington

reason for wrong clocks may be absence of asrc driver, so one can try with nxp linux

from source.codeaurora.org/external/imx repository (note Linux kernel version 4.9.9 is not supported

by nxp), which support asrc, like linux L4.9.11

linux-imx - i.MX Linux kernel 

documentation :

i.MX Software | NXP 

Best regards
igor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
Reply

22 Views
remingtonfurman
Contributor II

I should mention that at one point in my debugging I had sound coming out of the speaker, but the I2S clocks were still very low, so the sound was only noise.  At least that shows that the hardware is somewhat functional.

0 Kudos
Reply