]> git.sur5r.net Git - u-boot/blob - cpu/blackfin/serial.c
powerpc: Fix bootm to boot up again with a Ramdisk
[u-boot] / cpu / blackfin / serial.c
1 /*
2  * U-boot - serial.c Blackfin Serial Driver
3  *
4  * Copyright (c) 2005-2008 Analog Devices Inc.
5  *
6  * Copyright (c) 2003   Bas Vermeulen <bas@buyways.nl>,
7  *                      BuyWays B.V. (www.buyways.nl)
8  *
9  * Based heavily on:
10  * blkfinserial.c: Serial driver for BlackFin DSP internal USRTs.
11  * Copyright(c) 2003    Metrowerks      <mwaddel@metrowerks.com>
12  * Copyright(c) 2001    Tony Z. Kou     <tonyko@arcturusnetworks.com>
13  * Copyright(c) 2001-2002 Arcturus Networks Inc. <www.arcturusnetworks.com>
14  *
15  * Based on code from 68328 version serial driver imlpementation which was:
16  * Copyright (C) 1995       David S. Miller    <davem@caip.rutgers.edu>
17  * Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
18  * Copyright (C) 1998, 1999 D. Jeff Dionne     <jeff@uclinux.org>
19  * Copyright (C) 1999       Vladimir Gurevich  <vgurevic@cisco.com>
20  *
21  * (C) Copyright 2000-2004
22  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
23  *
24  * Licensed under the GPL-2 or later.
25  */
26
27 #include <common.h>
28 #include <watchdog.h>
29 #include <asm/blackfin.h>
30 #include <asm/mach-common/bits/uart.h>
31
32 #if defined(UART_LSR) && (CONFIG_UART_CONSOLE != 0)
33 # error CONFIG_UART_CONSOLE must be 0 on parts with only one UART
34 #endif
35
36 #include "serial.h"
37
38 /* Symbol for our assembly to call. */
39 void serial_set_baud(uint32_t baud)
40 {
41         serial_early_set_baud(baud);
42 }
43
44 /* Symbol for common u-boot code to call.
45  * Setup the baudrate (brg: baudrate generator).
46  */
47 void serial_setbrg(void)
48 {
49         DECLARE_GLOBAL_DATA_PTR;
50         serial_set_baud(gd->baudrate);
51 }
52
53 /* Symbol for our assembly to call. */
54 void serial_initialize(void)
55 {
56         serial_early_init();
57 }
58
59 /* Symbol for common u-boot code to call. */
60 int serial_init(void)
61 {
62         serial_initialize();
63         serial_setbrg();
64         return 0;
65 }
66
67 void serial_putc(const char c)
68 {
69         /* send a \r for compatibility */
70         if (c == '\n')
71                 serial_putc('\r');
72
73         WATCHDOG_RESET();
74
75         /* wait for the hardware fifo to clear up */
76         while (!(*pUART_LSR & THRE))
77                 continue;
78
79         /* queue the character for transmission */
80         *pUART_THR = c;
81         SSYNC();
82
83         WATCHDOG_RESET();
84
85         /* wait for the byte to be shifted over the line */
86         while (!(*pUART_LSR & TEMT))
87                 continue;
88 }
89
90 int serial_tstc(void)
91 {
92         WATCHDOG_RESET();
93         return (*pUART_LSR & DR) ? 1 : 0;
94 }
95
96 int serial_getc(void)
97 {
98         uint16_t uart_lsr_val, uart_rbr_val;
99
100         /* wait for data ! */
101         while (!serial_tstc())
102                 continue;
103
104         /* clear the status and grab the new byte */
105         uart_lsr_val = *pUART_LSR;
106         uart_rbr_val = *pUART_RBR;
107
108         if (uart_lsr_val & (OE|PE|FE|BI)) {
109                 /* Some parts are read-to-clear while others are
110                  * write-to-clear.  Just do the write for everyone
111                  * since it cant hurt (other than code size).
112                  */
113                 *pUART_LSR = (OE|PE|FE|BI);
114                 return -1;
115         }
116
117         return uart_rbr_val & 0xFF;
118 }
119
120 void serial_puts(const char *s)
121 {
122         while (*s)
123                 serial_putc(*s++);
124 }