bperez77 / xilinx_axidma

A zero-copy Linux driver and a userspace interface library for Xilinx's AXI DMA and VDMA IP blocks. These serve as bridges for communication between the processing system and FPGA programmable logic fabric, through one of the DMA ports on the Zynq processing system. Distributed under the MIT License.
MIT License
464 stars 227 forks source link

Failed to perform the AXI DMA read-write transfer: Timer expired #80

Closed GOOD-Stuff closed 5 years ago

GOOD-Stuff commented 5 years ago

Sometimes, when try to use two way transfer I get timeout error (in receive part). Also, I see that data correctly send out from DMA, but in some causes incorrect received (if set false on wait). the ILA shows that sometimes for some reason there is no interruption for s2mm, and this (may be) is the cause of this error. Here code example of my using DMA API.

[  199.522896] axidma: axidma_dma.c: axidma_start_transfer: 301: DMA receive transaction timed out.
[  200.531613] xilinx-vdma 80400000.dma: Cannot stop channel df739010: 10008
[  211.042928] axidma: axidma_dma.c: axidma_start_transfer: 301: DMA receive transaction timed out.
[  221.282891] axidma: axidma_dma.c: axidma_start_transfer: 301: DMA receive transaction timed out.

Here PDF version of block design. I use kernel of linux version by 4.14, VIvado 2018.2, Zynq-7010 with custom board. Device tree:

/ {
    amba_pl: amba_pl {
        #address-cells = <1>;
        #size-cells = <1>;
        compatible = "simple-bus";
        ranges ;
    axidma_chrdev: axidma_chrdev@0 {
            compatible = "xlnx,axidma-chrdev";
            dmas = <&axi_dma_0 0 &axi_dma_0 1>;
            dma-names = "tx_channel", "rx_channel";
        };
        axi_dma_0: dma@80400000 {
            #dma-cells = <1>;
            clock-names = "s_axi_lite_aclk", "m_axi_sg_aclk", "m_axi_mm2s_aclk", "m_axi_s2mm_aclk";
            clocks = <&misc_clk_0>, <&misc_clk_0>, <&misc_clk_0>, <&misc_clk_0>;
            compatible = "xlnx,axi-dma-1.00.a";
            interrupt-names = "mm2s_introut", "s2mm_introut";
            interrupt-parent = <&intc>;
            interrupts = <0 34 4 0 33 4>;
            reg = <0x80400000 0x10000>;
            xlnx,addrwidth = <0x20>;
            xlnx,include-sg ;
            xlnx,sg-length-width = <0x17>;
            dma-channel@80400000 {
                compatible = "xlnx,axi-dma-mm2s-channel";
                dma-channels = <0x1>;
                interrupts = <0 34 4>;
                xlnx,datawidth = <0x10>;
                xlnx,device-id = <0x0>;
                xlnx,include-dre ;
            };
            dma-channel@80400030 {
                compatible = "xlnx,axi-dma-s2mm-channel";
                dma-channels = <0x1>;
                interrupts = <0 33 4>;
                xlnx,datawidth = <0x8>;
                xlnx,device-id = <0x1>;
                xlnx,include-dre ;
            };
        };
        axi_ethernet_0: ethernet@41000000 {
            axistream-connected = <&axi_ethernet_0_dma>;
            axistream-control-connected = <&axi_ethernet_0_dma>;
            clock-frequency = <100000000>;
            clock-names = "ref_clk";
            clocks = <&clkc 0>;
            compatible = "xlnx,axi-ethernet-1.00.a";
            device_type = "network";
            interrupt-names = "mac_irq", "interrupt";
            interrupt-parent = <&intc>;
            interrupts = <0 29 1 0 30 4>;
            phy-mode = "rgmii";
            reg = <0x41000000 0x40000>;
            xlnx = <0x0>;
            xlnx,axiliteclkrate = <0x0>;
            xlnx,axisclkrate = <0x0>;
            xlnx,clockselection = <0x0>;
            xlnx,enableasyncsgmii = <0x0>;
            xlnx,gt-type = <0x0>;
            xlnx,gtinex = <0x0>;
            xlnx,gtlocation = <0x0>;
            xlnx,gtrefclksrc = <0x0>;
            xlnx,include-dre ;
            xlnx,instantiatebitslice0 = <0x0>;
            xlnx,phy-type = <0x3>;
            xlnx,phyaddr = <0x1>;
            xlnx,rable = <0x0>;
            xlnx,rxcsum = <0x0>;
            xlnx,rxlane0-placement = <0x0>;
            xlnx,rxlane1-placement = <0x0>;
            xlnx,rxmem = <0x2000>;
            xlnx,rxnibblebitslice0used = <0x1>;
            xlnx,tx-in-upper-nibble = <0x1>;
            xlnx,txcsum = <0x0>;
            xlnx,txlane0-placement = <0x0>;
            xlnx,txlane1-placement = <0x0>;
            phy-handle = <&phy0>;
            axi_ethernet_0_mdio: mdio {
                #address-cells = <1>;
                #size-cells = <0>;
                phy0: phy@7{
                    compatible = "marvell,88e1111";
                    device_type = "ethernet-phy";
                    reg = <7>;
                };
            };
        };
        axi_ethernet_0_dma: dma@40400000 {
            #dma-cells = <1>;
            axistream-connected = <&axi_ethernet_0>;
            axistream-control-connected = <&axi_ethernet_0>;
            clock-names = "s_axi_lite_aclk";
            clocks = <&misc_clk_0>;
            compatible = "xlnx,eth-dma";
            interrupt-names = "mm2s_introut", "s2mm_introut";
            interrupt-parent = <&intc>;
            interrupts = <0 31 4 0 32 4>;
            reg = <0x40400000 0x10000>;
            xlnx,include-dre ;
        };
        misc_clk_0: misc_clk_0 {
            #clock-cells = <0>;
            clock-frequency = <125000000>;
            compatible = "fixed-clock";
        };
    };
};
GOOD-Stuff commented 5 years ago

The problem was in my PL design. I use in project axis clock converter which was incorrect set and have connected ILA between AXI DMA and custom module (may be to incorrect clock). After changed clock (to 150 MHz for DMA) and synchronization stages (to 8, in axi4-stream clock converter) and removed ILA, all started work.