]> git.karo-electronics.de Git - karo-tx-uboot.git/blob - drivers/serial/serial_pxa.c
Merge branch 'master' of git://git.denx.de/u-boot-video
[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  * SPDX-License-Identifier:     GPL-2.0+
18  */
19
20 #include <common.h>
21 #include <asm/arch/pxa-regs.h>
22 #include <asm/arch/regs-uart.h>
23 #include <asm/io.h>
24 #include <linux/compiler.h>
25 #include <serial.h>
26 #include <watchdog.h>
27
28 DECLARE_GLOBAL_DATA_PTR;
29
30 /*
31  * The numbering scheme differs here for PXA25x, PXA27x and PXA3xx so we can
32  * easily handle enabling of clock.
33  */
34 #ifdef  CONFIG_CPU_MONAHANS
35 #define UART_CLK_BASE   CKENA_21_BTUART
36 #define UART_CLK_REG    CKENA
37 #define BTUART_INDEX    0
38 #define FFUART_INDEX    1
39 #define STUART_INDEX    2
40 #elif   CONFIG_CPU_PXA25X
41 #define UART_CLK_BASE   (1 << 4)        /* HWUART */
42 #define UART_CLK_REG    CKEN
43 #define HWUART_INDEX    0
44 #define STUART_INDEX    1
45 #define FFUART_INDEX    2
46 #define BTUART_INDEX    3
47 #else   /* PXA27x */
48 #define UART_CLK_BASE   CKEN5_STUART
49 #define UART_CLK_REG    CKEN
50 #define STUART_INDEX    0
51 #define FFUART_INDEX    1
52 #define BTUART_INDEX    2
53 #endif
54
55 /*
56  * Only PXA250 has HWUART, to avoid poluting the code with more macros,
57  * artificially introduce this.
58  */
59 #ifndef CONFIG_CPU_PXA25X
60 #define HWUART_INDEX    0xff
61 #endif
62
63 static uint32_t pxa_uart_get_baud_divider(void)
64 {
65         if (gd->baudrate == 1200)
66                 return 768;
67         else if (gd->baudrate == 9600)
68                 return 96;
69         else if (gd->baudrate == 19200)
70                 return 48;
71         else if (gd->baudrate == 38400)
72                 return 24;
73         else if (gd->baudrate == 57600)
74                 return 16;
75         else if (gd->baudrate == 115200)
76                 return 8;
77         else    /* Unsupported baudrate */
78                 return 0;
79 }
80
81 static struct pxa_uart_regs *pxa_uart_index_to_regs(uint32_t uart_index)
82 {
83         switch (uart_index) {
84         case FFUART_INDEX: return (struct pxa_uart_regs *)FFUART_BASE;
85         case BTUART_INDEX: return (struct pxa_uart_regs *)BTUART_BASE;
86         case STUART_INDEX: return (struct pxa_uart_regs *)STUART_BASE;
87         case HWUART_INDEX: return (struct pxa_uart_regs *)HWUART_BASE;
88         default:
89                 return NULL;
90         }
91 }
92
93 static void pxa_uart_toggle_clock(uint32_t uart_index, int enable)
94 {
95         uint32_t clk_reg, clk_offset, reg;
96
97         clk_reg = UART_CLK_REG;
98         clk_offset = UART_CLK_BASE << uart_index;
99
100         reg = readl(clk_reg);
101
102         if (enable)
103                 reg |= clk_offset;
104         else
105                 reg &= ~clk_offset;
106
107         writel(reg, clk_reg);
108 }
109
110 /*
111  * Enable clock and set baud rate, parity etc.
112  */
113 void pxa_setbrg_dev(uint32_t uart_index)
114 {
115         uint32_t divider = 0;
116         struct pxa_uart_regs *uart_regs;
117
118         divider = pxa_uart_get_baud_divider();
119         if (!divider)
120                 hang();
121
122         uart_regs = pxa_uart_index_to_regs(uart_index);
123         if (!uart_regs)
124                 hang();
125
126         pxa_uart_toggle_clock(uart_index, 1);
127
128         /* Disable interrupts and FIFOs */
129         writel(0, &uart_regs->ier);
130         writel(0, &uart_regs->fcr);
131
132         /* Set baud rate */
133         writel(LCR_WLS0 | LCR_WLS1 | LCR_DLAB, &uart_regs->lcr);
134         writel(divider & 0xff, &uart_regs->dll);
135         writel(divider >> 8, &uart_regs->dlh);
136         writel(LCR_WLS0 | LCR_WLS1, &uart_regs->lcr);
137
138         /* Enable UART */
139         writel(IER_UUE, &uart_regs->ier);
140 }
141
142 /*
143  * Initialise the serial port with the given baudrate. The settings
144  * are always 8 data bits, no parity, 1 stop bit, no start bits.
145  */
146 int pxa_init_dev(unsigned int uart_index)
147 {
148         pxa_setbrg_dev (uart_index);
149         return 0;
150 }
151
152 /*
153  * Output a single byte to the serial port.
154  */
155 void pxa_putc_dev(unsigned int uart_index, const char c)
156 {
157         struct pxa_uart_regs *uart_regs;
158
159         /* If \n, also do \r */
160         if (c == '\n')
161                 pxa_putc_dev(uart_index, '\r');
162
163         uart_regs = pxa_uart_index_to_regs(uart_index);
164         if (!uart_regs)
165                 hang();
166
167         while (!(readl(&uart_regs->lsr) & LSR_TEMT))
168                 WATCHDOG_RESET();
169         writel(c, &uart_regs->thr);
170 }
171
172 /*
173  * Read a single byte from the serial port. Returns 1 on success, 0
174  * otherwise. When the function is succesfull, the character read is
175  * written into its argument c.
176  */
177 int pxa_tstc_dev(unsigned int uart_index)
178 {
179         struct pxa_uart_regs *uart_regs;
180
181         uart_regs = pxa_uart_index_to_regs(uart_index);
182         if (!uart_regs)
183                 return -1;
184
185         return readl(&uart_regs->lsr) & LSR_DR;
186 }
187
188 /*
189  * Read a single byte from the serial port. Returns 1 on success, 0
190  * otherwise. When the function is succesfull, the character read is
191  * written into its argument c.
192  */
193 int pxa_getc_dev(unsigned int uart_index)
194 {
195         struct pxa_uart_regs *uart_regs;
196
197         uart_regs = pxa_uart_index_to_regs(uart_index);
198         if (!uart_regs)
199                 return -1;
200
201         while (!(readl(&uart_regs->lsr) & LSR_DR))
202                 WATCHDOG_RESET();
203         return readl(&uart_regs->rbr) & 0xff;
204 }
205
206 void pxa_puts_dev(unsigned int uart_index, const char *s)
207 {
208         while (*s)
209                 pxa_putc_dev(uart_index, *s++);
210 }
211
212 #define pxa_uart(uart, UART)                                            \
213         int uart##_init(void)                                           \
214         {                                                               \
215                 return pxa_init_dev(UART##_INDEX);                      \
216         }                                                               \
217                                                                         \
218         void uart##_setbrg(void)                                        \
219         {                                                               \
220                 return pxa_setbrg_dev(UART##_INDEX);                    \
221         }                                                               \
222                                                                         \
223         void uart##_putc(const char c)                                  \
224         {                                                               \
225                 return pxa_putc_dev(UART##_INDEX, c);                   \
226         }                                                               \
227                                                                         \
228         void uart##_puts(const char *s)                                 \
229         {                                                               \
230                 return pxa_puts_dev(UART##_INDEX, s);                   \
231         }                                                               \
232                                                                         \
233         int uart##_getc(void)                                           \
234         {                                                               \
235                 return pxa_getc_dev(UART##_INDEX);                      \
236         }                                                               \
237                                                                         \
238         int uart##_tstc(void)                                           \
239         {                                                               \
240                 return pxa_tstc_dev(UART##_INDEX);                      \
241         }                                                               \
242
243 #define pxa_uart_desc(uart)                                             \
244         struct serial_device serial_##uart##_device =                   \
245         {                                                               \
246                 .name   = "serial_"#uart,                               \
247                 .start  = uart##_init,                                  \
248                 .stop   = NULL,                                         \
249                 .setbrg = uart##_setbrg,                                \
250                 .getc   = uart##_getc,                                  \
251                 .tstc   = uart##_tstc,                                  \
252                 .putc   = uart##_putc,                                  \
253                 .puts   = uart##_puts,                                  \
254         };
255
256 #define pxa_uart_multi(uart, UART)                                      \
257         pxa_uart(uart, UART)                                            \
258         pxa_uart_desc(uart)
259
260 #if defined(CONFIG_HWUART)
261         pxa_uart_multi(hwuart, HWUART)
262 #endif
263 #if defined(CONFIG_STUART)
264         pxa_uart_multi(stuart, STUART)
265 #endif
266 #if defined(CONFIG_FFUART)
267         pxa_uart_multi(ffuart, FFUART)
268 #endif
269 #if defined(CONFIG_BTUART)
270         pxa_uart_multi(btuart, BTUART)
271 #endif
272
273 __weak struct serial_device *default_serial_console(void)
274 {
275 #if CONFIG_CONS_INDEX == 1
276         return &serial_hwuart_device;
277 #elif CONFIG_CONS_INDEX == 2
278         return &serial_stuart_device;
279 #elif CONFIG_CONS_INDEX == 3
280         return &serial_ffuart_device;
281 #elif CONFIG_CONS_INDEX == 4
282         return &serial_btuart_device;
283 #else
284 #error "Bad CONFIG_CONS_INDEX."
285 #endif
286 }
287
288 void pxa_serial_initialize(void)
289 {
290 #if defined(CONFIG_FFUART)
291         serial_register(&serial_ffuart_device);
292 #endif
293 #if defined(CONFIG_BTUART)
294         serial_register(&serial_btuart_device);
295 #endif
296 #if defined(CONFIG_STUART)
297         serial_register(&serial_stuart_device);
298 #endif
299 }