This is the driver API for the AXI DMA engine.
For a full description of DMA features, please see the hardware spec. This driver supports the following features:
Simple DMA
Simple DMA allows the application to define a single transaction between DMA and Device. It has two channels: one from the DMA to Device and the other from Device to DMA. Application has to set the buffer address and length fields to initiate the transfer in respective channel.
Transactions
The object used to describe a transaction is referred to as a Buffer Descriptor (BD). Buffer descriptors are allocated in the user application. The user application needs to set buffer address, transfer length, and control information for this transfer. The control information includes SOF and EOF. Definition of those masks are in xaxidma_hw.h
Scatter-Gather DMA
SGDMA allows the application to define a list of transactions in memory which the hardware will process without further application intervention. During this time, the application is free to continue adding more work to keep the Hardware busy.
User can check for the completion of transactions through polling the hardware, or interrupts.
SGDMA processes whole packets. A packet is defined as a series of data bytes that represent a message. SGDMA allows a packet of data to be broken up into one or more transactions. For example, take an Ethernet IP packet which consists of a 14 byte header followed by a 1 or more bytes of payload. With SGDMA, the application may point a BD to the header and another BD to the payload, then transfer them as a single message. This strategy can make a TCP/IP stack more efficient by allowing it to keep packet header and data in different memory regions instead of assembling packets into contiguous blocks of memory.
BD Ring Management
BD rings are shared by the software and the hardware.
The hardware expects BDs to be setup as a linked list. The DMA hardware walks through the list by following the next pointer field of a completed BD. The hardware stops processing when the just completed BD is the same as the BD specified in the Tail Ptr register in the hardware.
The last BD in the ring is linked to the first BD in the ring.
All BD management are done inside the driver. The user application should not directly modify the BD fields. Modifications to the BD fields should always go through the specific API functions.
Within the ring, the driver maintains four groups of BDs. Each group consists of 0 or more adjacent BDs:
BDs are expected to transition in the following way for continuous DMA transfers:
XAxiDma_BdRingAlloc() XAxiDma_BdRingToHw() Free ------------------------> Pre-process ----------------------> Hardware | /|\ | | XAxiDma_BdRingFree() XAxiDma_BdRingFromHw() | +--------------------------- Post-process <----------------------+
When a DMA transfer is to be cancelled before enqueuing to hardware, application can return the requested BDs to the Free group using XAxiDma_BdRingUnAlloc(), as shown below:
XAxiDma_BdRingUnAlloc() Free <----------------------- Pre-process
The API provides functions for BD list traversal:
These functions should be used with care as they do not understand where one group ends and another begins.
SGDMA Descriptor Ring Creation
BD ring is created using XAxiDma_BdRingCreate(). The memory for the BD ring is allocated by the application, and it has to be contiguous. Physical address is required to setup the BD ring.
The applicaiton can use XAxiDma_BdRingMemCalc() to find out the amount of memory needed for a certain number of BDs. XAxiDma_BdRingCntCalc() can be used to find out how many BDs can be allocated for certain amount of memory.
A helper function, XAxiDma_BdRingClone(), can speed up the BD ring setup if the BDs have same types of controls, for example, SOF and EOF. After using the XAxiDma_BdRingClone(), the application only needs to setup the buffer address and transfer length. Note that certain BDs in one packet, for example, the first BD and the last BD, may need to setup special control information.
Descriptor Ring State Machine
There are two states of the BD ring:
The following diagram shows the state transition for the DMA engine:
_____ XAxiDma_StartBdRingHw(), or XAxiDma_BdRingStart(), ______ | | or XAxiDma_Resume() | | | H |----------------------------------------------------->| NH | | |<-----------------------------------------------------| | ----- XAxiDma_Pause() or XAxiDma_Reset() ------
Interrupt Coalescing
SGDMA provides control over the frequency of interrupts through interrupt coalescing. The DMA engine provides two ways to tune the interrupt coalescing:
Interrupt
Interrupts are handled by the user application. Each DMA channel has its own interrupt ID. The driver provides APIs to enable/disable interrupt, and tune the interrupt frequency regarding to packet processing frequency.
Software Initialization
To use the Simple mode DMA engine for transfers, the following setup is required:
To use the SG mode DMA engine for transfers, the following setup are required:
How to start DMA transactions
The user application uses XAxiDma_BdRingToHw() to submit BDs to the hardware to start DMA transfers.
For both channels, if the DMA engine is currently stopped (using XAxiDma_Pause()), the newly added BDs will be accepted but not processed until the DMA engine is started, using XAxiDma_BdRingStart(), or resumed, using XAxiDma_Resume().
Software Post-Processing on completed DMA transactions
If the interrupt system has been set up and the interrupts are enabled, a DMA channels notifies the software about the completion of a transfer through interrupts. Otherwise, the user application can poll for completions of the BDs, using XAxiDma_BdRingFromHw() or XAxiDma_BdHwCompleted().
Examples
We provide five examples to show how to use the driver API:
Address Translation
All buffer addresses and BD addresses for the hardware are physical addresses. The user application is responsible to provide physical buffer address for the BD upon BD ring creation. The user application accesses BD through its virtual addess. The driver maintains the address translation between the physical and virtual address for BDs.
Cache Coherency
This driver expects all application buffers attached to BDs to be in cache coherent memory. If cache is used in the system, buffers for transmit MUST be flushed from the cache before passing the associated BD to this driver. Buffers for receive MUST be invalidated before accessing the data.
Alignment
For BDs:
Minimum alignment is defined by the constant XAXIDMA_BD_MINIMUM_ALIGNMENT. This is the smallest alignment allowed by both hardware and software for them to properly work.
If the descriptor ring is to be placed in cached memory, alignment also MUST be at least the processor's cache-line size. Otherwise, system instability occurs. For alignment larger than the cache line size, multiple cache line size alignment is required.
Aside from the initial creation of the descriptor ring (see XAxiDma_BdRingCreate()), there are no other run-time checks for proper alignment of BDs.
For application data buffers:
Application data buffers may reside on any alignment if DRE is built into the hardware. Otherwise, application data buffer must be word-aligned. The word is defined by XPAR_AXIDMA_0_M_AXIS_MM2S_TDATA_WIDTH for transmit and XPAR_AXIDMA_0_S_AXIS_S2MM_TDATA_WIDTH for receive.
For scatter gather transfers that have more than one BDs in the chain of BDs, Each BD transfer length must be multiple of word too. Otherwise, internal error happens in the hardware.
Error Handling
The DMA engine will halt on all error conditions. It requires the software to do a reset before it can start process new transfer requests.
Restart After Stopping
After the DMA engine has been stopped (through reset or reset after an error) the software keeps track of the current BD pointer when reset happens, and processing of BDs can be resumed through XAxiDma_BdRingStart().
Limitations
This driver does not have any mechanisms for mutual exclusion. It is up to the application to provide this protection.
Hardware Defaults & Exclusive Use
After the initialization or reset, the DMA engine is in the following default mode:
The driver has exclusive use of the registers and BDs. All accesses to the registers and BDs should go through the driver interface.
Debug Print
To see the debug print for the driver, please put "-DDEBUG" as the extra compiler flags in software platform settings. Also comment out the line in xdebug.h: "#undef DEBUG".
Changes From v1.00a
. We have changes return type for XAxiDma_BdSetBufAddr() from void to int . We added XAxiDma_LookupConfig() so that user does not need to look for the hardware settings anymore.
MODIFICATION HISTORY:
Ver Who Date Changes ----- ---- -------- ------------------------------------------------------- 1.00a jz 05/18/10 First release 2.00a jz 08/10/10 Second release, added in xaxidma_g.c, xaxidma_sinit.c, updated tcl file, added xaxidma_porting_guide.h 3.00a jz 11/22/10 Support IP core parameters change 4.00a rkv 02/22/11 Added support for simple DMA mode New API added for simple DMA mode are
Changed APIs: * XAxiDma_GetRxRing(InstancePtr, RingIndex) * XAxiDma_Start(XAxiDma * InstancePtr, int RingIndex) * XAxiDma_Started(XAxiDma * InstancePtr, int RingIndex) * XAxiDma_Pause(XAxiDma * InstancePtr, int RingIndex) * XAxiDma_Resume(XAxiDma * InstancePtr, int RingIndex) * XAxiDma_SimpleTransfer(XAxiDma *InstancePtr, u32 BuffAddr, u32 Length, int Direction, int RingIndex) * XAxiDma_StartBdRingHw(XAxiDma_BdRing * RingPtr, int RingIndex) * XAxiDma_BdRingStart(XAxiDma_BdRing * RingPtr, int RingIndex) * XAxiDma_BdRingToHw(XAxiDma_BdRing * RingPtr, int NumBd, XAxiDma_Bd * BdSetPtr, int RingIndex) * XAxiDma_BdRingDumpRegs(XAxiDma_BdRing * RingPtr, int RingIndex) * XAxiDma_BdRingSnapShotCurrBd(XAxiDma_BdRing * RingPtr, int RingIndex) * XAxiDma_BdSetLength(XAxiDma_Bd *BdPtr, u32 LenBytes, u32 LengthMask) * XAxiDma_BdGetActualLength(BdPtr, LengthMask) * XAxiDma_BdGetLength(BdPtr, LengthMask)
New APIs: * XAxiDma_SelectCyclicMode(XAxiDma *InstancePtr, int Direction, int Select) * XAxiDma_BdSetBufAddrMicroMode(XAxiDma_Bd*, u32)
Copyright © 1995-2014 Xilinx, Inc. All rights reserved.