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