Beispiel #1
0
/**
*
* This function sets the number of lanes to be used by DisplayPort TX Subsystem
* core.
*
* @param	InstancePtr is a pointer to the XDpTxSs instance.
* @param	LaneCount is the number of lanes to be used.
*		- 1 = XDPTXSS_LANE_COUNT_SET_1
*		- 2 = XDPTXSS_LANE_COUNT_SET_2
*		- 4 = XDPTXSS_LANE_COUNT_SET_4
* @return
*		- XST_SUCCESS if setting the new lane count was successful.
*		- XST_FAILURE otherwise.
*
* @note		Maximum supported lane count is used if given lane count is
*		greater than the maximum supported lane count.
*
******************************************************************************/
u32 XDpTxSs_SetLaneCount(XDpTxSs *InstancePtr, u8 LaneCount)
{
	u32 Status;

	/* Verify arguments. */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid((LaneCount == XDPTXSS_LANE_COUNT_SET_1) ||
			(LaneCount == XDPTXSS_LANE_COUNT_SET_2) ||
			(LaneCount == XDPTXSS_LANE_COUNT_SET_4));

	/* Check for maximum supported lane count */
	if (LaneCount > InstancePtr->DpPtr->Config.MaxLaneCount) {
		xdbg_printf(XDBG_DEBUG_GENERAL,"SS info: This lane count is "
			"not supported by Source/Sink.\n\rMax Supported lane "
			"count is 0x%x.\n\rSetting maximum supported lane "
			"count.\n\r", InstancePtr->DpPtr->Config.MaxLaneCount);
		LaneCount = InstancePtr->DpPtr->Config.MaxLaneCount;
	}

	/* Set lane count */
	Status = XDp_TxSetLaneCount(InstancePtr->DpPtr, LaneCount);
	if (Status != XST_SUCCESS) {
		xdbg_printf(XDBG_DEBUG_GENERAL,"SS ERR: Setting lane count "
			"failed.\n\r");
		Status = XST_FAILURE;
	}

	return Status;
}
Beispiel #2
0
/**
*
* This function sets the data rate to be used by the DisplayPort TX Subsystem
* core.
*
* @param	InstancePtr is a pointer to the XDpTxSs instance.
* @param	LinkRate is the rate at which link needs to be driven.
*		- XDPTXSS_LINK_BW_SET_162GBPS = 0x06(for a 1.62 Gbps data rate)
*		- XDPTXSS_LINK_BW_SET_270GBPS = 0x0A(for a 2.70 Gbps data rate)
*		- XDPTXSS_LINK_BW_SET_540GBPS = 0x14(for a 5.40 Gbps data rate)
*
* @return
*		- XST_SUCCESS if setting the new lane rate was successful.
*		- XST_FAILURE otherwise.
*
* @note		Maximum supported link rate is used if given link rate is
*		greater than the maximum supported link rate.
*
******************************************************************************/
u32 XDpTxSs_SetLinkRate(XDpTxSs *InstancePtr, u8 LinkRate)
{
	u32 Status;

	/* Verify arguments. */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid((LinkRate == XDPTXSS_LINK_BW_SET_162GBPS) ||
			(LinkRate == XDPTXSS_LINK_BW_SET_270GBPS) ||
			(LinkRate == XDPTXSS_LINK_BW_SET_540GBPS));

	/* Check for maximum supported link rate */
	if (LinkRate > InstancePtr->DpPtr->Config.MaxLinkRate) {
		xdbg_printf(XDBG_DEBUG_GENERAL,"SS info: This link rate is "
			"not supported by Source/Sink.\n\rMax Supported link "
			"rate is 0x%x.\n\rSetting maximum supported link "
			"rate.\n\r", InstancePtr->DpPtr->Config.MaxLinkRate);
		LinkRate = InstancePtr->DpPtr->Config.MaxLinkRate;
	}

	/* Set link rate */
	Status = XDp_TxSetLinkRate(InstancePtr->DpPtr, LinkRate);
	if (Status != XST_SUCCESS) {
		xdbg_printf(XDBG_DEBUG_GENERAL,"SS ERR: Setting link rate "
			"failed.\n\r");
		Status = XST_FAILURE;
	}

	return Status;
}
/*
* Check for transfer completion.
*
* If the DMA engine has errors or any of the finished BDs has error bit set,
* then the example should fail.
*
* @param	InstancePtr is pointer to the XAxiCdma instance.
*
* @return	Number of Bds that have been completed by hardware.
*
* @note		None
*
******************************************************************************/
static int CheckCompletion(XAxiCdma *InstancePtr)
{
	int BdCount;
	XAxiCdma_Bd *BdPtr;
	XAxiCdma_Bd *BdCurPtr;
	int Status;
	int Index;

	/* Check whether the hardware has encountered any problems.
	 * In some error cases, the DMA engine may not able to update the
	 * BD that has caused the problem.
	 */
	if (XAxiCdma_GetError(InstancePtr) != 0x0) {
		xdbg_printf(XDBG_DEBUG_ERROR, "Transfer error %x\r\n",
		    (unsigned int)XAxiCdma_GetError(InstancePtr));

		Error = 1;
		return 0;
	}

	/* Get all processed BDs from hardware
	 */
	BdCount = XAxiCdma_BdRingFromHw(InstancePtr, XAXICDMA_ALL_BDS, &BdPtr);

	/* Check finished BDs then release them
	 */
	if(BdCount > 0) {
		BdCurPtr = BdPtr;

		for (Index = 0; Index < BdCount; Index++) {

			/* If the completed BD has error bit set,
			 * then the example fails
			 */
			if (XAxiCdma_BdGetSts(BdCurPtr) &
			    XAXICDMA_BD_STS_ALL_ERR_MASK)	{
				Error = 1;
				return 0;
			}

			BdCurPtr = XAxiCdma_BdRingNext(InstancePtr, BdCurPtr);
		}

		/* Release the BDs so later submission can use them
		 */
		Status = XAxiCdma_BdRingFree(InstancePtr, BdCount, BdPtr);

		if(Status != XST_SUCCESS) {
			xdbg_printf(XDBG_DEBUG_ERROR,
			    "Error free BD %x\r\n", Status);

			Error = 1;
			return 0;
		}

		Done += BdCount;
	}

	return Done;
}
/**
*
* This function sets up the DMA engine to be ready for scatter gather transfer
*
* @param	InstancePtr is pointer to the XAxiCdma instance.
*
* @return
*		- XST_SUCCESS if the setup is successful
*		- XST_FAILURE if error occurs
*
* @note		None
*
******************************************************************************/
static int SetupTransfer(XAxiCdma * InstancePtr)
{
	int Status;
	XAxiCdma_Bd BdTemplate;
	int BdCount;
	u8 *SrcBufferPtr;
	int Index;

	/* Disable all interrupts
	 */
	XAxiCdma_IntrDisable(InstancePtr, XAXICDMA_XR_IRQ_ALL_MASK);

	/* Setup BD ring */
	BdCount = XAxiCdma_BdRingCntCalc(XAXICDMA_BD_MINIMUM_ALIGNMENT,
				    BD_SPACE_HIGH - BD_SPACE_BASE + 1,
				    (u32)BD_SPACE_BASE);

	Status = XAxiCdma_BdRingCreate(InstancePtr, BD_SPACE_BASE,
		BD_SPACE_BASE, XAXICDMA_BD_MINIMUM_ALIGNMENT, BdCount);
	if (Status != XST_SUCCESS) {
		xdbg_printf(XDBG_DEBUG_ERROR, "Create BD ring failed %d\r\n",
							 	Status);
		return XST_FAILURE;
	}

	/*
	 * Setup a BD template to copy to every BD.
	 */
	XAxiCdma_BdClear(&BdTemplate);
	Status = XAxiCdma_BdRingClone(InstancePtr, &BdTemplate);
	if (Status != XST_SUCCESS) {
		xdbg_printf(XDBG_DEBUG_ERROR, "Clone BD ring failed %d\r\n",
				Status);

		return XST_FAILURE;
	}

	/* Initialize receive buffer to 0's and transmit buffer with pattern
	 */
	memset((void *)ReceiveBufferPtr, 0,
		MAX_PKT_LEN * NUMBER_OF_BDS_TO_TRANSFER);

	SrcBufferPtr = (u8 *)TransmitBufferPtr;
	for(Index = 0; Index < MAX_PKT_LEN * NUMBER_OF_BDS_TO_TRANSFER; Index++) {
		SrcBufferPtr[Index] = Index & 0xFF;
	}

	/* Flush the SrcBuffer before the DMA transfer, in case the Data Cache
	 * is enabled
	 */
	Xil_DCacheFlushRange((UINTPTR)TransmitBufferPtr,
		MAX_PKT_LEN * NUMBER_OF_BDS_TO_TRANSFER);
#ifdef __aarch64__
	Xil_DCacheFlushRange((UINTPTR)ReceiveBufferPtr,
		MAX_PKT_LEN * NUMBER_OF_BDS_TO_TRANSFER);
#endif

	return XST_SUCCESS;
}
/**
 * Configure buffer addresses for one DMA channel
 *
 * The buffer addresses are physical addresses. 
 * Access to 32 Frame Buffer Addresses in direct mode is done through
 * XAxiVdma_ChannelHiFrmAddrEnable/Disable Functions.
 * 0 - Access Bank0 Registers (0x5C - 0x98) 
 * 1 - Access Bank1 Registers (0x5C - 0x98) 
 *
 * @param Channel is the pointer to the channel to work on
 * @param BufferAddrSet is the set of addresses for the transfers
 * @param NumFrames is the number of frames to set the address
 *
 * @return
 * - XST_SUCCESS if successful
 * - XST_FAILURE if channel has not being initialized
 * - XST_DEVICE_BUSY if the DMA channel is not idle, BDs are still being used
 * - XST_INVAID_PARAM if buffer address not valid, for example, unaligned
 * address with no DRE built in the hardware
 *
 *****************************************************************************/
int XAxiVdma_ChannelSetBufferAddr(XAxiVdma_Channel *Channel,
        u32 *BufferAddrSet, int NumFrames)
{
	int i;
	u32 WordLenBits;
	int HiFrmAddr = 0;
	int FrmBound = (XAXIVDMA_MAX_FRAMESTORE)/2 - 1;
	int Loop16 = 0;

	if (!Channel->IsValid) {
		xdbg_printf(XDBG_DEBUG_ERROR, "Channel not initialized\r\n");

		return XST_FAILURE;
	}

	WordLenBits = (u32)(Channel->WordLength - 1);

	/* If hardware has no DRE, then buffer addresses must
	 * be word-aligned
	 */
	for (i = 0; i < NumFrames; i++) {
		if (!Channel->HasDRE) {
			if (BufferAddrSet[i] & WordLenBits) {
				xdbg_printf(XDBG_DEBUG_ERROR,
				    "Unaligned address %d: %x without DRE\r\n",
				    i, BufferAddrSet[i]);

				return XST_INVALID_PARAM;
			}
		}
	}

	for (i = 0; i < NumFrames; i++, Loop16++) {
		XAxiVdma_Bd *BdPtr = (XAxiVdma_Bd *)(Channel->HeadBdAddr +
		         i * sizeof(XAxiVdma_Bd));

		if (Channel->HasSG) {
			XAxiVdma_BdSetAddr(BdPtr, BufferAddrSet[i]);
		}
		else {
			if ((i > FrmBound) && !HiFrmAddr) {
				XAxiVdma_ChannelHiFrmAddrEnable(Channel);
				HiFrmAddr = 1;
				Loop16 = 0;
			}
				
			XAxiVdma_WriteReg(Channel->StartAddrBase,
			    	XAXIVDMA_START_ADDR_OFFSET +
				Loop16 * XAXIVDMA_START_ADDR_LEN,
			    	BufferAddrSet[i]);

			if ((NumFrames > FrmBound) && (i == (NumFrames - 1)))
				XAxiVdma_ChannelHiFrmAddrDisable(Channel);
		}
	}

	return XST_SUCCESS;
}
/*
* This function does a multi-BD scatter gather transfer
*
* @param	InstancePtr points to the DMA engine instance
*
* @return
* 		- XST_SUCCESS if transfer finishes successfully
* 		- XST_FAILURE if transfer has errors
*
* @note		None.
*
******************************************************************************/
static int DoSgTransfer(XAxiCdma * InstancePtr)
{
	int Status;
	u8 *SrcPtr;
	u8 *DstPtr;

	SrcPtr = (u8 *)TransmitBufferPtr;
	DstPtr = (u8 *)ReceiveBufferPtr;

	/* Setup the BD ring
	 */
	Status = SetupSgTransfer(InstancePtr);
	if (Status != XST_SUCCESS) {
		xdbg_printf(XDBG_DEBUG_ERROR,
		    "Setup BD ring failed with %d\r\n", Status);

		return XST_FAILURE;
	}

	/* Submit BDs to the hardware
	 */
	Status = SubmitSgTransfer(InstancePtr);
	if (Status != XST_SUCCESS) {
		xdbg_printf(XDBG_DEBUG_ERROR,
		    "Submit transfer failed with %d\r\n", Status);

		return XST_FAILURE;
	}

	/* Wait until the DMA transfer is done
	 */
	while ((Done < NUMBER_OF_BDS_TO_TRANSFER) && !Error) {
		/* Wait */
	}

	if(Error) {
		xdbg_printf(XDBG_DEBUG_ERROR, "SG transfer has error %x\r\n",
		    (unsigned int)XAxiCdma_GetError(InstancePtr));

		return XST_FAILURE;
	}

	/* Transfer completes successfully, check data
	 */
	Status = CheckData(SrcPtr, DstPtr,
		MAX_PKT_LEN * NUMBER_OF_BDS_TO_TRANSFER);
	if (Status != XST_SUCCESS) {
		xdbg_printf(XDBG_DEBUG_ERROR, "Check data failed for sg "
		    "transfer\r\n");

		return XST_FAILURE;
	}

	/* Transfer finishes successfully
	 */
	return XST_SUCCESS;
}
/**
*
* This function sets up the TX channel of a DMA engine to be ready for packet
* transmission
*
* @param    AxiDmaInstPtr is the instance pointer to the DMA engine.
*
* @return   XST_SUCCESS if the setup is successful, XST_FAILURE otherwise.
*
* @note     None.
*
******************************************************************************/
static int TxSetup(XAxiDma * AxiDmaInstPtr)
{
	XAxiDma_BdRing *TxRingPtr;
	XAxiDma_Bd BdTemplate;
	int Delay = 0;
	int Coalesce = 1;
	int Status;
	u32 BdCount;

	TxRingPtr = XAxiDma_GetTxRing(&AxiDma);

	/* Disable all TX interrupts before TxBD space setup */

	XAxiDma_BdRingIntDisable(TxRingPtr, XAXIDMA_IRQ_ALL_MASK);

	/* Set TX delay and coalesce */
	XAxiDma_BdRingSetCoalesce(TxRingPtr, Coalesce, Delay);

	/* Setup TxBD space  */
	BdCount = XAxiDma_BdRingCntCalc(XAXIDMA_BD_MINIMUM_ALIGNMENT,
					TX_BD_SPACE_HIGH - TX_BD_SPACE_BASE + 1);

	Status = XAxiDma_BdRingCreate(TxRingPtr, TX_BD_SPACE_BASE,
				     TX_BD_SPACE_BASE,
				     XAXIDMA_BD_MINIMUM_ALIGNMENT, BdCount);
	if (Status != XST_SUCCESS) {
		xdbg_printf(XDBG_DEBUG_ERROR,
		    "failed create BD ring in txsetup\r\n");

		return XST_FAILURE;
	}

	/*
	 * We create an all-zero BD as the template.
	 */
	XAxiDma_BdClear(&BdTemplate);

	Status = XAxiDma_BdRingClone(TxRingPtr, &BdTemplate);
	if (Status != XST_SUCCESS) {
		xdbg_printf(XDBG_DEBUG_ERROR,
		    "failed bdring clone in txsetup %d\r\n", Status);

		return XST_FAILURE;
	}

	/* Start the TX channel */
	Status = XAxiDma_BdRingStart(TxRingPtr);
	if (Status != XST_SUCCESS) {
		xdbg_printf(XDBG_DEBUG_ERROR,
		    "failed start bdring txsetup %d\r\n", Status);

		return XST_FAILURE;
	}

	return XST_SUCCESS;
}
Beispiel #8
0
/*
*
* This function initializes a rxMapleBus instance/driver.
* All members of the rxMapleBus instance structure are initialized.
*
* @param	InstancePtr is a pointer to the rxMapleBus instance.
* @param	ConfigPtr points to the rxMapleBus device configuration structure.
* @param	EffectiveAddr is the device base address in the virtual memory
*           address space. If the address translation is not used then the
*           physical address should be passed. Unexpected errors may occur
*           if the address mapping is changed after this function is invoked.
*
* @return	XST_SUCCESS always.
*
* @note		None.
*
******************************************************************************/
int rxMapleBus_CfgInitialize(rxMapleBus *InstancePtr, rxMapleBus_Config *ConfigPtr,
				u32 EffectiveAddr)
{
	u32 reg;
	u32 timeout;

	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(ConfigPtr != NULL);

	/*
	 * Set some default values for instance data, don't indicate the device
	 * is ready to use until everything has been initialized successfully.
	 */
	InstancePtr->IsReady = 0;
	InstancePtr->MapleBusConfig.BaseAddr = EffectiveAddr;
	InstancePtr->MapleBusConfig.DeviceId = ConfigPtr->DeviceId;
	//InstancePtr->Handler = StubHandler;

	//TODO: We need to wait until TX and RX are 0 before we continue

	rxMapleBus_WriteReg(InstancePtr->MapleBusConfig.BaseAddr,
			  RXMAPLEBUS_REG0_OFFSET, RXMAPLEBUS_RESET_TX | RXMAPLEBUS_RESET_RX);
	
	for (timeout = 10; timeout > 0; --timeout) {
		reg = rxMapleBus_ReadReg(InstancePtr->MapleBusConfig.BaseAddr, RXMAPLEBUS_REG1_OFFSET);
		if (!reg) {
			break;
		}
	}
	if (!timeout) {
		xdbg_printf(XDBG_DEBUG_ERROR, "rxMapleBus failed reset in initialize\r\n");

		/* Need system hard reset to recover
		 */
		return XST_FAILURE;
	}

	rxMapleBus_WriteReg(InstancePtr->MapleBusConfig.BaseAddr,
			  RXMAPLEBUS_REG0_OFFSET, RXMAPLEBUS_ENABLE_LOOPBACK);

	reg = rxMapleBus_ReadReg(InstancePtr->MapleBusConfig.BaseAddr, RXMAPLEBUS_REG0_OFFSET);

	if (reg != RXMAPLEBUS_ENABLE_LOOPBACK) {
		xdbg_printf(XDBG_DEBUG_ERROR, "rxMapleBus failed setup in initialize\r\n");

		/* Hardware error */
		return XST_FAILURE;
	}

	/*
	 * Indicate the component is now ready to use.
	 */
	InstancePtr->IsReady = XIL_COMPONENT_IS_READY;

	return XST_SUCCESS;
}
Beispiel #9
0
/**
*
* Default Prefetch abort handler which prints prefetch fault status register through
* which information about instruction prefetch fault can be acquired
*
* @param	None
*
* @return	None.
*
* @note		None.
*
****************************************************************************/
void Xil_PrefetchAbortHandler(void *CallBackRef){
	u32 FaultStatus;
	#ifdef __GNUC__
		FaultStatus = mfcp(XREG_CP15_INST_FAULT_STATUS);
	#elif defined (__ICCARM__)
		mfcp(XREG_CP15_INST_FAULT_STATUS,FaultStatus);
	#else
		{ volatile register u32 Reg __asm(XREG_CP15_INST_FAULT_STATUS);
	  FaultStatus = Reg; }
	#endif
	xdbg_printf(XDBG_DEBUG_GENERAL, "Prefetch abort with Instruction Fault Status Register  %x\n",FaultStatus);
	xdbg_printf(XDBG_DEBUG_GENERAL, "Address of Instrcution causing Prefetch abort %x\n",PrefetchAbortAddr);
	while(1) {
		;
	}
}
/**
* @brief    Update the MPU configuration for the requested region number in
* 			the global MPU configuration table.
*
* @param	reg_num: The requested region number to be updated information for.
* @param	address: 32 bit address for start of the region.
* @param	size: Requested size of the region.
* @param	attrib: Attribute for the corresponding region.
* @return	XST_FAILURE: When the requested region number if 16 or more.
* 			XST_SUCCESS: When the MPU configuration table is updated.
*
*
******************************************************************************/
u32 Xil_UpdateMPUConfig(u32 reg_num, INTPTR address, u32 size, u32 attrib)
{
	u32 ReturnVal = XST_SUCCESS;
	u32 Tempsize = size;
	u32 Index;

	if (reg_num >=  MAX_POSSIBLE_MPU_REGS) {
		xdbg_printf(DEBUG, "Invalid region number\r\n");
		ReturnVal = XST_FAILURE;
		goto exit;
	}

	if (size & REGION_EN) {
		Mpu_Config[reg_num].RegionStatus = MPU_REG_ENABLED;
		Mpu_Config[reg_num].BaseAddress = address;
		Tempsize &= (~REGION_EN);
		Tempsize >>= 1;
		/* Lookup the size.  */
		for (Index = 0; Index <
				sizeof region_size / sizeof region_size[0]; Index++) {
			if (Tempsize <= region_size[Index].encoding) {
				Mpu_Config[reg_num].Size = region_size[Index].size;
				break;
			}
		}
		Mpu_Config[reg_num].Attribute = attrib;
	} else {
Beispiel #11
0
/**
*
* Default undefined exception handler which prints address of the undefined
* instruction if debug prints are enabled
*
* @param	None
*
* @return	None.
*
* @note		None.
*
****************************************************************************/
void Xil_UndefinedExceptionHandler(void *CallBackRef){

	xdbg_printf(XDBG_DEBUG_GENERAL, "Address of the undefined instruction %x\n",UndefinedExceptionAddr);
	while(1) {
		;
	}
}
/**
*
* Main function
*
* This function is the main entry of the tests on DMA core. It sets up
* DMA engine to be ready to receive and send packets, then a packet is
* transmitted and will be verified after it is received via the loopback on the
* Local Link interface of the DMA.
*
* @return   0 if tests pass, 1 otherwise.
*
* @note     None.
*
******************************************************************************/
int main(void)
{
	int Status;
	XAxiDma_Config *Config;

#if defined(XPAR_UARTNS550_0_BASEADDR)

	Uart550_Setup();

#endif

	xil_printf("\r\n--- Entering main() --- \r\n");

	Config = XAxiDma_LookupConfig(DMA_DEV_ID);
	if (!Config) {
		xdbg_printf(XDBG_DEBUG_ERROR,
		    "No config found for %d\r\n", DMA_DEV_ID);

		return 1;
	}

	/* Initialize DMA engine */
	Status = XAxiDma_CfgInitialize(&AxiDma, Config);
	if (Status != XST_SUCCESS) {
		xil_printf("Initialization failed %d\r\n", Status);
		return 1;
	}

	Status = TxSetup(&AxiDma);
	if (Status != XST_SUCCESS) {
		return 1;
	}

	Status = RxSetup(&AxiDma);
	if (Status != XST_SUCCESS) {
		return 1;
	}

	/* Send a packet */
	Status = SendPacket(&AxiDma);
	if (Status != XST_SUCCESS) {
		return 1;
	}

	/* Check DMA transfer result */
	Status = CheckDmaResult(&AxiDma);

	xil_printf("Test %s\r\n",
		(Status == XST_SUCCESS)? "passed":"failed");

	xil_printf("--- Exiting main() --- \r\n");

	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	return 0;
}
/**
 * Start a transfer
 *
 * This function setup the DMA engine and start the engine to do the transfer.
 *
 * @param Channel is the pointer to the channel to work on
 * @param ChannelCfgPtr is the pointer to the setup structure
 *
 * @return
 * - XST_SUCCESS for a successful submission
 * - XST_FAILURE if channel has not being initialized
 * - XST_DEVICE_BUSY if the DMA channel is not idle, BDs are still being used
 * - XST_INVAID_PARAM if parameters in config structure not valid
 *
 *****************************************************************************/
int XAxiVdma_ChannelStartTransfer(XAxiVdma_Channel *Channel,
    XAxiVdma_ChannelSetup *ChannelCfgPtr)
{
	int Status;

	if (!Channel->IsValid) {
		xdbg_printf(XDBG_DEBUG_ERROR, "Channel not initialized\r\n");

		return XST_FAILURE;
	}

	if (Channel->HasSG && XAxiVdma_ChannelIsBusy(Channel)) {
		xdbg_printf(XDBG_DEBUG_ERROR,
		    "Channel is busy, cannot setup engine for transfer\r\n");

		return XST_DEVICE_BUSY;
	}

	Status = XAxiVdma_ChannelConfig(Channel, ChannelCfgPtr);
	if (Status != XST_SUCCESS) {
		xdbg_printf(XDBG_DEBUG_ERROR,
		    "Channel config failed %d\r\n", Status);

		return Status;
	}

	Status = XAxiVdma_ChannelSetBufferAddr(Channel,
	    ChannelCfgPtr->FrameStoreStartAddr, Channel->AllCnt);
	if (Status != XST_SUCCESS) {
		xdbg_printf(XDBG_DEBUG_ERROR,
		    "Channel setup buffer addr failed %d\r\n", Status);

		return Status;
	}

	Status = XAxiVdma_ChannelStart(Channel);
	if (Status != XST_SUCCESS) {
		xdbg_printf(XDBG_DEBUG_ERROR,
		    "Channel start failed %d\r\n", Status);

		return Status;
	}

	return XST_SUCCESS;
}
/**
*
* This function performs self test on DisplayPort Receiver Subsystem
* sub-cores.
*
* @param	InstancePtr is a pointer to the XDpRxSs core instance.
*
* @return
*		- XST_SUCCESS if self test passed.
*		- Otherwise, prints self test failed message.
*
* @note		None.
*
******************************************************************************/
u32 XDpRxSs_SelfTest(XDpRxSs *InstancePtr)
{
	u32 Status;

	/* Verify argument. */
	Xil_AssertNonvoid(InstancePtr != NULL);

	/* Check DP availability */
	if (InstancePtr->DpPtr) {
		Status = XDp_SelfTest(InstancePtr->DpPtr);
		if (Status != XST_SUCCESS) {
			xdbg_printf(XDBG_DEBUG_GENERAL,"ERR::DP Self test "
				"failed\n\r");
		}
	}

#if (XPAR_XHDCP_NUM_INSTANCES > 0)
	if ((InstancePtr->Hdcp1xPtr) && (InstancePtr->Config.HdcpEnable)) {
		Status = XHdcp1x_SelfTest(InstancePtr->Hdcp1xPtr);
		if (Status != XST_SUCCESS) {
			xdbg_printf(XDBG_DEBUG_GENERAL,"ERR::HDCP Self test "
				"failed\r\n");
		}
	}

	if (InstancePtr->TmrCtrPtr) {
		Status = XTmrCtr_SelfTest(InstancePtr->TmrCtrPtr, 0);
		if (Status != XST_SUCCESS) {
			xdbg_printf(XDBG_DEBUG_GENERAL,"ERR::Timer Counter "
				"Self test failed\r\n");
		}
	}
#endif

	/* Check IIC availability */
	if (InstancePtr->IicPtr) {
		Status = (u32)XIic_SelfTest(InstancePtr->IicPtr);
		if (Status != XST_SUCCESS) {
			xdbg_printf(XDBG_DEBUG_GENERAL,"ERR::IIC Self test "
				"failed\n\r");
		}
	}

	return XST_SUCCESS;
}
Beispiel #15
0
/**
*
* This function sets transport mode (SST/MST).
*
* @param	InstancePtr is a pointer to the XDpTxSs core instance.
* @param	Mode specifies the type of transport mode that will be set.
*		- 0 = Single-Stream Transport mode,
*		- 1 = Multi-Stream Transport mode,
*
* @return
*		- XST_SUCCESS, if transport mode is set successfully to either
*		 MST or SST when RX device is MST and mode is less than or
*		 equal to supported mode.
*		- XST_FAILURE, if setting to already set mode or mode is
*		greater than supported mode.
*
* @note		Transport mode is set to either MST or SST when system is MST
*		and RX device is MST capable.
*
******************************************************************************/
u32 XDpTxSs_SetTransportMode(XDpTxSs *InstancePtr, u8 Mode)
{
	u32 Status;

	/* Verify arguments. */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid((Mode == 0x0) || (Mode == 0x1));

	/* Check for MST */
	if (Mode == InstancePtr->UsrOpt.MstSupport) {
		xdbg_printf(XDBG_DEBUG_GENERAL,"SS INFO:Subsystem is "
			"already in %s mode \n\r",Mode?"MST":"SST");
		Status = XST_FAILURE;
	}
	/* Check for mode less than supported mode */
	else if (Mode <= InstancePtr->Config.MstSupport) {
		/* Check RX device is MST capable */
		Status = XDp_TxMstCapable(InstancePtr->DpPtr);
		if ((Status != XST_SUCCESS) && (Mode >
					InstancePtr->UsrOpt.MstSupport)) {
			xdbg_printf(XDBG_DEBUG_GENERAL,"SS INFO: RX device "
				"is SST capable. No change in mode.\n\r");
			Status = XST_FAILURE;
		}
		else if ((Status == XST_SUCCESS) && ((Mode <
				InstancePtr->UsrOpt.MstSupport) ||
				(Mode > InstancePtr->UsrOpt.MstSupport))) {
			xdbg_printf(XDBG_DEBUG_GENERAL,"SS INFO::setting "
				"Subsystem mode from %s to %s mode \n\r",
				(InstancePtr->UsrOpt.MstSupport?"MST":"SST"),
				(Mode?"MST":"SST"));

			InstancePtr->UsrOpt.MstSupport = Mode;
			Status = XST_SUCCESS;
		}
	}
	/* Everything else */
	else {
		xdbg_printf(XDBG_DEBUG_GENERAL,"SS ERR::Subsystem does not "
			"support %s \n\r", Mode?"MST":"SST");
		Status = XST_FAILURE;
	}

	return Status;
}
Beispiel #16
0
void Xil_DataAbortHandler(void *CallBackRef){
	u32 FaultStatus;

        xdbg_printf(XDBG_DEBUG_ERROR, "Data abort \n");
        #ifdef __GNUC__
	FaultStatus = mfcp(XREG_CP15_DATA_FAULT_STATUS);
	    #elif defined (__ICCARM__)
	        mfcp(XREG_CP15_DATA_FAULT_STATUS,FaultStatus);
	    #else
	        { volatile register u32 Reg __asm(XREG_CP15_DATA_FAULT_STATUS);
	        FaultStatus = Reg; }
	    #endif
	xdbg_printf(XDBG_DEBUG_GENERAL, "Data abort with Data Fault Status Register  %x\n",FaultStatus);
	xdbg_printf(XDBG_DEBUG_GENERAL, "Address of Instrcution causing Data abort %x\n",DataAbortAddr);
	while(1) {
		;
	}
}
/**
 * Set the frame counter and delay counter for one channel
 *
 * @param Channel is the pointer to the channel to work on
 * @param FrmCnt is the frame counter value to be set
 * @param DlyCnt is the delay counter value to be set
 *
 * @return
 *   - XST_SUCCESS if setup finishes successfully
 *   - XST_FAILURE if channel is not initialized
 *   - XST_INVALID_PARAM if the configuration structure has invalid values
 *   - XST_NO_FEATURE if Frame Counter or Delay Counter is disabled
 *
 *****************************************************************************/
int XAxiVdma_ChannelSetFrmCnt(XAxiVdma_Channel *Channel, u8 FrmCnt, u8 DlyCnt)
{
	u32 CrBits;

	if (!Channel->IsValid) {
		xdbg_printf(XDBG_DEBUG_ERROR, "Channel not initialized\r\n");

		return XST_FAILURE;
	}

	if (!FrmCnt) {
		xdbg_printf(XDBG_DEBUG_ERROR,
		    "Frame counter value must be non-zero\r\n");

		return XST_INVALID_PARAM;
	}

	CrBits = XAxiVdma_ReadReg(Channel->ChanBase, XAXIVDMA_CR_OFFSET) &
		~(XAXIVDMA_DELAY_MASK | XAXIVDMA_FRMCNT_MASK);

	if (Channel->DbgFeatureFlags & XAXIVDMA_ENABLE_DBG_FRM_CNTR) {
		CrBits |= (FrmCnt << XAXIVDMA_FRMCNT_SHIFT);
	} else {
		xdbg_printf(XDBG_DEBUG_ERROR,
		    "Channel Frame counter is disabled\r\n");
		return XST_NO_FEATURE;
	}
	if (Channel->DbgFeatureFlags & XAXIVDMA_ENABLE_DBG_DLY_CNTR) {
		CrBits |= (DlyCnt << XAXIVDMA_DELAY_SHIFT);
	} else {
		xdbg_printf(XDBG_DEBUG_ERROR,
		    "Channel Delay counter is disabled\r\n");
		return XST_NO_FEATURE;
	}

	XAxiVdma_WriteReg(Channel->ChanBase, XAXIVDMA_CR_OFFSET,
	    CrBits);

	return XST_SUCCESS;
}
/**
*
* Default Prefetch abort handler which prints prefetch fault status register through
* which information about instruction prefetch fault can be acquired
*
* @param	None
*
* @return	None.
*
* @note		None.
*
****************************************************************************/
void Xil_PrefetchAbortHandler(void *CallBackRef){
	u32 FaultStatus;
	#ifdef __GNUC__
		FaultStatus = mfcp(XREG_CP15_INST_FAULT_STATUS);
	#elif defined (__ICCARM__)
		mfcp(XREG_CP15_INST_FAULT_STATUS,FaultStatus);
	#else
		{ volatile register unsigned int Reg __asm(XREG_CP15_INST_FAULT_STATUS);
	  FaultStatus = Reg; }
	#endif
	xdbg_printf(XDBG_DEBUG_ERROR, "Prefetch abort with Instruction Fault Status Register  %x\n",FaultStatus);
	while(1);
}
Beispiel #19
0
/**
 * Set the APP word at the specified APP word offset for a BD.
 *
 * @param	BdPtr is the BD to operate on.
 * @param	Offset is the offset inside the APP word, it is valid from
 *		0 to 4
 * @param	Word is the value to set
 *
 * @returns
 *		- XST_SUCCESS for success
 *		- XST_INVALID_PARAM under following error conditions:
 *		1) StsCntrlStrm is not built in hardware
 *		2) Offset is not in valid range
 *
 * @note
 *		If the hardware build has C_SG_USE_STSAPP_LENGTH set to 1,
 *		then the last APP word, XAXIDMA_LAST_APPWORD, must have
 *		non-zero value when AND with 0x7FFFFF. Not doing so will cause
 *		the hardware to stall.
 *		This function can be used only when DMA is in SG mode
 *
 *****************************************************************************/
int XAxiDma_BdSetAppWord(XAxiDma_Bd* BdPtr, int Offset, u32 Word)
{
	if (XAxiDma_BdRead(BdPtr, XAXIDMA_BD_HAS_STSCNTRL_OFFSET) == 0) {

		xdbg_printf(XDBG_DEBUG_ERROR, "BdRingSetAppWord: no sts cntrl"
			"stream in hardware build, cannot set app word\r\n");

		return XST_INVALID_PARAM;
	}

	if ((Offset < 0) || (Offset > XAXIDMA_LAST_APPWORD)) {

		xdbg_printf(XDBG_DEBUG_ERROR, "BdRingSetAppWord: invalid"
			"offset %d",Offset);

		return XST_INVALID_PARAM;
	}

	XAxiDma_BdWrite(BdPtr, XAXIDMA_BD_USR0_OFFSET + Offset * 4, Word);

	return XST_SUCCESS;
}
/*
* Callback function for the scatter gather transfer.
* It is called by the driver's interrupt handler.
*
* @param	CallBackRef is the reference pointer registered through
*		transfer submission. In this case, it is the pointer to the
*		driver instance
* @param	IrqMask is the interrupt mask the driver interrupt handler
*		passes to the callback function.
* @param	NumBdPtr is the pointer to number of BDs this handler handles
*
* @return	None
*
* @note		None.
*
******************************************************************************/
static void Example_SgCallBack(void *CallBackRef, u32 IrqMask, int *NumBdPtr)
{

	XAxiCdma *InstancePtr;
	int BdCount;
	XAxiCdma_Bd *BdPtr;
	int Status;
	int Tmp;

	InstancePtr = (XAxiCdma *)CallBackRef;
	Tmp = *NumBdPtr;

	/* If error interrupt happened, the driver interrupt handler
	 * has already reset the hardware
	 */
	if (IrqMask & XAXICDMA_XR_IRQ_ERROR_MASK) {
		Error = 1;
	}

	if (IrqMask & XAXICDMA_XR_IRQ_IOC_MASK) {

		/* Get all processed BDs from hardware
		 */
		BdCount = XAxiCdma_BdRingFromHw(InstancePtr, Tmp, &BdPtr);

		/* Release finished BDs
		 *
		 * It is ok if BdCount is zero as a previous callback may
		 * have ripen all finished BDs
		 */
		if(BdCount > 0) {

			Status = XAxiCdma_BdRingFree(InstancePtr,
			              BdCount, BdPtr);

			if(Status != XST_SUCCESS) {
				xdbg_printf(XDBG_DEBUG_ERROR,
				"Error free BD %x\r\n", Status);

				Error = 1;
				return;
			}

			Done += BdCount;
			*NumBdPtr = Tmp - BdCount;
		}
	}

	return;
}
Beispiel #21
0
/**
 * This function configures KeyHole Write/Read Feature
 *
 * @param	InstancePtr is the driver instance we are working on
 *
 * @param	Direction is WRITE/READ
 * @Select	Select is the option to enable (TRUE) or disable (FALSE).
 *
 * @return	- XST_SUCCESS for success
 *		- XST_DEVICE_BUSY when transfer is in progress
 *		- XST_NO_FEATURE when not configured with feature
 *
 * @note	None.
 *
 *****************************************************************************/
int XAxiCdma_SelectKeyHole(XAxiCdma *InstancePtr, u32 Direction, u32 Select)
{
	u32 Value;

	if (XAxiCdma_IsBusy(InstancePtr)) {
		xdbg_printf(XDBG_DEBUG_ERROR,
		    "KeyHole: Transfer is in Progress\n\r");
		return XST_DEVICE_BUSY;
	}

	Value = XAxiCdma_ReadReg(InstancePtr->BaseAddr, 
				XAXICDMA_CR_OFFSET);

	if (Select) {
		if (XPAR_AXICDMA_0_M_AXI_MAX_BURST_LEN == 16) {
			if (Direction == XAXICDMA_KEYHOLE_WRITE)
				Value |= XAXICDMA_CR_KHOLE_WR_MASK;
			else
				Value |= XAXICDMA_CR_KHOLE_RD_MASK;
		} else {
			xdbg_printf(XDBG_DEBUG_ERROR,
				"KeyHole: Max Burst length should be 16\n\r");
			return XST_NO_FEATURE;
		}
	}
	else {
		if (Direction == XAXICDMA_KEYHOLE_WRITE)
			Value &= ~XAXICDMA_CR_KHOLE_WR_MASK;
		else
			Value &= ~XAXICDMA_CR_KHOLE_RD_MASK; 
	}

	XAxiCdma_WriteReg(InstancePtr->BaseAddr,
			XAXICDMA_CR_OFFSET, Value);

	return XST_SUCCESS;
}
/**
 * Interrupt handler for the write channel
 *
 * @param InstancePtr is the pointer to the DMA engine to work on
 *
 * @return
 *  None
 *
 * @note
 * If the channel is invalid, then no interrupt handling
 *****************************************************************************/
void XAxiVdma_WriteIntrHandler(void * InstancePtr)
{
	XAxiVdma *DmaPtr;
	XAxiVdma_Channel *Channel;
	XAxiVdma_ChannelCallBack *CallBack;
	u32 PendingIntr;

	DmaPtr = (XAxiVdma *)InstancePtr;

	Channel = XAxiVdma_GetChannel(DmaPtr, XAXIVDMA_WRITE);

	if (!Channel->IsValid) {
		xdbg_printf(XDBG_DEBUG_ERROR,
		    "Write channel is invalid, no intr handling\n\r");

		return;
	}

	PendingIntr = XAxiVdma_ChannelGetPendingIntr(Channel);
	PendingIntr &= XAxiVdma_ChannelGetEnabledIntr(Channel);

	XAxiVdma_ChannelIntrClear(Channel, PendingIntr);

	CallBack = &(DmaPtr->WriteCallBack);

	if (!CallBack->CompletionCallBack) {

		return;
	}
	
	if (!PendingIntr || (PendingIntr & XAXIVDMA_IXR_ERROR_MASK)) {

		CallBack->ErrCallBack(CallBack->ErrRef,
		    PendingIntr & XAXIVDMA_IXR_ERROR_MASK);

		/* The channel's error callback should reset the channel
		 * There is no need to handle other interrupts
		 */
		return;
	}

	if (PendingIntr & XAXIVDMA_IXR_COMPLETION_MASK) {

		CallBack->CompletionCallBack(CallBack->CompletionRef,
		    PendingIntr);
	}

	return;
}
/**
 * Setup BD addresses to a different memory region
 *
 * In some systems, it is convenient to put BDs into a certain region of the
 * memory. This function enables that.
 *
 * @param Channel is the pointer to the channel to work on
 * @param BdAddrPhys is the physical starting address for BDs
 * @param BdAddrVirt is the Virtual starting address for BDs. For systems that
 *         do not use MMU, then virtual address is the same as physical address
 *
 * @return
 * - XST_SUCCESS for a successful setup
 * - XST_DEVICE_BUSY if the DMA channel is not idle, BDs are still being used
 *
 * @notes
 * We assume that the memory region starting from BdAddrPhys is large enough
 * to hold all the BDs.
 *
 *****************************************************************************/
int XAxiVdma_ChannelSetBdAddrs(XAxiVdma_Channel *Channel, UINTPTR BdAddrPhys,
		UINTPTR BdAddrVirt)
{
	int NumFrames = Channel->AllCnt;
	int i;
	UINTPTR NextPhys = BdAddrPhys;
	UINTPTR CurrVirt = BdAddrVirt;

	if (Channel->HasSG && XAxiVdma_ChannelIsBusy(Channel)) {
		xdbg_printf(XDBG_DEBUG_ERROR,
		    "Channel is busy, cannot setup engine for transfer\r\n");

		return XST_DEVICE_BUSY;
	}

	memset((void *)BdAddrPhys, 0, NumFrames * sizeof(XAxiVdma_Bd));
	memset((void *)BdAddrVirt, 0, NumFrames * sizeof(XAxiVdma_Bd));

	/* Set up the BD link list */
	for (i = 0; i < NumFrames; i++) {
		XAxiVdma_Bd *BdPtr;

		BdPtr = (XAxiVdma_Bd *)CurrVirt;

		/* The last BD connects to the first BD
		 */
		if (i == (NumFrames - 1)) {
			NextPhys = BdAddrPhys;
		}
		else {
			NextPhys += sizeof(XAxiVdma_Bd);
		}

		XAxiVdma_BdSetNextPtr(BdPtr, NextPhys);
		CurrVirt += sizeof(XAxiVdma_Bd);
	}

	/* Setup the BD addresses so that access the head/tail BDs fast
	 *
	 */
	Channel->HeadBdPhysAddr = BdAddrPhys;
	Channel->HeadBdAddr = BdAddrVirt;
	Channel->TailBdPhysAddr = BdAddrPhys +
	                          (NumFrames - 1) * sizeof(XAxiVdma_Bd);
	Channel->TailBdAddr = BdAddrVirt +
	                          (NumFrames - 1) * sizeof(XAxiVdma_Bd);

	return XST_SUCCESS;
}
Beispiel #24
0
/**
 * Get the APP word at the specified APP word offset for a BD.
 *
 * @param	BdPtr is the BD to operate on.
 * @param	Offset is the offset inside the APP word, it is valid from
 *		0 to 4
 * @param	Valid is to tell the caller whether parameters are valid
 *
 * @returns
 *		The APP word. Passed in parameter Valid holds 0 for failure,
 *		and 1 for success.
 *
 * @note	This function can be used only when DMA is in SG mode
 *
 *****************************************************************************/
u32 XAxiDma_BdGetAppWord(XAxiDma_Bd* BdPtr, int Offset, int *Valid)
{
	*Valid = 0;

	if (XAxiDma_BdRead(BdPtr, XAXIDMA_BD_HAS_STSCNTRL_OFFSET) == 0) {

		xdbg_printf(XDBG_DEBUG_ERROR, "BdRingGetAppWord: no sts cntrl "
			"stream in hardware build, no app word available\r\n");

		return (u32)0;
	}

	if((Offset < 0) || (Offset > XAXIDMA_LAST_APPWORD)) {

		xdbg_printf(XDBG_DEBUG_ERROR, "BdRingGetAppWord: invalid"
			" offset %d", Offset);

		return (u32)0;
	}

	*Valid = 1;

	return XAxiDma_BdRead(BdPtr, XAXIDMA_BD_USR0_OFFSET + Offset * 4);
}
Beispiel #25
0
/**
 * Set the length field for the given BD.
 *
 * Length has to be non-zero and less than LengthMask.
 *
 * For TX channels, the value passed in should be the number of bytes to
 * transmit from the TX buffer associated with the given BD.
 *
 * For RX channels, the value passed in should be the size of the RX buffer
 * associated with the given BD in bytes. This is to notify the RX channel
 * the capability of the RX buffer to avoid buffer overflow.
 *
 * The actual receive length can be equal or smaller than the specified length.
 * The actual transfer length will be updated by the hardware in the
 * XAXIDMA_BD_STS_OFFSET word in the BD.
 *
 * @param	BdPtr is the BD to operate on.
 * @param	LenBytes is the requested transfer length
 * @param	LengthMask is the maximum transfer length
 *
 * @returns
 *		- XST_SUCCESS for success
 *		- XST_INVALID_PARAM for invalid BD length
 *
 * @note	This function can be used only when DMA is in SG mode
 *
 *****************************************************************************/
int XAxiDma_BdSetLength(XAxiDma_Bd *BdPtr, u32 LenBytes, u32 LengthMask)
{
	if (LenBytes <= 0 || (LenBytes > LengthMask)) {

		xdbg_printf(XDBG_DEBUG_ERROR, "invalid length %d\n",
		    (int)LenBytes);

		return XST_INVALID_PARAM;
	}

	XAxiDma_BdWrite((BdPtr), XAXIDMA_BD_CTRL_LEN_OFFSET,
		((XAxiDma_BdRead((BdPtr), XAXIDMA_BD_CTRL_LEN_OFFSET) & \
		~LengthMask)) | LenBytes);

	return XST_SUCCESS;
}
Beispiel #26
0
/**
 * Get a channel
 *
 * @param InstancePtr is the DMA engine to work on
 * @param Direction is the direction for the channel to get
 *
 * @return
 * The pointer to the channel. Upon error, return NULL.
 *
 * @note
 * Since this function is internally used, we assume Direction is valid
 *****************************************************************************/
XAxiVdma_Channel *XAxiVdma_GetChannel(XAxiVdma *InstancePtr,
        u16 Direction)
{

	if (Direction == XAXIVDMA_READ) {
		return &(InstancePtr->ReadChannel);
	}
	else if (Direction == XAXIVDMA_WRITE) {
		return &(InstancePtr->WriteChannel);
	}
	else {
		xdbg_printf(XDBG_DEBUG_ERROR,
		    "Invalid direction %x\r\n", Direction);

		return NULL;
	}
}
/**
 * Get the frame counter and delay counter for both channels
 *
 * @param Channel is the pointer to the channel to work on
 * @param FrmCnt is the pointer for the returning frame counter value
 * @param DlyCnt is the pointer for the returning delay counter value
 *
 * @return
 *  None
 *
 * @note
 *  If FrmCnt return as 0, then the channel is not initialized
 *****************************************************************************/
void XAxiVdma_ChannelGetFrmCnt(XAxiVdma_Channel *Channel, u8 *FrmCnt,
        u8 *DlyCnt)
{
	u32 CrBits;

	if (!Channel->IsValid) {
		xdbg_printf(XDBG_DEBUG_ERROR, "Channel not initialized\r\n");

		*FrmCnt = 0;
		return;
	}

	CrBits = XAxiVdma_ReadReg(Channel->ChanBase, XAXIVDMA_CR_OFFSET);

	if (Channel->DbgFeatureFlags & XAXIVDMA_ENABLE_DBG_FRM_CNTR) {
		*FrmCnt = (CrBits & XAXIVDMA_FRMCNT_MASK) >>
				XAXIVDMA_FRMCNT_SHIFT;
	} else {
/**
 * Set the channel to run in parking mode
 *
 * @param Channel is the pointer to the channel to work on
 *
 * @return
 *   - XST_SUCCESS if everything is fine
 *   - XST_FAILURE if hardware is not running
 *
 *****************************************************************************/
int XAxiVdma_ChannelStartParking(XAxiVdma_Channel *Channel)
{
	u32 CrBits;

	if (!XAxiVdma_ChannelIsRunning(Channel)) {
		xdbg_printf(XDBG_DEBUG_ERROR,
		    "Channel is not running, cannot start park mode\r\n");

		return XST_FAILURE;
	}

	CrBits = XAxiVdma_ReadReg(Channel->ChanBase, XAXIVDMA_CR_OFFSET) &
	            ~XAXIVDMA_CR_TAIL_EN_MASK;

	XAxiVdma_WriteReg(Channel->ChanBase, XAXIVDMA_CR_OFFSET,
	    CrBits);

	return XST_SUCCESS;
}
/*
* This function checks that two buffers have the same data
*
* @param	SrcPtr is the source buffer
* @param	DestPtr is the destination buffer
* @param	Length is the length of the buffer to check
*
* @return
*		- XST_SUCCESS if the two buffer matches
*		- XST_FAILURE otherwise
*
* @note		None
*
******************************************************************************/
static int CheckData(u8 *SrcPtr, u8 *DestPtr, int Length)
{
	int Index;

	/* Invalidate the DestBuffer before receiving the data, in case the
	 * Data Cache is enabled
	 */
	Xil_DCacheInvalidateRange((u32)DestPtr, Length);

	for (Index = 0; Index < Length; Index++) {
		if ( DestPtr[Index] != SrcPtr[Index]) {
			xdbg_printf(XDBG_DEBUG_ERROR,
			    "Data check failure %d: %x/%x\r\n",
			    Index, DestPtr[Index], SrcPtr[Index]);

			return XST_FAILURE;
		}
	}

	return XST_SUCCESS;
}
/**
* @brief    Set the memory attributes for a section of memory in the
*           translation table.
*
* @param	Addr: 32-bit address for which memory attributes need to be set..
* @param	size: size is the size of the region.
* @param	attrib: Attribute for the given memory region.
* @return	None.
*
*
******************************************************************************/
u32 Xil_SetMPURegion(INTPTR addr, u64 size, u32 attrib)
{
	u32 Regionsize = 0;
	INTPTR Localaddr = addr;
	u32 NextAvailableMemRegion;
	unsigned int i;

	NextAvailableMemRegion = Xil_GetNextMPURegion();
	if (NextAvailableMemRegion == 0xFF) {
		xdbg_printf(DEBUG, "No regions available\r\n");
		return XST_FAILURE;
	}

	Xil_DCacheFlush();
	Xil_ICacheInvalidate();

	mtcp(XREG_CP15_MPU_MEMORY_REG_NUMBER,NextAvailableMemRegion);
	isb();

	/* Lookup the size.  */
	for (i = 0; i < sizeof region_size / sizeof region_size[0]; i++) {
		if (size <= region_size[i].size) {
			Regionsize = region_size[i].encoding;
			break;
		}
	}

	Localaddr &= ~(region_size[i].size - 1);

	Regionsize <<= 1;
	Regionsize |= REGION_EN;
	dsb();
	mtcp(XREG_CP15_MPU_REG_BASEADDR, Localaddr);	/* Set base address of a region */
	mtcp(XREG_CP15_MPU_REG_ACCESS_CTRL, attrib);	/* Set the control attribute */
	mtcp(XREG_CP15_MPU_REG_SIZE_EN, Regionsize);	/* set the region size and enable it*/
	dsb();
	isb();
	Xil_UpdateMPUConfig(NextAvailableMemRegion, Localaddr, Regionsize, attrib);
	return XST_SUCCESS;
}