Add port for the lpc2292sodimm evaluation board from EmbeddedArtists
[platform/kernel/u-boot.git] / cpu / arm720t / serial.c
1 /*
2  * (C) Copyright 2002-2004
3  * Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
4  *
5  * (C) Copyright 2002
6  * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
7  * Marius Groeger <mgroeger@sysgo.de>
8  *
9  * (C) Copyright 2002
10  * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
11  * Alex Zuepke <azu@sysgo.de>
12  *
13  * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
14  *
15  * This program is free software; you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License as published by
17  * the Free Software Foundation; either version 2 of the License, or
18  * (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28  *
29  */
30
31 #include <common.h>
32
33 #if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_ARMADILLO)
34
35 #include <clps7111.h>
36
37 DECLARE_GLOBAL_DATA_PTR;
38
39 void serial_setbrg (void)
40 {
41         unsigned int reg = 0;
42
43         switch (gd->baudrate) {
44         case   1200:    reg = 191;      break;
45         case   9600:    reg =  23;      break;
46         case  19200:    reg =  11;      break;
47         case  38400:    reg =   5;      break;
48         case  57600:    reg =   3;      break;
49         case 115200:    reg =   1;      break;
50         default:        hang ();        break;
51         }
52
53         /* init serial serial 1,2 */
54         IO_SYSCON1 = SYSCON1_UART1EN;
55         IO_SYSCON2 = SYSCON2_UART2EN;
56
57         reg |= UBRLCR_WRDLEN8;
58
59         IO_UBRLCR1 = reg;
60         IO_UBRLCR2 = reg;
61 }
62
63
64 /*
65  * Initialise the serial port with the given baudrate. The settings
66  * are always 8 data bits, no parity, 1 stop bit, no start bits.
67  *
68  */
69 int serial_init (void)
70 {
71         serial_setbrg ();
72
73         return (0);
74 }
75
76
77 /*
78  * Output a single byte to the serial port.
79  */
80 void serial_putc (const char c)
81 {
82         int tmo;
83
84         /* If \n, also do \r */
85         if (c == '\n')
86                 serial_putc ('\r');
87
88         tmo = get_timer (0) + 1 * CFG_HZ;
89         while (IO_SYSFLG1 & SYSFLG1_UTXFF)
90                 if (get_timer (0) > tmo)
91                         break;
92
93         IO_UARTDR1 = c;
94 }
95
96 /*
97  * Read a single byte from the serial port. Returns 1 on success, 0
98  * otherwise. When the function is succesfull, the character read is
99  * written into its argument c.
100  */
101 int serial_tstc (void)
102 {
103         return !(IO_SYSFLG1 & SYSFLG1_URXFE);
104 }
105
106 /*
107  * Read a single byte from the serial port. Returns 1 on success, 0
108  * otherwise. When the function is succesfull, the character read is
109  * written into its argument c.
110  */
111 int serial_getc (void)
112 {
113         while (IO_SYSFLG1 & SYSFLG1_URXFE);
114
115         return IO_UARTDR1 & 0xff;
116 }
117
118 void
119 serial_puts (const char *s)
120 {
121         while (*s) {
122                 serial_putc (*s++);
123         }
124 }
125
126 #elif defined(CONFIG_LPC2292)
127
128 #include <asm/arch/hardware.h>
129
130 void serial_setbrg (void)
131 {
132         DECLARE_GLOBAL_DATA_PTR;
133
134         unsigned short divisor = 0;
135
136         switch (gd->baudrate) {
137         case   1200:    divisor = 3072; break;
138         case   9600:    divisor =  384; break;
139         case  19200:    divisor =  192; break;
140         case  38400:    divisor =   96; break;
141         case  57600:    divisor =   64; break;
142         case 115200:    divisor =   32; break;
143         default:        hang ();        break;
144         }
145
146         /* init serial UART0 */
147         PUT8(U0LCR, 0);
148         PUT8(U0IER, 0);
149         PUT8(U0LCR, 0x80);      /* DLAB=1 */
150         PUT8(U0DLL, (unsigned char)(divisor & 0x00FF));
151         PUT8(U0DLM, (unsigned char)(divisor >> 8));
152         PUT8(U0LCR, 0x03);      /* 8N1, DLAB=0  */
153         PUT8(U0FCR, 1);         /* Enable RX and TX FIFOs */
154 }
155
156 int serial_init (void)
157 {
158         unsigned long pinsel0;
159
160         serial_setbrg ();
161
162         pinsel0 = GET32(PINSEL0);
163         pinsel0 &= ~(0x00000003);
164         pinsel0 |= 5;
165         PUT32(PINSEL0, pinsel0);
166
167         return (0);
168 }
169
170 void serial_putc (const char c)
171 {
172         if (c == '\n')
173         {
174                 while((GET8(U0LSR) & (1<<5)) == 0); /* Wait for empty U0THR */
175                 PUT8(U0THR, '\r');
176         }
177
178         while((GET8(U0LSR) & (1<<5)) == 0); /* Wait for empty U0THR */
179         PUT8(U0THR, c);
180 }
181
182 int serial_getc (void)
183 {
184         while((GET8(U0LSR) & 1) == 0);
185         return GET8(U0RBR);
186 }
187
188 void
189 serial_puts (const char *s)
190 {
191         while (*s) {
192                 serial_putc (*s++);
193         }
194 }
195
196 /* Test if there is a byte to read */
197 int serial_tstc (void)
198 {
199         return (GET8(U0LSR) & 1);
200 }
201
202 #endif