UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Visitor trexmsuee
Visitor
8,397 Views
Registered: ‎07-21-2015

Problem with UIO for AXI-DMA

Hello,

I am trying to develop host code utilizing UIO as a method to access DMA as an alternative to the kernel device driver. This method is illustrated in:


http://www.wiki.xilinx.com/Zynq-7000+AP+SoC+Spectrum+Analyzer+part+5+-+Accelerating+Software+-+Accelerating+an+FFT+with+ACP+Coprocessor+Tech+Tip+2014.3

 

And the well-referenced application note by J. Linn:
https://forums.xilinx.com/xlnx/attachments/xlnx/ELINUX/10693/1/Linux%20DMA%20from%20User%20Space-public.pdf

 

I’m using the most recently Xilinx OSL kernel, 4.0.0. The project bitstream is the common loopback_dma example, as illustrated here:
http://www.fpgadeveloper.com/2014/08/using-the-axi-dma-in-vivado.html

 

The problem: I cannot get the uio driver to instantiate, based on my device tree bindings. The sys/class/uio folder is EMPTY. I was expecting to see subdirectories for each UIO device named uioXX.

 

I found the note about the patch removing the “generic-uio” compatibility string as discussed here:
https://forums.xilinx.com/t5/Embedded-Linux/generic-UIO-broken/td-p/564259

 

Applying this fix, an excerpt from my system.dts file is:
    chosen {
        bootargs = "console=ttyPS0,115200 earlyprintk uio_pdrv_genirq.of_id=generic-uio";
    };


In addition, my PL.dtsi file is as follows:

{
amba_pl: amba_pl {
  #address-cells = <1>;
  #size-cells = <1>;
  compatible = "simple-bus";
  ranges ;
  loopback_dma: dma@40400000 {
    compatible = "generic-uio";
    #dma-cells = <1>;
    interrupt-parent = <&intc>;
    interrupts = <0 29 4 0 30 4>;
    reg = <0x40400000 0x10000>;
    xlnx,mm2s-burst-size = <0x10>;
    xlnx,s2mm-burst-size = <0x10>;
    xlnx,include-sg ;
    dma-channel@40400000 {
        compatible = "xlnx,axi-dma-mm2s-channel";
        interrupts = <0 29 4>;
        xlnx,datawidth = <0x20>;
        xlnx,device-id = <0x0>;
    };
    dma-channel@40400030 {
        compatible = "xlnx,axi-dma-mm2s-channel";
        interrupts = <0 30 4>;
        xlnx,datawidth = <0x20>;
        xlnx,device-id = <0x0>;
     };
   };

     };

   };


For the “compatible” property, I have tried combinations of "generic-uio" and “xlnx, generic-uio”, and so forth.
UIO is enabled in the kernel config, and compiled as modules:
    CONFIG_UIO=m
    CONFIG_UIO_PDRV_GENIRQ=m
    CONFIG_UIO_DMEM_GENIRQ=m


According to lsmod on the target, I think they are being loaded correctly:
    [root@alarm proc]# lsmod
        Module Size Used by
        uio_pdrv_genirq 2650 0
        uio 6934 1 uio_pdrv_genirq
        ipv6 256700 20


The dma module appears to be correctly recognized as shown in sys/bus/platform/devices:
    [root@alarm devices]# ls
        40400000.dma e000d000.spi f8891000.pmu
        etc ...


Could someone please point me in the right direction? Am I missing something?


Also, if someone has example code of using UIO for DMA access in a host application, that would be greatly appreciated!


Thanks in advance,

 

 

Tags (3)
0 Kudos
4 Replies
Xilinx Employee
Xilinx Employee
8,393 Views
Registered: ‎09-10-2008

Re: Problem with UIO for AXI-DMA

I don't see anything obvious you missed.  Does the boot log (or /proc/cmdline) verify the command line did get updated for the uio?

 

I looked and nothing has changed in the UIO driver for a long time.

 

Thanks,

John

Visitor trexmsuee
Visitor
8,384 Views
Registered: ‎07-21-2015

Re: Problem with UIO for AXI-DMA

Hello 

 

 

For the reference of future readers, my bootargs statement looks like this:

bootargs=console=ttyPS0,115200 earlyprintk uio_pdrv_genirq.of_id=generic-uio rootfstype=ext4 root=/dev/mmcblk0p2 rw rootwait

 

One the target, it now looks like uio0 has been properly recognized and bound to the dma peripheral:

 

in sys/class/uio:
uio0
[root@alarm uio]# cd uio0
[root@alarm uio0]# ls
dev device event maps name power subsystem uevent version
[root@alarm uio0]# cd device
[root@alarm device]# ls
driver driver_override modalias power subsystem uevent uio
[root@alarm device]# cd driver
[root@alarm driver]# ls
40400000.dma bind module uevent unbind

 

Also, other than the aformentioned "Zynq-7000 A SoC Spectrum Analyzer part5" tech note, can you or other readers recommend any additional references to using UIO as a method of utilizing AXI-DMA? This seems to be a very common utilization of Zynq processors. For folks like me who are not Linux kernel experts, the integration of streaming data into host code in Linux seems like a substantial hurdle.

 

 

Best Regards, 

 

 

0 Kudos
Xilinx Employee
Xilinx Employee
8,377 Views
Registered: ‎09-10-2008

Re: Problem with UIO for AXI-DMA

Wow, it's not often it's that easy. Glad to hear you're up and running. You're welcome.
0 Kudos
Visitor trexmsuee
Visitor
8,350 Views
Registered: ‎07-21-2015

Re: Problem with UIO for AXI-DMA

Hello linnj,

 

I don't want to be a bother, but I thought you could offer quick insight on this issue. I also realize this is probably a basic question, of which I just haven't processed the right knowledge yet...

 

I am very near having the UIO-based DMA driver working, which is heavily patterned after some bare-metal code I've had working for some time now, and also uses techniques in the psttc-uio.c code you posted some time ago. This example is DMA register-direct mode, no scatter-gather. In my test setup, the PL contains a simple S2MM data source (for testing, just a counter with GPIO-programmable packet size, increment and rollover). I configure the stream, start data flow, and process interrupts when returned via the blocking UIO file read. The configuration of the DMA controller and reception of the interupts is working exactly as I intended. Each interrupt I also display the MM2S_DMACR register - the DMA controller appears happy. 

 

The difficulty I'm having is reading data back from the data buffer. Each interrupt, I simply print the value at the beginning of the packet. This corresponds to contents at the register location specified by MM2S_DA. I am either getting all zeros or occasionaly some other "random" number. I have mmapped an area in memory based on the number of bytes expected from each packet at a hardware address outside of that occupied by the kernel (I think) (DRAM_BUFFER_ADDR). In bootargs, I changed the kernel size to mem=512M. I expected to simply malloc an array in user-space, and memcpy out the data using the virtual address returned by mmap. 

 

Obviously, I've either done something incorrectly, or I do not exactly understand what I'm doing (or both) ...

 

Could you please take a second in review the attached code? I have redacted the GPIO control, as that is not germane to this issue. If I can get this working, I'll be happy to post the complete code for future users, as this seems to be a common request.

 

I appreciate in advance your insights!

 

Best Regards,

0 Kudos