XilinxProcessorIPLib/drivers/axidma/src/xaxidma_bdring.c
int XAxiDma_UpdateBdRingCDesc(XAxiDma_BdRing* RingPtr)
{
	UINTPTR RegBase;
	UINTPTR BdPtr;
	int RingIndex = RingPtr->RingIndex;

	/* BD list has yet to be created for this channel */
	if (RingPtr->AllCnt == 0) {

		xdbg_printf(XDBG_DEBUG_ERROR, "BdRingStart: no bds\r\n");

		return XST_DMA_SG_NO_LIST;
	}

	/* Do nothing if already started */
	if (RingPtr->RunState == AXIDMA_CHANNEL_NOT_HALTED) {
		/* Need to update tail pointer if needed (Engine is not
		 * transferring)
		 */
		return XST_SUCCESS;
	}

	if (!XAxiDma_BdRingHwIsStarted(RingPtr)) {
		/* If hardware is not running, then we need to put a valid current
		 * BD pointer to the current BD register before start the hardware
		 */
		RegBase = RingPtr->ChanBase;

		/* Put a valid BD pointer in the current BD pointer register
		 * So, the hardware is ready to go when tail BD pointer is updated
		 */
		BdPtr = (UINTPTR)(void *)(RingPtr->BdaRestart);

		if (!XAxiDma_BdHwCompleted(BdPtr)) {
			if (RingPtr->IsRxChannel) {
				if (!RingIndex) {
					XAxiDma_WriteReg(RegBase,
							 XAXIDMA_CDESC_OFFSET,
							 (XAXIDMA_VIRT_TO_PHYS(BdPtr) & XAXIDMA_DESC_LSB_MASK));
					if (RingPtr->Addr_ext)
						XAxiDma_WriteReg(RegBase,
								 XAXIDMA_CDESC_MSB_OFFSET,
								 UPPER_32_BITS(XAXIDMA_VIRT_TO_PHYS(BdPtr)));
				}
				else {
					XAxiDma_WriteReg(RegBase,
					(XAXIDMA_RX_CDESC0_OFFSET +
					(RingIndex - 1) * XAXIDMA_RX_NDESC_OFFSET),
					(XAXIDMA_VIRT_TO_PHYS(BdPtr) & XAXIDMA_DESC_LSB_MASK));
					if (RingPtr->Addr_ext)
						XAxiDma_WriteReg(RegBase,
								 (XAXIDMA_RX_CDESC0_MSB_OFFSET +
								 (RingIndex - 1) * XAXIDMA_RX_NDESC_OFFSET),
								 UPPER_32_BITS(XAXIDMA_VIRT_TO_PHYS(BdPtr)));
				}
			}
			else {
				XAxiDma_WriteReg(RegBase,
						 XAXIDMA_CDESC_OFFSET,
						 (XAXIDMA_VIRT_TO_PHYS(BdPtr) & XAXIDMA_DESC_LSB_MASK));
				if (RingPtr->Addr_ext)
					XAxiDma_WriteReg(RegBase, XAXIDMA_CDESC_MSB_OFFSET,
							 UPPER_32_BITS(XAXIDMA_VIRT_TO_PHYS(BdPtr)));
			}
		}
		else {
			/* Look for an uncompleted BD
			*/
			while (XAxiDma_BdHwCompleted(BdPtr)) {
				BdPtr = XAxiDma_BdRingNext(RingPtr, BdPtr);

				if ((UINTPTR)BdPtr == (UINTPTR) RingPtr->BdaRestart) {
					xdbg_printf(XDBG_DEBUG_ERROR,
					"StartBdRingHw: Cannot find valid cdesc\r\n");

					return XST_DMA_ERROR;
				}

				if (!XAxiDma_BdHwCompleted(BdPtr)) {
					if (RingPtr->IsRxChannel) {
						if (!RingIndex) {
							XAxiDma_WriteReg(RegBase,
								XAXIDMA_CDESC_OFFSET,
								(XAXIDMA_VIRT_TO_PHYS(BdPtr) & XAXIDMA_DESC_LSB_MASK));
							if (RingPtr->Addr_ext)
								XAxiDma_WriteReg(RegBase, XAXIDMA_CDESC_MSB_OFFSET,
									UPPER_32_BITS(XAXIDMA_VIRT_TO_PHYS(BdPtr)));
						}
						else {
							XAxiDma_WriteReg(RegBase,
								(XAXIDMA_RX_CDESC0_OFFSET +
								(RingIndex - 1) * XAXIDMA_RX_NDESC_OFFSET),
								(XAXIDMA_VIRT_TO_PHYS(BdPtr) & XAXIDMA_DESC_LSB_MASK));
							if (RingPtr->Addr_ext)
								XAxiDma_WriteReg(RegBase,
									(XAXIDMA_RX_CDESC0_MSB_OFFSET +
									(RingIndex - 1) * XAXIDMA_RX_NDESC_OFFSET),
									UPPER_32_BITS(XAXIDMA_VIRT_TO_PHYS(BdPtr)));
						}
					}
					else {
						XAxiDma_WriteReg(RegBase,
								XAXIDMA_CDESC_OFFSET,
								(XAXIDMA_VIRT_TO_PHYS(BdPtr) & XAXIDMA_DESC_LSB_MASK));
						if (RingPtr->Addr_ext)
							XAxiDma_WriteReg(RegBase, XAXIDMA_CDESC_MSB_OFFSET,
									 UPPER_32_BITS(XAXIDMA_VIRT_TO_PHYS(BdPtr)));
					}
					break;
				}
			}
		}

	}

	return XST_SUCCESS;
}
/*****************************************************************************/
/**
 * Update Current Descriptor
 *
 * @param	RingPtr is the Channel instance to be worked on
 *
 * @return
 *		- XST_SUCCESS upon success
 *		- XST_DMA_ERROR if no valid BD available to put into current
 *		BD register
 *
 * @note	This function can be used only when DMA is in SG mode
 *
 *****************************************************************************/
Update Current Descriptor
@param       RingPtr is the Channel instance to be worked on

@return
- XST_SUCCESS upon success
- XST_DMA_ERROR if no valid BD available to put into current
BD register

@note        This function can be used only when DMA is in SG mode
Update Current Descriptor @param RingPtr is the Channel instance to be worked on @return - XST_SUCCESS upon success - XST_DMA_ERROR if no valid BD available to put into current BD register @note This function can be used only when DMA is in SG mode
int XAxiDma_UpdateBdRingCDesc(XAxiDma_BdRing* RingPtr)
{
	UINTPTR RegBase;
	UINTPTR BdPtr;
	int RingIndex = RingPtr->RingIndex;
	if (RingPtr->AllCnt == 0) {
		xdbg_printf(XDBG_DEBUG_ERROR, "BdRingStart: no bds\r\n");
		return XST_DMA_SG_NO_LIST;
	}
	if (RingPtr->RunState == AXIDMA_CHANNEL_NOT_HALTED) {
		return XST_SUCCESS;
	}
	if (!XAxiDma_BdRingHwIsStarted(RingPtr)) {
		RegBase = RingPtr->ChanBase;
		BdPtr = (UINTPTR)(void *)(RingPtr->BdaRestart);
		if (!XAxiDma_BdHwCompleted(BdPtr)) {
			if (RingPtr->IsRxChannel) {
				if (!RingIndex) {
					XAxiDma_WriteReg(RegBase,
							 XAXIDMA_CDESC_OFFSET,
							 (XAXIDMA_VIRT_TO_PHYS(BdPtr) & XAXIDMA_DESC_LSB_MASK));
					if (RingPtr->Addr_ext)
						XAxiDma_WriteReg(RegBase,
								 XAXIDMA_CDESC_MSB_OFFSET,
								 UPPER_32_BITS(XAXIDMA_VIRT_TO_PHYS(BdPtr)));
				}
				else {
					XAxiDma_WriteReg(RegBase,
					(XAXIDMA_RX_CDESC0_OFFSET +
					(RingIndex - 1) * XAXIDMA_RX_NDESC_OFFSET),
					(XAXIDMA_VIRT_TO_PHYS(BdPtr) & XAXIDMA_DESC_LSB_MASK));
					if (RingPtr->Addr_ext)
						XAxiDma_WriteReg(RegBase,
								 (XAXIDMA_RX_CDESC0_MSB_OFFSET +
								 (RingIndex - 1) * XAXIDMA_RX_NDESC_OFFSET),
								 UPPER_32_BITS(XAXIDMA_VIRT_TO_PHYS(BdPtr)));
				}
			}
			else {
				XAxiDma_WriteReg(RegBase,
						 XAXIDMA_CDESC_OFFSET,
						 (XAXIDMA_VIRT_TO_PHYS(BdPtr) & XAXIDMA_DESC_LSB_MASK));
				if (RingPtr->Addr_ext)
					XAxiDma_WriteReg(RegBase, XAXIDMA_CDESC_MSB_OFFSET,
							 UPPER_32_BITS(XAXIDMA_VIRT_TO_PHYS(BdPtr)));
			}
		}
		else {
			while (XAxiDma_BdHwCompleted(BdPtr)) {
				BdPtr = XAxiDma_BdRingNext(RingPtr, BdPtr);
				if ((UINTPTR)BdPtr == (UINTPTR) RingPtr->BdaRestart) {
					xdbg_printf(XDBG_DEBUG_ERROR,
					"StartBdRingHw: Cannot find valid cdesc\r\n");
					return XST_DMA_ERROR;
				}
				if (!XAxiDma_BdHwCompleted(BdPtr)) {
					if (RingPtr->IsRxChannel) {
						if (!RingIndex) {
							XAxiDma_WriteReg(RegBase,
								XAXIDMA_CDESC_OFFSET,
								(XAXIDMA_VIRT_TO_PHYS(BdPtr) & XAXIDMA_DESC_LSB_MASK));
							if (RingPtr->Addr_ext)
								XAxiDma_WriteReg(RegBase, XAXIDMA_CDESC_MSB_OFFSET,
									UPPER_32_BITS(XAXIDMA_VIRT_TO_PHYS(BdPtr)));
						}
						else {
							XAxiDma_WriteReg(RegBase,
								(XAXIDMA_RX_CDESC0_OFFSET +
								(RingIndex - 1) * XAXIDMA_RX_NDESC_OFFSET),
								(XAXIDMA_VIRT_TO_PHYS(BdPtr) & XAXIDMA_DESC_LSB_MASK));
							if (RingPtr->Addr_ext)
								XAxiDma_WriteReg(RegBase,
									(XAXIDMA_RX_CDESC0_MSB_OFFSET +
									(RingIndex - 1) * XAXIDMA_RX_NDESC_OFFSET),
									UPPER_32_BITS(XAXIDMA_VIRT_TO_PHYS(BdPtr)));
						}
					}
					else {
						XAxiDma_WriteReg(RegBase,
								XAXIDMA_CDESC_OFFSET,
								(XAXIDMA_VIRT_TO_PHYS(BdPtr) & XAXIDMA_DESC_LSB_MASK));
						if (RingPtr->Addr_ext)
							XAxiDma_WriteReg(RegBase, XAXIDMA_CDESC_MSB_OFFSET,
									 UPPER_32_BITS(XAXIDMA_VIRT_TO_PHYS(BdPtr)));
					}
					break;
				}
			}
		}
	}
	return XST_SUCCESS;
}
int XAxiDma_UpdateBdRingCDesc ( XAxiDma_BdRing * RingPtr ) { UINTPTR RegBase ; UINTPTR BdPtr ; int RingIndex = RingPtr -> RingIndex ; if ( RingPtr -> AllCnt == 0 ) { xdbg_printf ( XDBG_DEBUG_ERROR , " \r \n " ) ; return XST_DMA_SG_NO_LIST ; } if ( RingPtr -> RunState == AXIDMA_CHANNEL_NOT_HALTED ) { return XST_SUCCESS ; } if ( ! XAxiDma_BdRingHwIsStarted ( RingPtr ) ) { RegBase = RingPtr -> ChanBase ; BdPtr = ( UINTPTR ) ( void * ) ( RingPtr -> BdaRestart ) ; if ( ! XAxiDma_BdHwCompleted ( BdPtr ) ) { if ( RingPtr -> IsRxChannel ) { if ( ! RingIndex ) { XAxiDma_WriteReg ( RegBase , XAXIDMA_CDESC_OFFSET , ( XAXIDMA_VIRT_TO_PHYS ( BdPtr ) & XAXIDMA_DESC_LSB_MASK ) ) ; if ( RingPtr -> Addr_ext ) XAxiDma_WriteReg ( RegBase , XAXIDMA_CDESC_MSB_OFFSET , UPPER_32_BITS ( XAXIDMA_VIRT_TO_PHYS ( BdPtr ) ) ) ; } else { XAxiDma_WriteReg ( RegBase , ( XAXIDMA_RX_CDESC0_OFFSET + ( RingIndex - 1 ) * XAXIDMA_RX_NDESC_OFFSET ) , ( XAXIDMA_VIRT_TO_PHYS ( BdPtr ) & XAXIDMA_DESC_LSB_MASK ) ) ; if ( RingPtr -> Addr_ext ) XAxiDma_WriteReg ( RegBase , ( XAXIDMA_RX_CDESC0_MSB_OFFSET + ( RingIndex - 1 ) * XAXIDMA_RX_NDESC_OFFSET ) , UPPER_32_BITS ( XAXIDMA_VIRT_TO_PHYS ( BdPtr ) ) ) ; } } else { XAxiDma_WriteReg ( RegBase , XAXIDMA_CDESC_OFFSET , ( XAXIDMA_VIRT_TO_PHYS ( BdPtr ) & XAXIDMA_DESC_LSB_MASK ) ) ; if ( RingPtr -> Addr_ext ) XAxiDma_WriteReg ( RegBase , XAXIDMA_CDESC_MSB_OFFSET , UPPER_32_BITS ( XAXIDMA_VIRT_TO_PHYS ( BdPtr ) ) ) ; } } else { while ( XAxiDma_BdHwCompleted ( BdPtr ) ) { BdPtr = XAxiDma_BdRingNext ( RingPtr , BdPtr ) ; if ( ( UINTPTR ) BdPtr == ( UINTPTR ) RingPtr -> BdaRestart ) { xdbg_printf ( XDBG_DEBUG_ERROR , " \r \n " ) ; return XST_DMA_ERROR ; } if ( ! XAxiDma_BdHwCompleted ( BdPtr ) ) { if ( RingPtr -> IsRxChannel ) { if ( ! RingIndex ) { XAxiDma_WriteReg ( RegBase , XAXIDMA_CDESC_OFFSET , ( XAXIDMA_VIRT_TO_PHYS ( BdPtr ) & XAXIDMA_DESC_LSB_MASK ) ) ; if ( RingPtr -> Addr_ext ) XAxiDma_WriteReg ( RegBase , XAXIDMA_CDESC_MSB_OFFSET , UPPER_32_BITS ( XAXIDMA_VIRT_TO_PHYS ( BdPtr ) ) ) ; } else { XAxiDma_WriteReg ( RegBase , ( XAXIDMA_RX_CDESC0_OFFSET + ( RingIndex - 1 ) * XAXIDMA_RX_NDESC_OFFSET ) , ( XAXIDMA_VIRT_TO_PHYS ( BdPtr ) & XAXIDMA_DESC_LSB_MASK ) ) ; if ( RingPtr -> Addr_ext ) XAxiDma_WriteReg ( RegBase , ( XAXIDMA_RX_CDESC0_MSB_OFFSET + ( RingIndex - 1 ) * XAXIDMA_RX_NDESC_OFFSET ) , UPPER_32_BITS ( XAXIDMA_VIRT_TO_PHYS ( BdPtr ) ) ) ; } } else { XAxiDma_WriteReg ( RegBase , XAXIDMA_CDESC_OFFSET , ( XAXIDMA_VIRT_TO_PHYS ( BdPtr ) & XAXIDMA_DESC_LSB_MASK ) ) ; if ( RingPtr -> Addr_ext ) XAxiDma_WriteReg ( RegBase , XAXIDMA_CDESC_MSB_OFFSET , UPPER_32_BITS ( XAXIDMA_VIRT_TO_PHYS ( BdPtr ) ) ) ; } break ; } } } } return XST_SUCCESS ; }
Update Current Descriptor
 @param       RingPtr is the Channel instance to be worked on
Update Current Descriptor @param RingPtr is the Channel instance to be worked on
/* BD list has yet to be created for this channel */ /* Do nothing if already started */ /* Need to update tail pointer if needed (Engine is not
		 * transferring)
		 */ /* If hardware is not running, then we need to put a valid current
		 * BD pointer to the current BD register before start the hardware
		 */ /* Put a valid BD pointer in the current BD pointer register
		 * So, the hardware is ready to go when tail BD pointer is updated
		 */ /* Look for an uncompleted BD
			*/