/
Linux Soft DMA Driver

Linux Soft DMA Driver

This page covers the Linux driver for the Xilinx Soft DMA IPs, including AXI DMA, AXI CDMA, AXI MCMDA and AXI VDMA for Zynq, Zynq Ultrascale+ MPSoC, Versal and Microblaze.


Table of Contents

Introduction


The Soft IP DMA (AXI DMA/CDMA/MCDMA/VDMA) driver is available as part of the Xilinx Linux distribution and in open source Linux as drivers/dma/xilinx_dma.c

HW IP features

AXI DMA

The AXI Direct Memory Access (AXI DMA) IP provides high-bandwidth direct memory access between the AXI4 memory mapped and AXI4-Stream-type target peripherals. Its optional scatter-gather capabilities also offload data movement tasks from the Central Processing Unit (CPU) in processor-based systems. Initialization, status, and management registers are accessed through an AXI4-Lite slave interface.
  • AXI4 and AXI4-Stream compliant
  • Optional Scatter/Gather (SG) DMA support. When Scatter/gather mode is not selected the IP operates in Simple DMA mode.
  • Primary AXI4 Memory Map and AXI4-Stream data width support of 32, 64, 128, 256, 512, and 1024 bits
  • Optional Data Re-Alignment Engine
  • Optional AXI Control and Status Streams
  • Optional Keyhole support
  • Optional Micro DMA mode support
  • Support for up to 64-bit Addressing

Features supported in the driver

  • Optional Scatter/Gather (SG) DMA support. When Scatter/gather mode is not selected the IP operates in Simple DMA mode.
  • Primary AXI4 Memory Map and AXI4-Stream data width support of 32, 64, 128, 256, 512, and 1024 bits
  • Optional Data Re-Alignment Engine
  • Optional AXI Control and Status Streams
  • 64-bit Addressing support

Note: Multi-channel mode is no longer a supported mode of operation for AXI DMA.

AXI CDMA

The AXI CDMA provides high-bandwidth direct memory access (DMA) between a memory mapped source address and a memory mapped destination address using the AXI4 protocol. An optional Scatter Gather (SG) feature can be used to offload control and sequencing tasks from the System CPU. Initialization, status, and control registers are accessed through an AXI4-Lite slave interface.
  • AXI4 Compliant
  • Primary AXI Memory Map data width support of 32, 64, 128, and 256 bits
  • Primary AXI Stream data width support of 8, 16, 32, 64, 128, and 256 bits
  • Optional Data Re-Alignment Engine
  • Optional Gen-Lock Synchronization
  • Independent, asynchronous channel operation
  • Provides Simple DMA only mode and an optional hybrid mode supporting both Simple DMA and Scatter-Gather automation
  • Optional Store and Forward operation mode with internal Data FIFO (First In First Out)

Features supported in the driver

  • Optional Scatter/Gather (SG) DMA support. When Scatter/gather mode is not selected the IP operates in Simple DMA mode.
  • Primary AXI4 Memory Map and AXI4-Stream data width support of 32, 64, 128, 256, 512, and 1024 bits
  • Optional Data Re-Alignment Engine
  • 64-bit Addressing Support
  • Simple DMA mode
  • Scatter-Gather DMA mode

AXI VDMA

The AXI Video Direct Memory Access (AXI VDMA) core is a soft Xilinx IP core that provides high-bandwidth direct memory access between memory and AXI4-Stream type video target peripherals. The core provides efficient two dimensional DMA operations with independent asynchronous read and write channel operation. Initialization, status, interrupt and management registers are accessed through an AXI4-Lite slave interface.
  • High-bandwidth direct memory access for video streams
  • Efficient two-dimensional DMA operations
  • Independent, asynchronous read and write channel operation
  • Gen-Lock frame buffer synchronization
  • Supports a maximum of 32 frame buffers
  • Supports dynamic video format changes
  • Configurable Burst Size and Line Buffer depth for efficient video streaming
  • Processor accessible initialization, status, interrupt and management registers
  • Primary AXI Stream data width support for multiples of 8-bits: 8, 16, 24, 32, etc. up to 1024 bits
  • 64-bit Addressing

Features supported in the driver

  • Support for maximum 32 frame buffers
  • 64-bit Addressing
  • Gen-lock frame buffer synchronization


AXI MCMDA

The AXI Multichannel Direct Memory Access (AXI MCDMA) core is a soft Xilinx IP core for use with the Xilinx Vivado Design Suite. The AXI MCDMA provides high-bandwidth direct memory access between memory and AXI4-Stream target peripherals. The AXI MCDMA core provides Scatter Gather (SG) interface with multiple channel support with independent configuration

  • AXI4 data width support of 32, 64, 128, 256, 512, and 1,024 bits
  • AXI4-Stream data width support of 8, 16, 32, 64, 128, 256, 512, and 1,024 bits
  • Supports up to 16 independent channels
  • Supports per Channel Interrupt output
  • Supports data realignment engine (DRE) alignment for streaming data width of up to 512 bits
  • Supports up to 64 MB transfer per Buffer Descriptor (BD)
  • Optional AXI4-Stream Control and Status Streams

Features supported in the driver

  • Primary AXI4 Memory Map and AXI4-Stream data width support of 32, 64, 128, 256, 512, and 1024 bits
  • 64-bit Addressing Support
  • Scatter-Gather DMA mode on all supported 16 S2MM and MM2S channels.
  • 64 MB transfer per Buffer Descriptor (BD)


Missing Features and Known Issues/Limitations in Driver

AXI DMA

  • No support for Keyhole feature

AXI CDMA

  • None

AXI VDMA

  • Configurable Burst Size and Line Buffer depth for efficient video streaming

Kernel Configuration

The following config options should be enabled in order to build SoftIP DMA'S(AXI DMA/CDMA/VDMA/MCMDA) driver
CONFIG_DMADEVICES
CONFIG_XILINX_DMA




The driver is available at,
https://github.com/Xilinx/linux-xlnx/blob/master/drivers/dma/xilinx/xilinx_dma.c

Devicetree

The device tree node for AXI DMA/CDMA/MCMDA/VDMA will be automatically generated, if the core is configured in the HW design, using the Device Tree BSP.

Steps to generate device-tree is documented here,
http://www.wiki.xilinx.com/Build+Device+Tree+Blob

And a sample binding is shown below and the description of DT property is documented here:

AXI DMA
 axi_dma_1: dma@40400000 {
                        #dma-cells = <1>;
                        clock-names = "s_axi_lite_aclk", "m_axi_sg_aclk", "m_axi_mm2s_aclk", "m_axi_s2mm_aclk";
                        clocks = <&clkc 15>, <&clkc 15>, <&clkc 15>, <&clkc 15>;
                        compatible = "xlnx,axi-dma-1.00.a";
                        interrupt-parent = <&intc>;
                        interrupts = <0 29 4 0 30 4>;
                        reg = <0x40400000 0x10000>;
                        xlnx,addrwidth = <0x20>;
                        xlnx,include-sg ;
                        dma-channel@40400000 {
                                compatible = "xlnx,axi-dma-mm2s-channel";
                                dma-channels = <0x1>;
                                interrupts = <0 29 4>;
                                xlnx,datawidth = <0x20>;
                                xlnx,device-id = <0x0>;
                                xlnx,include-dre ;
                        };
                        dma-channel@40400030 {
                                compatible = "xlnx,axi-dma-s2mm-channel";
                                dma-channels = <0x1>;
                                interrupts = <0 30 4>;
                                xlnx,datawidth = <0x20>;
                                xlnx,device-id = <0x0>;
                                xlnx,include-dre ;
                        };
                };
 


AXI CDMA
axi_cdma_0: dma@4e200000 {
                        #dma-cells = <1>;
                        clock-names = "s_axi_lite_aclk", "m_axi_aclk";
                        clocks = <&&clkc 15>, <&&clkc 15>;
                        compatible = "xlnx,axi-cdma-1.00.a";
                        interrupt-parent = <&&intc>;
                        interrupts = <0 31 4>;
                        reg = <0x4e200000 0x10000>;
                        xlnx,addrwidth = <0x20>;
                        xlnx,include-sg ;
                        dma-channel@4e200000 {
                                compatible = "xlnx,axi-cdma-channel";
                                interrupts = <0 31 4>;
                                xlnx,datawidth = <0x20>;
                                xlnx,device-id = <0x0>;
                                xlnx,include-dre ;
                                xlnx,max-burst-len = <0x10>;
                        };
                };
 

AXI VDMA
axi_vdma_0: dma@43000000 {
                        #dma-cells = <1>;
                        clock-names = "s_axi_lite_aclk", "m_axi_mm2s_aclk", "m_axi_mm2s_aclk", "m_axi_s2mm_aclk", "m_axi_s2mm_aclk";
                        clocks = <&clkc 15>, <&clkc 15>, <&clkc 15>, <&clkc 15>, <&clkc 15>;
                        compatible = "xlnx,axi-vdma-1.00.a";
                        interrupt-parent = <&intc>;
                        interrupts = <0 32 4 0 33 4>;
                        reg = <0x43000000 0x10000>;
                        xlnx,addrwidth = <0x20>;
                        xlnx,flush-fsync = <0x1>;
                        xlnx,num-fstores = <0x1>;
                        dma-channel@43000000 {
                                compatible = "xlnx,axi-vdma-mm2s-channel";
                                interrupts = <0 32 4>;
                                xlnx,datawidth = <0x20>;
                                xlnx,device-id = <0x0>;
                                xlnx,genlock-mode ;
                                xlnx,include-dre ;
                        };
                        dma-channel@43000030 {
                                compatible = "xlnx,axi-vdma-s2mm-channel";
                                interrupts = <0 33 4>;
                                xlnx,datawidth = <0x20>;
                                xlnx,device-id = <0x0>;
                                xlnx,genlock-mode ;
                                xlnx,include-dre ;
                        };
                };
 
AXI MCDMA
axi_mcdma_0: axi_mcdma@a4040000 {
			#dma-cells = <1>;
			clock-names = "s_axi_aclk", "s_axi_lite_aclk";
			clocks = <&misc_clk_0>, <&misc_clk_0&