/****************************************************************************** * * Author: Xilinx, Inc. * * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A * COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS * ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD, * XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE * FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING * ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY * WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM * CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE. * * * Xilinx hardware products are not intended for use in life support * appliances, devices, or systems. Use in such applications is * expressly prohibited. * * * (c) Copyright 2002-2004 Xilinx Inc. * All rights reserved. * * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. * * FILENAME: * * xdma_channel.h * * DESCRIPTION: * * This file contains the DMA channel component implementation. This component * supports a distributed DMA design in which each device can have it's own * dedicated DMA channel, as opposed to a centralized DMA design. * A device which uses DMA typically contains two DMA channels, one for * sending data and the other for receiving data. * * This component is designed to be used as a basic building block for * designing a device driver. It provides registers accesses such that all * DMA processing can be maintained easier, but the device driver designer * must still understand all the details of the DMA channel. * * The DMA channel allows a CPU to minimize the CPU interaction required to move * data between a memory and a device. The CPU requests the DMA channel to * perform a DMA operation and typically continues performing other processing * until the DMA operation completes. DMA could be considered a primitive form * of multiprocessing such that caching and address translation can be an issue. * * Scatter Gather Operations * * The DMA channel may support scatter gather operations. A scatter gather * operation automates the DMA channel such that multiple buffers can be * sent or received with minimal software interaction with the hardware. Buffer * descriptors, contained in the XBufDescriptor component, are used by the * scatter gather operations of the DMA channel to describe the buffers to be * processed. * * Scatter Gather List Operations * * A scatter gather list may be supported by each DMA channel. The scatter * gather list allows buffer descriptors to be put into the list by a device * driver which requires scatter gather. The hardware processes the buffer * descriptors which are contained in the list and modifies the buffer * descriptors to reflect the status of the DMA operations. The device driver * is notified by interrupt that specific DMA events occur including scatter * gather events. The device driver removes the completed buffer descriptors * from the scatter gather list to evaluate the status of each DMA operation. * * The scatter gather list is created and buffer descriptors are inserted into * the list. Buffer descriptors are never removed from the list after it's * creation such that a put operation copies from a temporary buffer descriptor * to a buffer descriptor in the list. Get operations don't copy from the list * to a temporary, but return a pointer to the buffer descriptor in the list. * A buffer descriptor in the list may be locked to prevent it from being * overwritten by a put operation. This allows the device driver to get a * descriptor from a scatter gather list and prevent it from being overwritten * until the buffer associated with the buffer descriptor has been processed. * * Typical Scatter Gather Processing * * The following steps illustrate the typical processing to use the * scatter gather features of a DMA channel. * * 1. Create a scatter gather list for the DMA channel which puts empty buffer * descriptors into the list. * 2. Create buffer descriptors which describe the buffers to be filled with * receive data or the buffers which contain data to be sent. * 3. Put buffer descriptors into the DMA channel scatter list such that scatter * gather operations are requested. * 4. Commit the buffer descriptors in the list such that they are ready to be * used by the DMA channel hardware. * 5. Start the scatter gather operations of the DMA channel. * 6. Process any interrupts which occur as a result of the scatter gather * operations or poll the DMA channel to determine the status. * * Interrupts * * Each DMA channel has the ability to generate an interrupt. This component * does not perform processing for the interrupt as this processing is typically * tightly coupled with the device which is using the DMA channel. It is the * responsibility of the caller of DMA functions to manage the interrupt * including connecting to the interrupt and enabling/disabling the interrupt. * * Critical Sections * * It is the responsibility of the device driver designer to use critical * sections as necessary when calling functions of the DMA channel. This * component does not use critical sections and it does access registers using * read-modify-write operations. Calls to DMA functions from a main thread * and from an interrupt context could produce unpredictable behavior such that * the caller must provide the appropriate critical sections. * * Address Translation * * All addresses of data structures which are passed to DMA functions must * be physical (real) addresses as opposed to logical (virtual) addresses. * * Caching * * The memory which is passed to the function which creates the scatter gather * list must not be cached such that buffer descriptors are non-cached. This * is necessary because the buffer descriptors are kept in a ring buffer and * not directly accessible to the caller of DMA functions. * * The caller of DMA functions is responsible for ensuring that any data * buffers which are passed to the DMA channel are cache-line aligned if * necessary. * * The caller of DMA functions is responsible for ensuring that any data * buffers which are passed to the DMA channel have been flushed from the cache. * * The caller of DMA functions is responsible for ensuring that the cache is * invalidated prior to using any data buffers which are the result of a DMA * operation. * * Memory Alignment * * The addresses of data buffers which are passed to DMA functions must be * 32 bit word aligned since the DMA hardware performs 32 bit word transfers. * * Mutual Exclusion * * The functions of the DMA channel are not thread safe such that the caller * of all DMA functions is responsible for ensuring mutual exclusion for a * DMA channel. Mutual exclusion across multiple DMA channels is not * necessary. * * NOTES: * * Many of the provided functions which are register accessors don't provide * a lot of error detection. The caller is expected to understand the impact * of a function call based upon the current state of the DMA channel. This * is done to minimize the overhead in this component. * ******************************************************************************/ #ifndef XDMA_CHANNEL_H /* prevent circular inclusions */ #define XDMA_CHANNEL_H /* by using protection macros */ /***************************** Include Files *********************************/ #include "xdma_channel_i.h" /* constants shared with buffer descriptor */ #include "xbasic_types.h" #include "xstatus.h" #include "xversion.h" #include "xbuf_descriptor.h" /************************** Constant Definitions *****************************/ /* the following constants provide access to the bit fields of the DMA control * register (DMACR) */ #define XDC_DMACR_SOURCE_INCR_MASK 0x80000000UL /* increment source address */ #define XDC_DMACR_DEST_INCR_MASK 0x40000000UL /* increment dest address */ #define XDC_DMACR_SOURCE_LOCAL_MASK 0x20000000UL /* local source address */ #define XDC_DMACR_DEST_LOCAL_MASK 0x10000000UL /* local dest address */ #define XDC_DMACR_SG_DISABLE_MASK 0x08000000UL /* scatter gather disable */ #define XDC_DMACR_GEN_BD_INTR_MASK 0x04000000UL /* descriptor interrupt */ #define XDC_DMACR_LAST_BD_MASK XDC_CONTROL_LAST_BD_MASK /* last buffer */ /* descriptor */ /* the following constants provide access to the bit fields of the DMA status * register (DMASR) */ #define XDC_DMASR_BUSY_MASK 0x80000000UL /* channel is busy */ #define XDC_DMASR_BUS_ERROR_MASK 0x40000000UL /* bus error occurred */ #define XDC_DMASR_BUS_TIMEOUT_MASK 0x20000000UL /* bus timeout occurred */ #define XDC_DMASR_LAST_BD_MASK XDC_STATUS_LAST_BD_MASK /* last buffer */ /* descriptor */ #define XDC_DMASR_SG_BUSY_MASK 0x08000000UL /* scatter gather is busy */ /* the following constants provide access to the bit fields of the interrupt * status register (ISR) and the interrupt enable register (IER), bit masks * match for both registers such that they are named IXR */ #define XDC_IXR_DMA_DONE_MASK 0x1UL /* dma operation done */ #define XDC_IXR_DMA_ERROR_MASK 0x2UL /* dma operation error */ #define XDC_IXR_PKT_DONE_MASK 0x4UL /* packet done */ #define XDC_IXR_PKT_THRESHOLD_MASK 0x8UL /* packet count threshold */ #define XDC_IXR_PKT_WAIT_BOUND_MASK 0x10UL /* packet wait bound reached */ #define XDC_IXR_SG_DISABLE_ACK_MASK 0x20UL /* scatter gather disable acknowledge occurred */ #define XDC_IXR_SG_END_MASK 0x40UL /* last buffer descriptor disabled scatter gather */ #define XDC_IXR_BD_MASK 0x80UL /* buffer descriptor done */ /**************************** Type Definitions *******************************/ /* * the following structure contains data which is on a per instance basis * for the XDmaChannel component */ typedef struct XDmaChannelTag { XVersion Version; /* version of the driver */ u32 RegBaseAddress; /* base address of registers */ u32 IsReady; /* device is initialized and ready */ XBufDescriptor *PutPtr; /* keep track of where to put into list */ XBufDescriptor *GetPtr; /* keep track of where to get from list */ XBufDescriptor *CommitPtr; /* keep track of where to commit in list */ XBufDescriptor *LastPtr; /* keep track of the last put in the list */ u32 TotalDescriptorCount; /* total # of descriptors in the list */ u32 ActiveDescriptorCount; /* # of descriptors pointing to buffers * in the buffer descriptor list */ } XDmaChannel; /***************** Macros (Inline Functions) Definitions *********************/ /************************** Function Prototypes ******************************/ XStatus XDmaChannel_Initialize(XDmaChannel * InstancePtr, u32 BaseAddress); u32 XDmaChannel_IsReady(XDmaChannel * InstancePtr); XVersion *XDmaChannel_GetVersion(XDmaChannel * InstancePtr); XStatus XDmaChannel_SelfTest(XDmaChannel * InstancePtr); void XDmaChannel_Reset(XDmaChannel * InstancePtr); /* Control functions */ u32 XDmaChannel_GetControl(XDmaChannel * InstancePtr); void XDmaChannel_SetControl(XDmaChannel * InstancePtr, u32 Control); /* Status functions */ u32 XDmaChannel_GetStatus(XDmaChannel * InstancePtr); void XDmaChannel_SetIntrStatus(XDmaChannel * InstancePtr, u32 Status); u32 XDmaChannel_GetIntrStatus(XDmaChannel * InstancePtr); void XDmaChannel_SetIntrEnable(XDmaChannel * InstancePtr, u32 Enable); u32 XDmaChannel_GetIntrEnable(XDmaChannel * InstancePtr); /* DMA without scatter gather functions */ void XDmaChannel_Transfer(XDmaChannel * InstancePtr, u32 * SourcePtr, u32 * DestinationPtr, u32 ByteCount); /* Scatter gather functions */ XStatus XDmaChannel_SgStart(XDmaChannel * InstancePtr); XStatus XDmaChannel_SgStop(XDmaChannel * InstancePtr, XBufDescriptor ** BufDescriptorPtr); XStatus XDmaChannel_CreateSgList(XDmaChannel * InstancePtr, u32 * MemoryPtr, u32 ByteCount); u32 XDmaChannel_IsSgListEmpty(XDmaChannel * InstancePtr); XStatus XDmaChannel_PutDescriptor(XDmaChannel * InstancePtr, XBufDescriptor * BufDescriptorPtr); XStatus XDmaChannel_CommitPuts(XDmaChannel * InstancePtr); XStatus XDmaChannel_GetDescriptor(XDmaChannel * InstancePtr, XBufDescriptor ** BufDescriptorPtr); /* Packet functions for interrupt collescing */ u32 XDmaChannel_GetPktCount(XDmaChannel * InstancePtr); void XDmaChannel_DecrementPktCount(XDmaChannel * InstancePtr); XStatus XDmaChannel_SetPktThreshold(XDmaChannel * InstancePtr, u8 Threshold); u8 XDmaChannel_GetPktThreshold(XDmaChannel * InstancePtr); void XDmaChannel_SetPktWaitBound(XDmaChannel * InstancePtr, u32 WaitBound); u32 XDmaChannel_GetPktWaitBound(XDmaChannel * InstancePtr); #endif /* end of protection macro */