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

📄 dma1.c

📁 s3c2410开发板的U-boot移植
💻 C
📖 第 1 页 / 共 2 页
字号:
   if ( DMA_Get_Stat( host, eumbbar, channel, &stat ) != DMASUCCESS )   {		   return DMAINVALID;   }   if ( stat.cb == 1 )   {	   /* DMA is not free */	   return DMACHNBUSY;   }   mode = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG] );   /* clear DMA_MR(CS) */   mode &= 0xfffffffe;   store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG], mode );   /* set DMA_MR(CS) */   mode |= CS;   store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG], mode );   return DMASUCCESS;}/*********************************************************** * function: DMA_Halt * * description: halt the current dma transaction on the specified *              channel. *              return DMASUCCESS if success otherwise return DMAINVALID * * note: if the specified DMA channel is idle, nothing happens *************************************************************/staticDMAStatus DMA_Halt( LOCATION host, unsigned int eumbbar, unsigned int channel ){   unsigned int mode;   if ( channel != 0 && channel != 1 )   {	   return DMAINVALID;   }   mode = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG]);   /* clear DMA_MR(CS) */   mode &= 0xfffffffe;   store_runtime_reg(eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG], mode );   return DMASUCCESS;}/************************************************************* * function: DMA_Chn_Cnt * * description: set the DMA_MR(CC) bit for a given channel *              that is in chaining mode. *              return DMASUCCESS if successfule, otherwise return *              DMAINVALID. * * note: if the given channel is not in chaining mode, nothing *       happen. * *************************************************************/staticDMAStatus DMA_Chn_Cnt( LOCATION host, unsigned int eumbbar, unsigned int channel ){	DMA_MR mode;	if ( channel != 0 && channel != 1 )	{		return DMAINVALID;	}	if ( DMA_Get_Mode( host, eumbbar, channel, &mode ) != DMASUCCESS )	{			return DMAINVALID;	}	if ( mode.ctm == 0 )	{		/* either illegal mode or not chaining mode */		return DMAINVALID;	}	mode.cc = 1;	return DMA_Set_Mode( host, eumbbar, channel, mode );}/************************************************************** * function: DMA_Bld_Desp * * description: set current descriptor address register *              according to the desp for a given channel * *              if the given channel is busy return DMACHNBUSY *              and no change made, otherwise return DMASUCCESS. * * note: **************************************************************/staticDMAStatus DMA_Bld_Desp( LOCATION host,						   unsigned int eumbbar,						   unsigned int channel,						   DMA_CDAR     desp ){	DMA_SR status;	unsigned int temp;	if ( channel != 0 && channel != 1 )	{		/* channel number out of range */		return DMAINVALID;	}	if ( DMA_Get_Stat( host, eumbbar, channel, &status ) != DMASUCCESS )	{			return DMAINVALID;	}	if ( status.cb == 1 )	{		/* channel busy */		return DMACHNBUSY;	}	temp = ( desp.cda & 0x7ffffff ) << 5;	temp |= (( desp.snen & 0x1 ) << 4 );	temp |= (( desp.eosie & 0x1 ) << 3 );	temp |= (( desp.ctt   & 0x3 ) << 1 );    temp |= ( desp.eotd  & 0x1 );    store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], temp );#ifdef DMADBG0   PRINT( "%s(%d): %s DMA %d (0x%08x) cdar := 0x%08x\n", __FILE__, __LINE__,		  ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], temp );#endif	return DMASUCCESS;}/************************************************************** * function: DMA_Poke_Desp * * description: poke the current descriptor address register *              for a given channel * *              return DMASUCCESS if no error * * note: Due to the undeterministic parallellism of DMA operation, *       the value returned by this function shall be taken as *       the most recently used descriptor when the last time *       DMA starts a chaining mode operation. **************************************************************/staticDMAStatus DMA_Poke_Desp( LOCATION host,						    unsigned int eumbbar,						    unsigned int channel,						    DMA_CDAR     *desp ){	unsigned int cdar;	if ( channel != 0 && channel != 1 || desp == 0 )	{			return DMAINVALID;	}    cdar = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG] );#ifdef DMADBG0   PRINT( "%s(%d): %s DMA %d (0x%08x) cdar : 0x%08x\n", __FILE__, __LINE__,		  ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], cdar );#endif	desp->cda   = ( cdar & 0xffffffe0 ) >> 5;	desp->snen  = ( cdar & 0x00000010 ) >> 4;	desp->eosie = ( cdar & 0x00000008 ) >> 3;	desp->ctt   = ( cdar & 0x00000006 ) >> 1;	desp->eotd  = ( cdar & 0x00000001 );	return DMASUCCESS;}/************************************************************** * function: DMA_Bld_Curr * * description: set current src, dest, byte count registers *              according to the desp for a given channel *              return DMASUCCESS if no error. * * note: **************************************************************/staticDMAStatus DMA_Bld_Curr( LOCATION host,					   unsigned int eumbbar,					   unsigned int channel,					   DMA_CURR     desp ){	DMA_SR status;	if ( channel != 0 && channel != 1 )	{		/* channel number out of range */		return DMAINVALID;	}	if ( DMA_Get_Stat( host, eumbbar, channel, &status ) != DMASUCCESS )	{		 return DMAINVALID;	}	if ( status.cb == 1  )	{		/* channel busy */		return DMACHNBUSY;	}	desp.byte_cnt &= 0x03ffffff; /* upper 6-bits are 0s */    store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_SAR_REG], desp.src_addr );#ifdef DMADBG0   PRINT( "%s(%d): %s DMA %d (0x%08x) src := 0x%08x\n", __FILE__, __LINE__,		  ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp.src_addr );#endif    store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_DAR_REG], desp.dest_addr );#ifdef DMADBG0   PRINT( "%s(%d): %s DMA %d (0x%08x) dest := 0x%08x\n", __FILE__, __LINE__,		  ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp.dest_addr );#endif    store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_BCR_REG], desp.byte_cnt );#ifdef DMADBG0   PRINT( "%s(%d): %s DMA %d (0x%08x) count := 0x%08x\n", __FILE__, __LINE__,		  ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp.byte_cnt );#endif	return DMASUCCESS;}/************************************************************** * function: DMA_Poke_Curr * * description: poke the current src, dest, byte count registers *              for a given channel. * *              return DMASUCCESS if no error * * note:        Due to the undeterministic parallelism, in chaining *              mode, the value returned by this function shall *              be taken as reference when the query is made rather *              than the absolute snapshot when the value is returned. **************************************************************/staticDMAStatus DMA_Poke_Curr( LOCATION host,					    unsigned int eumbbar,					    unsigned int channel,					    DMA_CURR*    desp ){	if ( channel != 0 && channel != 1 || desp == 0 )	{			return DMAINVALID;	}	desp->src_addr = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_SAR_REG] );#ifdef DMADBG0   PRINT( "%s(%d): %s DMA %d (0x%08x) src : 0x%08x\n", __FILE__, __LINE__,		  ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp->src_addr );#endif	desp->dest_addr = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_DAR_REG] );#ifdef DMADBG0   PRINT( "%s(%d): %s DMA %d (0x%08x) dest : 0x%08x\n", __FILE__, __LINE__,		  ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp->dest_addr );#endif    desp->byte_cnt = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_BCR_REG] );#ifdef DMADBG0   PRINT( "%s(%d): %s DMA %d (0x%08x) count : 0x%08x\n", __FILE__, __LINE__,		  ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp->byte_cnt );#endif	return DMASUCCESS;}/***************************************************************** * function: dma_error_func * * description: display the error information * * note: This seems like a highly convoluted way to handle messages, * but I'll leave it as it was in device.c when I moved it into the * DMA library source. ****************************************************************/staticDMAStatus dma_error_func( unsigned int eumbbar, unsigned int chn, DMAStatus err){	unsigned char *msg[] =		{			"Local Memory Error",			"PCI Error",			"Channel Busy",			"End-of-Segment Interrupt",			"End-of-Chain/Direct Interrupt",		};	   if ( err >= DMALMERROR && err <= DMAEOCAINT )	   {	     PRINT( "DMA Status: channel %d  %s\n", chn, msg[err-DMASUCCESS-1] );	   }	   return err;}/************************************************************* * function: DMA_ISR * * description: DMA interrupt service routine *              return DMAStatus value based on *              the status * *************************************************************/staticDMAStatus DMA_ISR( unsigned int eumbbar,				  unsigned int channel,				  DMAStatus (*lme_func)( unsigned int, unsigned int, DMAStatus ),				  DMAStatus (*pe_func) ( unsigned int, unsigned int, DMAStatus ),				  DMAStatus (*eosi_func)( unsigned int, unsigned int, DMAStatus ),				  DMAStatus (*eocai_func)(unsigned int, unsigned int, DMAStatus )){	DMA_SR stat;	DMAStatus rval = DMANOEVENT;    unsigned int temp;	if ( channel != 0 && channel != 1 )	{		return DMAINVALID;	}	if ( DMA_Get_Stat( LOCAL, eumbbar, channel, &stat ) != DMASUCCESS )	{			return DMAINVALID;	}	if ( stat.lme == 1 )	{		/* local memory error */		rval = DMALMERROR;		if ( lme_func != 0 )		{		  rval = (*lme_func)(eumbbar, channel, DMALMERROR );	    }	}	else if ( stat.pe == 1 )	{	/* PCI error */		rval = DMAPERROR;		if ( pe_func != 0 )		{		  rval = (*pe_func)(eumbbar, channel, DMAPERROR );	    }	}	else if ( stat.eosi == 1 )	{		/* end-of-segment interrupt */		rval = DMAEOSINT;		if ( eosi_func != 0 )		{		  rval = (*eosi_func)(eumbbar, channel, DMAEOSINT );	    }	}	else	{		/* End-of-chain/direct interrupt */		rval = DMAEOCAINT;		if ( eocai_func != 0 )		{		  rval = (*eocai_func)(eumbbar, channel, DMAEOCAINT );	    }	}    temp = ( stat.reserved0 & 0xffffff ) << 8;	temp |= ( ( stat.lme       & 0x1 ) << 7 );  /* write one to clear */	temp |= ( ( stat.reserved1 & 0x3 ) << 5 );    temp |= ( ( stat.pe        & 0x1 ) << 4 );  /* write one to clear */    temp |= ( ( stat.reserved2 & 0x1 ) << 3 );	temp |= ( ( stat.cb        & 0x1 ) << 2 );  /* write one to clear */    temp |= ( ( stat.eosi      & 0x1 ) << 1 );  /* write one to clear */    temp |= ( stat.eocai & 0x1 );               /* write one to clear */    store_runtime_reg( eumbbar, dma_reg_tb[LOCAL][channel*NUM_DMA_REG + DMA_SR_REG], temp );#ifdef DMADBG0	PRINT( "%s(%d): DMA channel %d SR := 0x%08x\n", __FILE__, __LINE__, channel, temp );#endif	return rval;}

⌨️ 快捷键说明

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