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