blob: 8185ec5a12cdb26705c03ef81ce1121071290c52 [file] [log] [blame]
Masahiro Yamadaca8b80e2019-07-02 22:03:16 +09001/*
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
19struct 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 */
25int uniphier_console_putc(int character, struct console *console);
26int uniphier_console_getc(struct console *console);
27int uniphier_console_flush(struct console *console);
28
29static 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 */
46static 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
61static 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
68void 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}