blob: 36851ad5ca86dcb95833ceb509b24d56bfebc4e5 [file] [log] [blame]
wdenk281e00a2004-08-01 22:48:16 +00001/*
2 * (C) Copyright 2002
3 * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
wdenkc6097192002-11-03 00:24:07 +000016 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20
21#include <common.h>
wdenk281e00a2004-08-01 22:48:16 +000022#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB)
23
wdenkc6097192002-11-03 00:24:07 +000024#if defined(CONFIG_S3C2400) || defined(CONFIG_TRAB)
25#include <s3c2400.h>
26#elif defined(CONFIG_S3C2410)
27#include <s3c2410.h>
28#endif
29
Wolfgang Denkd87080b2006-03-31 18:32:53 +020030DECLARE_GLOBAL_DATA_PTR;
31
wdenk48b42612003-06-19 23:01:32 +000032#ifdef CONFIG_SERIAL1
33#define UART_NR S3C24X0_UART0
34
wdenk42dfe7a2004-03-14 22:25:36 +000035#elif defined(CONFIG_SERIAL2)
wdenk48b42612003-06-19 23:01:32 +000036# if defined(CONFIG_TRAB)
wdenkf54ebdf2003-09-17 15:10:32 +000037# error "TRAB supports only CONFIG_SERIAL1"
wdenk48b42612003-06-19 23:01:32 +000038# endif
39#define UART_NR S3C24X0_UART1
40
wdenk42dfe7a2004-03-14 22:25:36 +000041#elif defined(CONFIG_SERIAL3)
wdenk48b42612003-06-19 23:01:32 +000042# if defined(CONFIG_TRAB)
43# #error "TRAB supports only CONFIG_SERIAL1"
44# endif
45#define UART_NR S3C24X0_UART2
46
47#else
48#error "Bad: you didn't configure serial ..."
49#endif
wdenkc6097192002-11-03 00:24:07 +000050
51void serial_setbrg (void)
52{
wdenk48b42612003-06-19 23:01:32 +000053 S3C24X0_UART * const uart = S3C24X0_GetBase_UART(UART_NR);
wdenkc6097192002-11-03 00:24:07 +000054 int i;
55 unsigned int reg = 0;
56
57 /* value is calculated so : (int)(PCLK/16./baudrate) -1 */
58 reg = get_PCLK() / (16 * gd->baudrate) - 1;
59
wdenkc6097192002-11-03 00:24:07 +000060 /* FIFO enable, Tx/Rx FIFO clear */
wdenk48b42612003-06-19 23:01:32 +000061 uart->UFCON = 0x07;
62 uart->UMCON = 0x0;
wdenkc6097192002-11-03 00:24:07 +000063 /* Normal,No parity,1 stop,8 bit */
wdenk48b42612003-06-19 23:01:32 +000064 uart->ULCON = 0x3;
wdenkc6097192002-11-03 00:24:07 +000065 /*
66 * tx=level,rx=edge,disable timeout int.,enable rx error int.,
67 * normal,interrupt or polling
68 */
wdenk48b42612003-06-19 23:01:32 +000069 uart->UCON = 0x245;
70 uart->UBRDIV = reg;
wdenkc6097192002-11-03 00:24:07 +000071
72#ifdef CONFIG_HWFLOW
wdenk48b42612003-06-19 23:01:32 +000073 uart->UMCON = 0x1; /* RTS up */
wdenkc6097192002-11-03 00:24:07 +000074#endif
75 for (i = 0; i < 100; i++);
wdenkc6097192002-11-03 00:24:07 +000076}
77
78/*
79 * Initialise the serial port with the given baudrate. The settings
80 * are always 8 data bits, no parity, 1 stop bit, no start bits.
81 *
82 */
83int serial_init (void)
84{
85 serial_setbrg ();
86
87 return (0);
88}
89
90/*
91 * Read a single byte from the serial port. Returns 1 on success, 0
92 * otherwise. When the function is succesfull, the character read is
93 * written into its argument c.
94 */
95int serial_getc (void)
96{
wdenk48b42612003-06-19 23:01:32 +000097 S3C24X0_UART * const uart = S3C24X0_GetBase_UART(UART_NR);
wdenk8bde7f72003-06-27 21:31:46 +000098
wdenk48b42612003-06-19 23:01:32 +000099 /* wait for character to arrive */
100 while (!(uart->UTRSTAT & 0x1));
wdenkc6097192002-11-03 00:24:07 +0000101
wdenk48b42612003-06-19 23:01:32 +0000102 return uart->URXH & 0xff;
wdenkc6097192002-11-03 00:24:07 +0000103}
104
105#ifdef CONFIG_HWFLOW
106static int hwflow = 0; /* turned off by default */
107int hwflow_onoff(int on)
108{
109 switch(on) {
110 case 0:
111 default:
112 break; /* return current */
113 case 1:
114 hwflow = 1; /* turn on */
115 break;
116 case -1:
117 hwflow = 0; /* turn off */
118 break;
119 }
120 return hwflow;
121}
122#endif
123
124#ifdef CONFIG_MODEM_SUPPORT
125static int be_quiet = 0;
126void disable_putc(void)
127{
128 be_quiet = 1;
129}
130
131void enable_putc(void)
132{
133 be_quiet = 0;
134}
135#endif
136
137
138/*
139 * Output a single byte to the serial port.
140 */
141void serial_putc (const char c)
142{
wdenk48b42612003-06-19 23:01:32 +0000143 S3C24X0_UART * const uart = S3C24X0_GetBase_UART(UART_NR);
wdenkc6097192002-11-03 00:24:07 +0000144#ifdef CONFIG_MODEM_SUPPORT
145 if (be_quiet)
146 return;
147#endif
148
wdenk48b42612003-06-19 23:01:32 +0000149 /* wait for room in the tx FIFO */
150 while (!(uart->UTRSTAT & 0x2));
wdenkc6097192002-11-03 00:24:07 +0000151
152#ifdef CONFIG_HWFLOW
153 /* Wait for CTS up */
wdenk48b42612003-06-19 23:01:32 +0000154 while(hwflow && !(uart->UMSTAT & 0x1))
wdenkc6097192002-11-03 00:24:07 +0000155 ;
156#endif
157
wdenk48b42612003-06-19 23:01:32 +0000158 uart->UTXH = c;
wdenkc6097192002-11-03 00:24:07 +0000159
160 /* If \n, also do \r */
161 if (c == '\n')
162 serial_putc ('\r');
163}
164
165/*
166 * Test whether a character is in the RX buffer
167 */
168int serial_tstc (void)
169{
wdenk48b42612003-06-19 23:01:32 +0000170 S3C24X0_UART * const uart = S3C24X0_GetBase_UART(UART_NR);
171
172 return uart->UTRSTAT & 0x1;
wdenkc6097192002-11-03 00:24:07 +0000173}
174
175void
176serial_puts (const char *s)
177{
178 while (*s) {
179 serial_putc (*s++);
180 }
181}
wdenk281e00a2004-08-01 22:48:16 +0000182
183#endif /* defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB) */