blob: a8d7f6bd98aa813aed15f2da0d6060a5f028dfc8 [file] [log] [blame]
/*******************************************************************************
* Copyright (C) 2016, ZIXC Corporation.
*
* File Name:
* File Mark:
* Description:
* Others:
* Version: v1.0
* Author: zhouqi
* Date: 2012-10-23
* History 1:
* Date:
* Version:
* Author:
* Modification:
* History 2:
********************************************************************************/
#include <common.h>
#include <asm/arch/hardware.h>
#include <asm/arch/uart.h>
#include <asm/arch/lsp_crpm.h>
#include <config.h>
DECLARE_GLOBAL_DATA_PTR;
/*******************************************************************************
* Function:
* Description: ÉèÖô®¿ÚµÄʱÖÓ
* Parameters:
* Input:
*
* Output:
*
* Returns:
*
*
* Others:
********************************************************************************/
unsigned int serial_getclock(void)
{
#if 0
if( __REG(PLL_624_208_CFG0_REG) & PLL_624_208_CFG0_LOCK )
return 104000000;
else
{
return 26000000/6;
}
#endif
return 26000000;
}
/*******************************************************************************
* Function: serial_gpio_config
* Description:
* Parameters:
* Input:
*
* Output:
*
* Returns:
*
*
* Others:
********************************************************************************/
static void serial_gpio_config(void)
{
#ifdef CONFIG_ZX297520V3E_CPE
unsigned int tmp = 0;
/*uart0_cts----->uart1_txd*/
__REG(PAD_TOP_FUNC_BASE+0x20) |= (1<<2);
tmp = __REG(PAD_PD_FUNC_BASE+0x4);
tmp &= ~(0x3<<2);
__REG(PAD_PD_FUNC_BASE+0x4) = tmp | (0x1<<2);
/*uart0_rts----->uart1_rxd*/
__REG(PAD_TOP_FUNC_BASE+0x20) |= (1<<3);
tmp = __REG(PAD_PD_FUNC_BASE+0x4);
tmp &= ~(0x3<<4);
__REG(PAD_PD_FUNC_BASE+0x4) = tmp | (0x1<<4);
#endif
}
/*******************************************************************************
* Function:
* Description: ÉèÖô®¿ÚµÄ²¨ÌØÂÊ
* Parameters:
* Input:
*
* Output:
*
* Returns:
*
*
* Others:
********************************************************************************/
void serial_setbrg(void)
{
u32 uartClk = serial_getclock();
u32 ibrd = uartClk / (CONFIG_BAUDRATE << 4);
u32 fbrd = (((uartClk-((ibrd*CONFIG_BAUDRATE)<<4))<<6)+(CONFIG_BAUDRATE<<3))/(CONFIG_BAUDRATE<<4);
__REG(UART_IBRD) = ibrd;
__REG(UART_FBRD) = fbrd;
}
/*******************************************************************************
* Function:
* Description: ³õʼ»¯´®¿Ú²ÎÊý 115200
* Parameters:
* Input:
*
* Output:
*
* Returns:
*
*
* Others:
********************************************************************************/
int serial_init(void)
{
//Òý½Å¸´ÓÃÉèÖÃ,ʹÓÃUART1(2)
//gpio_set_reuse(UART0_TXD, 0); //FPGA NOUSED
//gpio_set_reuse(UART0_RXD, 0);
/* Òý½Å¸´ÓÃÉèÖà */
serial_gpio_config();
// ½ûÓÃUART
__REG(UART_ICR) = 0xffff;
__REG(UART_CR) &= (~UART_EN );
// ²¨ÌØÂÊÉèÖÃ
serial_setbrg();
// ÉèÖô«Êä¸ñʽΪ: ÎÞУÑé/1λֹͣλ/8λÊý¾Ýλ/ʹÄÜ FIFO £»¼Ä´æÆ÷³õʼ»¯Îª 0x0
__REG(UART_LCR_H) &= (~(UART_BREAK | UART_PEN | UART_STP2 ));
__REG(UART_LCR_H) |= (UART_WLEN_8 | UART_FEN );
// ÆÁ±ÎËùÓеÄuartÄ£¿é·¢³öµÄÖжÏ
__REG(UART_IMSC) &= (~UART_INT_MASK);
// ʹÄÜUART
__REG(UART_CR) |= (UART_TXE | UART_RXE | UART_EN );
return 0;
}
/*******************************************************************************
* Function:
* Description: ´Ó´®¿Ú¶Á³öÒ»¸ö×Ö½ÚÊý¾Ý
* Parameters:
* Input:
*
* Output:
*
* Returns:
*
*
* Others:
********************************************************************************/
int serial_getc(void)
{
while ((__REG(UART_FR) & UART_RXFE) != 0 );
return (__REG(UART_DR) & 0xff);
}
#ifdef CONFIG_CTRL_X_SWTCH_UART
/*******************************************************************************
* Function: check if user press ctrl +x from uboot serial
* Description: read console flag before start kernel
* Parameters: us °´¼ü·À¶¶Ê±¼ä£¬wait µÈ´ý°´¼ü×Üʱ¼ä
* Input:
*
* Output:
*
* Returns:
*
*
* Others:
********************************************************************************/
extern bool g_flg_ctrl_x;
void serial_getc_cons_key_flag(unsigned long us,unsigned int wait)
{
int c1,c2;
static int cnt_wait = 0;
while(1)
{
if((__REG(UART_FR) & UART_RXFE) == 0)
c1 = (__REG(UART_DR) & 0xff);
udelay(us);
if((__REG(UART_FR) & UART_RXFE) == 0)
c2 = (__REG(UART_DR) & 0xff);
if((c1 == c2) && (c1 == 24)){
g_flg_ctrl_x = false;
debug("ctrk+x:get.\n");
return 1;
}
if(cnt_wait > wait){
debug("ctrk+x:not get.\n");
g_flg_ctrl_x = true;
cnt_wait = 0;
return 0;
}else{
cnt_wait++;
}
}
return 0;
}
#endif
#ifdef CONFIG_HWFLOW
static int hwflow = 0; /* turned off by default */
int hwflow_onoff(int on)
{
switch(on) {
case 0:
default:
break; /* return current */
case 1:
hwflow = 1; /* turn on */
break;
case -1:
hwflow = 0; /* turn off */
break;
}
return hwflow;
}
#endif
#ifdef CONFIG_MODEM_SUPPORT
static int be_quiet = 0;
void disable_putc(void)
{
be_quiet = 1;
}
void enable_putc(void)
{
be_quiet = 0;
}
#endif
/*******************************************************************************
* Function:
* Description: Ïò´®¿ÚÊä³öÒ»¸ö×Ö½ÚÊý¾Ý
* Parameters:
* Input:
*
* Output:
*
* Returns:
*
*
* Others:
********************************************************************************/
void serial_putc(const char c)
{
#ifdef CONFIG_MODEM_SUPPORT
if (be_quiet)
return;
#endif
/* µÈ´ý·¢ËÍ FIFO ²»Âú£¬¿ÉÒÔдÊý¾Ý */
while ((__REG(UART_FR) & UART_TXFF) != 0 );
__REG(UART_DR) = c;
/* If \n, also do \r */
if (c == '\n')
serial_putc('\r');
}
/*******************************************************************************
* Function:
* Description: ²âÊÔ½ÓÊÕ FIFO ÖÐÊÇ·ñÓÐÊý¾Ý£» Test whether a character is in the RX buffer
* Parameters:
* Input:
*
* Output:
*
* Returns:
*
*
* Others:
********************************************************************************/
int serial_tstc(void)
{
if( __REG(UART_FR) & UART_RXFE )
return 0; //µÈÓÚ1ʱ£¬½ÓÊÕFIFOΪ¿Õ£¬Ã»ÓÐÊý¾Ý
else
return 1; //µÈÓÚ0ʱ£¬½ÓÊÕFIFO²»Îª¿Õ£¬ÓÐÊý¾Ý;
}
/*******************************************************************************
* Function:
* Description:
* Parameters:
* Input:
*
* Output:
*
* Returns:
*
*
* Others:
********************************************************************************/
void serial_puts(const char *s)
{
while (*s)
serial_putc(*s++);
}
/*******************************************************************************
* Function:
* Description:
* Parameters:
* Input:
*
* Output:
*
* Returns:
*
*
* Others:
********************************************************************************/
int UART_Read(char *pchBuf, int dwLen)
{
int i = 0;
for(i=0;i<dwLen;i++)
{
pchBuf[i] = (char)serial_getc();
}
return dwLen;
}
/*******************************************************************************
* Function:
* Description:
* Parameters:
* Input:
*
* Output:
*
* Returns:
*
*
* Others:
********************************************************************************/
int UART_Write(char *pchBuf, int dwLen)
{
int i = 0;
for(i=0;i<dwLen;i++)
{
serial_putc(pchBuf[i]);
}
return dwLen;
}
int UART_CmdRead(char *pchBuf, int dwLen)
{
int i = 0;
for(i=0;i<64;i++)
{
pchBuf[i] = (char)serial_getc();
if(pchBuf[i] == 0)
break;
}
return (i+1);
}