1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40#include <common.h>
41#include <post.h>
42#include <watchdog.h>
43#include <serial.h>
44#include <linux/compiler.h>
45#include <asm/blackfin.h>
46#include <asm/mach-common/bits/uart.h>
47
48DECLARE_GLOBAL_DATA_PTR;
49
50#ifdef CONFIG_UART_CONSOLE
51
52#include "serial.h"
53
54#ifdef CONFIG_DEBUG_SERIAL
55static uint16_t cached_lsr[256];
56static uint16_t cached_rbr[256];
57static size_t cache_count;
58
59
60
61
62
63
64static uint16_t uart_lsr_save;
65static uint16_t uart_lsr_read(uint32_t uart_base)
66{
67 uint16_t lsr = bfin_read(&pUART->lsr);
68 uart_lsr_save |= (lsr & (OE|PE|FE|BI));
69 return lsr | uart_lsr_save;
70}
71
72static void uart_lsr_clear(uint32_t uart_base)
73{
74 uart_lsr_save = 0;
75 bfin_write(&pUART->lsr, bfin_read(&pUART->lsr) | -1);
76}
77#else
78
79
80
81
82static inline uint16_t uart_lsr_read(uint32_t uart_base)
83{
84 return bfin_read(&pUART->lsr);
85}
86static void uart_lsr_clear(uint32_t uart_base)
87{
88 bfin_write(&pUART->lsr, bfin_read(&pUART->lsr) | -1);
89}
90#endif
91
92static void uart_putc(uint32_t uart_base, const char c)
93{
94
95 if (c == '\n')
96 serial_putc('\r');
97
98 WATCHDOG_RESET();
99
100
101 while (!(uart_lsr_read(uart_base) & THRE))
102 continue;
103
104
105 bfin_write(&pUART->thr, c);
106 SSYNC();
107
108 WATCHDOG_RESET();
109}
110
111static int uart_tstc(uint32_t uart_base)
112{
113 WATCHDOG_RESET();
114 return (uart_lsr_read(uart_base) & DR) ? 1 : 0;
115}
116
117static int uart_getc(uint32_t uart_base)
118{
119 uint16_t uart_rbr_val;
120
121
122 while (!uart_tstc(uart_base))
123 continue;
124
125
126 uart_rbr_val = bfin_read(&pUART->rbr);
127
128#ifdef CONFIG_DEBUG_SERIAL
129
130 uint16_t uart_lsr_val = uart_lsr_read(uart_base);
131
132 cached_lsr[cache_count] = uart_lsr_val;
133 cached_rbr[cache_count] = uart_rbr_val;
134 cache_count = (cache_count + 1) % ARRAY_SIZE(cached_lsr);
135
136 if (uart_lsr_val & (OE|PE|FE|BI)) {
137 uint16_t dll, dlh;
138 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 do {
145 --cache_count;
146 printf("\t%3zu: RBR=0x%02x LSR=0x%02x\n", cache_count,
147 cached_rbr[cache_count], cached_lsr[cache_count]);
148 } while (cache_count > 0);
149 return -1;
150 }
151#endif
152 uart_lsr_clear(uart_base);
153
154 return uart_rbr_val;
155}
156
157#if CONFIG_POST & CONFIG_SYS_POST_UART
158# define LOOP(x) x
159#else
160# define LOOP(x)
161#endif
162
163LOOP(
164static void uart_loop(uint32_t uart_base, int state)
165{
166 u16 mcr;
167
168
169 while (!(uart_lsr_read(uart_base) & TEMT))
170 continue;
171
172 mcr = bfin_read(&pUART->mcr);
173 if (state)
174 mcr |= LOOP_ENA | MRTS;
175 else
176 mcr &= ~(LOOP_ENA | MRTS);
177 bfin_write(&pUART->mcr, mcr);
178}
179)
180
181#ifdef CONFIG_SYS_BFIN_UART
182
183static void uart_puts(uint32_t uart_base, const char *s)
184{
185 while (*s)
186 uart_putc(uart_base, *s++);
187}
188
189#define DECL_BFIN_UART(n) \
190static int uart##n##_init(void) \
191{ \
192 const unsigned short pins[] = { _P_UART(n, RX), _P_UART(n, TX), 0, }; \
193 peripheral_request_list(pins, "bfin-uart"); \
194 uart_init(MMR_UART(n)); \
195 serial_early_set_baud(MMR_UART(n), gd->baudrate); \
196 uart_lsr_clear(MMR_UART(n)); \
197 return 0; \
198} \
199\
200static int uart##n##_uninit(void) \
201{ \
202 return serial_early_uninit(MMR_UART(n)); \
203} \
204\
205static void uart##n##_setbrg(void) \
206{ \
207 serial_early_set_baud(MMR_UART(n), gd->baudrate); \
208} \
209\
210static int uart##n##_getc(void) \
211{ \
212 return uart_getc(MMR_UART(n)); \
213} \
214\
215static int uart##n##_tstc(void) \
216{ \
217 return uart_tstc(MMR_UART(n)); \
218} \
219\
220static void uart##n##_putc(const char c) \
221{ \
222 uart_putc(MMR_UART(n), c); \
223} \
224\
225static void uart##n##_puts(const char *s) \
226{ \
227 uart_puts(MMR_UART(n), s); \
228} \
229\
230LOOP( \
231static void uart##n##_loop(int state) \
232{ \
233 uart_loop(MMR_UART(n), state); \
234} \
235) \
236\
237struct serial_device bfin_serial##n##_device = { \
238 .name = "bfin_uart"#n, \
239 .init = uart##n##_init, \
240 .uninit = uart##n##_uninit, \
241 .setbrg = uart##n##_setbrg, \
242 .getc = uart##n##_getc, \
243 .tstc = uart##n##_tstc, \
244 .putc = uart##n##_putc, \
245 .puts = uart##n##_puts, \
246 LOOP(.loop = uart##n##_loop) \
247};
248
249#ifdef UART0_DLL
250DECL_BFIN_UART(0)
251#endif
252#ifdef UART1_DLL
253DECL_BFIN_UART(1)
254#endif
255#ifdef UART2_DLL
256DECL_BFIN_UART(2)
257#endif
258#ifdef UART3_DLL
259DECL_BFIN_UART(3)
260#endif
261
262__weak struct serial_device *default_serial_console(void)
263{
264#if CONFIG_UART_CONSOLE == 0
265 return &bfin_serial0_device;
266#elif CONFIG_UART_CONSOLE == 1
267 return &bfin_serial1_device;
268#elif CONFIG_UART_CONSOLE == 2
269 return &bfin_serial2_device;
270#elif CONFIG_UART_CONSOLE == 3
271 return &bfin_serial3_device;
272#endif
273}
274
275void serial_register_bfin_uart(void)
276{
277#ifdef UART0_DLL
278 serial_register(&bfin_serial0_device);
279#endif
280#ifdef UART1_DLL
281 serial_register(&bfin_serial1_device);
282#endif
283#ifdef UART2_DLL
284 serial_register(&bfin_serial2_device);
285#endif
286#ifdef UART3_DLL
287 serial_register(&bfin_serial3_device);
288#endif
289}
290
291#else
292
293
294void serial_set_baud(uint32_t baud)
295{
296 serial_early_set_baud(UART_DLL, baud);
297}
298
299
300
301
302void serial_setbrg(void)
303{
304 serial_set_baud(gd->baudrate);
305}
306
307
308void serial_initialize(void)
309{
310 serial_early_init(UART_DLL);
311}
312
313
314int serial_init(void)
315{
316 serial_initialize();
317 serial_setbrg();
318 uart_lsr_clear(UART_DLL);
319 return 0;
320}
321
322int serial_tstc(void)
323{
324 return uart_tstc(UART_DLL);
325}
326
327int serial_getc(void)
328{
329 return uart_getc(UART_DLL);
330}
331
332void serial_putc(const char c)
333{
334 uart_putc(UART_DLL, c);
335}
336
337void serial_puts(const char *s)
338{
339 while (*s)
340 serial_putc(*s++);
341}
342
343LOOP(
344void serial_loop(int state)
345{
346 uart_loop(UART_DLL, state);
347}
348)
349
350#endif
351
352#endif
353