This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Linux/AM3354: McASP bit clock issue

Part Number: AM3354

Tool/software: Linux

Hi,

I am using AM3354 and mcasp0 for audio and I have made processor as master and applied 24Mhz mclock on AHCLKX pin. as per the clocking block of TRM I read mcasp register and Its showing proper devider values for bclock but when I measure bclock shows 24MHz clock, my audio is not playing and I am able to hear only noice on speaker. 

I have gone through register description and and found in AHCLKXCTL register description that :

"In the special case where the transmit bit clock (ACLKX) is internally generated and the programmable bit clock divider is set to divide-
by-1 (CLKXDIV = 0 in ACLKXCTL), AHCLKX is directly passed through to the ACLKX pin."

Thats true in my case when initialization << [get reg] reg [b0], val [0x60] >> but bclock  is calculated and devider value is filled when doing aplay for the first time. 
 
These are my register dumps  when doing "aplay test.wav" :

Here is mapping
44h GBLCTL
A0h XGBLCTL
B0h ACLKXCTL
B4h AHCLKXCTL


base :  0x48038000 ( All reg address and values are in hex )
[set bits]:     reg [a0] val [200]
[get reg]     reg [a0], val [200]
[set bits]:     reg [a0] val [100]
[get reg]     reg [a0], val [300]
[set bits]:     reg [a0] val [400]
[get reg]     reg [a0], val [700]
[get reg]     reg [c0], val [10c]
[set bits]:     reg [a0] val [800]
[get reg]     reg [a0], val [f00]
[set bits]:     reg [a0] val [1000]
[get reg]     reg [a0], val [1f00]
[set bits]:     reg [bc] val [1]

[get reg]     reg [a0], val [1f00]  // printing these registers in "mcasp_start_tx" function.
[get reg]     reg [44], val [1f00]  // printing these registers in "mcasp_start_tx" function.
[get reg]     reg [b4], val [00]     // printing these registers in "mcasp_start_tx" function.
[get reg]     reg [b0], val [2f]       // printing these registers in "mcasp_start_tx" function. ( I have set 'f'  as bclock devider ACLKX register here is the proff)


Starts Audio widget Shutdown process.
[clear bits] :     reg [bc] val [1]
[get reg]     reg [6c], val [13]
[get reg]     reg [b0], val [2f]
[set reg]     reg [a0], val [0]
[set reg]     reg [c0], val [ffffffff]
[clear bits] :     reg [fa039000] val [10000]


This is my sound node with generic "simple-audio-codec driver"
 
sound {
        compatible = "simple-audio-card";
        simple-audio-card,name = "Price";
        simple-audio-card,widgets =
            "Speaker", "Speaker";
        simple-audio-card,routing =
            "Speaker", "SPKOUTRN",
            "Speaker", "SPKOUTRP",
            "Speaker", "SPKOUTLN",
            "Speaker", "SPKOUTLP";
        simple-audio-card,format = "i2s";
        simple-audio-card,bitclock-master = <&cpu_master>;
        simple-audio-card,frame-master = <&cpu_master>;
        cpu_master: simple-audio-card,cpu {
            sound-dai = <&mcasp0>;
            system-clock-frequency = <24576000>;
            system-clock-id = <MCASP_CLK_HCLK_AHCLK>;
        };

        sound_master: simple-audio-card,codec {
            sound-dai = <&codec>;
            system-clock-frequency = <24576000>;
            system-clock-id = <1>;
        };
    };


 mcasp0_pins: mcasp0_pins {                              /* CHECK */
        pinctrl-single,pins = <
            0x1a0 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)     /* mcasp0_aclkr.AUD_BCLK */
            0x190 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)     /* mcasp0_aclkx.AUD_BCLK */

            0x1a4 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp0_fsr.AUD_FSR */
            0x194 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp0_fsx.AUD_FSX */

            0x198 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp0_axr0.AUD_OUT */
            0x1a8 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp0_axr1.AUD_IN*/

            0x19c (PIN_INPUT_PULLUP | MUX_MODE0) /* mcasp0_ahclkr.AUD_MCLK */
            0x1ac (PIN_INPUT_PULLUP | MUX_MODE0) /* mcasp0_ahclkx.AUD_MCLK */
        >;
    };


Can you help me out in this case?  Do I have to initialize divider in initialization?

  • Hi Chintan,

    Do you use TI PSDK v5.00.00.15?

    First you need to check if McASP0 module is enabled. You can do that from user space with devmem2 or omapconf tool, check what value you have in CM_PER_MCASP0_CLKCTRL/0x44E00034.

    Then you need to check if some code has overwritten your McASP0 pinmux settings. Please check these pimux registers from user space with devmem2 or omapconf tool:

    conf_mcasp0_aclkx
    conf_mcasp0_ahclkx
    conf_mcasp0_fsx
    conf_mcasp0_axr0
    conf_mcasp0_axr1

    Please also attach your DTS file for review.

    Regards,
    Pavel
  • Please also let me know:

    - what is the frequency supplied by your main OSC (CLK_M_OSC), 19.2MHz, 24MHz, 25MHz or 26MHz?
    - what frequency you have on mcasp0_aclkx pin (bit clock) and what frequency you expect to have?

    Regards,
    Pavel
  • /cfs-file/__key/communityserver-discussions-components-files/791/3542.am335x_2D00_prcheck.txt

    Hi,

    I have attached device tree file, I dont think any of the pinmuxing is conflicting with McASP.

    (When I am doing `devmem2 0x48038000` its showing Memory mapped at address 0xb6f04000.[ 4851.868073] Unhandled fault: external abort on non-linefetch (0x1018) at 0xb6f04000 error)

    Thanks,
    Chintan.

  • Following are answers:

    1) Oscillator frequency (CLK_M_OSC) is 24Mhz, I found it was my mistake any I changed my sound node to

    sound {
    compatible = "simple-audio-card";
    simple-audio-card,name = "Price";
    simple-audio-card,widgets =
    "Speaker", "Speaker";
    simple-audio-card,routing =
    "Speaker", "SPKOUTRN",
    "Speaker", "SPKOUTRP",
    "Speaker", "SPKOUTLN",
    "Speaker", "SPKOUTLP";
    simple-audio-card,format = "i2s";
    simple-audio-card,bitclock-master = <&cpu_master>;
    simple-audio-card,frame-master = <&cpu_master>;
    cpu_master: simple-audio-card,cpu {
    sound-dai = <&mcasp0>;
    system-clock-frequency = <24000000>;
    system-clock-id = <MCASP_CLK_HCLK_AHCLK>;
    };

    sound_master: simple-audio-card,codec {
    sound-dai = <&codec>;
    system-clock-frequency = <24576000>; //Codec generates 24567000 from mclk 24Mhz and FLL settings)
    system-clock-id = <1>;
    };
    };

    I am using wlf, wm5102 audio codec.


    2) I am seeing frequency as 24Mhz on aclkx pin, I am expecting 1.52Mhz as BCLK clock for 48K bitrate audio file.

    Thanks,
    Chintan.
  • Chintan,

    Do you use TI PSDK v5.00.00.15?

    Can you also provide me the value you have in PDIR/0x14 register?

    You need to set bit AHCLKX[15] HCLKXM to 1, thus you will export the McASP0 auxclk on mcasp0_aclkx pin. But the value will be 1.6MHz (24MHz/15). You can try to add "system-clock-direction-out" in your DTS. This should set SND_SOC_CLOCK_OUT, instead of SND_SOC_CLOCK_IN.

    Refer to the below pointers for more info:

    linux-kernel/sound/soc/davinci/davinci-mcasp.c -> see function davinci_mcasp_set_sysclk()
    linux-kernel/sound/soc/generic/simple-card-utils.c -> see function asoc_simple_card_parse_clk()
    linux-kernel/Documentation/devicetree/bindings/sound/simple-card.txt
    linux-kernel/arch/arm/boot/dts/am437x-gp-evm-hdmi.dts

    www.ti.com/.../sprac09a.pdf
    processors.wiki.ti.com/.../Sitara_Linux_Audio_DAC_Example

    e2e.ti.com/.../211493
    e2e.ti.com/.../237626

    Regards,
    Pavel
  • Hi,

    I am using ti-processor-sdk-linux-am335x-evm-03.02.00.05 SDK, but I can switch to latest one.
    and my 0x14 register value when I do aplay is [ 0xb4000002].

    I am bit confuse here. I am giving external clock from CLKOUT pin to my AHCLKX as input as Audio system clock. following are my quesstions :

    1) Is there anything wrong in above method?
    2) I tried  with your suggested configuration but I am not able to see system clock out from AHCLKX pin. Can you suggest me registers to write or changes I have to make in device tree or driver to use system clock (CLK_M_OSC) as Audio aux clock? I think thats missing.

    Thanks,
    Chintan. 

  • Chintan Jobanputra said:
    I am bit confuse here. I am giving external clock from CLKOUT pin to my AHCLKX as input as Audio system clock. following are my quesstions :

    I am also confused now. Do you provide 24MHz clock from AM335x CLKOUT1 pin to AM335x AHCLKX pin? What about codec MCLK pin, who is providing clock there?

    Chintan Jobanputra said:
    1) Is there anything wrong in above method?

    I would recommend you to use auxclk to produce McASP AHCLKX (to supply external codec, if needed), ACLKX (bit clock) and AFSX (Frame Sync). auxclk is based on OSC_M_OSC/24MHz clock, it is supplied internally.

    The serial clock (clock at the bit rate) (bit clock) may be sourced:

    - Internally - by passing through two clock dividers off the internal clock source (AUXCLK)

    - Externally - directly from ACLKX pin

    - Mixed - an external high-frequency clock is input to the McASP on either the AHCLKX or AHCLKR pins, and divided down to produce the bit rate clock.

    In the internal/mixed cases, the bit rate clock is generated internally and should be driven out on the ACLKX (for transmit) or ACLKR (for receive) pins. In the internal case, an internally-generated high- frequency clock may be driven out onto the AHCLKX or AHCLKR pins to serve as a reference clock for other components in the system.

    Chintan Jobanputra said:
    2) I tried  with your suggested configuration but I am not able to see system clock out from AHCLKX pin. Can you suggest me registers to write or changes I have to make in device tree or driver to use system clock (CLK_M_OSC) as Audio aux clock? I think thats missing.

    You need to change only DTS file. Do not change drivers or registers directly, drivers and registers should be configured according to settings in DTS file. Refer to the below pointers for more info:

    Regards,
    Pavel

  • 1) I am giving same clock to codec. so, master clock is generated from CLKOUT1 and same clock has been supplied to both processor and codec on appropriate mclk pin. ( "an external high-frequency clock is input to the McASP on either the AHCLKX or AHCLKR pins, and divided down to produce the bit rate clock." I am using this right now.)  Audio clock block suggest I should be able to see devided bclock when I supply high frequecy clock at AHCLKX pin.

    2) I have changed sound node config to :
        

      ....
            simple-audio-card,format = "i2s";
            simple-audio-card,bitclock-master = <&cpu_master>;
            simple-audio-card,frame-master = <&cpu_master>;
            simple-audio-card,bitclock-inversion;
    
            cpu_master: simple-audio-card,cpu {
                sound-dai = <&mcasp0>;
                system-clock-frequency = <24000000>;
                system-clock-direction = "out";
                /*system-clock-id = <MCASP_CLK_HCLK_AHCLK>;*/
                system-clock-id = <MCASP_CLK_HCLK_AUXCLK>;
               
            };
     ...

     and changed pinmux for AHCLKX and AHCLKR pin to PIN_OUTPUT_PULLDOWN

    Now, That should give me clock at AHCLKX pin of 24Mhz, Is that correct understanding?


    Thanks,
    Chintan.



  • Chintan Jobanputra said:
    1) I am giving same clock to codec. so, master clock is generated from CLKOUT1 and same clock has been supplied to both processor and codec on appropriate mclk pin. ( "an external high-frequency clock is input to the McASP on either the AHCLKX or AHCLKR pins, and divided down to produce the bit rate clock." I am using this right now.)  Audio clock block suggest I should be able to see devided bclock when I supply high frequecy clock at AHCLKX pin.

    Yes, this approach might also work but has been not tested.

    Chintan Jobanputra said:
    system-clock-direction = "out";

    Not correct, should be "system-clock-direction-out"

    Chintan Jobanputra said:
    Now, That should give me clock at AHCLKX pin of 24Mhz, Is that correct understanding?

    Yes

  • With this configuration I am not able to see mclk on AHCLK pin.
  • Chintan Jobanputra said:
    With this configuration I am not able to see mclk on AHCLK pin.

    With which configuration?

  • simple-audio-card,format = "i2s";
            simple-audio-card,bitclock-master = <&cpu_master>;
            simple-audio-card,frame-master = <&cpu_master>;
            simple-audio-card,bitclock-inversion;
    
            cpu_master: simple-audio-card,cpu {
                sound-dai = <&mcasp0>;
                system-clock-frequency = <24000000>;
                system-clock-direction-out;
                system-clock-id = <MCASP_CLK_HCLK_AUXCLK>;
            };

    Is there anything missing to connect CLK_M_OSC ---> AUXCLK?  

  • Chintan Jobanputra said:
    cpu_master: simple-audio-card,cpu { sound-dai = <&mcasp0>; system-clock-frequency = <24000000>; system-clock-direction-out; system-clock-id = <MCASP_CLK_HCLK_AUXCLK>; };

    Please try with the below update and report back the result.

    cpu_master: simple-audio-card,cpu {
                sound-dai = <&mcasp0>;
                system-clock-frequency = <24000000>;
                 system-clock-direction = "out",
            };


    The same approach (using auxclk to produce bit clock) is used in below DTS files, check for reference:

    linux-kernel/arch/arm/boot/dts/am335x-boneblack.dts

    linux-kernel/arch/arm/boot/dts/am57xx-cl-som-am57x.dts

    linux-kernel/arch/arm/boot/dts/am437x-gp-evm-hdmi.dts

    linux-kernel/arch/arm/boot/dts/dta7-evm-common.dtsi

    Please have a try and report back the result. If you still do not have 24MHz clock on mcasp0_ahclkx pin, please provide me:

    - your latest DTS file

    - value of register conf_mcasp0_ahclkx in user space

    - values of registers PDIR, GBLCTL, XGBLCTL, ACLKXCTL, AHCLKXCTL

    Regards,
    Pavel