Commit a12c51f640c4a28899a6215e938fd01058f06831

Authored by Sonic Zhang
Committed by sonic
1 parent a2979dcdbe

blackfin: bf60x: add serial support

Add serial for bf60x.

Signed-off-by: Sonic Zhang <sonic.zhang@analog.com>
Signed-off-by: Bob Liu <lliubbo@gmail.com>
Signed-off-by: Sonic Zhang <sonic.adi@gmail.com>

Showing 7 changed files with 642 additions and 238 deletions Side-by-side Diff

arch/blackfin/cpu/serial.c
... ... @@ -43,7 +43,6 @@
43 43 #include <serial.h>
44 44 #include <linux/compiler.h>
45 45 #include <asm/blackfin.h>
46   -#include <asm/mach-common/bits/uart.h>
47 46  
48 47 DECLARE_GLOBAL_DATA_PTR;
49 48  
... ... @@ -52,8 +51,8 @@
52 51 #include "serial.h"
53 52  
54 53 #ifdef CONFIG_DEBUG_SERIAL
55   -static uint16_t cached_lsr[256];
56   -static uint16_t cached_rbr[256];
  54 +static uart_lsr_t cached_lsr[256];
  55 +static uart_lsr_t cached_rbr[256];
57 56 static size_t cache_count;
58 57  
59 58 /* The LSR is read-to-clear on some parts, so we have to make sure status
60 59  
... ... @@ -61,10 +60,10 @@
61 60 * works around anomaly 05000099 at the same time by keeping a cumulative
62 61 * tally of all the status bits.
63 62 */
64   -static uint16_t uart_lsr_save;
65   -static uint16_t uart_lsr_read(uint32_t uart_base)
  63 +static uart_lsr_t uart_lsr_save;
  64 +static uart_lsr_t uart_lsr_read(uint32_t uart_base)
66 65 {
67   - uint16_t lsr = bfin_read(&pUART->lsr);
  66 + uart_lsr_t lsr = _lsr_read(pUART);
68 67 uart_lsr_save |= (lsr & (OE|PE|FE|BI));
69 68 return lsr | uart_lsr_save;
70 69 }
71 70  
72 71  
73 72  
... ... @@ -72,20 +71,20 @@
72 71 static void uart_lsr_clear(uint32_t uart_base)
73 72 {
74 73 uart_lsr_save = 0;
75   - bfin_write(&pUART->lsr, bfin_read(&pUART->lsr) | -1);
  74 + _lsr_write(pUART, -1);
76 75 }
77 76 #else
78 77 /* When debugging is disabled, we only care about the DR bit, so if other
79 78 * bits get set/cleared, we don't really care since we don't read them
80 79 * anyways (and thus anomaly 05000099 is irrelevant).
81 80 */
82   -static inline uint16_t uart_lsr_read(uint32_t uart_base)
  81 +static inline uart_lsr_t uart_lsr_read(uint32_t uart_base)
83 82 {
84   - return bfin_read(&pUART->lsr);
  83 + return _lsr_read(pUART);
85 84 }
86 85 static void uart_lsr_clear(uint32_t uart_base)
87 86 {
88   - bfin_write(&pUART->lsr, bfin_read(&pUART->lsr) | -1);
  87 + _lsr_write(pUART, -1);
89 88 }
90 89 #endif
91 90  
92 91  
93 92  
... ... @@ -127,20 +126,14 @@
127 126  
128 127 #ifdef CONFIG_DEBUG_SERIAL
129 128 /* grab & clear the LSR */
130   - uint16_t uart_lsr_val = uart_lsr_read(uart_base);
  129 + uart_lsr_t uart_lsr_val = uart_lsr_read(uart_base);
131 130  
132 131 cached_lsr[cache_count] = uart_lsr_val;
133 132 cached_rbr[cache_count] = uart_rbr_val;
134 133 cache_count = (cache_count + 1) % ARRAY_SIZE(cached_lsr);
135 134  
136 135 if (uart_lsr_val & (OE|PE|FE|BI)) {
137   - uint16_t dll, dlh;
138 136 printf("\n[SERIAL ERROR]\n");
139   - ACCESS_LATCH();
140   - dll = bfin_read(&pUART->dll);
141   - dlh = bfin_read(&pUART->dlh);
142   - ACCESS_PORT_IER();
143   - printf("\tDLL=0x%x DLH=0x%x\n", dll, dlh);
144 137 do {
145 138 --cache_count;
146 139 printf("\t%3zu: RBR=0x%02x LSR=0x%02x\n", cache_count,
... ... @@ -160,6 +153,8 @@
160 153 # define LOOP(x)
161 154 #endif
162 155  
  156 +#if BFIN_UART_HW_VER < 4
  157 +
163 158 LOOP(
164 159 static void uart_loop(uint32_t uart_base, int state)
165 160 {
... ... @@ -178,6 +173,28 @@
178 173 }
179 174 )
180 175  
  176 +#else
  177 +
  178 +LOOP(
  179 +static void uart_loop(uint32_t uart_base, int state)
  180 +{
  181 + u32 control;
  182 +
  183 + /* Drain the TX fifo first so bytes don't come back */
  184 + while (!(uart_lsr_read(uart_base) & TEMT))
  185 + continue;
  186 +
  187 + control = bfin_read(&pUART->control);
  188 + if (state)
  189 + control |= LOOP_ENA | MRTS;
  190 + else
  191 + control &= ~(LOOP_ENA | MRTS);
  192 + bfin_write(&pUART->control, control);
  193 +}
  194 +)
  195 +
  196 +#endif
  197 +
181 198 #ifdef CONFIG_SYS_BFIN_UART
182 199  
183 200 static void uart_puts(uint32_t uart_base, const char *s)
184 201  
185 202  
186 203  
... ... @@ -246,16 +263,16 @@
246 263 LOOP(.loop = uart##n##_loop) \
247 264 };
248 265  
249   -#ifdef UART0_DLL
  266 +#ifdef UART0_RBR
250 267 DECL_BFIN_UART(0)
251 268 #endif
252   -#ifdef UART1_DLL
  269 +#ifdef UART1_RBR
253 270 DECL_BFIN_UART(1)
254 271 #endif
255   -#ifdef UART2_DLL
  272 +#ifdef UART2_RBR
256 273 DECL_BFIN_UART(2)
257 274 #endif
258   -#ifdef UART3_DLL
  275 +#ifdef UART3_RBR
259 276 DECL_BFIN_UART(3)
260 277 #endif
261 278  
262 279  
263 280  
264 281  
... ... @@ -274,16 +291,16 @@
274 291  
275 292 void bfin_serial_initialize(void)
276 293 {
277   -#ifdef UART0_DLL
  294 +#ifdef UART0_RBR
278 295 serial_register(&bfin_serial0_device);
279 296 #endif
280   -#ifdef UART1_DLL
  297 +#ifdef UART1_RBR
281 298 serial_register(&bfin_serial1_device);
282 299 #endif
283   -#ifdef UART2_DLL
  300 +#ifdef UART2_RBR
284 301 serial_register(&bfin_serial2_device);
285 302 #endif
286   -#ifdef UART3_DLL
  303 +#ifdef UART3_RBR
287 304 serial_register(&bfin_serial3_device);
288 305 #endif
289 306 }
... ... @@ -293,7 +310,7 @@
293 310 /* Symbol for our assembly to call. */
294 311 void serial_set_baud(uint32_t baud)
295 312 {
296   - serial_early_set_baud(UART_DLL, baud);
  313 + serial_early_set_baud(UART_BASE, baud);
297 314 }
298 315  
299 316 /* Symbol for common u-boot code to call.
... ... @@ -307,7 +324,7 @@
307 324 /* Symbol for our assembly to call. */
308 325 void serial_initialize(void)
309 326 {
310   - serial_early_init(UART_DLL);
  327 + serial_early_init(UART_BASE);
311 328 }
312 329  
313 330 /* Symbol for common u-boot code to call. */
314 331  
315 332  
316 333  
... ... @@ -315,23 +332,23 @@
315 332 {
316 333 serial_initialize();
317 334 serial_setbrg();
318   - uart_lsr_clear(UART_DLL);
  335 + uart_lsr_clear(UART_BASE);
319 336 return 0;
320 337 }
321 338  
322 339 int serial_tstc(void)
323 340 {
324   - return uart_tstc(UART_DLL);
  341 + return uart_tstc(UART_BASE);
325 342 }
326 343  
327 344 int serial_getc(void)
328 345 {
329   - return uart_getc(UART_DLL);
  346 + return uart_getc(UART_BASE);
330 347 }
331 348  
332 349 void serial_putc(const char c)
333 350 {
334   - uart_putc(UART_DLL, c);
  351 + uart_putc(UART_BASE, c);
335 352 }
336 353  
337 354 void serial_puts(const char *s)
... ... @@ -343,7 +360,7 @@
343 360 LOOP(
344 361 void serial_loop(int state)
345 362 {
346   - uart_loop(UART_DLL, state);
  363 + uart_loop(UART_BASE, state);
347 364 }
348 365 )
349 366  
arch/blackfin/cpu/serial.h
... ... @@ -3,7 +3,7 @@
3 3 * any functions defined here must be always_inline since
4 4 * initcode cannot have function calls.
5 5 *
6   - * Copyright (c) 2004-2007 Analog Devices Inc.
  6 + * Copyright (c) 2004-2011 Analog Devices Inc.
7 7 *
8 8 * Licensed under the GPL-2 or later.
9 9 */
... ... @@ -12,7 +12,7 @@
12 12 #define __BFIN_CPU_SERIAL_H__
13 13  
14 14 #include <asm/blackfin.h>
15   -#include <asm/mach-common/bits/uart.h>
  15 +#include <asm/portmux.h>
16 16  
17 17 #ifndef CONFIG_UART_CONSOLE
18 18 # define CONFIG_UART_CONSOLE 0
19 19  
20 20  
21 21  
22 22  
23 23  
24 24  
... ... @@ -24,88 +24,34 @@
24 24 # define BFIN_DEBUG_EARLY_SERIAL 0
25 25 #endif
26 26  
27   -#ifndef __ASSEMBLY__
28   -
29   -#include <asm/portmux.h>
30   -
31   -#define LOB(x) ((x) & 0xFF)
32   -#define HIB(x) (((x) >> 8) & 0xFF)
33   -
34   -#if defined(__ADSPBF50x__) || defined(__ADSPBF54x__)
  27 +#if defined(__ADSPBF60x__)
  28 +# define BFIN_UART_HW_VER 4
  29 +#elif defined(__ADSPBF50x__) || defined(__ADSPBF54x__)
35 30 # define BFIN_UART_HW_VER 2
36 31 #else
37 32 # define BFIN_UART_HW_VER 1
38 33 #endif
39 34  
40   -/*
41   - * All Blackfin system MMRs are padded to 32bits even if the register
42   - * itself is only 16bits. So use a helper macro to streamline this.
43   - */
44   -#define __BFP(m) u16 m; u16 __pad_##m
45   -struct bfin_mmr_serial {
46   -#if BFIN_UART_HW_VER == 2
47   - __BFP(dll);
48   - __BFP(dlh);
49   - __BFP(gctl);
50   - __BFP(lcr);
51   - __BFP(mcr);
52   - __BFP(lsr);
53   - __BFP(msr);
54   - __BFP(scr);
55   - __BFP(ier_set);
56   - __BFP(ier_clear);
57   - __BFP(thr);
58   - __BFP(rbr);
59   -#else
60   - union {
61   - u16 dll;
62   - u16 thr;
63   - const u16 rbr;
64   - };
65   - const u16 __spad0;
66   - union {
67   - u16 dlh;
68   - u16 ier;
69   - };
70   - const u16 __spad1;
71   - const __BFP(iir);
72   - __BFP(lcr);
73   - __BFP(mcr);
74   - __BFP(lsr);
75   - __BFP(msr);
76   - __BFP(scr);
77   - const u32 __spad2;
78   - __BFP(gctl);
79   -#endif
80   -};
81   -#undef __BFP
82   -
83 35 #define __PASTE_UART(num, pfx, sfx) pfx##num##_##sfx
84 36 #define _PASTE_UART(num, pfx, sfx) __PASTE_UART(num, pfx, sfx)
85   -#define MMR_UART(n) _PASTE_UART(n, UART, DLL)
86 37 #define _P_UART(n, pin) _PASTE_UART(n, P_UART, pin)
87 38 #define P_UART(pin) _P_UART(CONFIG_UART_CONSOLE, pin)
88 39  
89   -#ifndef UART_DLL
90   -# define UART_DLL MMR_UART(CONFIG_UART_CONSOLE)
91   -#else
92   -# define UART0_DLL UART_DLL
93   -# if CONFIG_UART_CONSOLE != 0
94   -# error CONFIG_UART_CONSOLE must be 0 on parts with only one UART
95   -# endif
96   -#endif
97 40 #define pUART ((volatile struct bfin_mmr_serial *)uart_base)
98 41  
99   -#if BFIN_UART_HW_VER == 2
100   -# define ACCESS_LATCH()
101   -# define ACCESS_PORT_IER()
  42 +#ifndef __ASSEMBLY__
  43 +__attribute__((always_inline))
  44 +static inline void serial_do_portmux(void);
  45 +#endif
  46 +
  47 +#if BFIN_UART_HW_VER < 4
  48 +# include "serial1.h"
102 49 #else
103   -# define ACCESS_LATCH() \
104   - bfin_write(&pUART->lcr, bfin_read(&pUART->lcr) | DLAB)
105   -# define ACCESS_PORT_IER() \
106   - bfin_write(&pUART->lcr, bfin_read(&pUART->lcr) & ~DLAB)
  50 +# include "serial4.h"
107 51 #endif
108 52  
  53 +#ifndef __ASSEMBLY__
  54 +
109 55 __attribute__((always_inline))
110 56 static inline void serial_do_portmux(void)
111 57 {
... ... @@ -115,143 +61,7 @@
115 61 return;
116 62 }
117 63  
118   -#if defined(__ADSPBF50x__)
119   -# define DO_MUX(port, mux_tx, mux_rx, tx, rx) \
120   - bfin_write_PORT##port##_MUX((bfin_read_PORT##port##_MUX() & ~(PORT_x_MUX_##mux_tx##_MASK | PORT_x_MUX_##mux_rx##_MASK)) | PORT_x_MUX_##mux_tx##_FUNC_1 | PORT_x_MUX_##mux_rx##_FUNC_1); \
121   - bfin_write_PORT##port##_FER(bfin_read_PORT##port##_FER() | P##port##tx | P##port##rx);
122   - switch (CONFIG_UART_CONSOLE) {
123   - case 0: DO_MUX(G, 7, 7, 12, 13); break; /* Port G; mux 7; PG12 and PG13 */
124   - case 1: DO_MUX(F, 3, 3, 6, 7); break; /* Port F; mux 3; PF6 and PF7 */
125   - }
126   - SSYNC();
127   -#elif defined(__ADSPBF51x__)
128   -# define DO_MUX(port, mux_tx, mux_rx, tx, rx) \
129   - bfin_write_PORT##port##_MUX((bfin_read_PORT##port##_MUX() & ~(PORT_x_MUX_##mux_tx##_MASK | PORT_x_MUX_##mux_rx##_MASK)) | PORT_x_MUX_##mux_tx##_FUNC_2 | PORT_x_MUX_##mux_rx##_FUNC_2); \
130   - bfin_write_PORT##port##_FER(bfin_read_PORT##port##_FER() | P##port##tx | P##port##rx);
131   - switch (CONFIG_UART_CONSOLE) {
132   - case 0: DO_MUX(G, 5, 5, 9, 10); break; /* Port G; mux 5; PG9 and PG10 */
133   - case 1: DO_MUX(F, 2, 3, 14, 15); break; /* Port H; mux 2/3; PH14 and PH15 */
134   - }
135   - SSYNC();
136   -#elif defined(__ADSPBF52x__)
137   -# define DO_MUX(port, mux, tx, rx) \
138   - bfin_write_PORT##port##_MUX((bfin_read_PORT##port##_MUX() & ~PORT_x_MUX_##mux##_MASK) | PORT_x_MUX_##mux##_FUNC_3); \
139   - bfin_write_PORT##port##_FER(bfin_read_PORT##port##_FER() | P##port##tx | P##port##rx);
140   - switch (CONFIG_UART_CONSOLE) {
141   - case 0: DO_MUX(G, 2, 7, 8); break; /* Port G; mux 2; PG2 and PG8 */
142   - case 1: DO_MUX(F, 5, 14, 15); break; /* Port F; mux 5; PF14 and PF15 */
143   - }
144   - SSYNC();
145   -#elif defined(__ADSPBF537__) || defined(__ADSPBF536__) || defined(__ADSPBF534__)
146   - const uint16_t func[] = { PFDE, PFTE, };
147   - bfin_write_PORT_MUX(bfin_read_PORT_MUX() & ~func[CONFIG_UART_CONSOLE]);
148   - bfin_write_PORTF_FER(bfin_read_PORTF_FER() |
149   - (1 << P_IDENT(P_UART(RX))) |
150   - (1 << P_IDENT(P_UART(TX))));
151   - SSYNC();
152   -#elif defined(__ADSPBF54x__)
153   -# define DO_MUX(port, tx, rx) \
154   - bfin_write_PORT##port##_MUX((bfin_read_PORT##port##_MUX() & ~(PORT_x_MUX_##tx##_MASK | PORT_x_MUX_##rx##_MASK)) | PORT_x_MUX_##tx##_FUNC_1 | PORT_x_MUX_##rx##_FUNC_1); \
155   - bfin_write_PORT##port##_FER(bfin_read_PORT##port##_FER() | P##port##tx | P##port##rx);
156   - switch (CONFIG_UART_CONSOLE) {
157   - case 0: DO_MUX(E, 7, 8); break; /* Port E; PE7 and PE8 */
158   - case 1: DO_MUX(H, 0, 1); break; /* Port H; PH0 and PH1 */
159   - case 2: DO_MUX(B, 4, 5); break; /* Port B; PB4 and PB5 */
160   - case 3: DO_MUX(B, 6, 7); break; /* Port B; PB6 and PB7 */
161   - }
162   - SSYNC();
163   -#elif defined(__ADSPBF561__)
164   - /* UART pins could be GPIO, but they aren't pin muxed. */
165   -#else
166   -# if (P_UART(RX) & P_DEFINED) || (P_UART(TX) & P_DEFINED)
167   -# error "missing portmux logic for UART"
168   -# endif
169   -#endif
170   -}
171   -
172   -__attribute__((always_inline))
173   -static inline int uart_init(uint32_t uart_base)
174   -{
175   - /* always enable UART -- avoids anomalies 05000309 and 05000350 */
176   - bfin_write(&pUART->gctl, UCEN);
177   -
178   - /* Set LCR to Word Lengh 8-bit word select */
179   - bfin_write(&pUART->lcr, WLS_8);
180   -
181   - SSYNC();
182   -
183   - return 0;
184   -}
185   -
186   -__attribute__((always_inline))
187   -static inline int serial_early_init(uint32_t uart_base)
188   -{
189   - /* handle portmux crap on different Blackfins */
190   - serial_do_portmux();
191   -
192   - return uart_init(uart_base);
193   -}
194   -
195   -__attribute__((always_inline))
196   -static inline int serial_early_uninit(uint32_t uart_base)
197   -{
198   - /* disable the UART by clearing UCEN */
199   - bfin_write(&pUART->gctl, 0);
200   -
201   - return 0;
202   -}
203   -
204   -__attribute__((always_inline))
205   -static inline void serial_early_put_div(uint32_t uart_base, uint16_t divisor)
206   -{
207   - /* Set DLAB in LCR to Access DLL and DLH */
208   - ACCESS_LATCH();
209   - SSYNC();
210   -
211   - /* Program the divisor to get the baud rate we want */
212   - bfin_write(&pUART->dll, LOB(divisor));
213   - bfin_write(&pUART->dlh, HIB(divisor));
214   - SSYNC();
215   -
216   - /* Clear DLAB in LCR to Access THR RBR IER */
217   - ACCESS_PORT_IER();
218   - SSYNC();
219   -}
220   -
221   -__attribute__((always_inline))
222   -static inline uint16_t serial_early_get_div(void)
223   -{
224   - uint32_t uart_base = UART_DLL;
225   -
226   - /* Set DLAB in LCR to Access DLL and DLH */
227   - ACCESS_LATCH();
228   - SSYNC();
229   -
230   - uint8_t dll = bfin_read(&pUART->dll);
231   - uint8_t dlh = bfin_read(&pUART->dlh);
232   - uint16_t divisor = (dlh << 8) | dll;
233   -
234   - /* Clear DLAB in LCR to Access THR RBR IER */
235   - ACCESS_PORT_IER();
236   - SSYNC();
237   -
238   - return divisor;
239   -}
240   -
241   -/* We cannot use get_sclk() early on as it uses caches in external memory */
242   -#if defined(BFIN_IN_INITCODE) || defined(CONFIG_DEBUG_EARLY_SERIAL)
243   -# define get_sclk() (CONFIG_CLKIN_HZ * CONFIG_VCO_MULT / CONFIG_SCLK_DIV)
244   -#endif
245   -
246   -__attribute__((always_inline))
247   -static inline void serial_early_set_baud(uint32_t uart_base, uint32_t baud)
248   -{
249   - /* Translate from baud into divisor in terms of SCLK. The
250   - * weird multiplication is to make sure we over sample just
251   - * a little rather than under sample the incoming signals.
252   - */
253   - serial_early_put_div(uart_base,
254   - (get_sclk() + (baud * 8)) / (baud * 16) - ANOMALY_05000230);
  64 + serial_early_do_portmux();
255 65 }
256 66  
257 67 #ifndef BFIN_IN_INITCODE
arch/blackfin/cpu/serial1.h
  1 +/*
  2 + * serial.h - common serial defines for early debug and serial driver.
  3 + * any functions defined here must be always_inline since
  4 + * initcode cannot have function calls.
  5 + *
  6 + * Copyright (c) 2004-2011 Analog Devices Inc.
  7 + *
  8 + * Licensed under the GPL-2 or later.
  9 + */
  10 +
  11 +#ifndef __BFIN_CPU_SERIAL1_H__
  12 +#define __BFIN_CPU_SERIAL1_H__
  13 +
  14 +#include <asm/mach-common/bits/uart.h>
  15 +
  16 +#ifndef __ASSEMBLY__
  17 +
  18 +#define MMR_UART(n) _PASTE_UART(n, UART, DLL)
  19 +#ifdef UART_DLL
  20 +# define UART0_DLL UART_DLL
  21 +# if CONFIG_UART_CONSOLE != 0
  22 +# error CONFIG_UART_CONSOLE must be 0 on parts with only one UART
  23 +# endif
  24 +#endif
  25 +#define UART_BASE MMR_UART(CONFIG_UART_CONSOLE)
  26 +
  27 +#define LOB(x) ((x) & 0xFF)
  28 +#define HIB(x) (((x) >> 8) & 0xFF)
  29 +
  30 +/*
  31 + * All Blackfin system MMRs are padded to 32bits even if the register
  32 + * itself is only 16bits. So use a helper macro to streamline this.
  33 + */
  34 +struct bfin_mmr_serial {
  35 +#if BFIN_UART_HW_VER == 2
  36 + u16 dll;
  37 + u16 __pad_0;
  38 + u16 dlh;
  39 + u16 __pad_1;
  40 + u16 gctl;
  41 + u16 __pad_2;
  42 + u16 lcr;
  43 + u16 __pad_3;
  44 + u16 mcr;
  45 + u16 __pad_4;
  46 + u16 lsr;
  47 + u16 __pad_5;
  48 + u16 msr;
  49 + u16 __pad_6;
  50 + u16 scr;
  51 + u16 __pad_7;
  52 + u16 ier_set;
  53 + u16 __pad_8;
  54 + u16 ier_clear;
  55 + u16 __pad_9;
  56 + u16 thr;
  57 + u16 __pad_10;
  58 + u16 rbr;
  59 + u16 __pad_11;
  60 +#else
  61 + union {
  62 + u16 dll;
  63 + u16 thr;
  64 + const u16 rbr;
  65 + };
  66 + const u16 __spad0;
  67 + union {
  68 + u16 dlh;
  69 + u16 ier;
  70 + };
  71 + const u16 __spad1;
  72 + const u16 iir;
  73 + u16 __pad_0;
  74 + u16 lcr;
  75 + u16 __pad_1;
  76 + u16 mcr;
  77 + u16 __pad_2;
  78 + u16 lsr;
  79 + u16 __pad_3;
  80 + u16 msr;
  81 + u16 __pad_4;
  82 + u16 scr;
  83 + u16 __pad_5;
  84 + const u32 __spad2;
  85 + u16 gctl;
  86 + u16 __pad_6;
  87 +#endif
  88 +};
  89 +
  90 +#define uart_lsr_t uint32_t
  91 +#define _lsr_read(p) bfin_read(&p->lsr)
  92 +#define _lsr_write(p, v) bfin_write(&p->lsr, v)
  93 +
  94 +#if BFIN_UART_HW_VER == 2
  95 +# define ACCESS_LATCH()
  96 +# define ACCESS_PORT_IER()
  97 +#else
  98 +# define ACCESS_LATCH() bfin_write_or(&pUART->lcr, DLAB)
  99 +# define ACCESS_PORT_IER() bfin_write_and(&pUART->lcr, ~DLAB)
  100 +#endif
  101 +
  102 +__attribute__((always_inline))
  103 +static inline void serial_early_do_mach_portmux(char port, int mux_mask,
  104 + int mux_func, int port_pin)
  105 +{
  106 + switch (port) {
  107 +#if defined(__ADSPBF54x__)
  108 + case 'B':
  109 + bfin_write_PORTB_MUX((bfin_read_PORTB_MUX() &
  110 + ~mux_mask) | mux_func);
  111 + bfin_write_PORTB_FER(bfin_read_PORTB_FER() | port_pin);
  112 + break;
  113 + case 'E':
  114 + bfin_write_PORTE_MUX((bfin_read_PORTE_MUX() &
  115 + ~mux_mask) | mux_func);
  116 + bfin_write_PORTE_FER(bfin_read_PORTE_FER() | port_pin);
  117 + break;
  118 +#endif
  119 +#if defined(__ADSPBF50x__) || defined(__ADSPBF51x__) || defined(__ADSPBF52x__)
  120 + case 'F':
  121 + bfin_write_PORTF_MUX((bfin_read_PORTF_MUX() &
  122 + ~mux_mask) | mux_func);
  123 + bfin_write_PORTF_FER(bfin_read_PORTF_FER() | port_pin);
  124 + break;
  125 + case 'G':
  126 + bfin_write_PORTG_MUX((bfin_read_PORTG_MUX() &
  127 + ~mux_mask) | mux_func);
  128 + bfin_write_PORTG_FER(bfin_read_PORTG_FER() | port_pin);
  129 + break;
  130 + case 'H':
  131 + bfin_write_PORTH_MUX((bfin_read_PORTH_MUX() &
  132 + ~mux_mask) | mux_func);
  133 + bfin_write_PORTH_FER(bfin_read_PORTH_FER() | port_pin);
  134 + break;
  135 +#endif
  136 + default:
  137 + break;
  138 + }
  139 +}
  140 +
  141 +__attribute__((always_inline))
  142 +static inline void serial_early_do_portmux(void)
  143 +{
  144 +#if defined(__ADSPBF50x__)
  145 + switch (CONFIG_UART_CONSOLE) {
  146 + case 0:
  147 + serial_early_do_mach_portmux('G', PORT_x_MUX_7_MASK,
  148 + PORT_x_MUX_7_FUNC_1, PG12); /* TX: G; mux 7; func 1; PG12 */
  149 + serial_early_do_mach_portmux('G', PORT_x_MUX_7_MASK,
  150 + PORT_x_MUX_7_FUNC_1, PG13); /* RX: G; mux 7; func 1; PG13 */
  151 + break;
  152 + case 1:
  153 + serial_early_do_mach_portmux('F', PORT_x_MUX_3_MASK,
  154 + PORT_x_MUX_3_FUNC_1, PF7); /* TX: F; mux 3; func 1; PF6 */
  155 + serial_early_do_mach_portmux('F', PORT_x_MUX_3_MASK,
  156 + PORT_x_MUX_3_FUNC_1, PF6); /* RX: F; mux 3; func 1; PF7 */
  157 + break;
  158 + }
  159 +#elif defined(__ADSPBF51x__)
  160 + switch (CONFIG_UART_CONSOLE) {
  161 + case 0:
  162 + serial_early_do_mach_portmux('G', PORT_x_MUX_5_MASK,
  163 + PORT_x_MUX_5_FUNC_2, PG9); /* TX: G; mux 5; func 2; PG9 */
  164 + serial_early_do_mach_portmux('G', PORT_x_MUX_5_MASK,
  165 + PORT_x_MUX_5_FUNC_2, PG10); /* RX: G; mux 5; func 2; PG10 */
  166 + break;
  167 + case 1:
  168 + serial_early_do_mach_portmux('H', PORT_x_MUX_3_MASK,
  169 + PORT_x_MUX_3_FUNC_2, PH7); /* TX: H; mux 3; func 2; PH6 */
  170 + serial_early_do_mach_portmux('H', PORT_x_MUX_3_MASK,
  171 + PORT_x_MUX_3_FUNC_2, PH6); /* RX: H; mux 3; func 2; PH7 */
  172 + break;
  173 + }
  174 +#elif defined(__ADSPBF52x__)
  175 + switch (CONFIG_UART_CONSOLE) {
  176 + case 0:
  177 + serial_early_do_mach_portmux('G', PORT_x_MUX_2_MASK,
  178 + PORT_x_MUX_2_FUNC_3, PG7); /* TX: G; mux 2; func 3; PG7 */
  179 + serial_early_do_mach_portmux('G', PORT_x_MUX_2_MASK,
  180 + PORT_x_MUX_2_FUNC_3, PG8); /* RX: G; mux 2; func 3; PG8 */
  181 + break;
  182 + case 1:
  183 + serial_early_do_mach_portmux('F', PORT_x_MUX_5_MASK,
  184 + PORT_x_MUX_5_FUNC_3, PF14); /* TX: F; mux 5; func 3; PF14 */
  185 + serial_early_do_mach_portmux('F', PORT_x_MUX_5_MASK,
  186 + PORT_x_MUX_5_FUNC_3, PF15); /* RX: F; mux 5; func 3; PF15 */
  187 + break;
  188 + }
  189 +#elif defined(__ADSPBF537__) || defined(__ADSPBF536__) || defined(__ADSPBF534__)
  190 + const uint16_t func[] = { PFDE, PFTE, };
  191 + bfin_write_PORT_MUX(bfin_read_PORT_MUX() & ~func[CONFIG_UART_CONSOLE]);
  192 + bfin_write_PORTF_FER(bfin_read_PORTF_FER() |
  193 + (1 << P_IDENT(P_UART(RX))) |
  194 + (1 << P_IDENT(P_UART(TX))));
  195 +#elif defined(__ADSPBF54x__)
  196 + switch (CONFIG_UART_CONSOLE) {
  197 + case 0:
  198 + serial_early_do_mach_portmux('E', PORT_x_MUX_7_MASK,
  199 + PORT_x_MUX_7_FUNC_1, PE7); /* TX: E; mux 7; func 1; PE7 */
  200 + serial_early_do_mach_portmux('E', PORT_x_MUX_8_MASK,
  201 + PORT_x_MUX_8_FUNC_1, PE8); /* RX: E; mux 8; func 1; PE8 */
  202 + break;
  203 + case 1:
  204 + serial_early_do_mach_portmux('H', PORT_x_MUX_0_MASK,
  205 + PORT_x_MUX_0_FUNC_1, PH0); /* TX: H; mux 0; func 1; PH0 */
  206 + serial_early_do_mach_portmux('H', PORT_x_MUX_1_MASK,
  207 + PORT_x_MUX_1_FUNC_1, PH1); /* RX: H; mux 1; func 1; PH1 */
  208 + break;
  209 + case 2:
  210 + serial_early_do_mach_portmux('B', PORT_x_MUX_4_MASK,
  211 + PORT_x_MUX_4_FUNC_1, PB4); /* TX: B; mux 4; func 1; PB4 */
  212 + serial_early_do_mach_portmux('B', PORT_x_MUX_5_MASK,
  213 + PORT_x_MUX_5_FUNC_1, PB5); /* RX: B; mux 5; func 1; PB5 */
  214 + break;
  215 + case 3:
  216 + serial_early_do_mach_portmux('B', PORT_x_MUX_6_MASK,
  217 + PORT_x_MUX_6_FUNC_1, PB6); /* TX: B; mux 6; func 1; PB6 */
  218 + serial_early_do_mach_portmux('B', PORT_x_MUX_7_MASK,
  219 + PORT_x_MUX_7_FUNC_1, PB7); /* RX: B; mux 7; func 1; PB7 */
  220 + break;
  221 + }
  222 +#elif defined(__ADSPBF561__)
  223 + /* UART pins could be GPIO, but they aren't pin muxed. */
  224 +#else
  225 +# if (P_UART(RX) & P_DEFINED) || (P_UART(TX) & P_DEFINED)
  226 +# error "missing portmux logic for UART"
  227 +# endif
  228 +#endif
  229 + SSYNC();
  230 +}
  231 +
  232 +__attribute__((always_inline))
  233 +static inline uint32_t uart_sclk(void)
  234 +{
  235 +#if defined(BFIN_IN_INITCODE) || defined(CONFIG_DEBUG_EARLY_SERIAL)
  236 + /* We cannot use get_sclk() early on as it uses
  237 + * caches in external memory
  238 + */
  239 + return CONFIG_CLKIN_HZ * CONFIG_VCO_MULT / CONFIG_SCLK_DIV;
  240 +#else
  241 + return get_sclk();
  242 +#endif
  243 +}
  244 +
  245 +__attribute__((always_inline))
  246 +static inline int uart_init(uint32_t uart_base)
  247 +{
  248 + /* always enable UART -- avoids anomalies 05000309 and 05000350 */
  249 + bfin_write(&pUART->gctl, UCEN);
  250 +
  251 + /* Set LCR to Word Lengh 8-bit word select */
  252 + bfin_write(&pUART->lcr, WLS_8);
  253 +
  254 + SSYNC();
  255 +
  256 + return 0;
  257 +}
  258 +
  259 +__attribute__((always_inline))
  260 +static inline int serial_early_init(uint32_t uart_base)
  261 +{
  262 + /* handle portmux crap on different Blackfins */
  263 + serial_do_portmux();
  264 +
  265 + return uart_init(uart_base);
  266 +}
  267 +
  268 +__attribute__((always_inline))
  269 +static inline int serial_early_uninit(uint32_t uart_base)
  270 +{
  271 + /* disable the UART by clearing UCEN */
  272 + bfin_write(&pUART->gctl, 0);
  273 +
  274 + return 0;
  275 +}
  276 +
  277 +__attribute__((always_inline))
  278 +static inline int serial_early_enabled(uint32_t uart_base)
  279 +{
  280 + return bfin_read(&pUART->gctl) & UCEN;
  281 +}
  282 +
  283 +__attribute__((always_inline))
  284 +static inline void serial_early_set_baud(uint32_t uart_base, uint32_t baud)
  285 +{
  286 + /* Translate from baud into divisor in terms of SCLK. The
  287 + * weird multiplication is to make sure we over sample just
  288 + * a little rather than under sample the incoming signals.
  289 + */
  290 + uint16_t divisor = (uart_sclk() + (baud * 8)) / (baud * 16) -
  291 + ANOMALY_05000230;
  292 +
  293 + /* Set DLAB in LCR to Access DLL and DLH */
  294 + ACCESS_LATCH();
  295 + SSYNC();
  296 +
  297 + /* Program the divisor to get the baud rate we want */
  298 + bfin_write(&pUART->dll, LOB(divisor));
  299 + bfin_write(&pUART->dlh, HIB(divisor));
  300 + SSYNC();
  301 +
  302 + /* Clear DLAB in LCR to Access THR RBR IER */
  303 + ACCESS_PORT_IER();
  304 + SSYNC();
  305 +}
  306 +
  307 +__attribute__((always_inline))
  308 +static inline void serial_early_put_div(uint16_t divisor)
  309 +{
  310 + uint32_t uart_base = UART_BASE;
  311 +
  312 + /* Set DLAB in LCR to Access DLL and DLH */
  313 + ACCESS_LATCH();
  314 + SSYNC();
  315 +
  316 + /* Program the divisor to get the baud rate we want */
  317 + bfin_write(&pUART->dll, LOB(divisor));
  318 + bfin_write(&pUART->dlh, HIB(divisor));
  319 + SSYNC();
  320 +
  321 + /* Clear DLAB in LCR to Access THR RBR IER */
  322 + ACCESS_PORT_IER();
  323 + SSYNC();
  324 +}
  325 +
  326 +__attribute__((always_inline))
  327 +static inline uint16_t serial_early_get_div(void)
  328 +{
  329 + uint32_t uart_base = UART_BASE;
  330 +
  331 + /* Set DLAB in LCR to Access DLL and DLH */
  332 + ACCESS_LATCH();
  333 + SSYNC();
  334 +
  335 + uint8_t dll = bfin_read(&pUART->dll);
  336 + uint8_t dlh = bfin_read(&pUART->dlh);
  337 + uint16_t divisor = (dlh << 8) | dll;
  338 +
  339 + /* Clear DLAB in LCR to Access THR RBR IER */
  340 + ACCESS_PORT_IER();
  341 + SSYNC();
  342 +
  343 + return divisor;
  344 +}
  345 +
  346 +#endif
  347 +
  348 +#endif
arch/blackfin/cpu/serial4.h
  1 +/*
  2 + * serial.h - common serial defines for early debug and serial driver.
  3 + * any functions defined here must be always_inline since
  4 + * initcode cannot have function calls.
  5 + *
  6 + * Copyright (c) 2004-2011 Analog Devices Inc.
  7 + *
  8 + * Licensed under the GPL-2 or later.
  9 + */
  10 +
  11 +#ifndef __BFIN_CPU_SERIAL4_H__
  12 +#define __BFIN_CPU_SERIAL4_H__
  13 +
  14 +#include <asm/mach-common/bits/uart4.h>
  15 +
  16 +#ifndef __ASSEMBLY__
  17 +
  18 +#define MMR_UART(n) _PASTE_UART(n, UART, REVID)
  19 +#define UART_BASE MMR_UART(CONFIG_UART_CONSOLE)
  20 +
  21 +struct bfin_mmr_serial {
  22 + u32 revid;
  23 + u32 control;
  24 + u32 status;
  25 + u32 scr;
  26 + u32 clock;
  27 + u32 emask;
  28 + u32 emaskst;
  29 + u32 emaskcl;
  30 + u32 rbr;
  31 + u32 thr;
  32 + u32 taip;
  33 + u32 tsr;
  34 + u32 rsr;
  35 + u32 txdiv_cnt;
  36 + u32 rxdiv_cnt;
  37 +};
  38 +#define uart_lsr_t uint32_t
  39 +#define _lsr_read(p) bfin_read(&p->status)
  40 +#define _lsr_write(p, v) bfin_write(&p->status, v)
  41 +
  42 +__attribute__((always_inline))
  43 +static inline void serial_early_do_mach_portmux(char port, int mux_mask,
  44 + int mux_func, int port_pin)
  45 +{
  46 + switch (port) {
  47 + case 'D':
  48 + bfin_write_PORTD_MUX((bfin_read_PORTD_MUX() &
  49 + ~mux_mask) | mux_func);
  50 + bfin_write_PORTD_FER_SET(port_pin);
  51 + break;
  52 + case 'G':
  53 + bfin_write_PORTG_MUX((bfin_read_PORTG_MUX() &
  54 + ~mux_mask) | mux_func);
  55 + bfin_write_PORTG_FER_SET(port_pin);
  56 + break;
  57 + }
  58 +}
  59 +
  60 +__attribute__((always_inline))
  61 +static inline void serial_early_do_portmux(void)
  62 +{
  63 +#if defined(__ADSPBF60x__)
  64 + switch (CONFIG_UART_CONSOLE) {
  65 + case 0:
  66 + serial_early_do_mach_portmux('D', PORT_x_MUX_7_MASK,
  67 + PORT_x_MUX_7_FUNC_2, PD7); /* TX: D; mux 7; func 2; PD7 */
  68 + serial_early_do_mach_portmux('D', PORT_x_MUX_8_MASK,
  69 + PORT_x_MUX_8_FUNC_2, PD8); /* RX: D; mux 8; func 2; PD8 */
  70 + break;
  71 + case 1:
  72 + serial_early_do_mach_portmux('G', PORT_x_MUX_15_MASK,
  73 + PORT_x_MUX_15_FUNC_1, PG15); /* TX: G; mux 15; func 1; PG15 */
  74 + serial_early_do_mach_portmux('G', PORT_x_MUX_14_MASK,
  75 + PORT_x_MUX_14_FUNC_1, PG14); /* RX: G; mux 14; func 1; PG14 */
  76 + break;
  77 + }
  78 +#else
  79 +# if (P_UART(RX) & P_DEFINED) || (P_UART(TX) & P_DEFINED)
  80 +# error "missing portmux logic for UART"
  81 +# endif
  82 +#endif
  83 + SSYNC();
  84 +}
  85 +
  86 +__attribute__((always_inline))
  87 +static inline uint32_t uart_sclk(void)
  88 +{
  89 +#if defined(BFIN_IN_INITCODE) || defined(CONFIG_DEBUG_EARLY_SERIAL)
  90 + /* We cannot use get_sclk() early on as it uses caches in
  91 + * external memory
  92 + */
  93 + return CONFIG_CLKIN_HZ * CONFIG_VCO_MULT / CONFIG_SCLK_DIV /
  94 + CONFIG_SCLK0_DIV;
  95 +#else
  96 + return get_sclk0();
  97 +#endif
  98 +}
  99 +
  100 +__attribute__((always_inline))
  101 +static inline int uart_init(uint32_t uart_base)
  102 +{
  103 + /* always enable UART to 8-bit mode */
  104 + bfin_write(&pUART->control, UEN | UMOD_UART | WLS_8);
  105 +
  106 + SSYNC();
  107 +
  108 + return 0;
  109 +}
  110 +
  111 +__attribute__((always_inline))
  112 +static inline int serial_early_init(uint32_t uart_base)
  113 +{
  114 + /* handle portmux crap on different Blackfins */
  115 + serial_do_portmux();
  116 +
  117 + return uart_init(uart_base);
  118 +}
  119 +
  120 +__attribute__((always_inline))
  121 +static inline int serial_early_uninit(uint32_t uart_base)
  122 +{
  123 + /* disable the UART by clearing UEN */
  124 + bfin_write(&pUART->control, 0);
  125 +
  126 + return 0;
  127 +}
  128 +
  129 +__attribute__((always_inline))
  130 +static inline int serial_early_enabled(uint32_t uart_base)
  131 +{
  132 + return bfin_read(&pUART->control) & UEN;
  133 +}
  134 +
  135 +__attribute__((always_inline))
  136 +static inline void serial_early_set_baud(uint32_t uart_base, uint32_t baud)
  137 +{
  138 + uint32_t divisor = uart_sclk() / (baud * 16);
  139 +
  140 + /* Program the divisor to get the baud rate we want */
  141 + bfin_write(&pUART->clock, divisor);
  142 + SSYNC();
  143 +}
  144 +
  145 +__attribute__((always_inline))
  146 +static inline void serial_early_put_div(uint32_t divisor)
  147 +{
  148 + uint32_t uart_base = UART_BASE;
  149 + bfin_write(&pUART->clock, divisor);
  150 +}
  151 +
  152 +__attribute__((always_inline))
  153 +static inline uint32_t serial_early_get_div(void)
  154 +{
  155 + uint32_t uart_base = UART_BASE;
  156 + return bfin_read(&pUART->clock);
  157 +}
  158 +
  159 +#endif
  160 +
  161 +#endif
arch/blackfin/include/asm/mach-bf533/BF531_def.h
... ... @@ -149,6 +149,7 @@
149 149 #define UART_LSR 0xFFC00414
150 150 #define UART_SCR 0xFFC0041C
151 151 #define UART_RBR 0xFFC00400 /* Receive Buffer */
  152 +#define UART0_RBR UART_RBR
152 153 #define UART_GCTL 0xFFC00424
153 154 #define SPT0_TX_CONFIG0 0xFFC00800
154 155 #define SPT0_TX_CONFIG1 0xFFC00804
arch/blackfin/include/asm/mach-bf561/BF561_def.h
... ... @@ -690,6 +690,7 @@
690 690 #define PPI1_FRAME 0xFFC01310
691 691 #define UART_THR 0xFFC00400
692 692 #define UART_RBR 0xFFC00400
  693 +#define UART0_RBR UART_RBR
693 694 #define UART_DLL 0xFFC00400
694 695 #define UART_DLH 0xFFC00404
695 696 #define UART_IER 0xFFC00404
arch/blackfin/include/asm/mach-common/bits/uart4.h
  1 +/*
  2 + * UART4 Masks
  3 + */
  4 +
  5 +#ifndef __BFIN_PERIPHERAL_UART4__
  6 +#define __BFIN_PERIPHERAL_UART4__
  7 +
  8 +/* UART_CONTROL */
  9 +#define UEN (1 << 0)
  10 +#define LOOP_ENA (1 << 1)
  11 +#define UMOD (3 << 4)
  12 +#define UMOD_UART (0 << 4)
  13 +#define UMOD_MDB (1 << 4)
  14 +#define UMOD_IRDA (1 << 4)
  15 +#define WLS (3 << 8)
  16 +#define WLS_5 (0 << 8)
  17 +#define WLS_6 (1 << 8)
  18 +#define WLS_7 (2 << 8)
  19 +#define WLS_8 (3 << 8)
  20 +#define STB (1 << 12)
  21 +#define STBH (1 << 13)
  22 +#define PEN (1 << 14)
  23 +#define EPS (1 << 15)
  24 +#define STP (1 << 16)
  25 +#define FPE (1 << 17)
  26 +#define FFE (1 << 18)
  27 +#define SB (1 << 19)
  28 +#define FCPOL (1 << 22)
  29 +#define RPOLC (1 << 23)
  30 +#define TPOLC (1 << 24)
  31 +#define MRTS (1 << 25)
  32 +#define XOFF (1 << 26)
  33 +#define ARTS (1 << 27)
  34 +#define ACTS (1 << 28)
  35 +#define RFIT (1 << 29)
  36 +#define RFRT (1 << 30)
  37 +
  38 +/* UART_STATUS */
  39 +#define DR (1 << 0)
  40 +#define OE (1 << 1)
  41 +#define PE (1 << 2)
  42 +#define FE (1 << 3)
  43 +#define BI (1 << 4)
  44 +#define THRE (1 << 5)
  45 +#define TEMT (1 << 7)
  46 +#define TFI (1 << 8)
  47 +#define ASTKY (1 << 9)
  48 +#define ADDR (1 << 10)
  49 +#define RO (1 << 11)
  50 +#define SCTS (1 << 12)
  51 +#define CTS (1 << 16)
  52 +#define RFCS (1 << 17)
  53 +
  54 +/* UART_EMASK */
  55 +#define ERBFI (1 << 0)
  56 +#define ETBEI (1 << 1)
  57 +#define ELSI (1 << 2)
  58 +#define EDSSI (1 << 3)
  59 +#define EDTPTI (1 << 4)
  60 +#define ETFI (1 << 5)
  61 +#define ERFCI (1 << 6)
  62 +#define EAWI (1 << 7)
  63 +#define ERXS (1 << 8)
  64 +#define ETXS (1 << 9)
  65 +
  66 +#endif