1 /******************************************************************************
3 * Copyright (C) 2014 Xilinx, Inc. All rights reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * Use of the Software is limited solely to applications:
16 * (a) running on a Xilinx device, or
17 * (b) that interact with a Xilinx device through a bus or interconnect.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
24 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 * Except as contained in this notice, the name of the Xilinx shall not be used
28 * in advertising or otherwise to promote the sale, use or other dealings in
29 * this Software without prior written authorization from Xilinx.
31 ******************************************************************************/
32 /*****************************************************************************/
36 * @addtogroup zdma_v1_0
39 * This file contains the implementation of the interface functions for ZDMA
40 * driver. Refer to the header file xzdma.h for more detailed information.
43 * MODIFICATION HISTORY:
45 * Ver Who Date Changes
46 * ----- ------ -------- ------------------------------------------------------
47 * 1.0 vns 2/27/15 First release
48 * vns 16/10/15 Corrected Destination descriptor addresss calculation
49 * in XZDma_CreateBDList API
50 * 1.1 vns 05/11/15 Modified XZDma_SetMode to return XST_FAILURE on
51 * selecting DMA mode other than normal mode in
52 * scatter gather mode data transfer and corrected
53 * XZDma_SetChDataConfig API to set over fetch and
54 * src issue parameters correctly.
57 ******************************************************************************/
59 /***************************** Include Files *********************************/
63 /************************** Function Prototypes ******************************/
65 static void StubCallBack(void *CallBackRef, u32 Mask);
66 static void StubDoneCallBack(void *CallBackRef);
67 static void XZDma_SimpleMode(XZDma *InstancePtr, XZDma_Transfer *Data);
68 static void XZDma_ScatterGather(XZDma *InstancePtr, XZDma_Transfer *Data,
70 static void XZDma_LinearMode(XZDma *InstancePtr, XZDma_Transfer *Data,
71 XZDma_LiDscr *SrcDscrPtr,XZDma_LiDscr *DstDscrPtr, u8 IsLast);
72 static void XZDma_ConfigLinear(XZDma_LiDscr *DscrPtr, u64 Addr, u32 Size,
74 static void XZDma_LinkedListMode(XZDma *InstancePtr, XZDma_Transfer *Data,
75 XZDma_LlDscr *SrcDscrPtr,XZDma_LlDscr *DstDscrPtr, u8 IsLast);
76 static void XZDma_ConfigLinkedList(XZDma_LlDscr *DscrPtr, u64 Addr, u32 Size,
77 u32 CtrlValue, u64 NextDscrAddr);
78 static void XZDma_Enable(XZDma *InstancePtr);
79 static void XZDma_GetConfigurations(XZDma *InstancePtr);
81 /************************** Function Definitions *****************************/
83 /*****************************************************************************/
86 * This function initializes an ZDMA core. This function must be called
87 * prior to using an ZDMA core. Initialization of an ZDMA includes setting
88 * up the instance data and ensuring the hardware is in a quiescent state and
89 * resets all the hardware configurations.
91 * @param InstancePtr is a pointer to the XZDma instance.
92 * @param CfgPtr is a reference to a structure containing information
93 * about a specific XZDma instance.
94 * @param EffectiveAddr is the device base address in the virtual memory
95 * address space. The caller is responsible for keeping the
96 * address mapping from EffectiveAddr to the device physical
97 * base address unchanged once this function is invoked.
98 * Unexpected errors may occur if the address mapping changes
99 * after this function is called. If address translation is not
100 * used, pass in the physical address instead.
103 * - XST_SUCCESS if initialization was successful.
107 ******************************************************************************/
108 s32 XZDma_CfgInitialize(XZDma *InstancePtr, XZDma_Config *CfgPtr,
112 /* Verify arguments. */
113 Xil_AssertNonvoid(InstancePtr != NULL);
114 Xil_AssertNonvoid(CfgPtr != NULL);
115 Xil_AssertNonvoid(EffectiveAddr != ((u32)0x00));
117 InstancePtr->Config.BaseAddress = CfgPtr->BaseAddress;
118 InstancePtr->Config.DeviceId = CfgPtr->DeviceId;
119 InstancePtr->Config.DmaType = CfgPtr->DmaType;
121 InstancePtr->Config.BaseAddress = EffectiveAddr;
123 InstancePtr->IsReady = (u32)(XIL_COMPONENT_IS_READY);
125 InstancePtr->IsSgDma = FALSE;
126 InstancePtr->Mode = XZDMA_NORMAL_MODE;
127 InstancePtr->IntrMask = 0x00U;
128 InstancePtr->ChannelState = XZDMA_IDLE;
131 * Set all handlers to stub values, let user configure this
134 InstancePtr->DoneHandler =
135 (XZDma_DoneHandler)((void *)StubDoneCallBack);
136 InstancePtr->ErrorHandler =
137 (XZDma_ErrorHandler)((void *)StubCallBack);
139 XZDma_Reset(InstancePtr);
140 XZDma_GetConfigurations(InstancePtr);
142 return (XST_SUCCESS);
146 /*****************************************************************************/
149 * This function sets the pointer type and mode in which ZDMA needs to transfer
152 * @param InstancePtr is a pointer to the XZDma instance.
153 * @param IsSgDma is a variable which specifies whether transfer has to
154 * to be done in scatter gather mode or simple mode.
155 * - TRUE - Scatter gather pointer type
156 * - FALSE - Simple pointer type
157 * @param Mode is the type of the mode in which data has to be initiated
158 * - XZDMA_NORMAL_MODE - Normal data transfer from source to
159 * destination (Valid for both Scatter
160 * gather and simple types)
161 * - XZDMA_WRONLY_MODE - Write only mode (Valid only for Simple)
162 * - XZDMA_RDONLY_MODE - Read only mode (Valid only for Simple)
165 * - XST_SUCCESS - If mode has been set successfully.
166 * - XST_FAILURE - If mode has not been set.
168 * @note Mode cannot be changed while ZDMA is not in IDLE state.
170 ******************************************************************************/
171 s32 XZDma_SetMode(XZDma *InstancePtr, u8 IsSgDma, XZDma_Mode Mode)
176 /* Verify arguments. */
177 Xil_AssertNonvoid(InstancePtr != NULL);
178 Xil_AssertNonvoid((IsSgDma == TRUE) || (IsSgDma == FALSE));
179 Xil_AssertNonvoid(Mode <= XZDMA_RDONLY_MODE);
181 if (InstancePtr->ChannelState != XZDMA_IDLE) {
182 Status = XST_FAILURE;
186 Data = XZDma_ReadReg(InstancePtr->Config.BaseAddress,
187 XZDMA_CH_CTRL0_OFFSET);
189 if (IsSgDma != TRUE) {
190 Data = (Data & (~XZDMA_CTRL0_POINT_TYPE_MASK));
191 if (Mode == XZDMA_NORMAL_MODE) {
192 Data &= (~XZDMA_CTRL0_MODE_MASK);
194 else if (Mode == XZDMA_WRONLY_MODE) {
195 Data |= XZDMA_CTRL0_WRONLY_MASK;
198 Data |= XZDMA_CTRL0_RDONLY_MASK;
200 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
201 XZDMA_CH_CTRL0_OFFSET, Data);
202 InstancePtr->IsSgDma = FALSE;
203 InstancePtr->Mode = Mode;
207 if (Mode != XZDMA_NORMAL_MODE) {
208 Status = XST_FAILURE;
212 Data |= (XZDMA_CTRL0_POINT_TYPE_MASK);
213 Data &= ~(XZDMA_CTRL0_MODE_MASK);
214 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
215 XZDMA_CH_CTRL0_OFFSET, Data);
217 InstancePtr->IsSgDma = TRUE;
218 InstancePtr->Mode = Mode;
221 Status = XST_SUCCESS;
229 /*****************************************************************************/
232 * This function sets the descriptor type and descriptor pointer's start address
233 * of both source and destination based on the memory allocated by user and also
234 * calculates no of descriptors(BDs) can be created in the allocated memory.
236 * @param InstancePtr is a pointer to the XZDma instance.
237 * @param TypeOfDscr is a variable which specifies descriptor type
238 * whether Linear or linked list type of descriptor.
239 * - XZDMA_LINEAR - Linear type of descriptor.
240 * - XZDMA_LINKEDLIST- Linked list type of descriptor.
241 * @param Dscr_MemPtr is a pointer to the allocated memory for creating
242 * descriptors. It Should be aligned to 64 bytes.
244 * @param NoOfBytes specifies the number of bytes allocated for
247 * @return The Count of the descriptors can be created.
249 * @note User should allocate the memory for descriptors which should
250 * be capable of how many transfers he wish to do in one start.
251 * For Linear mode each descriptor needs 128 bit memory so for
252 * one data transfer it requires 2*128 = 256 bits i.e. 32 bytes
253 * Similarly for Linked list mode for each descriptor it needs
254 * 256 bit, so for one data transfer it require 2*256 = 512 bits
257 ******************************************************************************/
258 u32 XZDma_CreateBDList(XZDma *InstancePtr, XZDma_DscrType TypeOfDscr,
259 UINTPTR Dscr_MemPtr, u32 NoOfBytes)
263 /* Verify arguments. */
264 Xil_AssertNonvoid(InstancePtr != NULL);
265 Xil_AssertNonvoid((TypeOfDscr == XZDMA_LINEAR) ||
266 (TypeOfDscr == XZDMA_LINKEDLIST));
267 Xil_AssertNonvoid(Dscr_MemPtr != 0x00);
268 Xil_AssertNonvoid(NoOfBytes != 0x00U);
270 InstancePtr->Descriptor.DscrType = TypeOfDscr;
272 if (TypeOfDscr == XZDMA_LINEAR) {
273 Size = sizeof(XZDma_LiDscr);
276 Size = sizeof(XZDma_LlDscr);
278 InstancePtr->Descriptor.DscrCount =
279 (NoOfBytes >> 1) / Size;
280 InstancePtr->Descriptor.SrcDscrPtr = (void *)Dscr_MemPtr;
281 InstancePtr->Descriptor.DstDscrPtr =
282 (void *)Dscr_MemPtr + (Size * InstancePtr->Descriptor.DscrCount);
284 Xil_DCacheInvalidateRange((INTPTR)Dscr_MemPtr, NoOfBytes);
286 return (InstancePtr->Descriptor.DscrCount);
289 /*****************************************************************************/
292 * This function sets the data attributes and control configurations of a
293 * ZDMA core based on the inputs provided.
295 * @param InstancePtr is a pointer to the XZDma instance.
296 * @param Configure is a pointer to the XZDma_ChDataConfig structure
297 * which has all the configuration fields.
298 * The fields of the structure are:
299 * - OverFetch - Allows over fetch or not
300 * - 0 - Not allowed to over-fetch on SRC
301 * - 1 - Allowed to over-fetch on SRC
302 * - SrcIssue - Outstanding transaction on SRC
304 * - SrcBurstType - Burst Type for SRC AXI transaction
305 * - XZDMA_FIXED_BURST - Fixed burst
306 * - XZDMA_INCR_BURST - Incremental burst
307 * - SrcBurstLen - AXI Length for Data Read.
308 * - Range of values is (1,2,4,8,16).
309 * - DstBurstType - Burst Type for SRC AXI transaction
310 * - XZDMA_FIXED_BURST - Fixed burst
311 * - XZDMA_INCR_BURST - Incremental burst
312 * - DstBurstLen - AXI Length for Data write.
313 * - Range of values is (1,2,4,8,16).
314 * - SrcCache - AXI cache bits for Data read
315 * - SrcQos - Configurable QoS bits for AXI Data read
316 * - DstCache - AXI cache bits for Data write
317 * - DstQos - configurable QoS bits for AXI Data write
320 * - XST_FAILURE If ZDMA Core is not in Idle state and
321 * - XST_SUCCESS If Configurations are made successfully
324 * - These configurations will last till we modify or Reset
325 * by XZDma_Reset(XZDma *InstancePtr).
326 * - Configurations should be modified only when ZDMA channel
327 * is IDLE this can be confirmed by using
328 * XZDma_ChannelState(XZDma *InstancePtr) API.
330 ******************************************************************************/
331 s32 XZDma_SetChDataConfig(XZDma *InstancePtr, XZDma_DataConfig *Configure)
336 /* Verify arguments */
337 Xil_AssertNonvoid(InstancePtr != NULL);
338 Xil_AssertNonvoid(Configure != NULL);
340 if (InstancePtr->ChannelState != XZDMA_IDLE) {
341 Status = XST_FAILURE;
344 InstancePtr->DataConfig.DstBurstType = Configure->DstBurstType;
345 InstancePtr->DataConfig.DstBurstLen = Configure->DstBurstLen;
346 InstancePtr->DataConfig.SrcBurstType = Configure->SrcBurstType;
347 InstancePtr->DataConfig.SrcBurstLen = Configure->SrcBurstLen;
348 InstancePtr->DataConfig.OverFetch = Configure->OverFetch;
349 InstancePtr->DataConfig.SrcIssue = Configure->SrcIssue;
350 InstancePtr->DataConfig.SrcCache = Configure->SrcCache;
351 InstancePtr->DataConfig.SrcQos = Configure->SrcQos;
352 InstancePtr->DataConfig.DstCache = Configure->DstCache;
353 InstancePtr->DataConfig.DstQos = Configure->DstQos;
355 /* Setting over fetch */
356 Data = XZDma_ReadReg(InstancePtr->Config.BaseAddress,
357 XZDMA_CH_CTRL0_OFFSET) & (~XZDMA_CTRL0_OVR_FETCH_MASK);
359 Data |= (((u32)(Configure->OverFetch) <<
360 XZDMA_CTRL0_OVR_FETCH_SHIFT) &
361 XZDMA_CTRL0_OVR_FETCH_MASK);
363 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
364 XZDMA_CH_CTRL0_OFFSET, Data);
366 /* Setting source issue */
367 Data = XZDma_ReadReg(InstancePtr->Config.BaseAddress,
368 XZDMA_CH_CTRL1_OFFSET) & (~XZDMA_CTRL1_SRC_ISSUE_MASK);
369 Data |= (u32)(Configure->SrcIssue & XZDMA_CTRL1_SRC_ISSUE_MASK);
371 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
372 XZDMA_CH_CTRL1_OFFSET, Data);
374 /* Setting Burst length and burst type */
375 Data = XZDma_ReadReg(InstancePtr->Config.BaseAddress,
376 XZDMA_CH_DATA_ATTR_OFFSET);
377 Data = (Data & (~(XZDMA_DATA_ATTR_ARBURST_MASK |
378 XZDMA_DATA_ATTR_ARLEN_MASK |
379 XZDMA_DATA_ATTR_AWBURST_MASK |
380 XZDMA_DATA_ATTR_AWLEN_MASK |
381 XZDMA_DATA_ATTR_ARCACHE_MASK |
382 XZDMA_DATA_ATTR_AWCACHE_MASK |
383 XZDMA_DATA_ATTR_AWQOS_MASK |
384 XZDMA_DATA_ATTR_ARQOS_MASK)));
386 Data |= ((((u32)(Configure->SrcBurstType) <<
387 XZDMA_DATA_ATTR_ARBURST_SHIFT) &
388 XZDMA_DATA_ATTR_ARBURST_MASK) |
389 (((u32)(Configure->SrcCache) <<
390 XZDMA_DATA_ATTR_ARCACHE_SHIFT) &
391 XZDMA_DATA_ATTR_ARCACHE_MASK) |
392 (((u32)(Configure->SrcQos) <<
393 XZDMA_DATA_ATTR_ARQOS_SHIFT) &
394 XZDMA_DATA_ATTR_ARQOS_MASK) |
395 (((u32)(Configure->SrcBurstLen) <<
396 XZDMA_DATA_ATTR_ARLEN_SHIFT) &
397 XZDMA_DATA_ATTR_ARLEN_MASK) |
398 (((u32)(Configure->DstBurstType) <<
399 XZDMA_DATA_ATTR_AWBURST_SHIFT) &
400 XZDMA_DATA_ATTR_AWBURST_MASK) |
401 (((u32)(Configure->DstCache) <<
402 XZDMA_DATA_ATTR_AWCACHE_SHIFT) &
403 XZDMA_DATA_ATTR_AWCACHE_MASK) |
404 (((u32)(Configure->DstQos) <<
405 XZDMA_DATA_ATTR_AWQOS_SHIFT) &
406 XZDMA_DATA_ATTR_AWQOS_MASK) |
407 (((u32)(Configure->DstBurstLen)) &
408 XZDMA_DATA_ATTR_AWLEN_MASK));
410 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
411 XZDMA_CH_DATA_ATTR_OFFSET, Data);
412 Status = XST_SUCCESS;
419 /*****************************************************************************/
422 * This function gets the data attributes and control configurations of a
425 * @param InstancePtr is a pointer to the XZDma instance.
426 * @param Configure is a pointer to the XZDma_ChDataConfig structure
427 * which has all the configuration fields.
428 * The fields of the structure are:
429 * - OverFetch - Allows over fetch or not
430 * - 0 - Not allowed to over-fetch on SRC
431 * - 1 - Allowed to over-fetch on SRC
432 * - SrcIssue - Outstanding transaction on SRC
434 * - SrcBurstType - Burst Type for SRC AXI transaction
435 * - XZDMA_FIXED_BURST - Fixed burst
436 * - XZDMA_INCR_BURST - Incremental burst
437 * - SrcBurstLen - AXI Length for Data Read.
438 * - Can be max of 16 to be compatible with AXI3
439 * - DstBurstType - Burst Type for SRC AXI transaction
440 * - XZDMA_FIXED_BURST - Fixed burst
441 * - XZDMA_INCR_BURST - Incremental burst
442 * - DstBurstLen - AXI Length for Data write.
443 * - Can be max of 16 to be compatible with AXI3
444 * - SrcCache - AXI cache bits for Data read
445 * - SrcQos - Configurable QoS bits for AXI Data read
446 * - DstCache - AXI cache bits for Data write
447 * - DstQos - Configurable QoS bits for AXI Data write
453 ******************************************************************************/
454 void XZDma_GetChDataConfig(XZDma *InstancePtr, XZDma_DataConfig *Configure)
457 /* Verify arguments */
458 Xil_AssertVoid(InstancePtr != NULL);
459 Xil_AssertVoid(Configure != NULL);
461 Configure->SrcBurstType = InstancePtr->DataConfig.SrcBurstType;
462 Configure->SrcCache = InstancePtr->DataConfig.SrcCache;
463 Configure->SrcQos = InstancePtr->DataConfig.SrcQos;
464 Configure->SrcBurstLen = InstancePtr->DataConfig.SrcBurstLen;
466 Configure->DstBurstType = InstancePtr->DataConfig.DstBurstType;
467 Configure->DstCache = InstancePtr->DataConfig.DstCache;
468 Configure->DstQos = InstancePtr->DataConfig.DstQos;
469 Configure->DstBurstLen = InstancePtr->DataConfig.DstBurstLen;
471 Configure->OverFetch = InstancePtr->DataConfig.OverFetch;
472 Configure->SrcIssue = InstancePtr->DataConfig.SrcIssue;
476 /*****************************************************************************/
479 * This function sets the descriptor attributes based on the inputs provided
482 * @param InstancePtr is a pointer to the XZDma instance.
483 * @param Configure is a pointer to the XZDma_ChDscrConfig structure
484 * which has all the configuration fields.
485 * The fields of the structure are:
486 * - AxCoherent - AXI transactions generated for the descriptor.
489 * - AXCache - AXI cache bit used for DSCR fetch
490 * (both on SRC and DST Side)
491 * - AXQos - QoS bit used for DSCR fetch
492 * (both on SRC and DST Side)
495 * - XST_FAILURE If ZDMA core is not in Idle state and
496 * - XST_SUCCESS If Configurations are made successfully
500 ******************************************************************************/
501 s32 XZDma_SetChDscrConfig(XZDma *InstancePtr, XZDma_DscrConfig *Configure)
506 /* Verify arguments */
507 Xil_AssertNonvoid(InstancePtr != NULL);
508 Xil_AssertNonvoid(Configure != NULL);
510 if (InstancePtr->ChannelState != XZDMA_IDLE) {
511 Status = XST_FAILURE;
515 InstancePtr->DscrConfig.AXCache = Configure->AXCache;
516 InstancePtr->DscrConfig.AXQos = Configure->AXQos;
517 InstancePtr->DscrConfig.AxCoherent = Configure->AxCoherent;
519 Data = ((((u32)(Configure->AxCoherent) <<
520 XZDMA_DSCR_ATTR_AXCOHRNT_SHIFT) &
521 XZDMA_DSCR_ATTR_AXCOHRNT_MASK) |
522 (((u32)(Configure->AXCache) <<
523 XZDMA_DSCR_ATTR_AXCACHE_SHIFT) &
524 XZDMA_DSCR_ATTR_AXCACHE_MASK) |
525 (((u32)Configure->AXQos) &
526 XZDMA_DSCR_ATTR_AXQOS_MASK));
528 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
529 XZDMA_CH_DSCR_ATTR_OFFSET, Data);
531 Status = XST_SUCCESS;
537 /*****************************************************************************/
540 * This function gets the descriptor attributes of the channel.
542 * @param InstancePtr is a pointer to the XZDma instance.
543 * @param Configure is a pointer to the XZDma_ChDscrConfig structure
544 * which has all the configuration fields.
545 * The fields of the structure are:
546 * - AxCoherent - AXI transactions generated for the descriptor.
549 * - AXCache - AXI cache bit used for DSCR fetch
550 * (both on SRC and DST Side)
551 * - AXQos - QoS bit used for DSCR fetch
552 * (both on SRC and DST Side)
558 ******************************************************************************/
559 void XZDma_GetChDscrConfig(XZDma *InstancePtr, XZDma_DscrConfig *Configure)
562 /* Verify arguments */
563 Xil_AssertVoid(InstancePtr != NULL);
564 Xil_AssertVoid(Configure != NULL);
566 Configure->AXCache = InstancePtr->DscrConfig.AXCache;
567 Configure->AXQos = InstancePtr->DscrConfig.AXQos;
568 Configure->AxCoherent = InstancePtr->DscrConfig.AxCoherent;
572 /*****************************************************************************/
575 * This function preloads the buffers which will be used in write only mode.
576 * In write only mode the data in the provided buffer will be written in
577 * destination address for specified size.
579 * @param InstancePtr is a pointer to the XZDma instance.
580 * @param Buffer is a pointer to an array of 64/128 bit data.
581 * i.e. pointer to 32 bit array of size 2/4
582 * - Array of Size 2 for ADMA
583 * - Array of Size 4 for GDMA
587 * @note Valid only in simple mode.
588 * Prior to call this function ZDMA instance should be set in
589 * Write only mode by using
590 * XZDma_SetMode(XZDma *InstancePtr, u8 IsSgDma,
592 * To initiate data transfer after this API need to call
593 * XZDma_Start(XZDma *InstancePtr, XZDma_Transfer *Data, u32 Num)
594 * In which only destination fields has to be filled.
596 ******************************************************************************/
597 void XZDma_WOData(XZDma *InstancePtr, u32 *Buffer)
599 u32 *LocBuf = Buffer;
601 /* Verify arguments */
602 Xil_AssertVoid(InstancePtr != NULL);
603 Xil_AssertVoid(Buffer != NULL);
605 if (InstancePtr->Config.DmaType == (u8)0) {
606 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
607 XZDMA_CH_WR_ONLY_WORD0_OFFSET, *LocBuf);
609 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
610 XZDMA_CH_WR_ONLY_WORD1_OFFSET, *LocBuf);
612 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
613 XZDMA_CH_WR_ONLY_WORD2_OFFSET, *LocBuf);
615 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
616 XZDMA_CH_WR_ONLY_WORD3_OFFSET, *LocBuf);
620 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
621 XZDMA_CH_WR_ONLY_WORD0_OFFSET, *LocBuf);
623 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
624 XZDMA_CH_WR_ONLY_WORD1_OFFSET, *LocBuf);
629 /*****************************************************************************/
632 * This function resume the paused state of ZDMA core and starts the transfer
633 * from where it has paused.
635 * @param InstancePtr is a pointer to the XZDma instance.
639 * @note Valid only for scatter gather mode.
641 ******************************************************************************/
642 void XZDma_Resume(XZDma *InstancePtr)
646 /* Verify arguments */
647 Xil_AssertVoid(InstancePtr != NULL);
648 Xil_AssertVoid(InstancePtr->IsSgDma == TRUE);
649 Xil_AssertVoid(InstancePtr->ChannelState == XZDMA_PAUSE);
651 Value = XZDma_ReadReg(InstancePtr->Config.BaseAddress,
652 XZDMA_CH_CTRL0_OFFSET) & (~XZDMA_CTRL0_CONT_ADDR_MASK);
653 Value |= XZDMA_CTRL0_CONT_MASK;
654 InstancePtr->ChannelState = XZDMA_BUSY;
655 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
656 XZDMA_CH_CTRL0_OFFSET, Value);
659 /*****************************************************************************/
662 * This function resets the ZDMA core.
664 * @param InstancePtr is a pointer to the XZDma instance.
668 * @note This function resets all the configurations made previously.
669 * Disables all the interrupts and clears interrupt status.
671 *****************************************************************************/
672 void XZDma_Reset(XZDma *InstancePtr)
675 /* Verify arguments */
676 Xil_AssertVoid(InstancePtr != NULL);
677 Xil_AssertVoid(InstancePtr->ChannelState == XZDMA_IDLE);
679 /* Disable's the channel */
680 XZDma_DisableCh(InstancePtr);
682 /* Disables all interrupts */
683 XZDma_DisableIntr(InstancePtr, XZDMA_IXR_ALL_INTR_MASK);
684 XZDma_IntrClear(InstancePtr, XZDMA_IXR_ALL_INTR_MASK);
685 InstancePtr->IntrMask = 0x00U;
687 /* All configurations are being reset */
688 XZDma_WriteReg(InstancePtr->Config.BaseAddress, XZDMA_CH_CTRL0_OFFSET,
689 XZDMA_CTRL0_RESET_VALUE);
690 XZDma_WriteReg(InstancePtr->Config.BaseAddress, XZDMA_CH_CTRL1_OFFSET,
691 XZDMA_CTRL1_RESET_VALUE);
692 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
693 XZDMA_CH_DATA_ATTR_OFFSET, XZDMA_DATA_ATTR_RESET_VALUE);
694 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
695 XZDMA_CH_DSCR_ATTR_OFFSET, XZDMA_DSCR_ATTR_RESET_VALUE);
697 /* Clears total byte */
698 XZDma_TotalByteClear(InstancePtr);
700 /* Clears interrupt count of both source and destination channels */
701 (void)XZDma_GetSrcIntrCnt(InstancePtr);
702 (void)XZDma_GetDstIntrCnt(InstancePtr);
704 InstancePtr->ChannelState = XZDMA_IDLE;
708 /*****************************************************************************/
711 * This function returns the state of ZDMA core.
713 * @param InstancePtr is a pointer to the XZDma instance.
715 * @return This function returns state of ZDMA core
716 * - XZDMA_IDLE - If ZDMA core is in idle state.
717 * - XZDMA_PAUSE - If ZDMA is in paused state.
718 * - XZDMA_BUSY - If ZDMA is in busy state.
721 * XZDmaState XZDma_ChannelState(XZDma *InstancePtr)
723 ******************************************************************************/
724 XZDmaState XZDma_ChannelState(XZDma *InstancePtr)
729 /* Verify arguments */
730 Xil_AssertNonvoid(InstancePtr != NULL);
732 Value = XZDma_ReadReg(InstancePtr->Config.BaseAddress,
733 (XZDMA_CH_STS_OFFSET)) & (XZDMA_STS_ALL_MASK);
735 if ((Value == XZDMA_STS_DONE_MASK) ||
736 (Value == XZDMA_STS_DONE_ERR_MASK)) {
739 else if (Value == XZDMA_STS_PAUSE_MASK) {
740 Status = XZDMA_PAUSE;
750 /*****************************************************************************/
753 * This function sets all the required fields for initiating data transfer. Data
754 * transfer elements needs to be passed through structure pointer.
755 * Data transfer can be done in any of the three modes (simple, Linear or Linked
756 * List) based on the selected mode but before calling this API make sure that
757 * ZDMA is in Idle state.
759 * @param InstancePtr is a pointer to the XZDma instance.
760 * @param Data is a pointer of array to the XZDma_Transfer structure which
761 * has all the configuration fields for initiating data transfer.
762 * The fields of the structure are:
763 * - SrcAddr - Source address
764 * - DstAddr - Destination address
765 * - Size - size of the data to be transferred in bytes
766 * - SrcCoherent - AXI transactions generated to process the
767 * descriptor payload for source channel
770 * - DstCoherent - AXI transactions generated to process the
771 * descriptor payload for destination channel
774 * - Pause - Valid only for scatter gather mode.
775 * Will pause after completion of this descriptor.
776 * @param Num specifies number of array elements of Data pointer.
777 * - For simple mode Num should be equal to 1
778 * - For Scatter gather mode (either linear or linked list) Num
779 * can be any choice. (But based on which memory should be
780 * allocated by Application) It should be less than the return
781 * value of XZDma_CreateBDList.
784 * - XST_SUCCESS - if ZDMA initiated the transfer.
785 * - XST_FAILURE - if ZDMA has not initiated data transfer.
787 * @note After Pause to resume the transfer need to use the following
790 * User should provide allocated memory and descriptor type in
791 * scatter gather mode through the following API before calling
793 * - XZDma_SetDescriptorType(XZDma *InstancePtr,
794 * XZDma_DscrType TypeOfDscr, UINTPTR Dscr_MemPtr,
797 ******************************************************************************/
798 s32 XZDma_Start(XZDma *InstancePtr, XZDma_Transfer *Data, u32 Num)
802 /* Verify arguments */
803 Xil_AssertNonvoid(InstancePtr != NULL);
804 Xil_AssertNonvoid(Data != NULL);
805 Xil_AssertNonvoid(Num != 0x00U);
807 if ((InstancePtr->ChannelState == XZDMA_BUSY) &&
808 (Num >= InstancePtr->Descriptor.DscrCount)) {
809 Status = XST_FAILURE;
812 if (InstancePtr->IsSgDma != TRUE) {
813 XZDma_SimpleMode(InstancePtr, Data);
814 Status = XST_SUCCESS;
818 XZDma_ScatterGather(InstancePtr, Data, Num);
819 Status = XST_SUCCESS;
822 XZDma_Enable(InstancePtr);
828 /*****************************************************************************/
831 * This static function sets all the required fields for initiating data
832 * transfer in simple mode.
834 * @param InstancePtr is a pointer to the XZDma instance.
835 * @param Data is a pointer of array to the XZDma_Transfer structure
836 * which has all the configuration fields for initiating data
843 ******************************************************************************/
844 static void XZDma_SimpleMode(XZDma *InstancePtr, XZDma_Transfer *Data)
849 /* Verify arguments */
850 Xil_AssertVoid(InstancePtr != NULL);
851 Xil_AssertVoid(Data != NULL);
853 XZDma_WriteReg((InstancePtr->Config.BaseAddress),
854 XZDMA_CH_SRC_DSCR_WORD0_OFFSET,
855 (Data->SrcAddr & XZDMA_WORD0_LSB_MASK));
856 XZDma_WriteReg((InstancePtr->Config.BaseAddress),
857 XZDMA_CH_SRC_DSCR_WORD1_OFFSET,
858 (((u64)Data->SrcAddr >> XZDMA_WORD1_MSB_SHIFT) &
859 XZDMA_WORD1_MSB_MASK));
861 XZDma_WriteReg((InstancePtr->Config.BaseAddress),
862 XZDMA_CH_DST_DSCR_WORD0_OFFSET,
863 (Data->DstAddr & XZDMA_WORD0_LSB_MASK));
864 XZDma_WriteReg((InstancePtr->Config.BaseAddress),
865 XZDMA_CH_DST_DSCR_WORD1_OFFSET,
866 (((u64)Data->DstAddr >> XZDMA_WORD1_MSB_SHIFT) &
867 XZDMA_WORD1_MSB_MASK));
869 XZDma_WriteReg((InstancePtr->Config.BaseAddress),
870 XZDMA_CH_SRC_DSCR_WORD2_OFFSET,
871 (Data->Size & XZDMA_WORD2_SIZE_MASK));
872 XZDma_WriteReg((InstancePtr->Config.BaseAddress),
873 XZDMA_CH_DST_DSCR_WORD2_OFFSET,
874 (Data->Size & XZDMA_WORD2_SIZE_MASK));
876 Value = (u32)(Data->SrcCoherent & XZDMA_WORD3_COHRNT_MASK);
877 XZDma_WriteReg((InstancePtr->Config.BaseAddress),
878 XZDMA_CH_SRC_DSCR_WORD3_OFFSET, Value);
880 Value = (u32)(Data->DstCoherent & XZDMA_WORD3_COHRNT_MASK);
881 XZDma_WriteReg((InstancePtr->Config.BaseAddress),
882 XZDMA_CH_DST_DSCR_WORD3_OFFSET, Value);
886 /*****************************************************************************/
889 * This static function sets all the required fields for initiating data
890 * transfer in scatter gather mode.
892 * @param InstancePtr is a pointer to the XZDma instance.
893 * @param Data is a pointer of array to the XZDma_Transfer structure
894 * which has all the configuration fields for initiating data
896 * @param Num specifies number of array elements of Data pointer.
902 ******************************************************************************/
903 static void XZDma_ScatterGather(XZDma *InstancePtr, XZDma_Transfer *Data,
908 XZDma_Transfer *LocalData = Data;
909 XZDma_LiDscr *LiSrcDscr =
910 (XZDma_LiDscr *)(void *)(InstancePtr->Descriptor.SrcDscrPtr);
911 XZDma_LiDscr *LiDstDscr =
912 (XZDma_LiDscr *)(void *)(InstancePtr->Descriptor.DstDscrPtr);
913 XZDma_LlDscr *LlSrcDscr =
914 (XZDma_LlDscr *)(void *)(InstancePtr->Descriptor.SrcDscrPtr);
915 XZDma_LlDscr *LlDstDscr =
916 (XZDma_LlDscr *)(void *)(InstancePtr->Descriptor.DstDscrPtr);
918 /* Verify arguments */
919 Xil_AssertVoid(InstancePtr != NULL);
920 Xil_AssertVoid(Data != NULL);
921 Xil_AssertVoid(Num != 0x00U);
923 if (InstancePtr->Descriptor.DscrType == XZDMA_LINEAR) {
926 if (Count == (Num- 1)) {
929 XZDma_LinearMode(InstancePtr, LocalData, LiSrcDscr,
935 } while(Count < Num);
940 if (Count == (Num - 1)) {
943 XZDma_LinkedListMode(InstancePtr, LocalData, LlSrcDscr,
949 } while(Count < Num);
952 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
953 XZDMA_CH_SRC_START_LSB_OFFSET,
954 ((UINTPTR)(InstancePtr->Descriptor.SrcDscrPtr) &
955 XZDMA_WORD0_LSB_MASK));
956 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
957 XZDMA_CH_SRC_START_MSB_OFFSET,
958 (((u64)(UINTPTR)(InstancePtr->Descriptor.SrcDscrPtr) >>
959 XZDMA_WORD1_MSB_SHIFT) & XZDMA_WORD1_MSB_MASK));
960 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
961 XZDMA_CH_DST_START_LSB_OFFSET,
962 ((UINTPTR)(InstancePtr->Descriptor.DstDscrPtr) &
963 XZDMA_WORD0_LSB_MASK));
964 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
965 XZDMA_CH_DST_START_MSB_OFFSET,
966 (((u64)(UINTPTR)(InstancePtr->Descriptor.DstDscrPtr) >>
967 XZDMA_WORD1_MSB_SHIFT) & XZDMA_WORD1_MSB_MASK));
970 /*****************************************************************************/
973 * This static function sets all the required fields for initiating data
974 * transfer in Linear descriptor type.
976 * @param InstancePtr is a pointer to the XZDma instance.
977 * @param Data is a pointer of array to the XZDma_Transfer structure which
978 * has all the configuration fields for initiating data transfer.
979 * @param SrcDscrPtr is descriptor pointer of source in which Data fields
981 * @param DstDscrPtr is descriptor pointer of destination in which Data
982 * fields has to be filled.
983 * @param IsLast specifies whether provided descriptor pointer is last
985 * - XZDMA_TRUE - If descriptor is last
986 * - XZDMA_FALSE - If descriptor is not last
992 ******************************************************************************/
993 static void XZDma_LinearMode(XZDma *InstancePtr, XZDma_Transfer *Data,
994 XZDma_LiDscr *SrcDscrPtr, XZDma_LiDscr *DstDscrPtr, u8 IsLast)
998 /* Verify arguments */
999 Xil_AssertVoid(InstancePtr != NULL);
1000 Xil_AssertVoid(Data != NULL);
1001 Xil_AssertVoid(SrcDscrPtr != NULL);
1002 Xil_AssertVoid(DstDscrPtr != NULL);
1003 Xil_AssertVoid((IsLast == TRUE) || (IsLast == FALSE));
1005 if (Data->Pause == TRUE) {
1006 Value = XZDMA_WORD3_CMD_PAUSE_MASK;
1008 else if (IsLast == TRUE) {
1009 Value = XZDMA_WORD3_CMD_STOP_MASK;
1012 Value = XZDMA_WORD3_CMD_NXTVALID_MASK;
1014 if (Data->SrcCoherent == TRUE) {
1015 Value |= XZDMA_WORD3_COHRNT_MASK;
1018 XZDma_ConfigLinear(SrcDscrPtr, (u64)Data->SrcAddr, Data->Size, Value);
1022 if (Data->DstCoherent == TRUE) {
1023 Value |= XZDMA_WORD3_COHRNT_MASK;
1026 XZDma_ConfigLinear(DstDscrPtr, (u64)Data->DstAddr, Data->Size, Value);
1030 /*****************************************************************************/
1033 * This static function sets all the required fields for initiating data
1034 * transfer in Linear descriptor type.
1036 * @param DscrPtr is a pointer to source/destination descriptor.
1037 * @param Addr is a 64 bit variable which denotes the address of data.
1038 * @param Size specifies the amount of the data to be transferred.
1039 * @param CtrlValue contains all the control fields of descriptor.
1045 ******************************************************************************/
1046 static void XZDma_ConfigLinear(XZDma_LiDscr *DscrPtr, u64 Addr, u32 Size,
1049 /* Verify arguments */
1050 Xil_AssertVoid(DscrPtr != NULL);
1051 Xil_AssertVoid(Addr != 0x00U);
1053 DscrPtr->Address = Addr;
1054 DscrPtr->Size = Size & XZDMA_WORD2_SIZE_MASK;
1055 DscrPtr->Cntl = CtrlValue;
1057 Xil_DCacheFlushRange((UINTPTR)DscrPtr, sizeof(XZDma_LlDscr));
1061 /*****************************************************************************/
1064 * This static function sets all the required fields for initiating data
1065 * transfer in Linked list descriptor type.
1067 * @param InstancePtr is a pointer to the XZDma instance.
1068 * @param Data is a pointer of array to the XZDma_Transfer structure which
1069 * has all the configuration fields for initiating data transfer.
1070 * @param SrcDscrPtr is descriptor pointer of source in which Data fields
1072 * @param DstDscrPtr is descriptor pointer of destination in which Data
1073 * fields has to be filled.
1074 * @param IsLast specifies whether provided descriptor pointer is last
1076 * - TRUE - If descriptor is last
1077 * - FALSE - If descriptor is not last
1083 ******************************************************************************/
1084 static void XZDma_LinkedListMode(XZDma *InstancePtr, XZDma_Transfer *Data,
1085 XZDma_LlDscr *SrcDscrPtr,XZDma_LlDscr *DstDscrPtr, u8 IsLast)
1088 XZDma_LlDscr *NextSrc = SrcDscrPtr;
1089 XZDma_LlDscr *NextDst = DstDscrPtr;
1090 u64 NextSrcAdrs = 0x00U;
1091 u64 NextDstAdrs = 0x00U;
1093 /* Verify arguments */
1094 Xil_AssertVoid(InstancePtr != NULL);
1095 Xil_AssertVoid(Data != NULL);
1096 Xil_AssertVoid(SrcDscrPtr != NULL);
1097 Xil_AssertVoid(DstDscrPtr != NULL);
1098 Xil_AssertVoid((IsLast == TRUE) || (IsLast == FALSE));
1103 if (Data->Pause == TRUE) {
1104 Value = XZDMA_WORD3_CMD_PAUSE_MASK;
1105 if (IsLast != TRUE) {
1106 NextSrcAdrs = (u64)(UINTPTR)NextSrc;
1107 NextDstAdrs = (u64)(UINTPTR)NextDst;
1110 else if (IsLast == TRUE) {
1111 Value = XZDMA_WORD3_CMD_STOP_MASK;
1114 Value = XZDMA_WORD3_CMD_NXTVALID_MASK;
1115 NextSrcAdrs = (u64)(UINTPTR)NextSrc;
1116 NextDstAdrs = (u64)(UINTPTR)NextDst;
1118 if (Data->SrcCoherent == TRUE) {
1119 Value |= XZDMA_WORD3_COHRNT_MASK;
1122 XZDma_ConfigLinkedList(SrcDscrPtr, (u64)Data->SrcAddr,
1123 Data->Size, Value, NextSrcAdrs);
1127 if (Data->DstCoherent == TRUE) {
1128 Value |= XZDMA_WORD3_COHRNT_MASK;
1131 XZDma_ConfigLinkedList(DstDscrPtr, (u64)Data->DstAddr,
1132 Data->Size, Value, NextDstAdrs);
1136 /*****************************************************************************/
1139 * This static function sets all the required fields for initiating data
1140 * transfer in Linked list descriptor type.
1142 * @param DscrPtr is a pointer to source/destination descriptor.
1143 * @param Addr is a 64 bit variable which denotes the address of data.
1144 * @param Size specifies the amount of the data to be transferred.
1145 * @param CtrlValue contains all the control fields of descriptor.
1146 * @param NextDscrAddr is the address of next descriptor.
1152 ******************************************************************************/
1153 static void XZDma_ConfigLinkedList(XZDma_LlDscr *DscrPtr, u64 Addr, u32 Size,
1154 u32 CtrlValue, u64 NextDscrAddr)
1156 /* Verify arguments */
1157 Xil_AssertVoid(DscrPtr != NULL);
1158 Xil_AssertVoid(Addr != 0x00U);
1160 DscrPtr->Address = Addr;
1161 DscrPtr->Size = Size & XZDMA_WORD2_SIZE_MASK;
1162 DscrPtr->Cntl = CtrlValue;
1163 DscrPtr->NextDscr = NextDscrAddr;
1164 DscrPtr->Reserved = 0U;
1166 Xil_DCacheFlushRange((UINTPTR)DscrPtr, sizeof(XZDma_LlDscr));
1169 /*****************************************************************************/
1171 * This static function enable's all the interrupts which user intended to
1172 * enable and enables the ZDMA channel for initiating data transfer.
1174 * @param InstancePtr is a pointer to the XZDma instance.
1179 ******************************************************************************/
1181 static void XZDma_Enable(XZDma *InstancePtr)
1183 /* Verify arguments */
1184 Xil_AssertVoid(InstancePtr != NULL);
1186 XZDma_WriteReg(InstancePtr->Config.BaseAddress, XZDMA_CH_IEN_OFFSET,
1187 (InstancePtr->IntrMask & XZDMA_IXR_ALL_INTR_MASK));
1188 InstancePtr->ChannelState = XZDMA_BUSY;
1189 XZDma_EnableCh(InstancePtr);
1193 /*****************************************************************************/
1195 * This static function gets all the reset configurations of ZDMA.
1197 * @param InstancePtr is a pointer to the XZDma instance.
1203 ******************************************************************************/
1204 static void XZDma_GetConfigurations(XZDma *InstancePtr)
1206 /* Verify arguments */
1207 Xil_AssertVoid(InstancePtr != NULL);
1209 InstancePtr->DataConfig.SrcIssue = (u8)XZDMA_CTRL1_SRC_ISSUE_MASK;
1210 InstancePtr->DataConfig.SrcBurstType = XZDMA_INCR_BURST;
1211 InstancePtr->DataConfig.SrcBurstLen = 0xFU;
1212 InstancePtr->DataConfig.OverFetch = 1U;
1213 InstancePtr->DataConfig.DstBurstType = XZDMA_INCR_BURST;
1214 InstancePtr->DataConfig.DstBurstLen = 0xFU;
1215 InstancePtr->DataConfig.SrcCache = 0x2U;
1216 InstancePtr->DataConfig.DstCache = 0x2U;
1217 InstancePtr->DataConfig.SrcQos = 0x0U;
1218 InstancePtr->DataConfig.DstQos = 0x0U;
1220 InstancePtr->DscrConfig.AXCache = 0U;
1221 InstancePtr->DscrConfig.AXQos = 0U;
1222 InstancePtr->DscrConfig.AxCoherent = 0U;
1225 /*****************************************************************************/
1228 * This routine is a stub for the asynchronous callbacks. The stub is here in
1229 * case the upper layer forgot to set the handlers. On initialization, All
1230 * handlers are set to this callback. It is considered an error for this
1231 * handler to be invoked.
1233 * @param CallBackRef is a callback reference passed in by the upper
1234 * layer when setting the callback functions, and passed back to
1235 * the upper layer when the callback is invoked.
1236 * @param Mask is the type of the interrupts to enable. Use OR'ing of
1237 * XZDMA_IXR_DMA_*_MASK constants defined in xzdma_hw.h to create
1238 * this parameter value.
1244 ******************************************************************************/
1245 static void StubCallBack(void *CallBackRef, u32 Mask)
1247 /* Verify arguments. */
1248 Xil_AssertVoid(CallBackRef != NULL);
1249 Xil_AssertVoid(Mask != (u32)0x00);
1250 Xil_AssertVoidAlways();
1253 /*****************************************************************************/
1256 * This routine is a stub for the DMA done callback. The stub is here in
1257 * case the upper layer forgot to set the handlers. On initialization, Done
1258 * handler are set to this callback.
1260 * @param CallBackRef is a callback reference passed in by the upper
1261 * layer when setting the callback functions, and passed back to
1262 * the upper layer when the callback is invoked.
1268 ******************************************************************************/
1269 static void StubDoneCallBack(void *CallBackRef)
1271 /* Verify arguments. */
1272 Xil_AssertVoid(CallBackRef != NULL);
1273 Xil_AssertVoidAlways();