3 #include <linux/types.h>
4 #include <asm/arch/bits.h>
5 #include <asm/arch/migrate.h>
6 #include <asm/arch/chip_drv_config_extern.h>
7 #include <asm/arch/sio_drv.h>
8 #include <asm/arch/fdl_crc.h>
9 #include <asm/arch/packet.h>
10 #include <asm/arch/common.h>
11 #include <asm/arch/fdl_channel.h>
12 #include <asm/arch/mfp.h>
14 #define __REG(x) (*((volatile u32 *)(x)))
16 #ifdef CONFIG_SERIAL_MULTI
17 #warning "SC8800X driver does not support MULTI serials."
20 #if defined(PLATFORM_SC6800H)
21 #define GR_CTRL_REG 0x8b000004
22 /* GEN0_UART0_EN (0x1 << 1) */
23 /* GEN0_UART1_EN (0x1 << 2) */
24 #define GR_UART_CTRL_EN (0x3<<1)
25 #elif defined(CONFIG_SC8830) || defined(CONFIG_SC9630)
26 #define GR_CTRL_REG CTL_BASE_APB
27 #define GR_UART_CTRL_EN (0x3 << 13 )
28 #elif defined(CONFIG_SC8825)
29 #define GR_CTRL_REG 0x4b000008
30 #define GR_UART_CTRL_EN ((0x7 << 20 ) | (1)) /*UART0 UART1 UART2 UART3 enable*/
31 #elif defined(PLATFORM_SC8800G) || defined(CONFIG_SC8810)
32 #define GR_CTRL_REG 0x8b000004
33 /* GEN0_UART0_EN (0x1 << 20) */
34 /* GEN0_UART1_EN (0x1 << 21) */
35 #define GR_UART_CTRL_EN (0x3 << 20 )
37 #define GR_CTRL_REG 0x8b000018
38 #define GR_UART_CTRL_EN 0x00400000
41 #ifdef FPGA_VERIFICATION
42 #define ARM_APB_CLK 48000000UL
44 #define ARM_APB_CLK 26000000UL
47 #if defined(CONFIG_SC7710G2)
48 #define GR_CTRL_REG1 0x8b0000b4
49 #define GR_UART3_CTRL_EN 1
51 #define UART_RX_FLOW_EN BIT_7
52 #define UART_TX_FLOW_EN BIT_8
54 #define UART_RX_THRESHOLD 120
57 typedef struct UartPort
60 unsigned int baudRate;
63 UartPort_T gUart0PortInfo =
69 UartPort_T gUart1PortInfo =
75 #if defined(CONFIG_SC7710G2) || defined(CONFIG_SC8830) || defined(CONFIG_SC9630)
76 UartPort_T gUart3PortInfo =
83 #if defined(CONFIG_SC8830) || defined(CONFIG_SC9630)
84 UartPort_T gUart2PortInfo =
91 LOCAL unsigned int SIO_GetHwDivider (unsigned int baudrate)
93 return (unsigned int) ( (ARM_APB_CLK + baudrate / 2) / baudrate);
95 LOCAL void SIO_HwOpen (struct FDL_ChannelHandler *channel, unsigned int divider)
97 UartPort_T *port = (UartPort_T *) channel->priv;
99 #if defined(CONFIG_SC7710G2)
100 if(port->regBase == ARM_UART3_BASE){
102 * ( (volatile unsigned int *) (GR_CTRL_REG1)) &= ~ (GR_UART3_CTRL_EN);
103 /*Disable Interrupt */
104 * (volatile unsigned int *) (port->regBase + ARM_UART_IEN) = 0;
106 * (volatile unsigned int *) GR_CTRL_REG1 |= (GR_UART3_CTRL_EN);
112 * ( (volatile unsigned int *) (GR_CTRL_REG)) &= ~ (GR_UART_CTRL_EN);
113 /*Disable Interrupt */
114 * (volatile unsigned int *) (port->regBase + ARM_UART_IEN) = 0;
116 * (volatile unsigned int *) GR_CTRL_REG |= (GR_UART_CTRL_EN);
119 * (volatile unsigned int *) (port->regBase + ARM_UART_CLKD0) = LWORD (divider);
120 * (volatile unsigned int *) (port->regBase + ARM_UART_CLKD1) = HWORD (divider);
123 /* Set port for 8 bit, one stop, no parity */
124 * (volatile unsigned int *) (port->regBase + ARM_UART_CTL0) = UARTCTL_BL8BITS | UARTCTL_SL1BITS;
125 * (volatile unsigned int *) (port->regBase+ ARM_UART_CTL1) = 0;
126 * (volatile unsigned int *) (port->regBase + ARM_UART_CTL2) = 0;
129 LOCAL int SIO_Open (struct FDL_ChannelHandler *channel, unsigned int baudrate)
131 unsigned int divider;
134 UartPort_T *port = (UartPort_T *) channel->priv;
136 divider = SIO_GetHwDivider (baudrate);
137 SIO_HwOpen (channel, divider);
139 while(!SIO_TRANS_OVER(port->regBase)) /* Wait until all characters are sent out */
142 if(i >= UART_SET_BAUDRATE_TIMEOUT)
152 LOCAL int SIO_Read (struct FDL_ChannelHandler *channel, const unsigned char *buf, unsigned int len)
154 #ifndef CONFIG_NAND_SPL
155 unsigned char *pstart = (unsigned char *) buf;
156 const unsigned char *pend = pstart + len;
157 UartPort_T *port = (UartPort_T *) channel->priv;
159 while ( (pstart < pend)
160 && SIO_RX_READY (SIO_GET_RX_STATUS (port->regBase)))
162 *pstart++ = SIO_GET_CHAR (port->regBase);
165 return pstart - (unsigned char *) buf;
170 LOCAL char SIO_GetChar (struct FDL_ChannelHandler *channel)
172 #ifndef CONFIG_NAND_SPL
173 UartPort_T *port = (UartPort_T *) channel->priv;
175 while (!SIO_RX_READY (SIO_GET_RX_STATUS (port->regBase)))
180 return SIO_GET_CHAR (port->regBase);
185 LOCAL int SIO_GetSingleChar (struct FDL_ChannelHandler *channel)
187 #ifndef CONFIG_NAND_SPL
188 UartPort_T *port = (UartPort_T *) channel->priv;
191 if (!SIO_RX_READY (SIO_GET_RX_STATUS (port->regBase)))
198 ch = SIO_GET_CHAR (port->regBase);
206 LOCAL int SIO_Write (struct FDL_ChannelHandler *channel, const unsigned char *buf, unsigned int len)
208 #ifndef CONFIG_NAND_SPL
209 const unsigned char *pstart = (const unsigned char *) buf;
210 const unsigned char *pend = pstart + len;
211 UartPort_T *port = (UartPort_T *) channel->priv;
213 while (pstart < pend)
215 /* Check if tx port is ready.*/
216 /*lint -save -e506 -e731*/
217 while (!SIO_TX_READY (SIO_GET_TX_STATUS (port->regBase)))
223 SIO_PUT_CHAR (port->regBase, *pstart);
227 /* Ensure the last byte is written successfully */
228 while (!SIO_TX_READY (SIO_GET_TX_STATUS (port->regBase)))
233 return pstart - (const unsigned char *) buf;
239 LOCAL int SIO_PutChar (struct FDL_ChannelHandler *channel, const unsigned char ch)
241 #ifndef CONFIG_NAND_SPL
242 UartPort_T *port = (UartPort_T *) channel->priv;
244 while (!SIO_TX_READY (SIO_GET_TX_STATUS (port->regBase)))
249 SIO_PUT_CHAR (port->regBase, ch);
251 /* Ensure the last byte is written successfully */
252 while (!SIO_TX_READY (SIO_GET_TX_STATUS (port->regBase)))
262 LOCAL int SIO_SetBaudrate (struct FDL_ChannelHandler *channel, unsigned int baudrate)
265 channel->Open (channel, baudrate);
267 unsigned int divider;
268 UartPort_T *port = (UartPort_T *) channel->priv;
270 divider = SIO_GetHwDivider (baudrate);
272 * (volatile unsigned int *) (port->regBase + ARM_UART_CLKD0) = LWORD (divider);
273 * (volatile unsigned int *) (port->regBase + ARM_UART_CLKD1) = HWORD (divider);
278 LOCAL int SIO_Close (struct FDL_ChannelHandler *channel)
283 struct FDL_ChannelHandler gUart0Channel =
296 struct FDL_ChannelHandler gUart1Channel =
309 #if defined(CONFIG_SC7710G2) || defined(CONFIG_SC8830) || defined(CONFIG_SC9630)
310 struct FDL_ChannelHandler gUart3Channel =
324 #if defined(CONFIG_SC8830) || defined(CONFIG_SC9630)
325 struct FDL_ChannelHandler gUart2Channel =
339 DECLARE_GLOBAL_DATA_PTR;
340 int __dl_log_share__ = 0;
341 void serial_setbrg(void)
343 SIO_SetBaudrate(&gUart1Channel, 115200);
345 int serial_getc(void)
347 return SIO_GetChar (&gUart1Channel);
350 void serial_putc(const char c)
352 SIO_PutChar(&gUart1Channel, c);
354 /* If \n, also do \r */
355 if(__dl_log_share__ == 0){
362 * * Test whether a character is in the RX buffer
364 int serial_tstc (void)
366 UartPort_T *port = (&gUart1Channel)->priv;
367 /* If receive fifo is empty, return false */
368 return SIO_RX_READY( SIO_GET_RX_STATUS( port->regBase) ) ;
371 void serial_puts (const char *s)
373 if(__dl_log_share__ == 0){
381 * * Initialise the serial port with the given baudrate. The settings
382 * * are always 8 data bits, no parity, 1 stop bit, no start bits.
385 int serial_init (void)
387 SIO_Open(&gUart1Channel, 115200);
388 /* clear input buffer */
395 * add UART0 driver for modem boot
397 #if defined(CONFIG_SC7710G2)
398 void serial3_setbrg(void)
400 SIO_SetBaudrate(&gUart3Channel, 115200);
402 int serial3_getc(void)
404 return SIO_GetChar (&gUart3Channel);
407 void serial3_putc(const char c)
409 SIO_PutChar(&gUart3Channel, c);
413 * * Test whether a character is in the RX buffer
415 int serial3_tstc (void)
417 UartPort_T *port = (&gUart3Channel)->priv;
418 /* If receive fifo is empty, return false */
419 return SIO_RX_READY( SIO_GET_RX_STATUS( port->regBase) ) ;
422 void serial3_puts (const char *s)
429 int serial3_init (void)
431 SIO_Open(&gUart3Channel, 115200);
432 /* clear input buffer */
438 int serial3_flowctl_enable(void)
440 /*enable tx/rx flow control*/
441 * (volatile unsigned int *) (ARM_UART3_BASE + ARM_UART_CTL1) |= UART_RX_FLOW_EN | (UART_RX_THRESHOLD & 0x7F);
445 int serial1_SwitchToModem(void)
447 //Switch Uart1 from AP to CP
448 REG32(CHIPPIN_CTL_BEGIN + PIN_U1RXD_REG_OFFS) = 0x190;
449 REG32(CHIPPIN_CTL_BEGIN + PIN_U1TXD_REG_OFFS) = 0x110;