AnsweredAssumed Answered

axi-i2s: swapping from PL330 to axi-dma

Question asked by Stevo on Mar 3, 2016
Latest reply on Mar 4, 2016 by larsc

Hi,

 

I am unable to get AXI DMA to be recognized as a DMA controller.  It's driver boots ok but another driver trying to use it can't find it in the list of DMA controllers.  During boot the AXI DMA driver comes up with the boot message:

 

    xilinx-dma 40400000.dma: Probing xilinx axi dma engine...Successful

 

but when one of my kernel modules later tries to devm_snd_dmaengine_pcm_register() it, it fails with the error:

 

    of_dma_find_controller: can't find DMA controller /amba_pl/dma@40400000

 

The node "/amba_pl/dma@40400000" *does* actually exist, but tracing into of_dma_find_controller() reveals that it doesn't appear in the list of DMA controllers.

 

What do I need to do?

 

 

Background info:

 

I've written an ALSA driver for a picozed platform mounted on a custom carrier board with custom FPGA code for many audio channels.  The OS is PetaLinux 2014.4, which includes source for a 3.17 linux kernel.  The FPGA code was modified from the zedboard FPGA code, including a version of the ADI AXI-I2S IP modified for man more channels.

 

I modified the zed_adau1761.c and axi-i2s.c drivers for the custom soundcard and IP, and it works except for a (rare) spurious start-up sample fault, which with interleaved channels, causes a misalignment of all channels by one when it happens.  We've traced the fault to the DMA (or possibly how it's driven).

 

The ADI AXI-I2S IP and our modified version have a choice of 2 DMA types: PL330 (Zynq built-in DMAC) and streaming DMA.  We added an AXI DMA to the Vivado block diagram, changed selection to the streaming DMA and changed the devicetree for the modified AXI-I2S IP driver to refer to the generated AXI DMA devicetree.

 

The generated AXI DMA devicetree (I had to add the #dma-cells myself):


amba_pl: amba_pl {

...


     axi_dma_0: dma@40400000 {
          #dma-cells = <1>;
          compatible = "xlnx,axi-dma";
         interrupt-parent = <&intc>;
           interrupts = <0 33 4 0 34 4>;
         reg = <0x40400000 0x10000>;
         dma-channel@40400000 {
               compatible = "xlnx,axi-dma-mm2s-channel";
              interrupts = <0 33 4>;
             xlnx,datawidth = <0x20>;
               xlnx,device-id = <0x0>;
          };
          dma-channel@40400030 {
              compatible = "xlnx,axi-dma-s2mm-channel";
             interrupts = <0 34 4>;
               xlnx,datawidth = <0x20>;
              xlnx,device-id = <0x0>;
         };
      };

 

...

};

 

and the AXI I2S devicetree (only the "dmas" phandles modified from the PL330 version to substitute AXI DMA):

 

i2s: i2s@0x43c20000 {
      compatible = "acres,i2s-multicodec-1.00.a";
     reg = <0x43c20000 0x10000>;
     clocks = <&clkc 15>, <&clkc 16>;
     clock-names = "axi", "ref";
     dmas = <&axi_dma_0 0>, <&axi_dma_0 1>;
     dma-names = "tx", "rx";
};

 

Steve

Outcomes