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.

playback write error (DMA or IRQ trouble?) on Dra7xx platform

Other Parts Discussed in Thread: TLV320DAC3100, TLV320AIC3100

Hi All,
We have a DRA7xx based customised board (reference VAYU Board) and
I'm working to adapt an OS linux version based on GLSDK-7.0.2 (kernel  3.14) on our custum board.

When I try to play an audio wav file with alsa's player aplay, I get the following errors:

bash-3.2# aplay Alarm_Classic.wav
Playing WAVE 'Alarm_Classic.wav' :
Signed 16 bit Little Endian, Rate 44100 Hz, Stereo

After few seconds.....

pcm_write:1939: write error: Input/output error
-bash-3.2# dmesg
ALSA sound/core/pcm_lib.c:1957 playback write error (DMA or IRQ trouble?)


My registered sound card  is:

-bash-3.2# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: DRA7xxGHMIOS [DRA7xx-GHMIOS], device 0: AIC31XX tlv320aic31xx-hifi-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0

 
Playing the same file audio on the same board with OS Android 6AJ.1.3 ( kernel  3.8.13) ,
it sounds good with no error so I'm sure that is not a hardware problem.


Basically my  configurations in kernel 3.14 are these:

DTS:

  dac_pins: pinmux_dac_pins {
         pinctrl-single,pins = <
            0x298 0x00005   /* xref_clk1.mcasp2.atl_clk1  PIN OUTPUT */  /*MCLK pin TLV320DAC3100 */
            0x2B8 0x1000E   /* mcasp1_axr1.gpio5_3        PIN OUTPUT */    /*CODEC_RESET~ pin TLV320DAC3100 */
            0x2F4 0x00180   /* mcasp2_aclkx.mcasp2_aclkx  PIN OUTPUT */    /*BCLK pin TLV320DAC3100 */
            0x2F8 0x00180   /* mcasp2_fsx.mcasp2_fsx      PIN OUTPUT */    /*WCLK pin TLV320DAC3100 */
            0x30C 0x00180   /* mcasp2_axr2.mcasp2_axr2    PIN OUTPUT */    /*DIN pin TLV320DAC3100 */
         >;
     };

   mcasp2: mcasp@48464000 {
            compatible = "ti,dra7-mcasp-audio";
            ti,hwmods = "mcasp2";
            reg = <0x48464000 0x2000>;
            reg-names = "mpu";
            interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>, /* AREVT */
                       <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>; /* TXEVT */
            interrupt-names = "tx", "rx";
            dmas = <&sdma_xbar 131>, <&sdma_xbar 130>;
            dma-names = "tx", "rx";
            clocks = <&mcasp2_ahclkx_mux>;
            clock-names = "fck";
            status = "disabled";
        };


    primary_sound: primary_sound {
    compatible = "ti,dra7xx-ghmios-snd";
    ti,model = "DRA7xx-GHMIOS";
       
    ti,always-on;
    ti,audio-codec = <&tlv320dac3100>;
    ti,mcasp-controller = <&mcasp2>;
    ti,codec-clock-rate = <11289600>;
        ti,audio-slots = <2>;
        clocks = <&atl_clkin1_ck>;
    clock-names = "ti,codec-clock";
        ti,audio-mclk-freq = <11289600>;
        ti,audio-routing =
            "Headphone", "HPL",
            "Headphone", "HPR",
            "Speaker", "SPK";
    };

&atl {
    status = "okay";

    atl1 {
        bws = <DRA7_ATL_WS_MCASP2_FSX>;
        aws = <DRA7_ATL_WS_MCASP2_FSX>;
    };
};

&mcasp2 {
    pinctrl-names = "default";
    pinctrl-0 = <&dac_pins>;
    
    fck_parent = "atl_clkin1_ck";

    status = "okay";

    op-mode = <0>;  /* MCASP_IIS_MODE */
    tdm-slots = <2>;
    num-serializer = <16>;
    /* 16 serializer  channel 2 AXR2  0:INACTIVE, 1:TX, 2:RX */
    serial-dir = <0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0>;
    tx-num-evt = <8>;
    rx-num-evt = <8>;
};

&i2c1 {
    status = "okay";
    clock-frequency = <400000>;
        pinctrl-0 = <&i2c1_pins>;

    tlv320dac3100: tlv320dac3100@18 {
        compatible = "ti,tlv320aic3100";
        gpio-reset = <&gpio5 3 1>;
        reg = <0x18>;
        ai31xx-micbias-vg = <1>; //not used
        status = "okay";
        
        //      /* Regulators */
        AVDD-supply = <&evm_3v3_sw>;
        IOVDD-supply = <&evm_3v3_sw>;
        DRVDD-supply = <&evm_3v3_sw>;
        DVDD-supply = <&aic_dvdd>;
        
    };
     
};

I used the TLV320DAC3100 codec driver(tlv320aic31xx.c)
and a custom machine driver(dra7xx-ghmios-card.c derivated from dra7xx-jamr3-card.c )
to configure DAI interfaces.


static struct snd_soc_dai_link ghmios_snd_dai = {
    /*   McASP2 + tlv320dac3100 */
    .name = "TLV320AIC3XX",
    .stream_name    = "AIC31XX",
    .ops = &ghmios_snd_ops,
    .codec_dai_name = "tlv320aic31xx-hifi",
    .init = ghmios_snd_init,
    .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS |
           SND_SOC_DAIFMT_IB_NF,
};


Following an extract from dra7xx-ghmios-card.c hw_params function
****************************************************************
 /* McASP driver requires inverted frame for I2S */
    snd_soc_dai_set_fmt(cpu_dai, fmt | SND_SOC_DAIFMT_NB_IF);

/* Set McASP BCLK divider (clkid = 1) */
   snd_soc_dai_set_clkdiv(cpu_dai, 1,card_data->mclk_freq / bclk_freq);

/* Set McASP sysclk from AHCLKX sourced from ATL */
  snd_soc_dai_set_sysclk(cpu_dai, 0, card_data->mclk_freq,SND_SOC_CLOCK_IN);

  snd_soc_dai_set_fmt(codec_dai, fmt | SND_SOC_DAIFMT_NB_NF);
******************************************************************


With these configurations I 've got these clocks:

MCLK =  11289600 HZ
BCLK =  1411200 HZ

I inserted some printk in davinci_mcasp driver for debugging the issue and I saw that:

mcasp_start_tx:   McASP2.DAVINCI_MCASP_TXSTAT_REG = 12c (XDATA Transmit data ready flag is always 1)
mcasp_start_tx:   MCASP_XRSRCTL_REG(2) = 19

FROM TRM the XRDY BIT(4) is  0x1: The transmit buffer (MCASP_TXBUFn) is empty and needs to
be written before the start of the next time slot or a transmit underrun occurs.



From logs I see the following DMA croossbar setting for MCASP2:

[    2.857927] davinci-mcasp 48464000.mcasp: ASoC: Registered component '48464000.mcasp'
[    2.865842] ti-dma-crossbar 4a002b78.dma-crossbar: Mapping XBAR131 to DMA7
[    2.872760] omap-dma-engine 4a056000.dma-controller: allocating channel 7 for 8
[    2.880114] __dma_request_channel: success (dma1chan7)
[    2.885329] ti-dma-crossbar 4a002b78.dma-crossbar: Mapping XBAR130 to DMA8
[    2.892244] omap-dma-engine 4a056000.dma-controller: allocating channel 8 for 9
[    2.899598] __dma_request_channel: success (dma1chan8)


But the SDMA interrupts are not triggering and I' got the error
"ALSA sound/core/pcm_lib.c:1957 playback write error (DMA or IRQ trouble?)" .

My questions are:
What could be wrong or missing in DMA CROSSBAR mappings?
What cpu register must be checked to be sure that all DMA mapping for MCASP2 are correct?
Is it also necessary modify u-boot for macsp dma crossbar settings?



Thanks,

Antonio

  • Hi Antonio,

    "With these configurations I 've got these clocks:

    MCLK =  11289600 HZ
    BCLK =  1411200 HZ"

    Do you mean you can observe these clocks on the pins?

    Also, can you please dump and send me these:

    1. CM_L4PER2_MCASP2_CLKCTRL @0x4A00 9860

    2. MCASP registers

    Thanks,

    Stan

  • Hi Sten,
    thank you for reply.

    Yes, How I said , in my configuration the J6 produce the rights clocks:

    PIN E17 -> pinmux ( J6 output) -> MCASP2_AHCLKX = 11,28 MHZ  MCLK (  tlv320dac3100 input)

    Then when I am trying to play the media , the J6 produces the following clocks

    PIN A19 -> pinmux ( J6 output) -> MCASP2_ACLKX = 1,4 MHZ -> MCLK (  tlv320dac3100 input)
    PIN A18 -> pinmux ( J6 output) -> MCASP2_FSX (frame sync) = 44,1 KHZ -> WCLK (  tlv320dac3100 input)

    But I hadn't no sound because the signal on
    PIN C15 -> pinmux ( J6 output) -> MCASP2_AXR2 -> DIN (  tlv320dac3100 input)
    was not present.

    and aplay go out with the following error: "pcm_write:1939: write error: Input/output error" .

    If necessary I can upload  oscilloscope images.

    Meanwhile I get any improvements editing the mcasp2 configuration.
    I changed dma controller configuration passing from sdma_xbar instance to edma_xbar.

            mcasp2: mcasp@48464000 {
                compatible = "ti,dra7-mcasp-audio";
                ti,hwmods = "mcasp2";
                reg = <0x48464000 0x2000>,
                      <0x45C00000 0x1000>;
                reg-names = "mpu", "dat";
                interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>, /* AREVT */
                           <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>; /* TXEVT */
                interrupt-names = "tx", "rx";
                dmas = <&edma_xbar 131>, <&edma_xbar 130>;
                dma-names = "tx", "rx";
                clocks = <&mcasp2_ahclkx_mux>;
                clock-names = "fck";
                status = "disabled";
            };

    Fom BOOT log:

    [    6.137809] ti-dma-crossbar 4a002c78.dma-crossbar: Mapping XBAR131 to DMA0
    [    6.145071] __dma_request_channel: success (dma0chan0)
    [    6.150289] ti-dma-crossbar 4a002c78.dma-crossbar: Mapping XBAR130 to DMA1
    [    6.157208] __dma_request_channel: success (dma0chan1)

    With this modification finally I am able to get data on codec  DIN pin and I heard the sound.

    Unfortunately It works only with alternate phases, or rather ...
    the second  attempt  to play fails with the same error "pcm_write:1939: write error: Input/output error";
    the third works......the forth doesn't works ..etc


    The dump of CM_L4PER2_MCASP2_CLKCTRLreg is this:

    -bash-3.2# devmem2 0x4A009860 w
    /dev/mem opened.
    Memory mapped at address 0xb6ff1000.
    Value at address 0x4A009860 (0xb6ff1860): 0x5030000


    I've uploaded two logs: one when the sound is ok and another when is not ok.
    You can se any mcasp reg  traces derivated from davinci-mcasp.c (in attachment).

    If to understand the problem you need other mcasp traces, please tell me which are.
    My understanding is that the dma request is not triggered for a reason that I don't know .

    Thanks

    Antonio

    2068.mcasp_logs.zip

  • Antonio,

    I think the addition of the MCASP's DATA port did the job to start the transfers. MCASP driver configures MCASP to DATA port for data transfers, so MCASP will expect data only on DATA port  (driver sets MCASP_TXFMT[3] XBUSEL = 0).

    i.e. adding the below last 2 lines routed the DMA to the right MCASP address:

                reg = <0x48464000 0x2000>,
                      <0x45C00000 0x1000>;
                reg-names = "mpu", "dat";

    You can try to switch back to system DMA , if you want to or if you want to check if the above is true.

    Why it works only half of  times, I don't know exactly. What is bothering me is the ATL configuration. Don't know the ATL internals, but feeding the MCASP frame sync to ATL and using the same ATL as clock for MCASP doesn't make much sense to me.

    Please try a known good clock source for MCASP, such as  ABE_SYS_CLK, instead of ATL1 clk. It should be 20MHz on most systems.
    If you know what is exactly happening with ATL, please disregard my suggestion.

    Regards,

    Stan

  • Hi Stan,
    I am sorry for the delayed reply,
    in the meantime I have found the solutions because  "aplay" sound player works  for half of  times.
    I have set  zero value int the mcasp2 FIFO  configuration (tx-num-evt and rx-num-evt) and now it works very well.

    &mcasp2 {
        pinctrl-names = "default";
        pinctrl-0 = <&dac_pins>;    
        fck_parent = "atl_clkin1_ck";
        status = "okay";

        op-mode = <0>;          /* MCASP_IIS_MODE */
        tdm-slots = <2>;
        num-serializer = <16>;
        /* 16 serializer  channel 2 AXR2 */
           serial-dir = <0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0>; /* 0:INACTIVE, 1:TX, 2:RX  */
        tx-num-evt = <0>; /* FIFO 0 */
        rx-num-evt = <0>;
    };


     

    For the ATL1 clock source for MCASP2 I think that it doesn't have any problem in my hardware configuration.
    Also I tried to switch back to system DMA rather than EDMA but it doesn't work and I don't know why.

    Thanks for the support.

    Regards,

    Antonio