wdenk | 028ab6b | 2004-02-23 23:54:43 +0000 | [diff] [blame] | 1 | /****************************************************************************** |
| 2 | * |
| 3 | * Author: Xilinx, Inc. |
| 4 | * |
| 5 | * |
| 6 | * This program is free software; you can redistribute it and/or modify it |
| 7 | * under the terms of the GNU General Public License as published by the |
| 8 | * Free Software Foundation; either version 2 of the License, or (at your |
| 9 | * option) any later version. |
| 10 | * |
| 11 | * |
| 12 | * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A |
| 13 | * COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS |
| 14 | * ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD, |
| 15 | * XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE |
| 16 | * FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING |
| 17 | * ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. |
| 18 | * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO |
| 19 | * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY |
| 20 | * WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM |
| 21 | * CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND |
| 22 | * FITNESS FOR A PARTICULAR PURPOSE. |
| 23 | * |
| 24 | * |
| 25 | * Xilinx hardware products are not intended for use in life support |
| 26 | * appliances, devices, or systems. Use in such applications is |
| 27 | * expressly prohibited. |
| 28 | * |
| 29 | * |
| 30 | * (c) Copyright 2002-2004 Xilinx Inc. |
| 31 | * All rights reserved. |
| 32 | * |
| 33 | * |
| 34 | * You should have received a copy of the GNU General Public License along |
| 35 | * with this program; if not, write to the Free Software Foundation, Inc., |
| 36 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
| 37 | * |
| 38 | * FILENAME: |
| 39 | * |
| 40 | * xdma_channel.h |
| 41 | * |
| 42 | * DESCRIPTION: |
| 43 | * |
| 44 | * This file contains the DMA channel component implementation. This component |
| 45 | * supports a distributed DMA design in which each device can have it's own |
| 46 | * dedicated DMA channel, as opposed to a centralized DMA design. |
| 47 | * A device which uses DMA typically contains two DMA channels, one for |
| 48 | * sending data and the other for receiving data. |
| 49 | * |
| 50 | * This component is designed to be used as a basic building block for |
| 51 | * designing a device driver. It provides registers accesses such that all |
| 52 | * DMA processing can be maintained easier, but the device driver designer |
| 53 | * must still understand all the details of the DMA channel. |
| 54 | * |
| 55 | * The DMA channel allows a CPU to minimize the CPU interaction required to move |
| 56 | * data between a memory and a device. The CPU requests the DMA channel to |
| 57 | * perform a DMA operation and typically continues performing other processing |
| 58 | * until the DMA operation completes. DMA could be considered a primitive form |
| 59 | * of multiprocessing such that caching and address translation can be an issue. |
| 60 | * |
| 61 | * Scatter Gather Operations |
| 62 | * |
| 63 | * The DMA channel may support scatter gather operations. A scatter gather |
| 64 | * operation automates the DMA channel such that multiple buffers can be |
| 65 | * sent or received with minimal software interaction with the hardware. Buffer |
| 66 | * descriptors, contained in the XBufDescriptor component, are used by the |
| 67 | * scatter gather operations of the DMA channel to describe the buffers to be |
| 68 | * processed. |
| 69 | * |
| 70 | * Scatter Gather List Operations |
| 71 | * |
| 72 | * A scatter gather list may be supported by each DMA channel. The scatter |
| 73 | * gather list allows buffer descriptors to be put into the list by a device |
| 74 | * driver which requires scatter gather. The hardware processes the buffer |
| 75 | * descriptors which are contained in the list and modifies the buffer |
| 76 | * descriptors to reflect the status of the DMA operations. The device driver |
| 77 | * is notified by interrupt that specific DMA events occur including scatter |
| 78 | * gather events. The device driver removes the completed buffer descriptors |
| 79 | * from the scatter gather list to evaluate the status of each DMA operation. |
| 80 | * |
| 81 | * The scatter gather list is created and buffer descriptors are inserted into |
| 82 | * the list. Buffer descriptors are never removed from the list after it's |
| 83 | * creation such that a put operation copies from a temporary buffer descriptor |
| 84 | * to a buffer descriptor in the list. Get operations don't copy from the list |
| 85 | * to a temporary, but return a pointer to the buffer descriptor in the list. |
| 86 | * A buffer descriptor in the list may be locked to prevent it from being |
| 87 | * overwritten by a put operation. This allows the device driver to get a |
| 88 | * descriptor from a scatter gather list and prevent it from being overwritten |
| 89 | * until the buffer associated with the buffer descriptor has been processed. |
| 90 | * |
| 91 | * Typical Scatter Gather Processing |
| 92 | * |
| 93 | * The following steps illustrate the typical processing to use the |
| 94 | * scatter gather features of a DMA channel. |
| 95 | * |
| 96 | * 1. Create a scatter gather list for the DMA channel which puts empty buffer |
| 97 | * descriptors into the list. |
| 98 | * 2. Create buffer descriptors which describe the buffers to be filled with |
Wolfgang Denk | 53677ef | 2008-05-20 16:00:29 +0200 | [diff] [blame^] | 99 | * receive data or the buffers which contain data to be sent. |
wdenk | 028ab6b | 2004-02-23 23:54:43 +0000 | [diff] [blame] | 100 | * 3. Put buffer descriptors into the DMA channel scatter list such that scatter |
| 101 | * gather operations are requested. |
| 102 | * 4. Commit the buffer descriptors in the list such that they are ready to be |
| 103 | * used by the DMA channel hardware. |
| 104 | * 5. Start the scatter gather operations of the DMA channel. |
| 105 | * 6. Process any interrupts which occur as a result of the scatter gather |
| 106 | * operations or poll the DMA channel to determine the status. |
| 107 | * |
| 108 | * Interrupts |
| 109 | * |
| 110 | * Each DMA channel has the ability to generate an interrupt. This component |
| 111 | * does not perform processing for the interrupt as this processing is typically |
| 112 | * tightly coupled with the device which is using the DMA channel. It is the |
| 113 | * responsibility of the caller of DMA functions to manage the interrupt |
| 114 | * including connecting to the interrupt and enabling/disabling the interrupt. |
| 115 | * |
| 116 | * Critical Sections |
| 117 | * |
| 118 | * It is the responsibility of the device driver designer to use critical |
| 119 | * sections as necessary when calling functions of the DMA channel. This |
| 120 | * component does not use critical sections and it does access registers using |
| 121 | * read-modify-write operations. Calls to DMA functions from a main thread |
| 122 | * and from an interrupt context could produce unpredictable behavior such that |
| 123 | * the caller must provide the appropriate critical sections. |
| 124 | * |
| 125 | * Address Translation |
| 126 | * |
| 127 | * All addresses of data structures which are passed to DMA functions must |
| 128 | * be physical (real) addresses as opposed to logical (virtual) addresses. |
| 129 | * |
| 130 | * Caching |
| 131 | * |
| 132 | * The memory which is passed to the function which creates the scatter gather |
| 133 | * list must not be cached such that buffer descriptors are non-cached. This |
| 134 | * is necessary because the buffer descriptors are kept in a ring buffer and |
| 135 | * not directly accessible to the caller of DMA functions. |
| 136 | * |
| 137 | * The caller of DMA functions is responsible for ensuring that any data |
| 138 | * buffers which are passed to the DMA channel are cache-line aligned if |
| 139 | * necessary. |
| 140 | * |
| 141 | * The caller of DMA functions is responsible for ensuring that any data |
| 142 | * buffers which are passed to the DMA channel have been flushed from the cache. |
| 143 | * |
| 144 | * The caller of DMA functions is responsible for ensuring that the cache is |
| 145 | * invalidated prior to using any data buffers which are the result of a DMA |
| 146 | * operation. |
| 147 | * |
| 148 | * Memory Alignment |
| 149 | * |
| 150 | * The addresses of data buffers which are passed to DMA functions must be |
| 151 | * 32 bit word aligned since the DMA hardware performs 32 bit word transfers. |
| 152 | * |
| 153 | * Mutual Exclusion |
| 154 | * |
| 155 | * The functions of the DMA channel are not thread safe such that the caller |
| 156 | * of all DMA functions is responsible for ensuring mutual exclusion for a |
| 157 | * DMA channel. Mutual exclusion across multiple DMA channels is not |
| 158 | * necessary. |
| 159 | * |
| 160 | * NOTES: |
| 161 | * |
| 162 | * Many of the provided functions which are register accessors don't provide |
| 163 | * a lot of error detection. The caller is expected to understand the impact |
| 164 | * of a function call based upon the current state of the DMA channel. This |
| 165 | * is done to minimize the overhead in this component. |
| 166 | * |
| 167 | ******************************************************************************/ |
| 168 | |
| 169 | #ifndef XDMA_CHANNEL_H /* prevent circular inclusions */ |
| 170 | #define XDMA_CHANNEL_H /* by using protection macros */ |
| 171 | |
| 172 | /***************************** Include Files *********************************/ |
| 173 | |
| 174 | #include "xdma_channel_i.h" /* constants shared with buffer descriptor */ |
| 175 | #include "xbasic_types.h" |
| 176 | #include "xstatus.h" |
| 177 | #include "xversion.h" |
| 178 | #include "xbuf_descriptor.h" |
| 179 | |
| 180 | /************************** Constant Definitions *****************************/ |
| 181 | |
| 182 | /* the following constants provide access to the bit fields of the DMA control |
| 183 | * register (DMACR) |
| 184 | */ |
| 185 | #define XDC_DMACR_SOURCE_INCR_MASK 0x80000000UL /* increment source address */ |
| 186 | #define XDC_DMACR_DEST_INCR_MASK 0x40000000UL /* increment dest address */ |
| 187 | #define XDC_DMACR_SOURCE_LOCAL_MASK 0x20000000UL /* local source address */ |
| 188 | #define XDC_DMACR_DEST_LOCAL_MASK 0x10000000UL /* local dest address */ |
| 189 | #define XDC_DMACR_SG_DISABLE_MASK 0x08000000UL /* scatter gather disable */ |
| 190 | #define XDC_DMACR_GEN_BD_INTR_MASK 0x04000000UL /* descriptor interrupt */ |
| 191 | #define XDC_DMACR_LAST_BD_MASK XDC_CONTROL_LAST_BD_MASK /* last buffer */ |
| 192 | /* descriptor */ |
| 193 | |
| 194 | /* the following constants provide access to the bit fields of the DMA status |
| 195 | * register (DMASR) |
| 196 | */ |
| 197 | #define XDC_DMASR_BUSY_MASK 0x80000000UL /* channel is busy */ |
| 198 | #define XDC_DMASR_BUS_ERROR_MASK 0x40000000UL /* bus error occurred */ |
| 199 | #define XDC_DMASR_BUS_TIMEOUT_MASK 0x20000000UL /* bus timeout occurred */ |
| 200 | #define XDC_DMASR_LAST_BD_MASK XDC_STATUS_LAST_BD_MASK /* last buffer */ |
| 201 | /* descriptor */ |
| 202 | #define XDC_DMASR_SG_BUSY_MASK 0x08000000UL /* scatter gather is busy */ |
| 203 | |
| 204 | /* the following constants provide access to the bit fields of the interrupt |
| 205 | * status register (ISR) and the interrupt enable register (IER), bit masks |
| 206 | * match for both registers such that they are named IXR |
| 207 | */ |
| 208 | #define XDC_IXR_DMA_DONE_MASK 0x1UL /* dma operation done */ |
| 209 | #define XDC_IXR_DMA_ERROR_MASK 0x2UL /* dma operation error */ |
| 210 | #define XDC_IXR_PKT_DONE_MASK 0x4UL /* packet done */ |
Wolfgang Denk | 53677ef | 2008-05-20 16:00:29 +0200 | [diff] [blame^] | 211 | #define XDC_IXR_PKT_THRESHOLD_MASK 0x8UL /* packet count threshold */ |
wdenk | 028ab6b | 2004-02-23 23:54:43 +0000 | [diff] [blame] | 212 | #define XDC_IXR_PKT_WAIT_BOUND_MASK 0x10UL /* packet wait bound reached */ |
| 213 | #define XDC_IXR_SG_DISABLE_ACK_MASK 0x20UL /* scatter gather disable |
| 214 | acknowledge occurred */ |
| 215 | #define XDC_IXR_SG_END_MASK 0x40UL /* last buffer descriptor |
| 216 | disabled scatter gather */ |
| 217 | #define XDC_IXR_BD_MASK 0x80UL /* buffer descriptor done */ |
| 218 | |
| 219 | /**************************** Type Definitions *******************************/ |
| 220 | |
| 221 | /* |
| 222 | * the following structure contains data which is on a per instance basis |
| 223 | * for the XDmaChannel component |
| 224 | */ |
| 225 | typedef struct XDmaChannelTag { |
| 226 | XVersion Version; /* version of the driver */ |
| 227 | u32 RegBaseAddress; /* base address of registers */ |
| 228 | u32 IsReady; /* device is initialized and ready */ |
| 229 | |
| 230 | XBufDescriptor *PutPtr; /* keep track of where to put into list */ |
| 231 | XBufDescriptor *GetPtr; /* keep track of where to get from list */ |
| 232 | XBufDescriptor *CommitPtr; /* keep track of where to commit in list */ |
| 233 | XBufDescriptor *LastPtr; /* keep track of the last put in the list */ |
| 234 | u32 TotalDescriptorCount; /* total # of descriptors in the list */ |
| 235 | u32 ActiveDescriptorCount; /* # of descriptors pointing to buffers |
| 236 | * in the buffer descriptor list */ |
| 237 | } XDmaChannel; |
| 238 | |
| 239 | /***************** Macros (Inline Functions) Definitions *********************/ |
| 240 | |
| 241 | /************************** Function Prototypes ******************************/ |
| 242 | |
| 243 | XStatus XDmaChannel_Initialize(XDmaChannel * InstancePtr, u32 BaseAddress); |
| 244 | u32 XDmaChannel_IsReady(XDmaChannel * InstancePtr); |
| 245 | XVersion *XDmaChannel_GetVersion(XDmaChannel * InstancePtr); |
| 246 | XStatus XDmaChannel_SelfTest(XDmaChannel * InstancePtr); |
| 247 | void XDmaChannel_Reset(XDmaChannel * InstancePtr); |
| 248 | |
| 249 | /* Control functions */ |
| 250 | |
| 251 | u32 XDmaChannel_GetControl(XDmaChannel * InstancePtr); |
| 252 | void XDmaChannel_SetControl(XDmaChannel * InstancePtr, u32 Control); |
| 253 | |
| 254 | /* Status functions */ |
| 255 | |
| 256 | u32 XDmaChannel_GetStatus(XDmaChannel * InstancePtr); |
| 257 | void XDmaChannel_SetIntrStatus(XDmaChannel * InstancePtr, u32 Status); |
| 258 | u32 XDmaChannel_GetIntrStatus(XDmaChannel * InstancePtr); |
| 259 | void XDmaChannel_SetIntrEnable(XDmaChannel * InstancePtr, u32 Enable); |
| 260 | u32 XDmaChannel_GetIntrEnable(XDmaChannel * InstancePtr); |
| 261 | |
| 262 | /* DMA without scatter gather functions */ |
| 263 | |
| 264 | void XDmaChannel_Transfer(XDmaChannel * InstancePtr, |
| 265 | u32 * SourcePtr, u32 * DestinationPtr, u32 ByteCount); |
| 266 | |
| 267 | /* Scatter gather functions */ |
| 268 | |
| 269 | XStatus XDmaChannel_SgStart(XDmaChannel * InstancePtr); |
| 270 | XStatus XDmaChannel_SgStop(XDmaChannel * InstancePtr, |
| 271 | XBufDescriptor ** BufDescriptorPtr); |
| 272 | XStatus XDmaChannel_CreateSgList(XDmaChannel * InstancePtr, |
| 273 | u32 * MemoryPtr, u32 ByteCount); |
| 274 | u32 XDmaChannel_IsSgListEmpty(XDmaChannel * InstancePtr); |
| 275 | |
| 276 | XStatus XDmaChannel_PutDescriptor(XDmaChannel * InstancePtr, |
| 277 | XBufDescriptor * BufDescriptorPtr); |
| 278 | XStatus XDmaChannel_CommitPuts(XDmaChannel * InstancePtr); |
| 279 | XStatus XDmaChannel_GetDescriptor(XDmaChannel * InstancePtr, |
| 280 | XBufDescriptor ** BufDescriptorPtr); |
| 281 | |
| 282 | /* Packet functions for interrupt collescing */ |
| 283 | |
| 284 | u32 XDmaChannel_GetPktCount(XDmaChannel * InstancePtr); |
| 285 | void XDmaChannel_DecrementPktCount(XDmaChannel * InstancePtr); |
| 286 | XStatus XDmaChannel_SetPktThreshold(XDmaChannel * InstancePtr, u8 Threshold); |
| 287 | u8 XDmaChannel_GetPktThreshold(XDmaChannel * InstancePtr); |
| 288 | void XDmaChannel_SetPktWaitBound(XDmaChannel * InstancePtr, u32 WaitBound); |
| 289 | u32 XDmaChannel_GetPktWaitBound(XDmaChannel * InstancePtr); |
| 290 | |
| 291 | #endif /* end of protection macro */ |