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