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

📄 dma.c

📁 MTK平台绝密核心代码之 系统驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
					break;
				case DMA_CON_MASTER_UART1TX:
					UART_TrxHandler_VFIFO(&UARTPort[uart_port1]);
					break;
				case DMA_CON_MASTER_UART2RX:
					UART_RecHandler_VFIFO(&UARTPort[uart_port2]);
					break;
				case DMA_CON_MASTER_UART2TX:
					UART_TrxHandler_VFIFO(&UARTPort[uart_port2]);
					break;											
				case DMA_CON_MASTER_UART3RX:
					UART_RecHandler_VFIFO(&UARTPort[uart_port3]);
					break;
				case DMA_CON_MASTER_UART3TX:
					UART_TrxHandler_VFIFO(&UARTPort[uart_port3]);
					break;									
			}			
			DMA_ACKI(index);
		}
	}
#endif //__DMA_UART_VIRTUAL_FIFO__
	IRQClearInt(IRQ_DMA_CODE);
	IRQUnmask(IRQ_DMA_CODE);
}

void DMA_LISR(void)
{
   IRQMask(IRQ_DMA_CODE);

   drv_active_hisr(DRV_DMA_HISR_ID);
}

void DMA_Ini(void)
{
   kal_uint8 index;
   
   for (index = 0; index < DMA_MAX_CHANNEL; index++)
      DMA_Owner[index] = DMA_IDLE;

   DRV_Reg(DRVPDN_CON0) &= ~DRVPDN_CON0_DMA;
      
   IRQ_Register_LISR(IRQ_DMA_CODE, DMA_LISR, "DMA handler");

   DRV_Register_HISR(DRV_DMA_HISR_ID, DMA_HISR);

   IRQSensitivity(IRQ_DMA_CODE,LEVEL_SENSITIVE);

   IRQUnmask(IRQ_DMA_CODE);
}

kal_bool DMA_memcpy(const void *src, const void *dst, kal_uint32 length)
{
   kal_uint8 handle=0xff;
   DMA_INPUT input;
   DMA_SWCOPYMENU menu;
   
   if (length > 0xffff)
      return KAL_FALSE;

   handle = DMA_FullSize_GetChannel(DMA_SW);
   ASSERT(handle!=0xff);
   
   if (handle != 0xff)
   {
      menu.srcaddr = (kal_uint32)src;
      menu.dstaddr = (kal_uint32)dst;
      input.type = DMA_SWCOPY;
      input.menu = &menu;
      input.callback = NULL;
      
      if ((menu.srcaddr|menu.dstaddr|input.count) & 0x01)
      {
         input.size = DMA_BYTE;
         input.count = length;
      }
      else if ((menu.srcaddr|menu.dstaddr|input.count) & 0x02)
      {
         input.size = DMA_SHORT;
         input.count = length/2;
      }
      else
      {
         input.size = DMA_LONG;
         input.count = length/4;
      }

      DMA_FullSize_Config(handle,&input,KAL_TRUE);
      DMA_WaitUntilRdy(handle);
      return KAL_TRUE;
   }
   else
   {
      return KAL_FALSE;
   }
}


/*
 * This function is used to set the DMA Global Bandwidth Limiter.
 * All DMA channels' bandwidth limit will be updated.
 */
DMA_GBL_HANDLE DMA_SetGBL(DMA_GBL_CLASS dma_gbl_class)
{
   kal_uint8 is_update;
   kal_uint32 _savedMask;
   kal_uint8 limiter;
   kal_uint16 i;

   if (dma_gbl_class > DMA_MAX_GBL_CLASS)
      return (DMA_GBL_HANDLE)DMA_INVALID_GBL_HANDLE;

   is_update = 0;

   _savedMask = SaveAndSetIRQMask();

   if (dma_gbl_class != 0)
      dma_gbl_count[dma_gbl_class - 1]++;

   if (dma_gbl_class > dma_gbl_class_g) {
      dma_gbl_class_g = dma_gbl_class;
      is_update = 1;
   }

   RestoreIRQMask(_savedMask);

   if (is_update == 1) {

      /* need to set DMA bandwidth limit */

      limiter = dma_gbl_class_to_grade[dma_gbl_class];

#ifdef MT6218B
      for (i = 2; i <= DMA_MAX_CHANNEL; i++)
#else   /* MT6218B */
      for (i = 1; i <= DMA_MAX_CHANNEL; i++)
#endif   /* MT6218B */

         DRV_WriteReg8(DMA_LIMITER(i), limiter);

#if ( defined(MT6218B) || defined(MT6217) )
      lcd_dma_slow_down(dma_gbl_class);
#endif  
   }

   return (DMA_GBL_HANDLE)dma_gbl_class;
}


/*
 * This function is used to restore the DMA Global Bandwidth Limiter.
 * All DMA channels' limiter will be updated.
 */
void DMA_RestoreGBL(DMA_GBL_HANDLE dma_gbl_handle)
{
   DMA_GBL_CLASS dma_gbl_class;
   kal_uint8 is_update, max;
   kal_int16 i;
   kal_uint32 _savedMask;
   kal_uint8 limiter;

   if (dma_gbl_handle == DMA_INVALID_GBL_HANDLE)
      return ;

   dma_gbl_class = (DMA_GBL_CLASS)dma_gbl_handle;

   if (dma_gbl_class > DMA_MAX_GBL_CLASS)
      return ;

   is_update = 0;

   /* update DMA GBL */

   _savedMask = SaveAndSetIRQMask();

   if (dma_gbl_class != 0)
      dma_gbl_count[dma_gbl_class - 1]--;

   max = 0;

   /* get the current max of available DMA gbl */
   for (i = DMA_MAX_GBL_CLASS - 1; i >= 0; i--) {
      if (dma_gbl_count[i] > 0) {
         max = i + 1;
         break;
      }
   }

   if (max != dma_gbl_class_g) {

      dma_gbl_class_g = max;

      is_update = 1;
   }

   RestoreIRQMask(_savedMask);

   if (is_update == 0)
      return ;
   else {

      /* need to set DMA bandwidth limit */

      limiter = dma_gbl_class_to_grade[dma_gbl_class];

#ifdef MT6218B
      for (i = 2; i <= DMA_MAX_CHANNEL; i++)
#else  
      for (i = 1; i <= DMA_MAX_CHANNEL; i++)
#endif 

         DRV_WriteReg8(DMA_LIMITER(i), limiter);

#if ( defined(MT6218B) || defined(MT6217) )
      lcd_dma_slow_down(dma_gbl_class);
#endif  
   }
}

#endif  /* MT6205 || MT6208 || MT6205B || FPGA */



#ifdef MT6218B

/*
* FUNCTION
*	dma_ch1_init
*
* DESCRIPTION
*  This function is used to initialize DMA channel 1.
*
* CALLS
*
* PARAMETERS
*	None
*
* RETURNS
*	None
*
* GLOBALS AFFECTED
 */
void dma_ch1_init(kal_uint32 dstaddr, kal_uint16 len, kal_uint8 limiter)
{
   DRV_WriteReg32(DMA_DST(1), dstaddr);

   DRV_WriteReg32(DMA_COUNT(1), (kal_uint32)len);

   DRV_WriteReg32(DMA_CON(1), 0 | DMA_CON_SIZE_BYTE | DMA_CON_SINC);
   
   DRV_WriteReg32(DMA_LIMITER(1),limiter);
}

/*
 * This function is used to start DMA channel 1 for transfer.
 */
void dma_ch1_start(kal_uint32 srcaddr)
{
   DMA_Stop_Now(1);

   DMA_ACKI(1);

   DRV_WriteReg32(DMA_SRC(1), srcaddr);

   DMA_Start(1);
}

/*
 * This function is used to stop transfer of DMA channel 1.
 */
void dma_ch1_stop()
{
   DMA_Stop_Now(1);

   DMA_ACKI(1);
}

#endif   /* MT6218B */


static kal_uint32 dma_slowdown_handle;
static kal_uint32 dma_slowdown_mask;

kal_uint8 dma_slowdown_get_handle(void)
{
   ASSERT(dma_slowdown_handle<32);
   return dma_slowdown_handle++;
}

void dma_slowdown(kal_uint8 handle)
{
   kal_uint32 _savedMask;   

   _savedMask = SaveAndSetIRQMask();

   if (dma_slowdown_mask == 0) 
   {

      che_slowdown();

      /*
       * Original lcd_dma_slow_down(void) internally uses 0x3F as command
       * latency. Here we pass "4" to new lcd_dma_slow_down(level) such that
       * the command latency is longer than before.
       */

#if defined(MT6218B) || defined(MT6217)
      {
         kal_uint8 index;
         
         lcd_dma_slow_down(DMA_GBL_CLASS4);

#ifdef MT6218B
         /* nop */
#else   /* MT6218B */
         DRV_WriteReg32(DMA_LIMITER(1),0xff);
#endif   /* MT6218B */

         DRV_WriteReg32(DMA_LIMITER(2),0xff);

         DRV_WriteReg32(DMA_LIMITER(3),0xff);

         for(index = 4; index <= DMA_MAX_CHANNEL; index++) 
         {
            DRV_WriteReg32(DMA_LIMITER(index),0xc8);
         }
      }

#elif defined(MT6208) || defined(MT6205B)   /* MT6218B || MT6217 */

      lcd_dma_slow_down(4);

#endif   /* MT6218B || MT6217 */
   }

   dma_slowdown_mask |= (1 << handle);

   RestoreIRQMask(_savedMask);
}

/*
* FUNCTION
*	dma_recover
*
* DESCRIPTION
*  Recover DMA limiter
*
* CALLS
*
* PARAMETERS
*	None
*
* RETURNS
*	None
*
* GLOBALS AFFECTED
*/
void dma_recover(kal_uint8 handle)
{
   kal_uint32 _savedMask;

   _savedMask = SaveAndSetIRQMask();

   dma_slowdown_mask &= ~(1 << handle);

   if (dma_slowdown_mask == 0) 
   {
      che_recover();

#if defined(MT6208) || defined(MT6205B) || defined(MT6218B) || defined(MT6217)
      lcd_dma_recovery();
#endif   /* MT6208 || MT6205B || MT6218B || MT6217 */

#if defined(MT6218B) || defined(MT6217)
      {
         kal_uint8 index;
         kal_uint8 limiter;

         limiter = dma_gbl_class_to_grade[dma_gbl_class_g];

#ifdef MT6218B
         for(index = 2; index <= DMA_MAX_CHANNEL; index++) 
         {
#else   /* MT6218B */
         for(index = 1; index <= DMA_MAX_CHANNEL; index++) 
         {
#endif   /* MT6218B */

            DRV_WriteReg32(DMA_LIMITER(index), limiter);
         }
      }
#endif   /* MT6218B || MT6217 */
   }

   RestoreIRQMask(_savedMask);
}

/*
* FUNCTION
*	dma_recover_all
*
* DESCRIPTION
*  Recover all DMA limiter
*
* CALLS
*
* PARAMETERS
*	None
*
* RETURNS
*	None
*
* GLOBALS AFFECTED
*/
void dma_recover_all()
{
   kal_uint32 _savedMask;
   kal_uint8 index;
   
#if !defined(MT6205B) && !defined(MT6208)
   kal_uint8 limiter;
#endif

   _savedMask = SaveAndSetIRQMask();

#if defined(MT6205B) || defined(MT6218B) || defined(MT6217)
      lcd_dma_recovery();
#endif  

#if !defined(MT6205B) && !defined(MT6208)

   limiter = dma_gbl_class_to_grade[dma_gbl_class_g];

#ifdef MT6218B
   for(index = 2; index <= DMA_MAX_CHANNEL; index++) {
#else   /* MT6218B */
   for(index = 1; index <= DMA_MAX_CHANNEL; index++) {
#endif   /* MT6218B */

      DRV_WriteReg32(DMA_LIMITER(index), limiter);
   }

#endif

   RestoreIRQMask(_savedMask);
}


#ifdef __DMA_UART_VIRTUAL_FIFO__

/*
* FUNCTION
*	DMA_Vfifo_init
*
* DESCRIPTION
*  DMA virtual FIFO
*
* CALLS
*
* PARAMETERS
*	None
*
* RETURNS
*	None
*
* GLOBALS AFFECTED
*/
void DMA_Vfifo_init(void)
{
	kal_uint32 dma_con = 0;
	
	if(UART_VFIFO_support[uart_port1])
	{
	// DMA10 for UART1 RX, DMA12 for UART1 TX	
	dma_con = (DMA_CON_MASTER_UART1RX << 20)|DMA_CON_DIR|DMA_CON_DRQ|DMA_CON_ITEN;
	   //DRV_WriteReg32(DMA_CON(VDMA_UART1RX_CH),dma_con);	
	   DRV_WriteReg32(DMA_CON(UARTPort[uart_port1].Rx_DMA_Ch),dma_con);	
	dma_con = 0;
	dma_con = (DMA_CON_MASTER_UART1TX << 20)|DMA_CON_DRQ;
	   //DRV_WriteReg32(DMA_CON(VDMA_UART1TX_CH),dma_con);
	   DRV_WriteReg32(DMA_CON(UARTPort[uart_port1].Tx_DMA_Ch),dma_con);
   }	

   if(UART_VFIFO_support[uart_port2])
   {
	// DMA11 for UART2 Rx, DMA13 for UART2 TX
	dma_con = (DMA_CON_MASTER_UART2RX << 20)|DMA_CON_DIR|DMA_CON_DRQ|DMA_CON_ITEN;
	   //DRV_WriteReg32(DMA_CON(VDMA_UART2RX_CH),dma_con);
	   DRV_WriteReg32(DMA_CON(UARTPort[uart_port2].Rx_DMA_Ch),dma_con);	
	dma_con = 0;
	dma_con = (DMA_CON_MASTER_UART2TX << 20)|DMA_CON_DRQ;
	   //DRV_WriteReg32(DMA_CON(VDMA_UART2RX_CH),dma_con);
	   DRV_WriteReg32(DMA_CON(UARTPort[uart_port2].Tx_DMA_Ch),dma_con);
   }
	if(UART_VFIFO_support[uart_port3])
	{
	   // DMA13 for UART3 Rx, DMA14 for UART3 TX
	   dma_con = (DMA_CON_MASTER_UART3RX << 20)|DMA_CON_DIR|DMA_CON_DRQ|DMA_CON_ITEN;
	   //DRV_WriteReg32(DMA_CON(VDMA_UART3RX_CH),dma_con);
	   DRV_WriteReg32(DMA_CON(UARTPort[uart_port3].Rx_DMA_Ch),dma_con);	
	   dma_con = 0;
	   dma_con = (DMA_CON_MASTER_UART3TX << 20)|DMA_CON_DRQ;
	   //DRV_WriteReg32(DMA_CON(VDMA_UART3TX_CH),dma_con);
	   DRV_WriteReg32(DMA_CON(UARTPort[uart_port3].Tx_DMA_Ch),dma_con);
   }
}

/*
* FUNCTION
*	DMA_Vfifo_SetAdrs
*
* DESCRIPTION
*  DMA virtual FIFO set address
*
* CALLS
*
* PARAMETERS
*	None
*
* RETURNS
*	None
*
* GLOBALS AFFECTED
*/
void DMA_Vfifo_SetAdrs(kal_uint32 adrs, kal_uint32 len, DMA_VFIFO_UART ch, kal_bool IsTx )	
{
	DRV_WriteReg32(DMA_PGMADDR(ch), adrs);
	DRV_WriteReg32(DMA_FFSIZE(ch), len);
	DRV_WriteReg32(DMA_ALTLEN(ch), DMA_VIFOF_ALERT_LENGTH); //maximum of alert threshold will effect the flow control 
	DRV_Reg(DMA_COUNT(ch)) = (IsTx)?DMA_TX_TRIGGER_LEVEL(len):DMA_RX_TRIGGER_LEVEL(len); // set trigger level for DMA interrupt
}

/*
* FUNCTION
*	DMA_Vfifo_Flush
*
* DESCRIPTION
*  Flushing DMA virtual FIFO
*
* CALLS
*
* PARAMETERS
*	None
*
* RETURNS
*	None
*
* GLOBALS AFFECTED
*/
void DMA_Vfifo_Flush(DMA_VFIFO_UART ch)
{
   DMA_Stop(ch);
   DMA_Start(ch);
}

#endif //__DMA_UART_VIRTUAL_FIFO__


⌨️ 快捷键说明

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