|  | /****************************************************************************** | 
|  | * | 
|  | *     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 */ |