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 /*****************************************************************************/
37 * This file contains the implementation of the interface functions for ZDMA
38 * driver. Refer to the header file xzdma.h for more detailed information.
41 * MODIFICATION HISTORY:
43 * Ver Who Date Changes
44 * ----- ------ -------- ------------------------------------------------------
45 * 1.0 vns 2/27/15 First release
48 ******************************************************************************/
50 /***************************** Include Files *********************************/
54 /************************** Function Prototypes ******************************/
56 static void StubCallBack(void *CallBackRef, u32 Mask);
57 static void StubDoneCallBack(void *CallBackRef);
58 static void XZDma_SimpleMode(XZDma *InstancePtr, XZDma_Transfer *Data);
59 static void XZDma_ScatterGather(XZDma *InstancePtr, XZDma_Transfer *Data,
61 static void XZDma_LinearMode(XZDma *InstancePtr, XZDma_Transfer *Data,
62 XZDma_LiDscr *SrcDscrPtr,XZDma_LiDscr *DstDscrPtr, u8 IsLast);
63 static void XZDma_ConfigLinear(XZDma_LiDscr *DscrPtr, u64 Addr, u32 Size,
65 static void XZDma_LinkedListMode(XZDma *InstancePtr, XZDma_Transfer *Data,
66 XZDma_LlDscr *SrcDscrPtr,XZDma_LlDscr *DstDscrPtr, u8 IsLast);
67 static void XZDma_ConfigLinkedList(XZDma_LlDscr *DscrPtr, u64 Addr, u32 Size,
68 u32 CtrlValue, u64 NextDscrAddr);
69 static void XZDma_Enable(XZDma *InstancePtr);
70 static void XZDma_GetConfigurations(XZDma *InstancePtr);
72 /************************** Function Definitions *****************************/
74 /*****************************************************************************/
77 * This function initializes an ZDMA core. This function must be called
78 * prior to using an ZDMA core. Initialization of an ZDMA includes setting
79 * up the instance data and ensuring the hardware is in a quiescent state and
80 * resets all the hardware configurations.
82 * @param InstancePtr is a pointer to the XZDma instance.
83 * @param CfgPtr is a reference to a structure containing information
84 * about a specific XZDma instance.
85 * @param EffectiveAddr is the device base address in the virtual memory
86 * address space. The caller is responsible for keeping the
87 * address mapping from EffectiveAddr to the device physical
88 * base address unchanged once this function is invoked.
89 * Unexpected errors may occur if the address mapping changes
90 * after this function is called. If address translation is not
91 * used, pass in the physical address instead.
94 * - XST_SUCCESS if initialization was successful.
98 ******************************************************************************/
99 s32 XZDma_CfgInitialize(XZDma *InstancePtr, XZDma_Config *CfgPtr,
103 /* Verify arguments. */
104 Xil_AssertNonvoid(InstancePtr != NULL);
105 Xil_AssertNonvoid(CfgPtr != NULL);
106 Xil_AssertNonvoid(EffectiveAddr != ((u32)0x00));
108 InstancePtr->Config.BaseAddress = CfgPtr->BaseAddress;
109 InstancePtr->Config.DeviceId = CfgPtr->DeviceId;
110 InstancePtr->Config.DmaType = CfgPtr->DmaType;
112 InstancePtr->Config.BaseAddress = EffectiveAddr;
114 InstancePtr->IsReady = (u32)(XIL_COMPONENT_IS_READY);
116 InstancePtr->IsSgDma = FALSE;
117 InstancePtr->Mode = XZDMA_NORMAL_MODE;
118 InstancePtr->IntrMask = 0x00U;
119 InstancePtr->ChannelState = XZDMA_IDLE;
122 * Set all handlers to stub values, let user configure this
125 InstancePtr->DoneHandler =
126 (XZDma_DoneHandler)((void *)StubDoneCallBack);
127 InstancePtr->ErrorHandler =
128 (XZDma_ErrorHandler)((void *)StubCallBack);
130 XZDma_Reset(InstancePtr);
131 XZDma_GetConfigurations(InstancePtr);
133 return (XST_SUCCESS);
137 /*****************************************************************************/
140 * This function sets the pointer type and mode in which ZDMA needs to transfer
143 * @param InstancePtr is a pointer to the XZDma instance.
144 * @param IsSgDma is a variable which specifies whether transfer has to
145 * to be done in scatter gather mode or simple mode.
146 * - TRUE - Scatter gather pointer type
147 * - FALSE - Simple pointer type
148 * @param Mode is the type of the mode in which data has to be initiated
149 * - XZDMA_NORMAL_MODE - Normal data transfer from source to
150 * destination (Valid for both Scatter
151 * gather and simple types)
152 * - XZDMA_WRONLY_MODE - Write only mode (Valid only for Simple)
153 * - XZDMA_RDONLY_MODE - Read only mode (Valid only for Simple)
156 * - XST_SUCCESS - If mode has been set successfully.
157 * - XST_FAILURE - If mode has not been set.
159 * @note Mode cannot be changed while ZDMA is not in IDLE state.
161 ******************************************************************************/
162 s32 XZDma_SetMode(XZDma *InstancePtr, u8 IsSgDma, XZDma_Mode Mode)
167 /* Verify arguments. */
168 Xil_AssertNonvoid(InstancePtr != NULL);
169 Xil_AssertNonvoid((IsSgDma == TRUE) || (IsSgDma == FALSE));
170 Xil_AssertNonvoid(Mode <= XZDMA_RDONLY_MODE);
172 if (InstancePtr->ChannelState != XZDMA_IDLE) {
173 Status = XST_FAILURE;
176 Data = XZDma_ReadReg(InstancePtr->Config.BaseAddress,
177 XZDMA_CH_CTRL0_OFFSET);
179 if (IsSgDma != TRUE) {
180 Data = (Data & (~XZDMA_CTRL0_POINT_TYPE_MASK));
181 if (Mode == XZDMA_NORMAL_MODE) {
182 Data &= (~XZDMA_CTRL0_MODE_MASK);
184 else if (Mode == XZDMA_WRONLY_MODE) {
185 Data |= XZDMA_CTRL0_WRONLY_MASK;
188 Data |= XZDMA_CTRL0_RDONLY_MASK;
190 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
191 XZDMA_CH_CTRL0_OFFSET, Data);
192 InstancePtr->IsSgDma = FALSE;
193 InstancePtr->Mode = Mode;
197 if (Mode != XZDMA_NORMAL_MODE) {
198 Status = XST_FAILURE;
201 Data |= (XZDMA_CTRL0_POINT_TYPE_MASK);
202 Data &= ~(XZDMA_CTRL0_MODE_MASK);
203 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
204 XZDMA_CH_CTRL0_OFFSET, Data);
206 InstancePtr->IsSgDma = TRUE;
207 InstancePtr->Mode = Mode;
210 Status = XST_SUCCESS;
217 /*****************************************************************************/
220 * This function sets the descriptor type and descriptor pointer's start address
221 * of both source and destination based on the memory allocated by user and also
222 * calculates no of descriptors(BDs) can be created in the allocated memory.
224 * @param InstancePtr is a pointer to the XZDma instance.
225 * @param TypeOfDscr is a variable which specifies descriptor type
226 * whether Linear or linked list type of descriptor.
227 * - XZDMA_LINEAR - Linear type of descriptor.
228 * - XZDMA_LINKEDLIST- Linked list type of descriptor.
229 * @param Dscr_MemPtr is a pointer to the allocated memory for creating
230 * descriptors. It Should be aligned to 64 bytes.
232 * @param NoOfBytes specifies the number of bytes allocated for
235 * @return The Count of the descriptors can be created.
237 * @note User should allocate the memory for descriptors which should
238 * be capable of how many transfers he wish to do in one start.
239 * For Linear mode each descriptor needs 128 bit memory so for
240 * one data transfer it requires 2*128 = 256 bits i.e. 32 bytes
241 * Similarly for Linked list mode for each descriptor it needs
242 * 256 bit, so for one data transfer it require 2*256 = 512 bits
245 ******************************************************************************/
246 u32 XZDma_CreateBDList(XZDma *InstancePtr, XZDma_DscrType TypeOfDscr,
247 UINTPTR Dscr_MemPtr, u32 NoOfBytes)
249 XZDma_LiDscr *LocalLinearPtr = (XZDma_LiDscr *)(void *)Dscr_MemPtr;
250 XZDma_LlDscr *LocalLinklistPtr = (XZDma_LlDscr *)(void *)Dscr_MemPtr;
252 /* Verify arguments. */
253 Xil_AssertNonvoid(InstancePtr != NULL);
254 Xil_AssertNonvoid((TypeOfDscr == XZDMA_LINEAR) ||
255 (TypeOfDscr == XZDMA_LINKEDLIST));
256 Xil_AssertNonvoid(Dscr_MemPtr != 0x00);
257 Xil_AssertNonvoid(NoOfBytes != 0x00U);
259 InstancePtr->Descriptor.DscrType = TypeOfDscr;
261 if (TypeOfDscr == XZDMA_LINEAR) {
262 InstancePtr->Descriptor.SrcDscrPtr = (void *)Dscr_MemPtr;
263 LocalLinearPtr = ((LocalLinearPtr + (NoOfBytes >> 1)) + 1U);
264 InstancePtr->Descriptor.DstDscrPtr = (void *)LocalLinearPtr;
265 InstancePtr->Descriptor.DscrCount =
266 (NoOfBytes >> 1) / sizeof(XZDma_LiDscr);
269 InstancePtr->Descriptor.SrcDscrPtr = (void *)Dscr_MemPtr;
271 ((LocalLinklistPtr + (NoOfBytes >> 1)) + 1U);
272 InstancePtr->Descriptor.DstDscrPtr = (void *)LocalLinklistPtr;
273 InstancePtr->Descriptor.DscrCount =
274 (NoOfBytes >> 1) / sizeof(XZDma_LlDscr);
277 Xil_DCacheInvalidateRange((INTPTR)Dscr_MemPtr, NoOfBytes);
279 return (InstancePtr->Descriptor.DscrCount);
282 /*****************************************************************************/
285 * This function sets the data attributes and control configurations of a
286 * ZDMA core based on the inputs provided.
288 * @param InstancePtr is a pointer to the XZDma instance.
289 * @param Configure is a pointer to the XZDma_ChDataConfig structure
290 * which has all the configuration fields.
291 * The fields of the structure are:
292 * - OverFetch - Allows over fetch or not
293 * - 0 - Not allowed to over-fetch on SRC
294 * - 1 - Allowed to over-fetch on SRC
295 * - SrcIssue - Outstanding transaction on SRC
297 * - SrcBurstType - Burst Type for SRC AXI transaction
298 * - XZDMA_FIXED_BURST - Fixed burst
299 * - XZDMA_INCR_BURST - Incremental burst
300 * - SrcBurstLen - AXI Length for Data Read.
301 * - Range of values is (1,2,4,8,16).
302 * - DstBurstType - Burst Type for SRC AXI transaction
303 * - XZDMA_FIXED_BURST - Fixed burst
304 * - XZDMA_INCR_BURST - Incremental burst
305 * - DstBurstLen - AXI Length for Data write.
306 * - Range of values is (1,2,4,8,16).
307 * - SrcCache - AXI cache bits for Data read
308 * - SrcQos - Configurable QoS bits for AXI Data read
309 * - DstCache - AXI cache bits for Data write
310 * - DstQos - configurable QoS bits for AXI Data write
313 * - XST_FAILURE If ZDMA Core is not in Idle state and
314 * - XST_SUCCESS If Configurations are made successfully
317 * - These configurations will last till we modify or Reset
318 * by XZDma_Reset(XZDma *InstancePtr).
319 * - Configurations should be modified only when ZDMA channel
320 * is IDLE this can be confirmed by using
321 * XZDma_ChannelState(XZDma *InstancePtr) API.
323 ******************************************************************************/
324 s32 XZDma_SetChDataConfig(XZDma *InstancePtr, XZDma_DataConfig *Configure)
329 /* Verify arguments */
330 Xil_AssertNonvoid(InstancePtr != NULL);
331 Xil_AssertNonvoid(Configure != NULL);
333 if (InstancePtr->ChannelState != XZDMA_IDLE) {
334 Status = XST_FAILURE;
337 InstancePtr->DataConfig.DstBurstType = Configure->DstBurstType;
338 InstancePtr->DataConfig.DstBurstLen = Configure->DstBurstLen;
339 InstancePtr->DataConfig.SrcBurstType = Configure->SrcBurstType;
340 InstancePtr->DataConfig.SrcBurstLen = Configure->SrcBurstLen;
341 InstancePtr->DataConfig.OverFetch = Configure->OverFetch;
342 InstancePtr->DataConfig.SrcIssue = Configure->SrcIssue;
343 InstancePtr->DataConfig.SrcCache = Configure->SrcCache;
344 InstancePtr->DataConfig.SrcQos = Configure->SrcQos;
345 InstancePtr->DataConfig.DstCache = Configure->DstCache;
346 InstancePtr->DataConfig.DstQos = Configure->DstQos;
348 /* Setting over fetch */
349 Data = XZDma_ReadReg(InstancePtr->Config.BaseAddress,
350 XZDMA_CH_CTRL0_OFFSET);
352 Data |= (((u32)(Configure->OverFetch) <<
353 XZDMA_CTRL0_OVR_FETCH_SHIFT) &
354 XZDMA_CTRL0_OVR_FETCH_MASK);
356 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
357 XZDMA_CH_CTRL0_OFFSET, Data);
359 /* Setting source issue */
360 Data = XZDma_ReadReg(InstancePtr->Config.BaseAddress,
361 XZDMA_CH_CTRL1_OFFSET);
362 Data = (u32)(Configure->SrcIssue & XZDMA_CTRL1_SRC_ISSUE_MASK);
364 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
365 XZDMA_CH_CTRL1_OFFSET, Data);
367 /* Setting Burst length and burst type */
368 Data = XZDma_ReadReg(InstancePtr->Config.BaseAddress,
369 XZDMA_CH_DATA_ATTR_OFFSET);
370 Data = (Data & (~(XZDMA_DATA_ATTR_ARBURST_MASK |
371 XZDMA_DATA_ATTR_ARLEN_MASK |
372 XZDMA_DATA_ATTR_AWBURST_MASK |
373 XZDMA_DATA_ATTR_AWLEN_MASK |
374 XZDMA_DATA_ATTR_ARCACHE_MASK |
375 XZDMA_DATA_ATTR_AWCACHE_MASK |
376 XZDMA_DATA_ATTR_AWQOS_MASK |
377 XZDMA_DATA_ATTR_ARQOS_MASK)));
379 Data |= ((((u32)(Configure->SrcBurstType) <<
380 XZDMA_DATA_ATTR_ARBURST_SHIFT) &
381 XZDMA_DATA_ATTR_ARBURST_MASK) |
382 (((u32)(Configure->SrcCache) <<
383 XZDMA_DATA_ATTR_ARCACHE_SHIFT) &
384 XZDMA_DATA_ATTR_ARCACHE_MASK) |
385 (((u32)(Configure->SrcQos) <<
386 XZDMA_DATA_ATTR_ARQOS_SHIFT) &
387 XZDMA_DATA_ATTR_ARQOS_MASK) |
388 (((u32)(Configure->SrcBurstLen) <<
389 XZDMA_DATA_ATTR_ARLEN_SHIFT) &
390 XZDMA_DATA_ATTR_ARLEN_MASK) |
391 (((u32)(Configure->DstBurstType) <<
392 XZDMA_DATA_ATTR_AWBURST_SHIFT) &
393 XZDMA_DATA_ATTR_AWBURST_MASK) |
394 (((u32)(Configure->DstCache) <<
395 XZDMA_DATA_ATTR_AWCACHE_SHIFT) &
396 XZDMA_DATA_ATTR_AWCACHE_MASK) |
397 (((u32)(Configure->DstQos) <<
398 XZDMA_DATA_ATTR_AWQOS_SHIFT) &
399 XZDMA_DATA_ATTR_AWQOS_MASK) |
400 (((u32)(Configure->DstBurstLen)) &
401 XZDMA_DATA_ATTR_AWLEN_MASK));
403 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
404 XZDMA_CH_DATA_ATTR_OFFSET, Data);
405 Status = XST_SUCCESS;
412 /*****************************************************************************/
415 * This function gets the data attributes and control configurations of a
418 * @param InstancePtr is a pointer to the XZDma instance.
419 * @param Configure is a pointer to the XZDma_ChDataConfig structure
420 * which has all the configuration fields.
421 * The fields of the structure are:
422 * - OverFetch - Allows over fetch or not
423 * - 0 - Not allowed to over-fetch on SRC
424 * - 1 - Allowed to over-fetch on SRC
425 * - SrcIssue - Outstanding transaction on SRC
427 * - SrcBurstType - Burst Type for SRC AXI transaction
428 * - XZDMA_FIXED_BURST - Fixed burst
429 * - XZDMA_INCR_BURST - Incremental burst
430 * - SrcBurstLen - AXI Length for Data Read.
431 * - Can be max of 16 to be compatible with AXI3
432 * - DstBurstType - Burst Type for SRC AXI transaction
433 * - XZDMA_FIXED_BURST - Fixed burst
434 * - XZDMA_INCR_BURST - Incremental burst
435 * - DstBurstLen - AXI Length for Data write.
436 * - Can be max of 16 to be compatible with AXI3
437 * - SrcCache - AXI cache bits for Data read
438 * - SrcQos - Configurable QoS bits for AXI Data read
439 * - DstCache - AXI cache bits for Data write
440 * - DstQos - Configurable QoS bits for AXI Data write
446 ******************************************************************************/
447 void XZDma_GetChDataConfig(XZDma *InstancePtr, XZDma_DataConfig *Configure)
450 /* Verify arguments */
451 Xil_AssertVoid(InstancePtr != NULL);
452 Xil_AssertVoid(Configure != NULL);
454 Configure->SrcBurstType = InstancePtr->DataConfig.SrcBurstType;
455 Configure->SrcCache = InstancePtr->DataConfig.SrcCache;
456 Configure->SrcQos = InstancePtr->DataConfig.SrcQos;
457 Configure->SrcBurstLen = InstancePtr->DataConfig.SrcBurstLen;
459 Configure->DstBurstType = InstancePtr->DataConfig.DstBurstType;
460 Configure->DstCache = InstancePtr->DataConfig.DstCache;
461 Configure->DstQos = InstancePtr->DataConfig.DstQos;
462 Configure->DstBurstLen = InstancePtr->DataConfig.DstBurstLen;
464 Configure->OverFetch = InstancePtr->DataConfig.OverFetch;
465 Configure->SrcIssue = InstancePtr->DataConfig.SrcIssue;
469 /*****************************************************************************/
472 * This function sets the descriptor attributes based on the inputs provided
475 * @param InstancePtr is a pointer to the XZDma instance.
476 * @param Configure is a pointer to the XZDma_ChDscrConfig structure
477 * which has all the configuration fields.
478 * The fields of the structure are:
479 * - AxCoherent - AXI transactions generated for the descriptor.
482 * - AXCache - AXI cache bit used for DSCR fetch
483 * (both on SRC and DST Side)
484 * - AXQos - QoS bit used for DSCR fetch
485 * (both on SRC and DST Side)
488 * - XST_FAILURE If ZDMA core is not in Idle state and
489 * - XST_SUCCESS If Configurations are made successfully
493 ******************************************************************************/
494 s32 XZDma_SetChDscrConfig(XZDma *InstancePtr, XZDma_DscrConfig *Configure)
499 /* Verify arguments */
500 Xil_AssertNonvoid(InstancePtr != NULL);
501 Xil_AssertNonvoid(Configure != NULL);
503 if (InstancePtr->ChannelState != XZDMA_IDLE) {
504 Status = XST_FAILURE;
508 InstancePtr->DscrConfig.AXCache = Configure->AXCache;
509 InstancePtr->DscrConfig.AXQos = Configure->AXQos;
510 InstancePtr->DscrConfig.AxCoherent = Configure->AxCoherent;
512 Data = ((((u32)(Configure->AxCoherent) <<
513 XZDMA_DSCR_ATTR_AXCOHRNT_SHIFT) &
514 XZDMA_DSCR_ATTR_AXCOHRNT_MASK) |
515 (((u32)(Configure->AXCache) <<
516 XZDMA_DSCR_ATTR_AXCACHE_SHIFT) &
517 XZDMA_DSCR_ATTR_AXCACHE_MASK) |
518 (((u32)Configure->AXQos) &
519 XZDMA_DSCR_ATTR_AXQOS_MASK));
521 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
522 XZDMA_CH_DSCR_ATTR_OFFSET, Data);
524 Status = XST_SUCCESS;
530 /*****************************************************************************/
533 * This function gets the descriptor attributes of the channel.
535 * @param InstancePtr is a pointer to the XZDma instance.
536 * @param Configure is a pointer to the XZDma_ChDscrConfig structure
537 * which has all the configuration fields.
538 * The fields of the structure are:
539 * - AxCoherent - AXI transactions generated for the descriptor.
542 * - AXCache - AXI cache bit used for DSCR fetch
543 * (both on SRC and DST Side)
544 * - AXQos - QoS bit used for DSCR fetch
545 * (both on SRC and DST Side)
551 ******************************************************************************/
552 void XZDma_GetChDscrConfig(XZDma *InstancePtr, XZDma_DscrConfig *Configure)
555 /* Verify arguments */
556 Xil_AssertVoid(InstancePtr != NULL);
557 Xil_AssertVoid(Configure != NULL);
559 Configure->AXCache = InstancePtr->DscrConfig.AXCache;
560 Configure->AXQos = InstancePtr->DscrConfig.AXQos;
561 Configure->AxCoherent = InstancePtr->DscrConfig.AxCoherent;
565 /*****************************************************************************/
568 * This function preloads the buffers which will be used in write only mode.
569 * In write only mode the data in the provided buffer will be written in
570 * destination address for specified size.
572 * @param InstancePtr is a pointer to the XZDma instance.
573 * @param Buffer is a pointer to an array of 64/128 bit data.
574 * i.e. pointer to 32 bit array of size 2/4
575 * - Array of Size 2 for ADMA
576 * - Array of Size 4 for GDMA
580 * @note Valid only in simple mode.
581 * Prior to call this function ZDMA instance should be set in
582 * Write only mode by using
583 * XZDma_SetMode(XZDma *InstancePtr, u8 IsSgDma,
585 * To initiate data transfer after this API need to call
586 * XZDma_Start(XZDma *InstancePtr, XZDma_Transfer *Data, u32 Num)
587 * In which only destination fields has to be filled.
589 ******************************************************************************/
590 void XZDma_WOData(XZDma *InstancePtr, u32 *Buffer)
592 u32 *LocBuf = Buffer;
594 /* Verify arguments */
595 Xil_AssertVoid(InstancePtr != NULL);
596 Xil_AssertVoid(Buffer != NULL);
598 if (InstancePtr->Config.DmaType == (u8)0) {
599 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
600 XZDMA_CH_WR_ONLY_WORD0_OFFSET, *LocBuf);
602 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
603 XZDMA_CH_WR_ONLY_WORD1_OFFSET, *LocBuf);
605 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
606 XZDMA_CH_WR_ONLY_WORD2_OFFSET, *LocBuf);
608 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
609 XZDMA_CH_WR_ONLY_WORD3_OFFSET, *LocBuf);
613 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
614 XZDMA_CH_WR_ONLY_WORD0_OFFSET, *LocBuf);
616 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
617 XZDMA_CH_WR_ONLY_WORD1_OFFSET, *LocBuf);
622 /*****************************************************************************/
625 * This function resume the paused state of ZDMA core and starts the transfer
626 * from where it has paused.
628 * @param InstancePtr is a pointer to the XZDma instance.
632 * @note Valid only for scatter gather mode.
634 ******************************************************************************/
635 void XZDma_Resume(XZDma *InstancePtr)
639 /* Verify arguments */
640 Xil_AssertVoid(InstancePtr != NULL);
641 Xil_AssertVoid(InstancePtr->IsSgDma == TRUE);
642 Xil_AssertVoid(InstancePtr->ChannelState == XZDMA_PAUSE);
644 Value = XZDma_ReadReg(InstancePtr->Config.BaseAddress,
645 XZDMA_CH_CTRL0_OFFSET) & (~XZDMA_CTRL0_CONT_ADDR_MASK);
646 Value |= XZDMA_CTRL0_CONT_MASK;
647 InstancePtr->ChannelState = XZDMA_BUSY;
648 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
649 XZDMA_CH_CTRL0_OFFSET, Value);
652 /*****************************************************************************/
655 * This function resets the ZDMA core.
657 * @param InstancePtr is a pointer to the XZDma instance.
661 * @note This function resets all the configurations made previously.
662 * Disables all the interrupts and clears interrupt status.
664 *****************************************************************************/
665 void XZDma_Reset(XZDma *InstancePtr)
668 /* Verify arguments */
669 Xil_AssertVoid(InstancePtr != NULL);
670 Xil_AssertVoid(InstancePtr->ChannelState == XZDMA_IDLE);
672 /* Disable's the channel */
673 XZDma_DisableCh(InstancePtr);
675 /* Disables all interrupts */
676 XZDma_DisableIntr(InstancePtr, XZDMA_IXR_ALL_INTR_MASK);
677 XZDma_IntrClear(InstancePtr, XZDMA_IXR_ALL_INTR_MASK);
678 InstancePtr->IntrMask = 0x00U;
680 /* All configurations are being reset */
681 XZDma_WriteReg(InstancePtr->Config.BaseAddress, XZDMA_CH_CTRL0_OFFSET,
682 XZDMA_CTRL0_RESET_VALUE);
683 XZDma_WriteReg(InstancePtr->Config.BaseAddress, XZDMA_CH_CTRL1_OFFSET,
684 XZDMA_CTRL1_RESET_VALUE);
685 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
686 XZDMA_CH_DATA_ATTR_OFFSET, XZDMA_DATA_ATTR_RESET_VALUE);
687 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
688 XZDMA_CH_DSCR_ATTR_OFFSET, XZDMA_DSCR_ATTR_RESET_VALUE);
690 /* Clears total byte */
691 XZDma_TotalByteClear(InstancePtr);
693 /* Clears interrupt count of both source and destination channels */
694 (void)XZDma_GetSrcIntrCnt(InstancePtr);
695 (void)XZDma_GetDstIntrCnt(InstancePtr);
697 InstancePtr->ChannelState = XZDMA_IDLE;
701 /*****************************************************************************/
704 * This function returns the state of ZDMA core.
706 * @param InstancePtr is a pointer to the XZDma instance.
708 * @return This function returns state of ZDMA core
709 * - XZDMA_IDLE - If ZDMA core is in idle state.
710 * - XZDMA_PAUSE - If ZDMA is in paused state.
711 * - XZDMA_BUSY - If ZDMA is in busy state.
714 * XZDmaState XZDma_ChannelState(XZDma *InstancePtr)
716 ******************************************************************************/
717 XZDmaState XZDma_ChannelState(XZDma *InstancePtr)
722 /* Verify arguments */
723 Xil_AssertNonvoid(InstancePtr != NULL);
725 Value = XZDma_ReadReg(InstancePtr->Config.BaseAddress,
726 (XZDMA_CH_STS_OFFSET)) & (XZDMA_STS_ALL_MASK);
728 if ((Value == XZDMA_STS_DONE_MASK) ||
729 (Value == XZDMA_STS_DONE_ERR_MASK)) {
732 else if (Value == XZDMA_STS_PAUSE_MASK) {
733 Status = XZDMA_PAUSE;
743 /*****************************************************************************/
746 * This function sets all the required fields for initiating data transfer. Data
747 * transfer elements needs to be passed through structure pointer.
748 * Data transfer can be done in any of the three modes (simple, Linear or Linked
749 * List) based on the selected mode but before calling this API make sure that
750 * ZDMA is in Idle state.
752 * @param InstancePtr is a pointer to the XZDma instance.
753 * @param Data is a pointer of array to the XZDma_Transfer structure which
754 * has all the configuration fields for initiating data transfer.
755 * The fields of the structure are:
756 * - SrcAddr - Source address
757 * - DstAddr - Destination address
758 * - Size - size of the data to be transferred in bytes
759 * - SrcCoherent - AXI transactions generated to process the
760 * descriptor payload for source channel
763 * - DstCoherent - AXI transactions generated to process the
764 * descriptor payload for destination channel
767 * - Pause - Valid only for scatter gather mode.
768 * Will pause after completion of this descriptor.
769 * @param Num specifies number of array elements of Data pointer.
770 * - For simple mode Num should be equal to 1
771 * - For Scatter gather mode (either linear or linked list) Num
772 * can be any choice. (But based on which memory should be
773 * allocated by Application) It should be less than the return
774 * value of XZDma_CreateBDList.
777 * - XST_SUCCESS - if ZDMA initiated the transfer.
778 * - XST_FAILURE - if ZDMA has not initiated data transfer.
780 * @note After Pause to resume the transfer need to use the following
783 * User should provide allocated memory and descriptor type in
784 * scatter gather mode through the following API before calling
786 * - XZDma_SetDescriptorType(XZDma *InstancePtr,
787 * XZDma_DscrType TypeOfDscr, UINTPTR Dscr_MemPtr,
790 ******************************************************************************/
791 s32 XZDma_Start(XZDma *InstancePtr, XZDma_Transfer *Data, u32 Num)
795 /* Verify arguments */
796 Xil_AssertNonvoid(InstancePtr != NULL);
797 Xil_AssertNonvoid(Data != NULL);
798 Xil_AssertNonvoid(Num != 0x00U);
800 if ((InstancePtr->ChannelState == XZDMA_BUSY) &&
801 (Num >= InstancePtr->Descriptor.DscrCount)) {
802 Status = XST_FAILURE;
805 if (InstancePtr->IsSgDma != TRUE) {
806 XZDma_SimpleMode(InstancePtr, Data);
807 Status = XST_SUCCESS;
811 XZDma_ScatterGather(InstancePtr, Data, Num);
812 Status = XST_SUCCESS;
815 XZDma_Enable(InstancePtr);
821 /*****************************************************************************/
824 * This static function sets all the required fields for initiating data
825 * transfer in simple mode.
827 * @param InstancePtr is a pointer to the XZDma instance.
828 * @param Data is a pointer of array to the XZDma_Transfer structure
829 * which has all the configuration fields for initiating data
836 ******************************************************************************/
837 static void XZDma_SimpleMode(XZDma *InstancePtr, XZDma_Transfer *Data)
842 /* Verify arguments */
843 Xil_AssertVoid(InstancePtr != NULL);
844 Xil_AssertVoid(Data != NULL);
846 XZDma_WriteReg((InstancePtr->Config.BaseAddress),
847 XZDMA_CH_SRC_DSCR_WORD0_OFFSET,
848 (Data->SrcAddr & XZDMA_WORD0_LSB_MASK));
849 XZDma_WriteReg((InstancePtr->Config.BaseAddress),
850 XZDMA_CH_SRC_DSCR_WORD1_OFFSET,
851 (((u64)Data->SrcAddr >> XZDMA_WORD1_MSB_SHIFT) &
852 XZDMA_WORD1_MSB_MASK));
854 XZDma_WriteReg((InstancePtr->Config.BaseAddress),
855 XZDMA_CH_DST_DSCR_WORD0_OFFSET,
856 (Data->DstAddr & XZDMA_WORD0_LSB_MASK));
857 XZDma_WriteReg((InstancePtr->Config.BaseAddress),
858 XZDMA_CH_DST_DSCR_WORD1_OFFSET,
859 (((u64)Data->DstAddr >> XZDMA_WORD1_MSB_SHIFT) &
860 XZDMA_WORD1_MSB_MASK));
862 XZDma_WriteReg((InstancePtr->Config.BaseAddress),
863 XZDMA_CH_SRC_DSCR_WORD2_OFFSET,
864 (Data->Size & XZDMA_WORD2_SIZE_MASK));
865 XZDma_WriteReg((InstancePtr->Config.BaseAddress),
866 XZDMA_CH_DST_DSCR_WORD2_OFFSET,
867 (Data->Size & XZDMA_WORD2_SIZE_MASK));
869 Value = (u32)(Data->SrcCoherent & XZDMA_WORD3_COHRNT_MASK);
870 XZDma_WriteReg((InstancePtr->Config.BaseAddress),
871 XZDMA_CH_SRC_DSCR_WORD3_OFFSET, Value);
873 Value = (u32)(Data->DstCoherent & XZDMA_WORD3_COHRNT_MASK);
874 XZDma_WriteReg((InstancePtr->Config.BaseAddress),
875 XZDMA_CH_DST_DSCR_WORD3_OFFSET, Value);
879 /*****************************************************************************/
882 * This static function sets all the required fields for initiating data
883 * transfer in scatter gather mode.
885 * @param InstancePtr is a pointer to the XZDma instance.
886 * @param Data is a pointer of array to the XZDma_Transfer structure
887 * which has all the configuration fields for initiating data
889 * @param Num specifies number of array elements of Data pointer.
895 ******************************************************************************/
896 static void XZDma_ScatterGather(XZDma *InstancePtr, XZDma_Transfer *Data,
901 XZDma_Transfer *LocalData = Data;
902 XZDma_LiDscr *LiSrcDscr =
903 (XZDma_LiDscr *)(void *)(InstancePtr->Descriptor.SrcDscrPtr);
904 XZDma_LiDscr *LiDstDscr =
905 (XZDma_LiDscr *)(void *)(InstancePtr->Descriptor.DstDscrPtr);
906 XZDma_LlDscr *LlSrcDscr =
907 (XZDma_LlDscr *)(void *)(InstancePtr->Descriptor.SrcDscrPtr);
908 XZDma_LlDscr *LlDstDscr =
909 (XZDma_LlDscr *)(void *)(InstancePtr->Descriptor.DstDscrPtr);
911 /* Verify arguments */
912 Xil_AssertVoid(InstancePtr != NULL);
913 Xil_AssertVoid(Data != NULL);
914 Xil_AssertVoid(Num != 0x00U);
916 if (InstancePtr->Descriptor.DscrType == XZDMA_LINEAR) {
919 if (Count == (Num- 1)) {
922 XZDma_LinearMode(InstancePtr, LocalData, LiSrcDscr,
928 } while(Count < Num);
933 if (Count == (Num - 1)) {
936 XZDma_LinkedListMode(InstancePtr, LocalData, LlSrcDscr,
942 } while(Count < Num);
945 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
946 XZDMA_CH_SRC_START_LSB_OFFSET,
947 ((UINTPTR)(InstancePtr->Descriptor.SrcDscrPtr) &
948 XZDMA_WORD0_LSB_MASK));
949 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
950 XZDMA_CH_SRC_START_MSB_OFFSET,
951 (((u64)(UINTPTR)(InstancePtr->Descriptor.SrcDscrPtr) >>
952 XZDMA_WORD1_MSB_SHIFT) & XZDMA_WORD1_MSB_MASK));
953 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
954 XZDMA_CH_DST_START_LSB_OFFSET,
955 ((UINTPTR)(InstancePtr->Descriptor.DstDscrPtr) &
956 XZDMA_WORD0_LSB_MASK));
957 XZDma_WriteReg(InstancePtr->Config.BaseAddress,
958 XZDMA_CH_DST_START_MSB_OFFSET,
959 (((u64)(UINTPTR)(InstancePtr->Descriptor.DstDscrPtr) >>
960 XZDMA_WORD1_MSB_SHIFT) & XZDMA_WORD1_MSB_MASK));
963 /*****************************************************************************/
966 * This static function sets all the required fields for initiating data
967 * transfer in Linear descriptor type.
969 * @param InstancePtr is a pointer to the XZDma instance.
970 * @param Data is a pointer of array to the XZDma_Transfer structure which
971 * has all the configuration fields for initiating data transfer.
972 * @param SrcDscrPtr is descriptor pointer of source in which Data fields
974 * @param DstDscrPtr is descriptor pointer of destination in which Data
975 * fields has to be filled.
976 * @param IsLast specifies whether provided descriptor pointer is last
978 * - XZDMA_TRUE - If descriptor is last
979 * - XZDMA_FALSE - If descriptor is not last
985 ******************************************************************************/
986 static void XZDma_LinearMode(XZDma *InstancePtr, XZDma_Transfer *Data,
987 XZDma_LiDscr *SrcDscrPtr, XZDma_LiDscr *DstDscrPtr, u8 IsLast)
991 /* Verify arguments */
992 Xil_AssertVoid(InstancePtr != NULL);
993 Xil_AssertVoid(Data != NULL);
994 Xil_AssertVoid(SrcDscrPtr != NULL);
995 Xil_AssertVoid(DstDscrPtr != NULL);
996 Xil_AssertVoid((IsLast == TRUE) || (IsLast == FALSE));
998 if (Data->Pause == TRUE) {
999 Value = XZDMA_WORD3_CMD_PAUSE_MASK;
1001 else if (IsLast == TRUE) {
1002 Value = XZDMA_WORD3_CMD_STOP_MASK;
1005 Value = XZDMA_WORD3_CMD_NXTVALID_MASK;
1007 if (Data->SrcCoherent == TRUE) {
1008 Value |= XZDMA_WORD3_COHRNT_MASK;
1011 XZDma_ConfigLinear(SrcDscrPtr, (u64)Data->SrcAddr, Data->Size, Value);
1015 if (Data->DstCoherent == TRUE) {
1016 Value |= XZDMA_WORD3_COHRNT_MASK;
1019 XZDma_ConfigLinear(DstDscrPtr, (u64)Data->DstAddr, Data->Size, Value);
1023 /*****************************************************************************/
1026 * This static function sets all the required fields for initiating data
1027 * transfer in Linear descriptor type.
1029 * @param DscrPtr is a pointer to source/destination descriptor.
1030 * @param Addr is a 64 bit variable which denotes the address of data.
1031 * @param Size specifies the amount of the data to be transferred.
1032 * @param CtrlValue contains all the control fields of descriptor.
1038 ******************************************************************************/
1039 static void XZDma_ConfigLinear(XZDma_LiDscr *DscrPtr, u64 Addr, u32 Size,
1042 /* Verify arguments */
1043 Xil_AssertVoid(DscrPtr != NULL);
1044 Xil_AssertVoid(Addr != 0x00U);
1046 DscrPtr->Address = Addr;
1047 DscrPtr->Size = Size & XZDMA_WORD2_SIZE_MASK;
1048 DscrPtr->Cntl = CtrlValue;
1050 Xil_DCacheFlushRange((UINTPTR)DscrPtr, sizeof(XZDma_LlDscr));
1054 /*****************************************************************************/
1057 * This static function sets all the required fields for initiating data
1058 * transfer in Linked list descriptor type.
1060 * @param InstancePtr is a pointer to the XZDma instance.
1061 * @param Data is a pointer of array to the XZDma_Transfer structure which
1062 * has all the configuration fields for initiating data transfer.
1063 * @param SrcDscrPtr is descriptor pointer of source in which Data fields
1065 * @param DstDscrPtr is descriptor pointer of destination in which Data
1066 * fields has to be filled.
1067 * @param IsLast specifies whether provided descriptor pointer is last
1069 * - TRUE - If descriptor is last
1070 * - FALSE - If descriptor is not last
1076 ******************************************************************************/
1077 static void XZDma_LinkedListMode(XZDma *InstancePtr, XZDma_Transfer *Data,
1078 XZDma_LlDscr *SrcDscrPtr,XZDma_LlDscr *DstDscrPtr, u8 IsLast)
1081 XZDma_LlDscr *NextSrc = SrcDscrPtr;
1082 XZDma_LlDscr *NextDst = DstDscrPtr;
1083 u64 NextSrcAdrs = 0x00U;
1084 u64 NextDstAdrs = 0x00U;
1086 /* Verify arguments */
1087 Xil_AssertVoid(InstancePtr != NULL);
1088 Xil_AssertVoid(Data != NULL);
1089 Xil_AssertVoid(SrcDscrPtr != NULL);
1090 Xil_AssertVoid(DstDscrPtr != NULL);
1091 Xil_AssertVoid((IsLast == TRUE) || (IsLast == FALSE));
1096 if (Data->Pause == TRUE) {
1097 Value = XZDMA_WORD3_CMD_PAUSE_MASK;
1098 if (IsLast != TRUE) {
1099 NextSrcAdrs = (u64)(UINTPTR)NextSrc;
1100 NextDstAdrs = (u64)(UINTPTR)NextDst;
1103 else if (IsLast == TRUE) {
1104 Value = XZDMA_WORD3_CMD_STOP_MASK;
1107 Value = XZDMA_WORD3_CMD_NXTVALID_MASK;
1108 NextSrcAdrs = (u64)(UINTPTR)NextSrc;
1109 NextDstAdrs = (u64)(UINTPTR)NextDst;
1111 if (Data->SrcCoherent == TRUE) {
1112 Value |= XZDMA_WORD3_COHRNT_MASK;
1115 XZDma_ConfigLinkedList(SrcDscrPtr, (u64)Data->SrcAddr,
1116 Data->Size, Value, NextSrcAdrs);
1120 if (Data->DstCoherent == TRUE) {
1121 Value |= XZDMA_WORD3_COHRNT_MASK;
1124 XZDma_ConfigLinkedList(DstDscrPtr, (u64)Data->DstAddr,
1125 Data->Size, Value, NextDstAdrs);
1129 /*****************************************************************************/
1132 * This static function sets all the required fields for initiating data
1133 * transfer in Linked list descriptor type.
1135 * @param DscrPtr is a pointer to source/destination descriptor.
1136 * @param Addr is a 64 bit variable which denotes the address of data.
1137 * @param Size specifies the amount of the data to be transferred.
1138 * @param CtrlValue contains all the control fields of descriptor.
1139 * @param NextDscrAddr is the address of next descriptor.
1145 ******************************************************************************/
1146 static void XZDma_ConfigLinkedList(XZDma_LlDscr *DscrPtr, u64 Addr, u32 Size,
1147 u32 CtrlValue, u64 NextDscrAddr)
1149 /* Verify arguments */
1150 Xil_AssertVoid(DscrPtr != NULL);
1151 Xil_AssertVoid(Addr != 0x00U);
1153 DscrPtr->Address = Addr;
1154 DscrPtr->Size = Size & XZDMA_WORD2_SIZE_MASK;
1155 DscrPtr->Cntl = CtrlValue;
1156 DscrPtr->NextDscr = NextDscrAddr;
1157 DscrPtr->Reserved = 0U;
1159 Xil_DCacheFlushRange((UINTPTR)DscrPtr, sizeof(XZDma_LlDscr));
1162 /*****************************************************************************/
1164 * This static function enable's all the interrupts which user intended to
1165 * enable and enables the ZDMA channel for initiating data transfer.
1167 * @param InstancePtr is a pointer to the XZDma instance.
1172 ******************************************************************************/
1174 static void XZDma_Enable(XZDma *InstancePtr)
1176 /* Verify arguments */
1177 Xil_AssertVoid(InstancePtr != NULL);
1179 XZDma_WriteReg(InstancePtr->Config.BaseAddress, XZDMA_CH_IEN_OFFSET,
1180 (InstancePtr->IntrMask & XZDMA_IXR_ALL_INTR_MASK));
1181 InstancePtr->ChannelState = XZDMA_BUSY;
1182 XZDma_EnableCh(InstancePtr);
1186 /*****************************************************************************/
1188 * This static function gets all the reset configurations of ZDMA.
1190 * @param InstancePtr is a pointer to the XZDma instance.
1196 ******************************************************************************/
1197 static void XZDma_GetConfigurations(XZDma *InstancePtr)
1199 /* Verify arguments */
1200 Xil_AssertVoid(InstancePtr != NULL);
1202 InstancePtr->DataConfig.SrcIssue = (u8)XZDMA_CTRL1_SRC_ISSUE_MASK;
1203 InstancePtr->DataConfig.SrcBurstType = XZDMA_INCR_BURST;
1204 InstancePtr->DataConfig.SrcBurstLen = 0xFU;
1205 InstancePtr->DataConfig.OverFetch = 1U;
1206 InstancePtr->DataConfig.DstBurstType = XZDMA_INCR_BURST;
1207 InstancePtr->DataConfig.DstBurstLen = 0xFU;
1208 InstancePtr->DataConfig.SrcCache = 0x2U;
1209 InstancePtr->DataConfig.DstCache = 0x2U;
1210 InstancePtr->DataConfig.SrcQos = 0x0U;
1211 InstancePtr->DataConfig.DstQos = 0x0U;
1213 InstancePtr->DscrConfig.AXCache = 0U;
1214 InstancePtr->DscrConfig.AXQos = 0U;
1215 InstancePtr->DscrConfig.AxCoherent = 0U;
1218 /*****************************************************************************/
1221 * This routine is a stub for the asynchronous callbacks. The stub is here in
1222 * case the upper layer forgot to set the handlers. On initialization, All
1223 * handlers are set to this callback. It is considered an error for this
1224 * handler to be invoked.
1226 * @param CallBackRef is a callback reference passed in by the upper
1227 * layer when setting the callback functions, and passed back to
1228 * the upper layer when the callback is invoked.
1229 * @param Mask is the type of the interrupts to enable. Use OR'ing of
1230 * XZDMA_IXR_DMA_*_MASK constants defined in xzdma_hw.h to create
1231 * this parameter value.
1237 ******************************************************************************/
1238 static void StubCallBack(void *CallBackRef, u32 Mask)
1240 /* Verify arguments. */
1241 Xil_AssertVoid(CallBackRef != NULL);
1242 Xil_AssertVoid(Mask != (u32)0x00);
1243 Xil_AssertVoidAlways();
1246 /*****************************************************************************/
1249 * This routine is a stub for the DMA done callback. The stub is here in
1250 * case the upper layer forgot to set the handlers. On initialization, Done
1251 * handler are set to this callback.
1253 * @param CallBackRef is a callback reference passed in by the upper
1254 * layer when setting the callback functions, and passed back to
1255 * the upper layer when the callback is invoked.
1261 ******************************************************************************/
1262 static void StubDoneCallBack(void *CallBackRef)
1264 /* Verify arguments. */
1265 Xil_AssertVoid(CallBackRef != NULL);
1266 Xil_AssertVoidAlways();