]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/serial/serial_pxa.c
Merge branch 'u-boot-imx/master' into 'u-boot-arm/master'
[karo-tx-uboot.git] / 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 static uint32_t pxa_uart_get_baud_divider(void)
77 {
78         if (gd->baudrate == 1200)
79                 return 768;
80         else if (gd->baudrate == 9600)
81                 return 96;
82         else if (gd->baudrate == 19200)
83                 return 48;
84         else if (gd->baudrate == 38400)
85                 return 24;
86         else if (gd->baudrate == 57600)
87                 return 16;
88         else if (gd->baudrate == 115200)
89                 return 8;
90         else    /* Unsupported baudrate */
91                 return 0;
92 }
93
94 static struct pxa_uart_regs *pxa_uart_index_to_regs(uint32_t uart_index)
95 {
96         switch (uart_index) {
97         case FFUART_INDEX: return (struct pxa_uart_regs *)FFUART_BASE;
98         case BTUART_INDEX: return (struct pxa_uart_regs *)BTUART_BASE;
99         case STUART_INDEX: return (struct pxa_uart_regs *)STUART_BASE;
100         case HWUART_INDEX: return (struct pxa_uart_regs *)HWUART_BASE;
101         default:
102                 return NULL;
103         }
104 }
105
106 static void pxa_uart_toggle_clock(uint32_t uart_index, int enable)
107 {
108         uint32_t clk_reg, clk_offset, reg;
109
110         clk_reg = UART_CLK_REG;
111         clk_offset = UART_CLK_BASE << uart_index;
112
113         reg = readl(clk_reg);
114
115         if (enable)
116                 reg |= clk_offset;
117         else
118                 reg &= ~clk_offset;
119
120         writel(reg, clk_reg);
121 }
122
123 /*
124  * Enable clock and set baud rate, parity etc.
125  */
126 void pxa_setbrg_dev(uint32_t uart_index)
127 {
128         uint32_t divider = 0;
129         struct pxa_uart_regs *uart_regs;
130
131         divider = pxa_uart_get_baud_divider();
132         if (!divider)
133                 hang();
134
135         uart_regs = pxa_uart_index_to_regs(uart_index);
136         if (!uart_regs)
137                 hang();
138
139         pxa_uart_toggle_clock(uart_index, 1);
140
141         /* Disable interrupts and FIFOs */
142         writel(0, &uart_regs->ier);
143         writel(0, &uart_regs->fcr);
144
145         /* Set baud rate */
146         writel(LCR_WLS0 | LCR_WLS1 | LCR_DLAB, &uart_regs->lcr);
147         writel(divider & 0xff, &uart_regs->dll);
148         writel(divider >> 8, &uart_regs->dlh);
149         writel(LCR_WLS0 | LCR_WLS1, &uart_regs->lcr);
150
151         /* Enable UART */
152         writel(IER_UUE, &uart_regs->ier);
153 }
154
155 /*
156  * Initialise the serial port with the given baudrate. The settings
157  * are always 8 data bits, no parity, 1 stop bit, no start bits.
158  */
159 int pxa_init_dev(unsigned int uart_index)
160 {
161         pxa_setbrg_dev (uart_index);
162         return 0;
163 }
164
165 /*
166  * Output a single byte to the serial port.
167  */
168 void pxa_putc_dev(unsigned int uart_index, const char c)
169 {
170         struct pxa_uart_regs *uart_regs;
171
172         uart_regs = pxa_uart_index_to_regs(uart_index);
173         if (!uart_regs)
174                 hang();
175
176         while (!(readl(&uart_regs->lsr) & LSR_TEMT))
177                 WATCHDOG_RESET();
178         writel(c, &uart_regs->thr);
179
180         /* If \n, also do \r */
181         if (c == '\n')
182                 pxa_putc_dev (uart_index,'\r');
183 }
184
185 /*
186  * Read a single byte from the serial port. Returns 1 on success, 0
187  * otherwise. When the function is succesfull, the character read is
188  * written into its argument c.
189  */
190 int pxa_tstc_dev(unsigned int uart_index)
191 {
192         struct pxa_uart_regs *uart_regs;
193
194         uart_regs = pxa_uart_index_to_regs(uart_index);
195         if (!uart_regs)
196                 return -1;
197
198         return readl(&uart_regs->lsr) & LSR_DR;
199 }
200
201 /*
202  * Read a single byte from the serial port. Returns 1 on success, 0
203  * otherwise. When the function is succesfull, the character read is
204  * written into its argument c.
205  */
206 int pxa_getc_dev(unsigned int uart_index)
207 {
208         struct pxa_uart_regs *uart_regs;
209
210         uart_regs = pxa_uart_index_to_regs(uart_index);
211         if (!uart_regs)
212                 return -1;
213
214         while (!(readl(&uart_regs->lsr) & LSR_DR))
215                 WATCHDOG_RESET();
216         return readl(&uart_regs->rbr) & 0xff;
217 }
218
219 void pxa_puts_dev(unsigned int uart_index, const char *s)
220 {
221         while (*s)
222                 pxa_putc_dev(uart_index, *s++);
223 }
224
225 #define pxa_uart(uart, UART)                                            \
226         int uart##_init(void)                                           \
227         {                                                               \
228                 return pxa_init_dev(UART##_INDEX);                      \
229         }                                                               \
230                                                                         \
231         void uart##_setbrg(void)                                        \
232         {                                                               \
233                 return pxa_setbrg_dev(UART##_INDEX);                    \
234         }                                                               \
235                                                                         \
236         void uart##_putc(const char c)                                  \
237         {                                                               \
238                 return pxa_putc_dev(UART##_INDEX, c);                   \
239         }                                                               \
240                                                                         \
241         void uart##_puts(const char *s)                                 \
242         {                                                               \
243                 return pxa_puts_dev(UART##_INDEX, s);                   \
244         }                                                               \
245                                                                         \
246         int uart##_getc(void)                                           \
247         {                                                               \
248                 return pxa_getc_dev(UART##_INDEX);                      \
249         }                                                               \
250                                                                         \
251         int uart##_tstc(void)                                           \
252         {                                                               \
253                 return pxa_tstc_dev(UART##_INDEX);                      \
254         }                                                               \
255
256 #define pxa_uart_desc(uart)                                             \
257         struct serial_device serial_##uart##_device =                   \
258         {                                                               \
259                 .name   = "serial_"#uart,                               \
260                 .start  = uart##_init,                                  \
261                 .stop   = NULL,                                         \
262                 .setbrg = uart##_setbrg,                                \
263                 .getc   = uart##_getc,                                  \
264                 .tstc   = uart##_tstc,                                  \
265                 .putc   = uart##_putc,                                  \
266                 .puts   = uart##_puts,                                  \
267         };
268
269 #define pxa_uart_multi(uart, UART)                                      \
270         pxa_uart(uart, UART)                                            \
271         pxa_uart_desc(uart)
272
273 #if defined(CONFIG_HWUART)
274         pxa_uart_multi(hwuart, HWUART)
275 #endif
276 #if defined(CONFIG_STUART)
277         pxa_uart_multi(stuart, STUART)
278 #endif
279 #if defined(CONFIG_FFUART)
280         pxa_uart_multi(ffuart, FFUART)
281 #endif
282 #if defined(CONFIG_BTUART)
283         pxa_uart_multi(btuart, BTUART)
284 #endif
285
286 __weak struct serial_device *default_serial_console(void)
287 {
288 #if CONFIG_CONS_INDEX == 1
289         return &serial_hwuart_device;
290 #elif CONFIG_CONS_INDEX == 2
291         return &serial_stuart_device;
292 #elif CONFIG_CONS_INDEX == 3
293         return &serial_ffuart_device;
294 #elif CONFIG_CONS_INDEX == 4
295         return &serial_btuart_device;
296 #else
297 #error "Bad CONFIG_CONS_INDEX."
298 #endif
299 }
300
301 void pxa_serial_initialize(void)
302 {
303 #if defined(CONFIG_FFUART)
304         serial_register(&serial_ffuart_device);
305 #endif
306 #if defined(CONFIG_BTUART)
307         serial_register(&serial_btuart_device);
308 #endif
309 #if defined(CONFIG_STUART)
310         serial_register(&serial_stuart_device);
311 #endif
312 }