xref: /rk3399_rockchip-uboot/drivers/serial/serial.c (revision 6d93e25806337d46ee75c6703b3ecc972cb179a5)
1 /*
2  * (C) Copyright 2004
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23 
24 #include <common.h>
25 #include <serial.h>
26 #include <stdio_dev.h>
27 #include <post.h>
28 #include <linux/compiler.h>
29 #include <errno.h>
30 
31 DECLARE_GLOBAL_DATA_PTR;
32 
33 static struct serial_device *serial_devices;
34 static struct serial_device *serial_current;
35 
36 static void serial_null(void)
37 {
38 }
39 
40 #define serial_initfunc(name)					\
41 	void name(void)						\
42 		__attribute__((weak, alias("serial_null")));
43 
44 serial_initfunc(mpc8xx_serial_initialize);
45 serial_initfunc(ns16550_serial_initialize);
46 serial_initfunc(pxa_serial_initialize);
47 serial_initfunc(s3c24xx_serial_initialize);
48 serial_initfunc(s5p_serial_initialize);
49 serial_initfunc(zynq_serial_initalize);
50 serial_initfunc(bfin_serial_initialize);
51 serial_initfunc(bfin_jtag_initialize);
52 serial_initfunc(mpc512x_serial_initialize);
53 serial_initfunc(uartlite_serial_initialize);
54 serial_initfunc(au1x00_serial_initialize);
55 serial_initfunc(asc_serial_initialize);
56 serial_initfunc(jz_serial_initialize);
57 serial_initfunc(mpc5xx_serial_initialize);
58 serial_initfunc(mpc8220_serial_initialize);
59 serial_initfunc(mpc8260_scc_serial_initialize);
60 serial_initfunc(mpc8260_smc_serial_initialize);
61 serial_initfunc(mpc85xx_serial_initialize);
62 serial_initfunc(iop480_serial_initialize);
63 serial_initfunc(leon2_serial_initialize);
64 serial_initfunc(leon3_serial_initialize);
65 serial_initfunc(marvell_serial_initialize);
66 serial_initfunc(amirix_serial_initialize);
67 serial_initfunc(bmw_serial_initialize);
68 serial_initfunc(cogent_serial_initialize);
69 serial_initfunc(cpci750_serial_initialize);
70 serial_initfunc(evb64260_serial_initialize);
71 serial_initfunc(ml2_serial_initialize);
72 serial_initfunc(sconsole_serial_initialize);
73 serial_initfunc(p3mx_serial_initialize);
74 serial_initfunc(altera_jtag_serial_initialize);
75 serial_initfunc(altera_serial_initialize);
76 serial_initfunc(atmel_serial_initialize);
77 serial_initfunc(lpc32xx_serial_initialize);
78 serial_initfunc(mcf_serial_initialize);
79 serial_initfunc(ns9750_serial_initialize);
80 serial_initfunc(oc_serial_initialize);
81 serial_initfunc(s3c4510b_serial_initialize);
82 serial_initfunc(s3c64xx_serial_initialize);
83 serial_initfunc(sandbox_serial_initialize);
84 serial_initfunc(clps7111_serial_initialize);
85 serial_initfunc(imx_serial_initialize);
86 serial_initfunc(ixp_serial_initialize);
87 serial_initfunc(ks8695_serial_initialize);
88 serial_initfunc(lh7a40x_serial_initialize);
89 serial_initfunc(lpc2292_serial_initialize);
90 serial_initfunc(max3100_serial_initialize);
91 serial_initfunc(mxc_serial_initialize);
92 serial_initfunc(netarm_serial_initialize);
93 serial_initfunc(pl01x_serial_initialize);
94 serial_initfunc(s3c44b0_serial_initialize);
95 serial_initfunc(sa1100_serial_initialize);
96 serial_initfunc(sh_serial_initialize);
97 
98 void serial_register(struct serial_device *dev)
99 {
100 #ifdef CONFIG_NEEDS_MANUAL_RELOC
101 	if (dev->start)
102 		dev->start += gd->reloc_off;
103 	if (dev->stop)
104 		dev->stop += gd->reloc_off;
105 	if (dev->setbrg)
106 		dev->setbrg += gd->reloc_off;
107 	if (dev->getc)
108 		dev->getc += gd->reloc_off;
109 	if (dev->tstc)
110 		dev->tstc += gd->reloc_off;
111 	if (dev->putc)
112 		dev->putc += gd->reloc_off;
113 	if (dev->puts)
114 		dev->puts += gd->reloc_off;
115 #endif
116 
117 	dev->next = serial_devices;
118 	serial_devices = dev;
119 }
120 
121 void serial_initialize(void)
122 {
123 	mpc8xx_serial_initialize();
124 	ns16550_serial_initialize();
125 	pxa_serial_initialize();
126 	s3c24xx_serial_initialize();
127 	s5p_serial_initialize();
128 	mpc512x_serial_initialize();
129 	bfin_serial_initialize();
130 	bfin_jtag_initialize();
131 	uartlite_serial_initialize();
132 	zynq_serial_initalize();
133 	au1x00_serial_initialize();
134 	asc_serial_initialize();
135 	jz_serial_initialize();
136 	mpc5xx_serial_initialize();
137 	mpc8220_serial_initialize();
138 	mpc8260_scc_serial_initialize();
139 	mpc8260_smc_serial_initialize();
140 	mpc85xx_serial_initialize();
141 	iop480_serial_initialize();
142 	leon2_serial_initialize();
143 	leon3_serial_initialize();
144 	marvell_serial_initialize();
145 	amirix_serial_initialize();
146 	bmw_serial_initialize();
147 	cogent_serial_initialize();
148 	cpci750_serial_initialize();
149 	evb64260_serial_initialize();
150 	ml2_serial_initialize();
151 	sconsole_serial_initialize();
152 	p3mx_serial_initialize();
153 	altera_jtag_serial_initialize();
154 	altera_serial_initialize();
155 	atmel_serial_initialize();
156 	lpc32xx_serial_initialize();
157 	mcf_serial_initialize();
158 	ns9750_serial_initialize();
159 	oc_serial_initialize();
160 	s3c4510b_serial_initialize();
161 	s3c64xx_serial_initialize();
162 	sandbox_serial_initialize();
163 	clps7111_serial_initialize();
164 	imx_serial_initialize();
165 	ixp_serial_initialize();
166 	ks8695_serial_initialize();
167 	lh7a40x_serial_initialize();
168 	lpc2292_serial_initialize();
169 	max3100_serial_initialize();
170 	mxc_serial_initialize();
171 	netarm_serial_initialize();
172 	pl01x_serial_initialize();
173 	s3c44b0_serial_initialize();
174 	sa1100_serial_initialize();
175 	sh_serial_initialize();
176 
177 	serial_assign(default_serial_console()->name);
178 }
179 
180 void serial_stdio_init(void)
181 {
182 	struct stdio_dev dev;
183 	struct serial_device *s = serial_devices;
184 
185 	while (s) {
186 		memset(&dev, 0, sizeof(dev));
187 
188 		strcpy(dev.name, s->name);
189 		dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT;
190 
191 		dev.start = s->start;
192 		dev.stop = s->stop;
193 		dev.putc = s->putc;
194 		dev.puts = s->puts;
195 		dev.getc = s->getc;
196 		dev.tstc = s->tstc;
197 
198 		stdio_register(&dev);
199 
200 		s = s->next;
201 	}
202 }
203 
204 int serial_assign(const char *name)
205 {
206 	struct serial_device *s;
207 
208 	for (s = serial_devices; s; s = s->next) {
209 		if (strcmp(s->name, name))
210 			continue;
211 		serial_current = s;
212 		return 0;
213 	}
214 
215 	return -EINVAL;
216 }
217 
218 void serial_reinit_all(void)
219 {
220 	struct serial_device *s;
221 
222 	for (s = serial_devices; s; s = s->next)
223 		s->start();
224 }
225 
226 static struct serial_device *get_current(void)
227 {
228 	struct serial_device *dev;
229 
230 	if (!(gd->flags & GD_FLG_RELOC) || !serial_current) {
231 		dev = default_serial_console();
232 
233 		/* We must have a console device */
234 		if (!dev) {
235 #ifdef CONFIG_SPL_BUILD
236 			puts("Cannot find console\n");
237 			hang();
238 #else
239 			panic("Cannot find console\n");
240 #endif
241 		}
242 	} else
243 		dev = serial_current;
244 	return dev;
245 }
246 
247 int serial_init(void)
248 {
249 	return get_current()->start();
250 }
251 
252 void serial_setbrg(void)
253 {
254 	get_current()->setbrg();
255 }
256 
257 int serial_getc(void)
258 {
259 	return get_current()->getc();
260 }
261 
262 int serial_tstc(void)
263 {
264 	return get_current()->tstc();
265 }
266 
267 void serial_putc(const char c)
268 {
269 	get_current()->putc(c);
270 }
271 
272 void serial_puts(const char *s)
273 {
274 	get_current()->puts(s);
275 }
276 
277 void default_serial_puts(const char *s)
278 {
279 	struct serial_device *dev = get_current();
280 	while (*s)
281 		dev->putc(*s++);
282 }
283 
284 #if CONFIG_POST & CONFIG_SYS_POST_UART
285 static const int bauds[] = CONFIG_SYS_BAUDRATE_TABLE;
286 
287 /* Mark weak until post/cpu/.../uart.c migrate over */
288 __weak
289 int uart_post_test(int flags)
290 {
291 	unsigned char c;
292 	int ret, saved_baud, b;
293 	struct serial_device *saved_dev, *s;
294 	bd_t *bd = gd->bd;
295 
296 	/* Save current serial state */
297 	ret = 0;
298 	saved_dev = serial_current;
299 	saved_baud = bd->bi_baudrate;
300 
301 	for (s = serial_devices; s; s = s->next) {
302 		/* If this driver doesn't support loop back, skip it */
303 		if (!s->loop)
304 			continue;
305 
306 		/* Test the next device */
307 		serial_current = s;
308 
309 		ret = serial_init();
310 		if (ret)
311 			goto done;
312 
313 		/* Consume anything that happens to be queued */
314 		while (serial_tstc())
315 			serial_getc();
316 
317 		/* Enable loop back */
318 		s->loop(1);
319 
320 		/* Test every available baud rate */
321 		for (b = 0; b < ARRAY_SIZE(bauds); ++b) {
322 			bd->bi_baudrate = bauds[b];
323 			serial_setbrg();
324 
325 			/*
326 			 * Stick to printable chars to avoid issues:
327 			 *  - terminal corruption
328 			 *  - serial program reacting to sequences and sending
329 			 *    back random extra data
330 			 *  - most serial drivers add in extra chars (like \r\n)
331 			 */
332 			for (c = 0x20; c < 0x7f; ++c) {
333 				/* Send it out */
334 				serial_putc(c);
335 
336 				/* Make sure it's the same one */
337 				ret = (c != serial_getc());
338 				if (ret) {
339 					s->loop(0);
340 					goto done;
341 				}
342 
343 				/* Clean up the output in case it was sent */
344 				serial_putc('\b');
345 				ret = ('\b' != serial_getc());
346 				if (ret) {
347 					s->loop(0);
348 					goto done;
349 				}
350 			}
351 		}
352 
353 		/* Disable loop back */
354 		s->loop(0);
355 
356 		/* XXX: There is no serial_stop() !? */
357 		if (s->stop)
358 			s->stop();
359 	}
360 
361  done:
362 	/* Restore previous serial state */
363 	serial_current = saved_dev;
364 	bd->bi_baudrate = saved_baud;
365 	serial_reinit_all();
366 	serial_setbrg();
367 
368 	return ret;
369 }
370 #endif
371