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