2 /******************************************************************************
4 * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
5 * AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
6 * SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE,
7 * OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
8 * APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
9 * THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
10 * AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
11 * FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY
12 * WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
13 * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
14 * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
15 * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
16 * FOR A PARTICULAR PURPOSE.
18 * (c) Copyright 2007-2008 Xilinx Inc.
19 * All rights reserved.
20 * This program is free software; you can redistribute it and/or modify it
21 * under the terms of the GNU General Public License as published by the
22 * Free Software Foundation; either version 2 of the License, or (at your
23 * option) any later version.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 ******************************************************************************/
30 /*****************************************************************************/
33 * @file xlldma_bdring.h
35 * This file contains DMA channel related structure and constant definition
36 * as well as function prototypes. Each DMA channel is managed by a Buffer
37 * Descriptor ring, and so XLlDma_BdRing is chosen as the symbol prefix used in
38 * this file. See xlldma.h for more information.
41 * MODIFICATION HISTORY:
43 * Ver Who Date Changes
44 * ----- ---- -------- -------------------------------------------------------
45 * 1.00a xd 12/21/06 First release
48 ******************************************************************************/
50 #ifndef XLLDMA_BDRING_H /* prevent circular inclusions */
51 #define XLLDMA_BDRING_H /* by using protection macros */
57 #include "xbasic_types.h"
59 #include "xlldma_hw.h"
60 #include "xlldma_bd.h"
62 /** Container structure for descriptor storage control. If address translation
63 * is enabled, then all addresses and pointers excluding FirstBdPhysAddr are
64 * expressed in terms of the virtual address.
67 u32 ChanBase
; /**< Virtual base address of channel registers
69 u32 IsRxChannel
; /**< Is this a receive channel ? */
70 u32 FirstBdPhysAddr
; /**< Physical address of 1st BD in list */
71 u32 FirstBdAddr
; /**< Virtual address of 1st BD in list */
72 u32 LastBdAddr
; /**< Virtual address of last BD in the list */
73 u32 Length
; /**< Total size of ring in bytes */
74 u32 RunState
; /**< Flag to indicate channel is started */
75 u32 Separation
; /**< Number of bytes between the starting
76 address of adjacent BDs */
77 XLlDma_Bd
*FreeHead
; /**< First BD in the free group */
78 XLlDma_Bd
*PreHead
; /**< First BD in the pre-work group */
79 XLlDma_Bd
*HwHead
; /**< First BD in the work group */
80 XLlDma_Bd
*HwTail
; /**< Last BD in the work group */
81 XLlDma_Bd
*PostHead
; /**< First BD in the post-work group */
82 XLlDma_Bd
*BdaRestart
; /**< BD to load when channel is started */
83 u32 FreeCnt
; /**< Number of allocatable BDs in free group */
84 u32 PreCnt
; /**< Number of BDs in pre-work group */
85 u32 HwCnt
; /**< Number of BDs in work group */
86 u32 PostCnt
; /**< Number of BDs in post-work group */
87 u32 AllCnt
; /**< Total Number of BDs for channel */
90 /*****************************************************************************/
92 * Use this macro at initialization time to determine how many BDs will fit
93 * within the given memory constraints.
95 * The results of this macro can be provided to XLlDma_BdRingCreate().
97 * @param Alignment specifies what byte alignment the BDs must fall on and
98 * must be a power of 2 to get an accurate calculation (32, 64, 126,...)
99 * @param Bytes is the number of bytes to be used to store BDs.
101 * @return Number of BDs that can fit in the given memory area
105 * u32 XLlDma_mBdRingCntCalc(u32 Alignment, u32 Bytes)
107 ******************************************************************************/
108 #define XLlDma_mBdRingCntCalc(Alignment, Bytes) \
109 (u32)((Bytes)/((sizeof(XLlDma_Bd)+((Alignment)-1))&~((Alignment)-1)))
112 /*****************************************************************************/
114 * Use this macro at initialization time to determine how many bytes of memory
115 * are required to contain a given number of BDs at a given alignment.
117 * @param Alignment specifies what byte alignment the BDs must fall on. This
118 * parameter must be a power of 2 to get an accurate calculation (32, 64,
120 * @param NumBd is the number of BDs to calculate memory size requirements for
122 * @return The number of bytes of memory required to create a BD list with the
123 * given memory constraints.
127 * u32 XLlDma_mBdRingMemCalc(u32 Alignment, u32 NumBd)
129 ******************************************************************************/
130 #define XLlDma_mBdRingMemCalc(Alignment, NumBd) \
131 (u32)((sizeof(XLlDma_Bd)+((Alignment)-1))&~((Alignment)-1))*(NumBd)
134 /****************************************************************************/
136 * Return the total number of BDs allocated by this channel with
137 * XLlDma_BdRingCreate().
139 * @param RingPtr is the BD ring to operate on.
141 * @return The total number of BDs allocated for this channel.
145 * u32 XLlDma_mBdRingGetCnt(XLlDma_BdRing* RingPtr)
147 *****************************************************************************/
148 #define XLlDma_mBdRingGetCnt(RingPtr) ((RingPtr)->AllCnt)
151 /****************************************************************************/
153 * Return the number of BDs allocatable with XLlDma_BdRingAlloc() for pre-
156 * @param RingPtr is the BD ring to operate on.
158 * @return The number of BDs currently allocatable.
162 * u32 XLlDma_mBdRingGetFreeCnt(XLlDma_BdRing* RingPtr)
164 *****************************************************************************/
165 #define XLlDma_mBdRingGetFreeCnt(RingPtr) ((RingPtr)->FreeCnt)
168 /****************************************************************************/
170 * Snap shot the latest BD a BD ring is processing.
172 * @param RingPtr is the BD ring to operate on.
178 * void XLlDma_mBdRingSnapShotCurrBd(XLlDma_BdRing* RingPtr)
180 *****************************************************************************/
181 #define XLlDma_mBdRingSnapShotCurrBd(RingPtr) \
183 (RingPtr)->BdaRestart = \
184 (XLlDma_Bd *)XLlDma_mReadReg((RingPtr)->ChanBase, \
185 XLLDMA_CDESC_OFFSET); \
189 /****************************************************************************/
191 * Return the next BD in the ring.
193 * @param RingPtr is the BD ring to operate on.
194 * @param BdPtr is the current BD.
196 * @return The next BD in the ring relative to the BdPtr parameter.
200 * XLlDma_Bd *XLlDma_mBdRingNext(XLlDma_BdRing* RingPtr, XLlDma_Bd *BdPtr)
202 *****************************************************************************/
203 #define XLlDma_mBdRingNext(RingPtr, BdPtr) \
204 (((u32)(BdPtr) >= (RingPtr)->LastBdAddr) ? \
205 (XLlDma_Bd*)(RingPtr)->FirstBdAddr : \
206 (XLlDma_Bd*)((u32)(BdPtr) + (RingPtr)->Separation))
209 /****************************************************************************/
211 * Return the previous BD in the ring.
213 * @param InstancePtr is the DMA channel to operate on.
214 * @param BdPtr is the current BD.
216 * @return The previous BD in the ring relative to the BdPtr parameter.
220 * XLlDma_Bd *XLlDma_mBdRingPrev(XLlDma_BdRing* RingPtr, XLlDma_Bd *BdPtr)
222 *****************************************************************************/
223 #define XLlDma_mBdRingPrev(RingPtr, BdPtr) \
224 (((u32)(BdPtr) <= (RingPtr)->FirstBdAddr) ? \
225 (XLlDma_Bd*)(RingPtr)->LastBdAddr : \
226 (XLlDma_Bd*)((u32)(BdPtr) - (RingPtr)->Separation))
228 /****************************************************************************/
230 * Retrieve the contents of the channel status register XLLDMA_SR_OFFSET
232 * @param RingPtr is the channel instance to operate on.
234 * @return Current contents of SR_OFFSET
238 * u32 XLlDma_mBdRingGetSr(XLlDma_BdRing* RingPtr)
240 *****************************************************************************/
241 #define XLlDma_mBdRingGetSr(RingPtr) \
242 XLlDma_mReadReg((RingPtr)->ChanBase, XLLDMA_SR_OFFSET)
245 /****************************************************************************/
247 * Retrieve the contents of the channel control register XLLDMA_CR_OFFSET
249 * @param RingPtr is the channel instance to operate on.
251 * @return Current contents of CR_OFFSET
255 * u32 XLlDma_mBdRingGetCr(XLlDma_BdRing* RingPtr)
257 *****************************************************************************/
258 #define XLlDma_mBdRingGetCr(RingPtr) \
259 XLlDma_mReadReg((RingPtr)->ChanBase, XLLDMA_CR_OFFSET)
262 /****************************************************************************/
264 * Set the contents of the channel control register XLLDMA_CR_OFFSET. This
265 * register does not affect the other DMA channel.
267 * @param RingPtr is the channel instance to operate on.
268 * @param Data is the data to write to CR_OFFSET
272 * u32 XLlDma_mBdRingSetCr(XLlDma_BdRing* RingPtr, u32 Data)
274 *****************************************************************************/
275 #define XLlDma_mBdRingSetCr(RingPtr, Data) \
276 XLlDma_mWriteReg((RingPtr)->ChanBase, XLLDMA_CR_OFFSET, (Data))
279 /****************************************************************************/
281 * Check if the current DMA channel is busy with a DMA operation.
283 * @param RingPtr is the channel instance to operate on.
285 * @return TRUE if the DMA is busy. FALSE otherwise
289 * XBoolean XLlDma_mBdRingBusy(XLlDma_BdRing* RingPtr)
291 *****************************************************************************/
292 #define XLlDma_mBdRingBusy(RingPtr) \
293 ((XLlDma_mReadReg((RingPtr)->ChanBase, XLLDMA_SR_OFFSET) \
294 & XLLDMA_SR_ENGINE_BUSY_MASK) ? TRUE : FALSE)
297 /****************************************************************************/
299 * Set interrupt enable bits for a channel. This operation will modify the
300 * XLLDMA_CR_OFFSET register.
302 * @param RingPtr is the channel instance to operate on.
303 * @param Mask consists of the interrupt signals to enable. They are formed by
304 * OR'ing one or more of the following bitmasks together:
305 * XLLDMA_CR_IRQ_EN_MASK, XLLDMA_CR_IRQ_ERROR_EN_MASK,
306 * XLLDMA_CR_IRQ_DELAY_EN_MASK, XLLDMA_CR_IRQ_COALESCE_EN_MASK and
307 * XLLDMA_CR_IRQ_ALL_EN_MASK. Bits not specified in the mask are not
312 * void XLlDma_mBdRingIntEnable(XLlDma_BdRing* RingPtr, u32 Mask)
314 *****************************************************************************/
315 #define XLlDma_mBdRingIntEnable(RingPtr, Mask) \
317 u32 Reg = XLlDma_mReadReg((RingPtr)->ChanBase, \
319 Reg |= ((Mask) & XLLDMA_CR_IRQ_ALL_EN_MASK); \
320 XLlDma_mWriteReg((RingPtr)->ChanBase, XLLDMA_CR_OFFSET, Reg);\
324 /****************************************************************************/
326 * Clear interrupt enable bits for a channel. This operation will modify the
327 * XLLDMA_CR_OFFSET register.
329 * @param RingPtr is the channel instance to operate on.
330 * @param Mask consists of the interrupt signals to disable. They are formed
331 * by OR'ing one or more of the following bitmasks together:
332 * XLLDMA_CR_IRQ_EN_MASK, XLLDMA_CR_IRQ_ERROR_EN_MASK,
333 * XLLDMA_CR_IRQ_DELAY_EN_MASK, XLLDMA_CR_IRQ_COALESCE_EN_MASK and
334 * XLLDMA_CR_IRQ_ALL_EN_MASK. Bits not specified in the mask are not
339 * void XLlDma_mBdRingIntDisable(XLlDma_BdRing* RingPtr, u32 Mask)
341 *****************************************************************************/
342 #define XLlDma_mBdRingIntDisable(RingPtr, Mask) \
344 u32 Reg = XLlDma_mReadReg((RingPtr)->ChanBase, \
346 Reg &= ~((Mask) & XLLDMA_CR_IRQ_ALL_EN_MASK); \
347 XLlDma_mWriteReg((RingPtr)->ChanBase, XLLDMA_CR_OFFSET, Reg);\
351 /****************************************************************************/
353 * Get enabled interrupts of a channel.
355 * @param RingPtr is the channel instance to operate on.
356 * @return Enabled interrupts of a channel. Use XLLDMA_CR_IRQ_* defined in
357 * xlldma_hw.h to interpret this returned value.
361 * u32 XLlDma_mBdRingIntGetEnabled(XLlDma_BdRing* RingPtr)
363 *****************************************************************************/
364 #define XLlDma_mBdRingIntGetEnabled(RingPtr) \
365 (XLlDma_mReadReg((RingPtr)->ChanBase, XLLDMA_CR_OFFSET) \
366 & XLLDMA_CR_IRQ_ALL_EN_MASK)
369 /****************************************************************************/
371 * Retrieve the contents of the channel's IRQ register XDMACR_IRQ_OFFSET. This
372 * operation can be used to see which interrupts are pending.
374 * @param RingPtr is the channel instance to operate on.
376 * @return Current contents of the IRQ_OFFSET register. Use XLLDMA_IRQ_***
377 * values defined in xlldma_hw.h to interpret the returned value.
381 * u32 XLlDma_mBdRingGetIrq(XLlDma_BdRing* RingPtr)
383 *****************************************************************************/
384 #define XLlDma_mBdRingGetIrq(RingPtr) \
385 XLlDma_mReadReg((RingPtr)->ChanBase, XLLDMA_IRQ_OFFSET)
388 /****************************************************************************/
390 * Acknowledge asserted interrupts.
392 * @param RingPtr is the channel instance to operate on.
393 * @param Mask are the interrupt signals to acknowledge and are made by Or'ing
394 * one or more of the following bits: XLLDMA_IRQ_ERROR_MASK,
395 * XLLDMA_IRQ_DELAY_MASK, XLLDMA_IRQ_COALESCE_MASK, XLLDMA_IRQ_ALL_MASK.
396 * Any mask bit set for an unasserted interrupt has no effect.
400 * u32 XLlDma_mBdRingAckIrq(XLlDma_BdRing* RingPtr)
402 *****************************************************************************/
403 #define XLlDma_mBdRingAckIrq(RingPtr, Mask) \
404 XLlDma_mWriteReg((RingPtr)->ChanBase, XLLDMA_IRQ_OFFSET,\
405 (Mask) & XLLDMA_IRQ_ALL_MASK)
407 /************************* Function Prototypes ******************************/
410 * Descriptor ring functions xlldma_bdring.c
412 int XLlDma_BdRingCreate(XLlDma_BdRing
* RingPtr
, u32 PhysAddr
,
413 u32 VirtAddr
, u32 Alignment
, unsigned BdCount
);
414 int XLlDma_BdRingCheck(XLlDma_BdRing
* RingPtr
);
415 int XLlDma_BdRingClone(XLlDma_BdRing
* RingPtr
, XLlDma_Bd
* SrcBdPtr
);
416 int XLlDma_BdRingAlloc(XLlDma_BdRing
* RingPtr
, unsigned NumBd
,
417 XLlDma_Bd
** BdSetPtr
);
418 int XLlDma_BdRingUnAlloc(XLlDma_BdRing
* RingPtr
, unsigned NumBd
,
419 XLlDma_Bd
* BdSetPtr
);
420 int XLlDma_BdRingToHw(XLlDma_BdRing
* RingPtr
, unsigned NumBd
,
421 XLlDma_Bd
* BdSetPtr
);
422 unsigned XLlDma_BdRingFromHw(XLlDma_BdRing
* RingPtr
, unsigned BdLimit
,
423 XLlDma_Bd
** BdSetPtr
);
424 int XLlDma_BdRingFree(XLlDma_BdRing
* RingPtr
, unsigned NumBd
,
425 XLlDma_Bd
* BdSetPtr
);
426 int XLlDma_BdRingStart(XLlDma_BdRing
* RingPtr
);
427 int XLlDma_BdRingSetCoalesce(XLlDma_BdRing
* RingPtr
, u32 Counter
, u32 Timer
);
428 void XLlDma_BdRingGetCoalesce(XLlDma_BdRing
* RingPtr
,
429 u32
*CounterPtr
, u32
*TimerPtr
);
434 #endif /* end of protection macro */