xref: /rk3399_ARM-atf/plat/socionext/uniphier/uniphier_console_setup.c (revision 36cfbf3ca28be833116a1ac7c7c1b98da50db95a)
1 /*
2  * Copyright (c) 2019, Socionext Inc. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <drivers/console.h>
8 #include <errno.h>
9 #include <lib/mmio.h>
10 #include <plat/common/platform.h>
11 
12 #include "uniphier.h"
13 #include "uniphier_console.h"
14 
15 #define UNIPHIER_UART_BASE	0x54006800
16 #define UNIPHIER_UART_END	0x54006c00
17 #define UNIPHIER_UART_OFFSET	0x100
18 
19 struct uniphier_console {
20 	struct console console;
21 	uintptr_t base;
22 };
23 
24 /* These callbacks are implemented in assembly to use crash_console_helpers.S */
25 int uniphier_console_putc(int character, struct console *console);
26 int uniphier_console_getc(struct console *console);
27 int uniphier_console_flush(struct console *console);
28 
29 static struct uniphier_console uniphier_console = {
30 	.console = {
31 		.flags = CONSOLE_FLAG_BOOT |
32 #if DEBUG
33 			 CONSOLE_FLAG_RUNTIME |
34 #endif
35 			 CONSOLE_FLAG_CRASH,
36 		.putc = uniphier_console_putc,
37 		.getc = uniphier_console_getc,
38 		.flush = uniphier_console_flush,
39 	},
40 };
41 
42 /*
43  * There are 4 UART ports available on this platform. By default, we want to
44  * use the same one as used in the previous firmware stage.
45  */
46 static uintptr_t uniphier_console_get_base(void)
47 {
48 	uintptr_t base = UNIPHIER_UART_BASE;
49 	uint32_t div;
50 
51 	while (base < UNIPHIER_UART_END) {
52 		div = mmio_read_32(base + UNIPHIER_UART_DLR);
53 		if (div)
54 			return base;
55 		base += UNIPHIER_UART_OFFSET;
56 	}
57 
58 	return 0;
59 }
60 
61 static void uniphier_console_init(uintptr_t base)
62 {
63 	mmio_write_32(base + UNIPHIER_UART_FCR, UNIPHIER_UART_FCR_ENABLE_FIFO);
64 	mmio_write_32(base + UNIPHIER_UART_LCR_MCR,
65 		      UNIPHIER_UART_LCR_WLEN8 << 8);
66 }
67 
68 void uniphier_console_setup(void)
69 {
70 	uintptr_t base;
71 
72 	base = uniphier_console_get_base();
73 	if (!base)
74 		plat_error_handler(-EINVAL);
75 
76 	uniphier_console.base = base;
77 	console_register(&uniphier_console.console);
78 
79 	/*
80 	 * The hardware might be still printing characters queued up in the
81 	 * previous firmware stage. Make sure the transmitter is empty before
82 	 * any initialization. Otherwise, the console might get corrupted.
83 	 */
84 	console_flush();
85 
86 	uniphier_console_init(base);
87 }
88