• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 			 CONSOLE_FLAG_TRANSLATE_CRLF,
37 		.putc = uniphier_console_putc,
38 		.getc = uniphier_console_getc,
39 		.flush = uniphier_console_flush,
40 	},
41 };
42 
43 /*
44  * There are 4 UART ports available on this platform. By default, we want to
45  * use the same one as used in the previous firmware stage.
46  */
uniphier_console_get_base(void)47 static uintptr_t uniphier_console_get_base(void)
48 {
49 	uintptr_t base = UNIPHIER_UART_BASE;
50 	uint32_t div;
51 
52 	while (base < UNIPHIER_UART_END) {
53 		div = mmio_read_32(base + UNIPHIER_UART_DLR);
54 		if (div)
55 			return base;
56 		base += UNIPHIER_UART_OFFSET;
57 	}
58 
59 	return 0;
60 }
61 
uniphier_console_init(uintptr_t base)62 static void uniphier_console_init(uintptr_t base)
63 {
64 	mmio_write_32(base + UNIPHIER_UART_FCR, UNIPHIER_UART_FCR_ENABLE_FIFO);
65 	mmio_write_32(base + UNIPHIER_UART_LCR_MCR,
66 		      UNIPHIER_UART_LCR_WLEN8 << 8);
67 }
68 
uniphier_console_setup(void)69 void uniphier_console_setup(void)
70 {
71 	uintptr_t base;
72 
73 	base = uniphier_console_get_base();
74 	if (!base)
75 		plat_error_handler(-EINVAL);
76 
77 	uniphier_console.base = base;
78 	console_register(&uniphier_console.console);
79 
80 	/*
81 	 * The hardware might be still printing characters queued up in the
82 	 * previous firmware stage. Make sure the transmitter is empty before
83 	 * any initialization. Otherwise, the console might get corrupted.
84 	 */
85 	console_flush();
86 
87 	uniphier_console_init(base);
88 }
89