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