⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mcd_dmaapi.c

📁 uboot详细解读可用启动引导LINUX2.6内核
💻 C
📖 第 1 页 / 共 3 页
字号:
				     contextSaveSpace)[CURRBD + CSAVE_OFFSET];		/* See if they match: */		if (prevRep.lastSrcAddr != progRep->lastSrcAddr		    || prevRep.lastDestAddr != progRep->lastDestAddr		    || prevRep.dmaSize != progRep->dmaSize		    || prevRep.currBufDesc != progRep->currBufDesc) {			/* If they don't match, remember previous values and			   try again: */			prevRep.lastSrcAddr = progRep->lastSrcAddr;			prevRep.lastDestAddr = progRep->lastDestAddr;			prevRep.dmaSize = progRep->dmaSize;			prevRep.currBufDesc = progRep->currBufDesc;			again = MCD_TRUE;		} else			again = MCD_FALSE;	} while (again == MCD_TRUE);	/* Update the dCount, srcAddr and destAddr */	/* To calculate dmaCount, we consider destination address. C	   overs M1,P1,Z for destination */	switch (MCD_remVariants.remDestRsdIncr[channel]) {	case MINUS1:		subModVal =		    ((int)progRep->		     lastDestAddr) & ((MCD_remVariants.remXferSize[channel]) -				      1);		addModVal =		    ((int)progRep->currBufDesc->		     destAddr) & ((MCD_remVariants.remXferSize[channel]) - 1);		LWAlignedInitDestAddr =		    (progRep->currBufDesc->destAddr) - addModVal;		LWAlignedCurrDestAddr = (progRep->lastDestAddr) - subModVal;		destDiffBytes = LWAlignedInitDestAddr - LWAlignedCurrDestAddr;		bytesNotXfered =		    (destDiffBytes / MCD_remVariants.remDestIncr[channel]) *		    (MCD_remVariants.remDestIncr[channel]		     + MCD_remVariants.remXferSize[channel]);		progRep->dmaSize =		    destDiffBytes - bytesNotXfered + addModVal - subModVal;		break;	case ZERO:		progRep->lastDestAddr = progRep->currBufDesc->destAddr;		break;	case PLUS1:		/* This value has to be subtracted from the final		   calculated dCount. */		subModVal =		    ((int)progRep->currBufDesc->		     destAddr) & ((MCD_remVariants.remXferSize[channel]) - 1);		/* These bytes are already in lastDestAddr. */		addModVal =		    ((int)progRep->		     lastDestAddr) & ((MCD_remVariants.remXferSize[channel]) -				      1);		LWAlignedInitDestAddr =		    (progRep->currBufDesc->destAddr) - subModVal;		LWAlignedCurrDestAddr = (progRep->lastDestAddr) - addModVal;		destDiffBytes = (progRep->lastDestAddr - LWAlignedInitDestAddr);		numIterations =		    (LWAlignedCurrDestAddr -		     LWAlignedInitDestAddr) /		    MCD_remVariants.remDestIncr[channel];		bytesNotXfered =		    numIterations * (MCD_remVariants.remDestIncr[channel]				     - MCD_remVariants.remXferSize[channel]);		progRep->dmaSize = destDiffBytes - bytesNotXfered - subModVal;		break;	default:		break;	}	/* This covers M1,P1,Z for source */	switch (MCD_remVariants.remSrcRsdIncr[channel]) {	case MINUS1:		progRep->lastSrcAddr =		    progRep->currBufDesc->srcAddr +		    (MCD_remVariants.remSrcIncr[channel] *		     (progRep->dmaSize / MCD_remVariants.remXferSize[channel]));		break;	case ZERO:		progRep->lastSrcAddr = progRep->currBufDesc->srcAddr;		break;	case PLUS1:		progRep->lastSrcAddr =		    progRep->currBufDesc->srcAddr +		    (MCD_remVariants.remSrcIncr[channel] *		     (progRep->dmaSize / MCD_remVariants.remXferSize[channel]));		break;	default:		break;	}	return (MCD_OK);}/******************* End of MCD_XferProgrQuery() ********************//********************************************************************//* MCD_resmActions() does the majority of the actions of a DMA resume. * It is called from MCD_killDma() and MCD_resumeDma().  It has to be * a separate function because the kill function has to negate the task * enable before resuming it, but the resume function has to do nothing * if there is no DMA on that channel (i.e., if the enable bit is 0). */static void MCD_resmActions(int channel){	MCD_dmaBar->debugControl = DBG_CTL_DISABLE;	MCD_dmaBar->debugStatus = MCD_dmaBar->debugStatus;	/* This register is selected to know which initiator is	   actually asserted. */	MCD_dmaBar->ptdDebug = PTD_DBG_TSK_VLD_INIT;	if ((MCD_dmaBar->ptdDebug >> channel) & 0x1)		MCD_chStatus[channel] = MCD_RUNNING;	else		MCD_chStatus[channel] = MCD_IDLE;}/********************* End of MCD_resmActions() *********************//********************************************************************//* Function:    MCD_killDma * Purpose:     Halt the DMA on the requested channel, without any *              intention of resuming the DMA. * Arguments:   channel - requested channel * Returns:     MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK * * Notes: *  A DMA may be killed from any state, including paused state, and it *  always goes to the MCD_HALTED state even if it is killed while in *  the MCD_NO_DMA or MCD_IDLE states. */int MCD_killDma(int channel){	/* MCD_XferProg progRep; */	if ((channel < 0) || (channel >= NCHANNELS))		return (MCD_CHANNEL_INVALID);	MCD_dmaBar->taskControl[channel] = 0x0;	MCD_resumeDma(channel);	/*	 * This must be after the write to the TCR so that the task doesn't	 * start up again momentarily, and before the status assignment so	 * as to override whatever MCD_resumeDma() may do to the channel	 * status.	 */	MCD_chStatus[channel] = MCD_HALTED;	/*	 * Update the current buffer descriptor's lastDestAddr field	 *	 * MCD_XferProgrQuery (channel, &progRep);	 * progRep.currBufDesc->lastDestAddr = progRep.lastDestAddr;	 */	return (MCD_OK);}/************************ End of MCD_killDma() **********************//********************************************************************//* Function:    MCD_continDma * Purpose:     Continue a DMA which as stopped due to encountering an *              unready buffer descriptor. * Arguments:   channel - channel to continue the DMA on * Returns:     MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK * * Notes: *  This routine does not check to see if there is a task which can *  be continued. Also this routine should not be used with single DMAs. */int MCD_continDma(int channel){	if ((channel < 0) || (channel >= NCHANNELS))		return (MCD_CHANNEL_INVALID);	MCD_dmaBar->taskControl[channel] |= TASK_CTL_EN;	MCD_chStatus[channel] = MCD_RUNNING;	return (MCD_OK);}/********************** End of MCD_continDma() **********************//********************************************************************* * MCD_pauseDma() and MCD_resumeDma() below use the DMA's debug unit * to freeze a task and resume it.  We freeze a task by breakpointing * on the stated task.  That is, not any specific place in the task, * but any time that task executes.  In particular, when that task * executes, we want to freeze that task and only that task. * * The bits of the debug control register influence interrupts vs. * breakpoints as follows: * - Bits 14 and 0 enable or disable debug functions.  If enabled, you *   will get the interrupt but you may or may not get a breakpoint. * - Bits 2 and 1 decide whether you also get a breakpoint in addition *   to an interrupt. * * The debug unit can do these actions in response to either internally * detected breakpoint conditions from the comparators, or in response * to the external breakpoint pin, or both. * - Bits 14 and 1 perform the above-described functions for *   internally-generated conditions, i.e., the debug comparators. * - Bits 0 and 2 perform the above-described functions for external *   conditions, i.e., the breakpoint external pin. * * Note that, although you "always" get the interrupt when you turn * the debug functions, the interrupt can nevertheless, if desired, be * masked by the corresponding bit in the PTD's IMR. Note also that * this means that bits 14 and 0 must enable debug functions before * bits 1 and 2, respectively, have any effect. * * NOTE: It's extremely important to not pause more than one DMA channel *  at a time. ********************************************************************//********************************************************************//* Function:    MCD_pauseDma * Purpose:     Pauses the DMA on a given channel (if any DMA is running *              on that channel). * Arguments:   channel * Returns:     MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK */int MCD_pauseDma(int channel){	/* MCD_XferProg progRep; */	if ((channel < 0) || (channel >= NCHANNELS))		return (MCD_CHANNEL_INVALID);	if (MCD_dmaBar->taskControl[channel] & TASK_CTL_EN) {		MCD_dmaBar->debugComp1 = channel;		MCD_dmaBar->debugControl =		    DBG_CTL_ENABLE | (1 << (channel + 16));		MCD_chStatus[channel] = MCD_PAUSED;		/*		 * Update the current buffer descriptor's lastDestAddr field		 *		 * MCD_XferProgrQuery (channel, &progRep);		 * progRep.currBufDesc->lastDestAddr = progRep.lastDestAddr;		 */	}	return (MCD_OK);}/************************* End of MCD_pauseDma() ********************//********************************************************************//* Function:    MCD_resumeDma * Purpose:     Resumes the DMA on a given channel (if any DMA is *              running on that channel). * Arguments:   channel - channel on which to resume DMA * Returns:     MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK */int MCD_resumeDma(int channel){	if ((channel < 0) || (channel >= NCHANNELS))		return (MCD_CHANNEL_INVALID);	if (MCD_dmaBar->taskControl[channel] & TASK_CTL_EN)		MCD_resmActions(channel);	return (MCD_OK);}/************************ End of MCD_resumeDma() ********************//********************************************************************//* Function:    MCD_csumQuery * Purpose:     Provide the checksum after performing a non-chained DMA * Arguments:   channel - channel to report on *              csum - pointer to where to write the checksum/CRC * Returns:     MCD_ERROR if the channel is invalid, else MCD_OK * * Notes: * */int MCD_csumQuery(int channel, u32 * csum){#ifdef MCD_INCLUDE_EU	if ((channel < 0) || (channel >= NCHANNELS))		return (MCD_CHANNEL_INVALID);	*csum = MCD_relocBuffDesc[channel].csumResult;	return (MCD_OK);#else	return (MCD_ERROR);#endif}/*********************** End of MCD_resumeDma() *********************//********************************************************************//* Function:    MCD_getCodeSize * Purpose:     Provide the size requirements of the microcoded tasks * Returns:     Size in bytes */int MCD_getCodeSize(void){#ifdef MCD_INCLUDE_EU	return (0x2b5c);#else	return (0x173c);#endif}/********************** End of MCD_getCodeSize() ********************//********************************************************************//* Function:    MCD_getVersion * Purpose:     Provide the version string and number * Arguments:   longVersion - user supplied pointer to a pointer to a char *                    which points to the version string * Returns:     Version number and version string (by reference) */char MCD_versionString[] = "Multi-channel DMA API Alpha v0.3 (2004-04-26)";#define MCD_REV_MAJOR   0x00#define MCD_REV_MINOR   0x03int MCD_getVersion(char **longVersion){	*longVersion = MCD_versionString;	return ((MCD_REV_MAJOR << 8) | MCD_REV_MINOR);}/********************** End of MCD_getVersion() *********************//********************************************************************//* Private version of memcpy() * Note that everything this is used for is longword-aligned. */static void MCD_memcpy(int *dest, int *src, u32 size){	u32 i;	for (i = 0; i < size; i += sizeof(int), dest++, src++)		*dest = *src;}#endif				/* CONFIG_FSLDMAFEC */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -