XilinxProcessorIPLib/drivers/mcdma/src/xmcdma_bd.c
u32 XMcDma_ChanBdCreate(XMcdma_ChanCtrl *Chan, UINTPTR Addr, u32 Count)
{
	UINTPTR BdStartAddr;
	UINTPTR NxtBdAddr;
	u32 i;

	if (Count <= 0)
		return XST_INVALID_PARAM;

	Chan->BdPendingCnt = 0;
	Chan->BdSubmitCnt = 0;
	Chan->BdCnt = 0;
	Chan->BdDoneCnt = 0;
	Chan->Separation = sizeof(XMcdma_Bd);

	memset((void *)Addr, 0, sizeof(XMcdma_Bd) * Count);

	BdStartAddr = Addr;
	NxtBdAddr = Addr + Chan->Separation;
	for (i = 1; i < Count; i++) {
		XMcdma_BdWrite(BdStartAddr, XMCDMA_BD_NDESC_OFFSET,
			       (u32)NxtBdAddr);
		XMcdma_BdWrite(BdStartAddr, XMCDMA_BD_NDESC_MSB_OFFSET,
			       UPPER_32_BITS(NxtBdAddr));
		if (Chan->IsRxChan) {
			XMcdma_BdWrite(BdStartAddr, XMCDMA_BD_HAS_DRE_OFFSET,
				       (((u32)(Chan->Has_Rxdre)) <<
					XMCDMA_BD_HAS_DRE_SHIFT) |
					    Chan->RxDataWidth);
		} else {
			XMcdma_BdWrite(BdStartAddr, XMCDMA_BD_HAS_DRE_OFFSET,
				       (((u32)(Chan->Has_Txdre)) <<
				       XMCDMA_BD_HAS_DRE_SHIFT) |
					   Chan->TxDataWidth);
		}
		XMcdma_BdWrite(BdStartAddr, XMCDMA_BD_HAS_CTRLSTS_OFFSET,
			       Chan->HasStsCntrlStrm);

		XMCDMA_CACHE_FLUSH(BdStartAddr);
		BdStartAddr += Chan->Separation;
		NxtBdAddr   += Chan->Separation;
	}

	/* Link the last Bd to the first Bd */
	XMCDMA_CACHE_FLUSH(BdStartAddr);
	XMcdma_BdWrite(BdStartAddr, XMCDMA_BD_NDESC_OFFSET, (u32)Addr);
	XMcdma_BdWrite(BdStartAddr, XMCDMA_BD_NDESC_MSB_OFFSET,
		       UPPER_32_BITS(Addr));
	if (Chan->IsRxChan) {
		XMcdma_BdWrite(BdStartAddr, XMCDMA_BD_HAS_DRE_OFFSET,
			       (((u32)(Chan->Has_Rxdre)) <<
				XMCDMA_BD_HAS_DRE_SHIFT) |
				    Chan->RxDataWidth);
	} else {
		XMcdma_BdWrite(BdStartAddr, XMCDMA_BD_HAS_DRE_OFFSET,
			       (((u32)(Chan->Has_Txdre)) <<
			       XMCDMA_BD_HAS_DRE_SHIFT) |
				   Chan->TxDataWidth);
	}
	XMcdma_BdWrite(BdStartAddr, XMCDMA_BD_HAS_CTRLSTS_OFFSET,
		       Chan->HasStsCntrlStrm);


	Chan->ChanState = XMCDMA_CHAN_IDLE;
	Chan->BdCnt = Count;
	Chan->FirstBdAddr = Addr;
	Chan->LastBdAddr = BdStartAddr;
	Chan->Length = Chan->LastBdAddr - Chan->FirstBdAddr +
			       Chan->Separation;
	Chan->BdHead = (XMcdma_Bd *) Addr;
	Chan->BdTail = (XMcdma_Bd *) Addr;
	Chan->BdRestart = (XMcdma_Bd *) Addr;

	return XST_SUCCESS;
}
/*****************************************************************************/
/**
* Using a memory segment allocated by the caller, This function creates and
* setup the BD Chain for the MCDMA Channel.
*
* @param	Chan is the MCDMA Channel to be worked on..
* @param	Addr is the address of the application memory region.
* @param	Count is the number of BDs to setup in the application memory
*		region.
*
* @return
*		- XST_SUCCESS if initialization was successful
*		- XST_INVALID_PARAM if Count is not positive.
*
*****************************************************************************/
Using a memory segment allocated by the caller, This function creates and
setup the BD Chain for the MCDMA Channel.
Using a memory segment allocated by the caller This function creates and setup the BD Chain for the MCDMA Channel .
u32 XMcDma_ChanBdCreate(XMcdma_ChanCtrl *Chan, UINTPTR Addr, u32 Count)
{
	UINTPTR BdStartAddr;
	UINTPTR NxtBdAddr;
	u32 i;
	if (Count <= 0)
		return XST_INVALID_PARAM;
	Chan->BdPendingCnt = 0;
	Chan->BdSubmitCnt = 0;
	Chan->BdCnt = 0;
	Chan->BdDoneCnt = 0;
	Chan->Separation = sizeof(XMcdma_Bd);
	memset((void *)Addr, 0, sizeof(XMcdma_Bd) * Count);
	BdStartAddr = Addr;
	NxtBdAddr = Addr + Chan->Separation;
	for (i = 1; i < Count; i++) {
		XMcdma_BdWrite(BdStartAddr, XMCDMA_BD_NDESC_OFFSET,
			       (u32)NxtBdAddr);
		XMcdma_BdWrite(BdStartAddr, XMCDMA_BD_NDESC_MSB_OFFSET,
			       UPPER_32_BITS(NxtBdAddr));
		if (Chan->IsRxChan) {
			XMcdma_BdWrite(BdStartAddr, XMCDMA_BD_HAS_DRE_OFFSET,
				       (((u32)(Chan->Has_Rxdre)) <<
					XMCDMA_BD_HAS_DRE_SHIFT) |
					    Chan->RxDataWidth);
		} else {
			XMcdma_BdWrite(BdStartAddr, XMCDMA_BD_HAS_DRE_OFFSET,
				       (((u32)(Chan->Has_Txdre)) <<
				       XMCDMA_BD_HAS_DRE_SHIFT) |
					   Chan->TxDataWidth);
		}
		XMcdma_BdWrite(BdStartAddr, XMCDMA_BD_HAS_CTRLSTS_OFFSET,
			       Chan->HasStsCntrlStrm);
		XMCDMA_CACHE_FLUSH(BdStartAddr);
		BdStartAddr += Chan->Separation;
		NxtBdAddr   += Chan->Separation;
	}
	XMCDMA_CACHE_FLUSH(BdStartAddr);
	XMcdma_BdWrite(BdStartAddr, XMCDMA_BD_NDESC_OFFSET, (u32)Addr);
	XMcdma_BdWrite(BdStartAddr, XMCDMA_BD_NDESC_MSB_OFFSET,
		       UPPER_32_BITS(Addr));
	if (Chan->IsRxChan) {
		XMcdma_BdWrite(BdStartAddr, XMCDMA_BD_HAS_DRE_OFFSET,
			       (((u32)(Chan->Has_Rxdre)) <<
				XMCDMA_BD_HAS_DRE_SHIFT) |
				    Chan->RxDataWidth);
	} else {
		XMcdma_BdWrite(BdStartAddr, XMCDMA_BD_HAS_DRE_OFFSET,
			       (((u32)(Chan->Has_Txdre)) <<
			       XMCDMA_BD_HAS_DRE_SHIFT) |
				   Chan->TxDataWidth);
	}
	XMcdma_BdWrite(BdStartAddr, XMCDMA_BD_HAS_CTRLSTS_OFFSET,
		       Chan->HasStsCntrlStrm);
	Chan->ChanState = XMCDMA_CHAN_IDLE;
	Chan->BdCnt = Count;
	Chan->FirstBdAddr = Addr;
	Chan->LastBdAddr = BdStartAddr;
	Chan->Length = Chan->LastBdAddr - Chan->FirstBdAddr +
			       Chan->Separation;
	Chan->BdHead = (XMcdma_Bd *) Addr;
	Chan->BdTail = (XMcdma_Bd *) Addr;
	Chan->BdRestart = (XMcdma_Bd *) Addr;
	return XST_SUCCESS;
}
u32 XMcDma_ChanBdCreate ( XMcdma_ChanCtrl * Chan , UINTPTR Addr , u32 Count ) { UINTPTR BdStartAddr ; UINTPTR NxtBdAddr ; u32 i ; if ( Count <= 0 ) return XST_INVALID_PARAM ; Chan -> BdPendingCnt = 0 ; Chan -> BdSubmitCnt = 0 ; Chan -> BdCnt = 0 ; Chan -> BdDoneCnt = 0 ; Chan -> Separation = sizeof ( XMcdma_Bd ) ; memset ( ( void * ) Addr , 0 , sizeof ( XMcdma_Bd ) * Count ) ; BdStartAddr = Addr ; NxtBdAddr = Addr + Chan -> Separation ; for ( i = 1 ; i < Count ; i ++ ) { XMcdma_BdWrite ( BdStartAddr , XMCDMA_BD_NDESC_OFFSET , ( u32 ) NxtBdAddr ) ; XMcdma_BdWrite ( BdStartAddr , XMCDMA_BD_NDESC_MSB_OFFSET , UPPER_32_BITS ( NxtBdAddr ) ) ; if ( Chan -> IsRxChan ) { XMcdma_BdWrite ( BdStartAddr , XMCDMA_BD_HAS_DRE_OFFSET , ( ( ( u32 ) ( Chan -> Has_Rxdre ) ) << XMCDMA_BD_HAS_DRE_SHIFT ) | Chan -> RxDataWidth ) ; } else { XMcdma_BdWrite ( BdStartAddr , XMCDMA_BD_HAS_DRE_OFFSET , ( ( ( u32 ) ( Chan -> Has_Txdre ) ) << XMCDMA_BD_HAS_DRE_SHIFT ) | Chan -> TxDataWidth ) ; } XMcdma_BdWrite ( BdStartAddr , XMCDMA_BD_HAS_CTRLSTS_OFFSET , Chan -> HasStsCntrlStrm ) ; XMCDMA_CACHE_FLUSH ( BdStartAddr ) ; BdStartAddr += Chan -> Separation ; NxtBdAddr += Chan -> Separation ; } XMCDMA_CACHE_FLUSH ( BdStartAddr ) ; XMcdma_BdWrite ( BdStartAddr , XMCDMA_BD_NDESC_OFFSET , ( u32 ) Addr ) ; XMcdma_BdWrite ( BdStartAddr , XMCDMA_BD_NDESC_MSB_OFFSET , UPPER_32_BITS ( Addr ) ) ; if ( Chan -> IsRxChan ) { XMcdma_BdWrite ( BdStartAddr , XMCDMA_BD_HAS_DRE_OFFSET , ( ( ( u32 ) ( Chan -> Has_Rxdre ) ) << XMCDMA_BD_HAS_DRE_SHIFT ) | Chan -> RxDataWidth ) ; } else { XMcdma_BdWrite ( BdStartAddr , XMCDMA_BD_HAS_DRE_OFFSET , ( ( ( u32 ) ( Chan -> Has_Txdre ) ) << XMCDMA_BD_HAS_DRE_SHIFT ) | Chan -> TxDataWidth ) ; } XMcdma_BdWrite ( BdStartAddr , XMCDMA_BD_HAS_CTRLSTS_OFFSET , Chan -> HasStsCntrlStrm ) ; Chan -> ChanState = XMCDMA_CHAN_IDLE ; Chan -> BdCnt = Count ; Chan -> FirstBdAddr = Addr ; Chan -> LastBdAddr = BdStartAddr ; Chan -> Length = Chan -> LastBdAddr - Chan -> FirstBdAddr + Chan -> Separation ; Chan -> BdHead = ( XMcdma_Bd * ) Addr ; Chan -> BdTail = ( XMcdma_Bd * ) Addr ; Chan -> BdRestart = ( XMcdma_Bd * ) Addr ; return XST_SUCCESS ; }
Using a memory segment allocated by the caller, This function creates and
setup the BD Chain for the MCDMA Channel.
Using a memory segment allocated by the caller This function creates and setup the BD Chain for the MCDMA Channel .
/* Link the last Bd to the first Bd */