]> git.ipfire.org Git - people/ms/u-boot.git/blob - drivers/serial/serial_pxa.c
b74e43957ff70d4024efc78d6b0618c437823664
[people/ms/u-boot.git] / drivers / serial / serial_pxa.c
1 /*
2 * (C) Copyright 2002
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 #include <watchdog.h>
33 #include <serial.h>
34 #include <asm/arch/pxa-regs.h>
35
36 DECLARE_GLOBAL_DATA_PTR;
37
38 #define FFUART_INDEX 0
39 #define BTUART_INDEX 1
40 #define STUART_INDEX 2
41
42 #ifndef CONFIG_SERIAL_MULTI
43 #if defined (CONFIG_FFUART)
44 #define UART_INDEX FFUART_INDEX
45 #elif defined (CONFIG_BTUART)
46 #define UART_INDEX BTUART_INDEX
47 #elif defined (CONFIG_STUART)
48 #define UART_INDEX STUART_INDEX
49 #else
50 #error "Bad: you didn't configure serial ..."
51 #endif
52 #endif
53
54 void pxa_setbrg_dev (unsigned int uart_index)
55 {
56 unsigned int quot = 0;
57
58 if (gd->baudrate == 1200)
59 quot = 768;
60 else if (gd->baudrate == 9600)
61 quot = 96;
62 else if (gd->baudrate == 19200)
63 quot = 48;
64 else if (gd->baudrate == 38400)
65 quot = 24;
66 else if (gd->baudrate == 57600)
67 quot = 16;
68 else if (gd->baudrate == 115200)
69 quot = 8;
70 else
71 hang ();
72
73 switch (uart_index) {
74 case FFUART_INDEX:
75 #ifdef CONFIG_CPU_MONAHANS
76 CKENA |= CKENA_22_FFUART;
77 #else
78 CKEN |= CKEN6_FFUART;
79 #endif /* CONFIG_CPU_MONAHANS */
80
81 FFIER = 0; /* Disable for now */
82 FFFCR = 0; /* No fifos enabled */
83
84 /* set baud rate */
85 FFLCR = LCR_WLS0 | LCR_WLS1 | LCR_DLAB;
86 FFDLL = quot & 0xff;
87 FFDLH = quot >> 8;
88 FFLCR = LCR_WLS0 | LCR_WLS1;
89
90 FFIER = IER_UUE; /* Enable FFUART */
91 break;
92
93 case BTUART_INDEX:
94 #ifdef CONFIG_CPU_MONAHANS
95 CKENA |= CKENA_21_BTUART;
96 #else
97 CKEN |= CKEN7_BTUART;
98 #endif /* CONFIG_CPU_MONAHANS */
99
100 BTIER = 0;
101 BTFCR = 0;
102
103 /* set baud rate */
104 BTLCR = LCR_DLAB;
105 BTDLL = quot & 0xff;
106 BTDLH = quot >> 8;
107 BTLCR = LCR_WLS0 | LCR_WLS1;
108
109 BTIER = IER_UUE; /* Enable BFUART */
110
111 break;
112
113 case STUART_INDEX:
114 #ifdef CONFIG_CPU_MONAHANS
115 CKENA |= CKENA_23_STUART;
116 #else
117 CKEN |= CKEN5_STUART;
118 #endif /* CONFIG_CPU_MONAHANS */
119
120 STIER = 0;
121 STFCR = 0;
122
123 /* set baud rate */
124 STLCR = LCR_DLAB;
125 STDLL = quot & 0xff;
126 STDLH = quot >> 8;
127 STLCR = LCR_WLS0 | LCR_WLS1;
128
129 STIER = IER_UUE; /* Enable STUART */
130 break;
131
132 default:
133 hang();
134 }
135 }
136
137
138 /*
139 * Initialise the serial port with the given baudrate. The settings
140 * are always 8 data bits, no parity, 1 stop bit, no start bits.
141 *
142 */
143 int pxa_init_dev (unsigned int uart_index)
144 {
145 pxa_setbrg_dev (uart_index);
146
147 return (0);
148 }
149
150
151 /*
152 * Output a single byte to the serial port.
153 */
154 void pxa_putc_dev (unsigned int uart_index,const char c)
155 {
156 switch (uart_index) {
157 case FFUART_INDEX:
158 /* wait for room in the tx FIFO on FFUART */
159 while ((FFLSR & LSR_TEMT) == 0)
160 WATCHDOG_RESET (); /* Reset HW Watchdog, if needed */
161 FFTHR = c;
162 break;
163
164 case BTUART_INDEX:
165 while ((BTLSR & LSR_TEMT ) == 0 )
166 WATCHDOG_RESET (); /* Reset HW Watchdog, if needed */
167 BTTHR = c;
168 break;
169
170 case STUART_INDEX:
171 while ((STLSR & LSR_TEMT ) == 0 )
172 WATCHDOG_RESET (); /* Reset HW Watchdog, if needed */
173 STTHR = c;
174 break;
175 }
176
177 /* If \n, also do \r */
178 if (c == '\n')
179 pxa_putc_dev (uart_index,'\r');
180 }
181
182 /*
183 * Read a single byte from the serial port. Returns 1 on success, 0
184 * otherwise. When the function is succesfull, the character read is
185 * written into its argument c.
186 */
187 int pxa_tstc_dev (unsigned int uart_index)
188 {
189 switch (uart_index) {
190 case FFUART_INDEX:
191 return FFLSR & LSR_DR;
192 case BTUART_INDEX:
193 return BTLSR & LSR_DR;
194 case STUART_INDEX:
195 return STLSR & LSR_DR;
196 }
197 return -1;
198 }
199
200 /*
201 * Read a single byte from the serial port. Returns 1 on success, 0
202 * otherwise. When the function is succesfull, the character read is
203 * written into its argument c.
204 */
205 int pxa_getc_dev (unsigned int uart_index)
206 {
207 switch (uart_index) {
208 case FFUART_INDEX:
209 while (!(FFLSR & LSR_DR))
210 WATCHDOG_RESET (); /* Reset HW Watchdog, if needed */
211 return (char) FFRBR & 0xff;
212
213 case BTUART_INDEX:
214 while (!(BTLSR & LSR_DR))
215 WATCHDOG_RESET (); /* Reset HW Watchdog, if needed */
216 return (char) BTRBR & 0xff;
217 case STUART_INDEX:
218 while (!(STLSR & LSR_DR))
219 WATCHDOG_RESET (); /* Reset HW Watchdog, if needed */
220 return (char) STRBR & 0xff;
221 }
222 return -1;
223 }
224
225 void
226 pxa_puts_dev (unsigned int uart_index,const char *s)
227 {
228 while (*s) {
229 pxa_putc_dev (uart_index,*s++);
230 }
231 }
232
233 #if defined (CONFIG_FFUART)
234 static int ffuart_init(void)
235 {
236 return pxa_init_dev(FFUART_INDEX);
237 }
238
239 static void ffuart_setbrg(void)
240 {
241 return pxa_setbrg_dev(FFUART_INDEX);
242 }
243
244 static void ffuart_putc(const char c)
245 {
246 return pxa_putc_dev(FFUART_INDEX,c);
247 }
248
249 static void ffuart_puts(const char *s)
250 {
251 return pxa_puts_dev(FFUART_INDEX,s);
252 }
253
254 static int ffuart_getc(void)
255 {
256 return pxa_getc_dev(FFUART_INDEX);
257 }
258
259 static int ffuart_tstc(void)
260 {
261 return pxa_tstc_dev(FFUART_INDEX);
262 }
263
264 struct serial_device serial_ffuart_device =
265 {
266 "serial_ffuart",
267 "PXA",
268 ffuart_init,
269 NULL,
270 ffuart_setbrg,
271 ffuart_getc,
272 ffuart_tstc,
273 ffuart_putc,
274 ffuart_puts,
275 };
276 #endif
277
278 #if defined (CONFIG_BTUART)
279 static int btuart_init(void)
280 {
281 return pxa_init_dev(BTUART_INDEX);
282 }
283
284 static void btuart_setbrg(void)
285 {
286 return pxa_setbrg_dev(BTUART_INDEX);
287 }
288
289 static void btuart_putc(const char c)
290 {
291 return pxa_putc_dev(BTUART_INDEX,c);
292 }
293
294 static void btuart_puts(const char *s)
295 {
296 return pxa_puts_dev(BTUART_INDEX,s);
297 }
298
299 static int btuart_getc(void)
300 {
301 return pxa_getc_dev(BTUART_INDEX);
302 }
303
304 static int btuart_tstc(void)
305 {
306 return pxa_tstc_dev(BTUART_INDEX);
307 }
308
309 struct serial_device serial_btuart_device =
310 {
311 "serial_btuart",
312 "PXA",
313 btuart_init,
314 NULL,
315 btuart_setbrg,
316 btuart_getc,
317 btuart_tstc,
318 btuart_putc,
319 btuart_puts,
320 };
321 #endif
322
323 #if defined (CONFIG_STUART)
324 static int stuart_init(void)
325 {
326 return pxa_init_dev(STUART_INDEX);
327 }
328
329 static void stuart_setbrg(void)
330 {
331 return pxa_setbrg_dev(STUART_INDEX);
332 }
333
334 static void stuart_putc(const char c)
335 {
336 return pxa_putc_dev(STUART_INDEX,c);
337 }
338
339 static void stuart_puts(const char *s)
340 {
341 return pxa_puts_dev(STUART_INDEX,s);
342 }
343
344 static int stuart_getc(void)
345 {
346 return pxa_getc_dev(STUART_INDEX);
347 }
348
349 static int stuart_tstc(void)
350 {
351 return pxa_tstc_dev(STUART_INDEX);
352 }
353
354 struct serial_device serial_stuart_device =
355 {
356 "serial_stuart",
357 "PXA",
358 stuart_init,
359 NULL,
360 stuart_setbrg,
361 stuart_getc,
362 stuart_tstc,
363 stuart_putc,
364 stuart_puts,
365 };
366 #endif
367
368
369 #ifndef CONFIG_SERIAL_MULTI
370 inline int serial_init(void) {
371 return (pxa_init_dev(UART_INDEX));
372 }
373 void serial_setbrg(void) {
374 pxa_setbrg_dev(UART_INDEX);
375 }
376 int serial_getc(void) {
377 return(pxa_getc_dev(UART_INDEX));
378 }
379 int serial_tstc(void) {
380 return(pxa_tstc_dev(UART_INDEX));
381 }
382 void serial_putc(const char c) {
383 pxa_putc_dev(UART_INDEX,c);
384 }
385 void serial_puts(const char *s) {
386 pxa_puts_dev(UART_INDEX,s);
387 }
388 #endif /* CONFIG_SERIAL_MULTI */