]> git.sur5r.net Git - u-boot/blob - drivers/serial/serial_pxa.c
serial: arm: Implement CONFIG_SERIAL_MULTI into atmel serial driver
[u-boot] / drivers / serial / serial_pxa.c
1 /*
2  * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
3  *
4  * (C) Copyright 2002
5  * Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
6  *
7  * (C) Copyright 2002
8  * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
9  * Marius Groeger <mgroeger@sysgo.de>
10  *
11  * (C) Copyright 2002
12  * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
13  * Alex Zuepke <azu@sysgo.de>
14  *
15  * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
16  *
17  * This program is free software; you can redistribute it and/or modify
18  * it under the terms of the GNU General Public License as published by
19  * the Free Software Foundation; either version 2 of the License, or
20  * (at your option) any later version.
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
30  *
31  */
32
33 #include <common.h>
34 #include <watchdog.h>
35 #include <serial.h>
36 #include <asm/arch/pxa-regs.h>
37 #include <asm/arch/regs-uart.h>
38 #include <asm/io.h>
39 #include <linux/compiler.h>
40
41 DECLARE_GLOBAL_DATA_PTR;
42
43 /*
44  * The numbering scheme differs here for PXA25x, PXA27x and PXA3xx so we can
45  * easily handle enabling of clock.
46  */
47 #ifdef  CONFIG_CPU_MONAHANS
48 #define UART_CLK_BASE   CKENA_21_BTUART
49 #define UART_CLK_REG    CKENA
50 #define BTUART_INDEX    0
51 #define FFUART_INDEX    1
52 #define STUART_INDEX    2
53 #elif   CONFIG_CPU_PXA25X
54 #define UART_CLK_BASE   (1 << 4)        /* HWUART */
55 #define UART_CLK_REG    CKEN
56 #define HWUART_INDEX    0
57 #define STUART_INDEX    1
58 #define FFUART_INDEX    2
59 #define BTUART_INDEX    3
60 #else   /* PXA27x */
61 #define UART_CLK_BASE   CKEN5_STUART
62 #define UART_CLK_REG    CKEN
63 #define STUART_INDEX    0
64 #define FFUART_INDEX    1
65 #define BTUART_INDEX    2
66 #endif
67
68 /*
69  * Only PXA250 has HWUART, to avoid poluting the code with more macros,
70  * artificially introduce this.
71  */
72 #ifndef CONFIG_CPU_PXA25X
73 #define HWUART_INDEX    0xff
74 #endif
75
76 #ifndef CONFIG_SERIAL_MULTI
77 #if defined(CONFIG_FFUART)
78 #define UART_INDEX      FFUART_INDEX
79 #elif defined(CONFIG_BTUART)
80 #define UART_INDEX      BTUART_INDEX
81 #elif defined(CONFIG_STUART)
82 #define UART_INDEX      STUART_INDEX
83 #elif defined(CONFIG_HWUART)
84 #define UART_INDEX      HWUART_INDEX
85 #else
86 #error "Please select CONFIG_(FF|BT|ST|HW)UART in board config file."
87 #endif
88 #endif
89
90 static uint32_t pxa_uart_get_baud_divider(void)
91 {
92         if (gd->baudrate == 1200)
93                 return 768;
94         else if (gd->baudrate == 9600)
95                 return 96;
96         else if (gd->baudrate == 19200)
97                 return 48;
98         else if (gd->baudrate == 38400)
99                 return 24;
100         else if (gd->baudrate == 57600)
101                 return 16;
102         else if (gd->baudrate == 115200)
103                 return 8;
104         else    /* Unsupported baudrate */
105                 return 0;
106 }
107
108 static struct pxa_uart_regs *pxa_uart_index_to_regs(uint32_t uart_index)
109 {
110         switch (uart_index) {
111         case FFUART_INDEX: return (struct pxa_uart_regs *)FFUART_BASE;
112         case BTUART_INDEX: return (struct pxa_uart_regs *)BTUART_BASE;
113         case STUART_INDEX: return (struct pxa_uart_regs *)STUART_BASE;
114         case HWUART_INDEX: return (struct pxa_uart_regs *)HWUART_BASE;
115         default:
116                 return NULL;
117         }
118 }
119
120 static void pxa_uart_toggle_clock(uint32_t uart_index, int enable)
121 {
122         uint32_t clk_reg, clk_offset, reg;
123
124         clk_reg = UART_CLK_REG;
125         clk_offset = UART_CLK_BASE << uart_index;
126
127         reg = readl(clk_reg);
128
129         if (enable)
130                 reg |= clk_offset;
131         else
132                 reg &= ~clk_offset;
133
134         writel(reg, clk_reg);
135 }
136
137 /*
138  * Enable clock and set baud rate, parity etc.
139  */
140 void pxa_setbrg_dev(uint32_t uart_index)
141 {
142         uint32_t divider = 0;
143         struct pxa_uart_regs *uart_regs;
144
145         divider = pxa_uart_get_baud_divider();
146         if (!divider)
147                 hang();
148
149         uart_regs = pxa_uart_index_to_regs(uart_index);
150         if (!uart_regs)
151                 hang();
152
153         pxa_uart_toggle_clock(uart_index, 1);
154
155         /* Disable interrupts and FIFOs */
156         writel(0, &uart_regs->ier);
157         writel(0, &uart_regs->fcr);
158
159         /* Set baud rate */
160         writel(LCR_WLS0 | LCR_WLS1 | LCR_DLAB, &uart_regs->lcr);
161         writel(divider & 0xff, &uart_regs->dll);
162         writel(divider >> 8, &uart_regs->dlh);
163         writel(LCR_WLS0 | LCR_WLS1, &uart_regs->lcr);
164
165         /* Enable UART */
166         writel(IER_UUE, &uart_regs->ier);
167 }
168
169 /*
170  * Initialise the serial port with the given baudrate. The settings
171  * are always 8 data bits, no parity, 1 stop bit, no start bits.
172  */
173 int pxa_init_dev(unsigned int uart_index)
174 {
175         pxa_setbrg_dev (uart_index);
176         return 0;
177 }
178
179 /*
180  * Output a single byte to the serial port.
181  */
182 void pxa_putc_dev(unsigned int uart_index, const char c)
183 {
184         struct pxa_uart_regs *uart_regs;
185
186         uart_regs = pxa_uart_index_to_regs(uart_index);
187         if (!uart_regs)
188                 hang();
189
190         while (!(readl(&uart_regs->lsr) & LSR_TEMT))
191                 WATCHDOG_RESET();
192         writel(c, &uart_regs->thr);
193
194         /* If \n, also do \r */
195         if (c == '\n')
196                 pxa_putc_dev (uart_index,'\r');
197 }
198
199 /*
200  * Read a single byte from the serial port. Returns 1 on success, 0
201  * otherwise. When the function is succesfull, the character read is
202  * written into its argument c.
203  */
204 int pxa_tstc_dev(unsigned int uart_index)
205 {
206         struct pxa_uart_regs *uart_regs;
207
208         uart_regs = pxa_uart_index_to_regs(uart_index);
209         if (!uart_regs)
210                 return -1;
211
212         return readl(&uart_regs->lsr) & LSR_DR;
213 }
214
215 /*
216  * Read a single byte from the serial port. Returns 1 on success, 0
217  * otherwise. When the function is succesfull, the character read is
218  * written into its argument c.
219  */
220 int pxa_getc_dev(unsigned int uart_index)
221 {
222         struct pxa_uart_regs *uart_regs;
223
224         uart_regs = pxa_uart_index_to_regs(uart_index);
225         if (!uart_regs)
226                 return -1;
227
228         while (!(readl(&uart_regs->lsr) & LSR_DR))
229                 WATCHDOG_RESET();
230         return readl(&uart_regs->rbr) & 0xff;
231 }
232
233 void pxa_puts_dev(unsigned int uart_index, const char *s)
234 {
235         while (*s)
236                 pxa_putc_dev(uart_index, *s++);
237 }
238
239 #define pxa_uart(uart, UART)                                            \
240         int uart##_init(void)                                           \
241         {                                                               \
242                 return pxa_init_dev(UART##_INDEX);                      \
243         }                                                               \
244                                                                         \
245         void uart##_setbrg(void)                                        \
246         {                                                               \
247                 return pxa_setbrg_dev(UART##_INDEX);                    \
248         }                                                               \
249                                                                         \
250         void uart##_putc(const char c)                                  \
251         {                                                               \
252                 return pxa_putc_dev(UART##_INDEX, c);                   \
253         }                                                               \
254                                                                         \
255         void uart##_puts(const char *s)                                 \
256         {                                                               \
257                 return pxa_puts_dev(UART##_INDEX, s);                   \
258         }                                                               \
259                                                                         \
260         int uart##_getc(void)                                           \
261         {                                                               \
262                 return pxa_getc_dev(UART##_INDEX);                      \
263         }                                                               \
264                                                                         \
265         int uart##_tstc(void)                                           \
266         {                                                               \
267                 return pxa_tstc_dev(UART##_INDEX);                      \
268         }                                                               \
269
270 #define pxa_uart_desc(uart)                                             \
271         struct serial_device serial_##uart##_device =                   \
272         {                                                               \
273                 .name   = "serial_"#uart,                               \
274                 .start  = uart##_init,                                  \
275                 .stop   = NULL,                                         \
276                 .setbrg = uart##_setbrg,                                \
277                 .getc   = uart##_getc,                                  \
278                 .tstc   = uart##_tstc,                                  \
279                 .putc   = uart##_putc,                                  \
280                 .puts   = uart##_puts,                                  \
281         };
282
283 #define pxa_uart_multi(uart, UART)                                      \
284         pxa_uart(uart, UART)                                            \
285         pxa_uart_desc(uart)
286
287 #if defined(CONFIG_HWUART)
288         pxa_uart_multi(hwuart, HWUART)
289 #endif
290 #if defined(CONFIG_STUART)
291         pxa_uart_multi(stuart, STUART)
292 #endif
293 #if defined(CONFIG_FFUART)
294         pxa_uart_multi(ffuart, FFUART)
295 #endif
296 #if defined(CONFIG_BTUART)
297         pxa_uart_multi(btuart, BTUART)
298 #endif
299
300 #ifndef CONFIG_SERIAL_MULTI
301         pxa_uart(serial, UART)
302 #else
303 __weak struct serial_device *default_serial_console(void)
304 {
305 #if CONFIG_CONS_INDEX == 1
306         return &serial_hwuart_device;
307 #elif CONFIG_CONS_INDEX == 2
308         return &serial_stuart_device;
309 #elif CONFIG_CONS_INDEX == 3
310         return &serial_ffuart_device;
311 #elif CONFIG_CONS_INDEX == 4
312         return &serial_btuart_device;
313 #else
314 #error "Bad CONFIG_CONS_INDEX."
315 #endif
316 }
317
318 void pxa_serial_initialize(void)
319 {
320 #if defined(CONFIG_FFUART)
321         serial_register(&serial_ffuart_device);
322 #endif
323 #if defined(CONFIG_BTUART)
324         serial_register(&serial_btuart_device);
325 #endif
326 #if defined(CONFIG_STUART)
327         serial_register(&serial_stuart_device);
328 #endif
329 }
330 #endif