]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - cpu/arm720t/serial_netarm.c
* Patch by Thomas Elste, 10 Feb 2004:
[karo-tx-uboot.git] / cpu / arm720t / serial_netarm.c
1 /*
2  * Serial Port stuff - taken from Linux
3  *
4  * (C) Copyright 2002
5  * MAZeT GmbH <www.mazet.de>
6  * Stephan Linz <linz@mazet.de>, <linz@li-pro.net>
7  *
8  * (c) 2004
9  * IMMS gGmbH <www.imms.de>
10  * Thomas Elste <info@elste.org>
11  *
12  * See file CREDITS for list of people who contributed to this
13  * project.
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 <asm/arch/netarm_registers.h>
33
34 #ifdef CONFIG_NETARM
35
36 #define PORTA   (*(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + NETARM_GEN_PORTA))
37 #define PORTB   (*(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + NETARM_GEN_PORTB))
38
39 /* wait until transmitter is ready for another character */
40 #define TXWAITRDY(registers)                                                    \
41 {                                                                               \
42         ulong tmo = get_timer(0) + 1 * CFG_HZ;                                  \
43         while (((registers)->status_a & NETARM_SER_STATA_TX_RDY) == 0 ) {       \
44                 if (get_timer(0) > tmo)                                         \
45                         break;                                                  \
46         }                                                                       \
47 }
48
49
50 volatile netarm_serial_channel_t *serial_reg_ch1 = get_serial_channel(0);
51 volatile netarm_serial_channel_t *serial_reg_ch2 = get_serial_channel(1);
52
53 extern void _netarm_led_FAIL1(void);
54
55 /*
56  * Setup both serial i/f with given baudrate
57  */
58 void serial_setbrg (void)
59 {
60         /* get the gd pointer */
61         DECLARE_GLOBAL_DATA_PTR;
62
63         /* set 0 ... make sure pins are configured for serial */
64         PORTA = PORTB =
65                 NETARM_GEN_PORT_MODE (0xef) | NETARM_GEN_PORT_DIR (0xe0);
66
67         /* first turn em off */
68         serial_reg_ch1->ctrl_a = serial_reg_ch2->ctrl_a = 0;
69
70         /* clear match register, we don't need it */
71         serial_reg_ch1->rx_match = serial_reg_ch2->rx_match = 0;
72
73         /* setup bit rate generator and rx buffer gap timer (1 byte only) */
74         if ((gd->baudrate >= MIN_BAUD_RATE)
75             && (gd->baudrate <= MAX_BAUD_RATE)) {
76                 serial_reg_ch1->bitrate = serial_reg_ch2->bitrate =
77                         NETARM_SER_BR_X16 (gd->baudrate);
78                 serial_reg_ch1->rx_buf_timer = serial_reg_ch2->rx_buf_timer =
79                         0;
80                 serial_reg_ch1->rx_char_timer = serial_reg_ch2->rx_char_timer =
81                         NETARM_SER_RXGAP (gd->baudrate);
82         } else {
83                 hang ();
84         }
85
86         /* setup port mode */
87         serial_reg_ch1->ctrl_b = serial_reg_ch2->ctrl_b =
88                 ( NETARM_SER_CTLB_RCGT_EN |
89                   NETARM_SER_CTLB_UART_MODE);
90         serial_reg_ch1->ctrl_a = serial_reg_ch2->ctrl_a =
91                 ( NETARM_SER_CTLA_ENABLE |
92                   NETARM_SER_CTLA_P_NONE |
93                   /* see errata */
94                   NETARM_SER_CTLA_2STOP |
95                   NETARM_SER_CTLA_8BITS |
96                   NETARM_SER_CTLA_DTR_EN |
97                   NETARM_SER_CTLA_RTS_EN);
98 }
99
100
101 /*
102  * Initialise the serial port with the given baudrate. The settings
103  * are always 8 data bits, no parity, 1 stop bit, no start bits.
104  */
105 int serial_init (void)
106 {
107         serial_setbrg ();
108         return 0;
109 }
110
111
112 /*
113  * Output a single byte to the serial port.
114  */
115 void serial_putc (const char c)
116 {
117         volatile unsigned char *fifo;
118
119         /* If \n, also do \r */
120         if (c == '\n')
121                 serial_putc ('\r');
122
123         fifo = (volatile unsigned char *) &(serial_reg_ch1->fifo);
124         TXWAITRDY (serial_reg_ch1);
125         *fifo = c;
126 }
127
128 /*
129  * Test of a single byte from the serial port. Returns 1 on success, 0
130  * otherwise.
131  */
132 int serial_tstc(void)
133 {
134         return serial_reg_ch1->status_a & NETARM_SER_STATA_RX_RDY;
135 }
136
137 /*
138  * Read a single byte from the serial port. Returns 1 on success, 0
139  * otherwise.
140  */
141 int serial_getc (void)
142 {
143         unsigned int ch_uint;
144         volatile unsigned int *fifo;
145         volatile unsigned char *fifo_char = NULL;
146         int buf_count = 0;
147
148         while (!(serial_reg_ch1->status_a & NETARM_SER_STATA_RX_RDY))
149                 /* NOP */ ;
150
151         fifo = (volatile unsigned int *) &(serial_reg_ch1->fifo);
152         fifo_char = (unsigned char *) &ch_uint;
153         ch_uint = *fifo;
154
155         buf_count = NETARM_SER_STATA_RXFDB (serial_reg_ch1->status_a);
156         switch (buf_count) {
157         case NETARM_SER_STATA_RXFDB_4BYTES:
158                 buf_count = 4;
159                 break;
160         case NETARM_SER_STATA_RXFDB_3BYTES:
161                 buf_count = 3;
162                 break;
163         case NETARM_SER_STATA_RXFDB_2BYTES:
164                 buf_count = 2;
165                 break;
166         case NETARM_SER_STATA_RXFDB_1BYTES:
167                 buf_count = 1;
168                 break;
169         default:
170                 /* panic, be never here */
171         }
172
173         serial_reg_ch1->status_a |= NETARM_SER_STATA_RX_CLOSED;
174
175         return ch_uint & 0xff;
176 }
177
178 void serial_puts (const char *s)
179 {
180         while (*s) {
181                 serial_putc (*s++);
182         }
183 }
184
185 #endif /* CONFIG_NETARM */