1ac9f1b55SMasahiro Yamada /* 24511322fSMasahiro Yamada * Copyright (c) 2019-2020, Socionext Inc. All rights reserved. 3ac9f1b55SMasahiro Yamada * 4ac9f1b55SMasahiro Yamada * SPDX-License-Identifier: BSD-3-Clause 5ac9f1b55SMasahiro Yamada */ 6ac9f1b55SMasahiro Yamada 74511322fSMasahiro Yamada #include <assert.h> 84511322fSMasahiro 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 184511322fSMasahiro Yamada #define UNIPHIER_UART_NR_PORTS 4 19ac9f1b55SMasahiro Yamada 20ac9f1b55SMasahiro Yamada /* These callbacks are implemented in assembly to use crash_console_helpers.S */ 21ac9f1b55SMasahiro Yamada int uniphier_console_putc(int character, struct console *console); 22ac9f1b55SMasahiro Yamada int uniphier_console_getc(struct console *console); 23831b0e98SJimmy Brisson void uniphier_console_flush(struct console *console); 24ac9f1b55SMasahiro Yamada 25af1e8fdaSAndre Przywara static console_t uniphier_console = { 26ac9f1b55SMasahiro Yamada .flags = CONSOLE_FLAG_BOOT | 27ac9f1b55SMasahiro Yamada #if DEBUG 28ac9f1b55SMasahiro Yamada CONSOLE_FLAG_RUNTIME | 29ac9f1b55SMasahiro Yamada #endif 30abfd5719SMasahiro Yamada CONSOLE_FLAG_CRASH | 31abfd5719SMasahiro Yamada CONSOLE_FLAG_TRANSLATE_CRLF, 32ac9f1b55SMasahiro Yamada .putc = uniphier_console_putc, 33*85bebe18SSandrine Bailleux #if ENABLE_CONSOLE_GETC 34ac9f1b55SMasahiro Yamada .getc = uniphier_console_getc, 35*85bebe18SSandrine Bailleux #endif 36ac9f1b55SMasahiro Yamada .flush = uniphier_console_flush, 37ac9f1b55SMasahiro Yamada }; 38ac9f1b55SMasahiro Yamada 394511322fSMasahiro Yamada static const uintptr_t uniphier_uart_base[] = { 404511322fSMasahiro Yamada [UNIPHIER_SOC_LD11] = 0x54006800, 414511322fSMasahiro Yamada [UNIPHIER_SOC_LD20] = 0x54006800, 424511322fSMasahiro Yamada [UNIPHIER_SOC_PXS3] = 0x54006800, 434511322fSMasahiro Yamada }; 444511322fSMasahiro Yamada 45ac9f1b55SMasahiro Yamada /* 46ac9f1b55SMasahiro Yamada * There are 4 UART ports available on this platform. By default, we want to 47ac9f1b55SMasahiro Yamada * use the same one as used in the previous firmware stage. 48ac9f1b55SMasahiro Yamada */ 494511322fSMasahiro Yamada static uintptr_t uniphier_console_get_base(unsigned int soc) 50ac9f1b55SMasahiro Yamada { 514511322fSMasahiro Yamada uintptr_t base, end; 52ac9f1b55SMasahiro Yamada uint32_t div; 53ac9f1b55SMasahiro Yamada 544511322fSMasahiro Yamada assert(soc < ARRAY_SIZE(uniphier_uart_base)); 554511322fSMasahiro Yamada base = uniphier_uart_base[soc]; 564511322fSMasahiro Yamada end = base + UNIPHIER_UART_OFFSET * UNIPHIER_UART_NR_PORTS; 574511322fSMasahiro Yamada 584511322fSMasahiro Yamada while (base < end) { 59ac9f1b55SMasahiro Yamada div = mmio_read_32(base + UNIPHIER_UART_DLR); 60ac9f1b55SMasahiro Yamada if (div) 61ac9f1b55SMasahiro Yamada return base; 62ac9f1b55SMasahiro Yamada base += UNIPHIER_UART_OFFSET; 63ac9f1b55SMasahiro Yamada } 64ac9f1b55SMasahiro Yamada 65ac9f1b55SMasahiro Yamada return 0; 66ac9f1b55SMasahiro Yamada } 67ac9f1b55SMasahiro Yamada 68ac9f1b55SMasahiro Yamada static void uniphier_console_init(uintptr_t base) 69ac9f1b55SMasahiro Yamada { 70ac9f1b55SMasahiro Yamada mmio_write_32(base + UNIPHIER_UART_FCR, UNIPHIER_UART_FCR_ENABLE_FIFO); 71ac9f1b55SMasahiro Yamada mmio_write_32(base + UNIPHIER_UART_LCR_MCR, 72ac9f1b55SMasahiro Yamada UNIPHIER_UART_LCR_WLEN8 << 8); 73ac9f1b55SMasahiro Yamada } 74ac9f1b55SMasahiro Yamada 754511322fSMasahiro Yamada void uniphier_console_setup(unsigned int soc) 76ac9f1b55SMasahiro Yamada { 77ac9f1b55SMasahiro Yamada uintptr_t base; 78ac9f1b55SMasahiro Yamada 794511322fSMasahiro Yamada base = uniphier_console_get_base(soc); 80ac9f1b55SMasahiro Yamada if (!base) 81ac9f1b55SMasahiro Yamada plat_error_handler(-EINVAL); 82ac9f1b55SMasahiro Yamada 83ac9f1b55SMasahiro Yamada uniphier_console.base = base; 84af1e8fdaSAndre Przywara console_register(&uniphier_console); 85ac9f1b55SMasahiro Yamada 86ac9f1b55SMasahiro Yamada /* 87ac9f1b55SMasahiro Yamada * The hardware might be still printing characters queued up in the 88ac9f1b55SMasahiro Yamada * previous firmware stage. Make sure the transmitter is empty before 89ac9f1b55SMasahiro Yamada * any initialization. Otherwise, the console might get corrupted. 90ac9f1b55SMasahiro Yamada */ 91ac9f1b55SMasahiro Yamada console_flush(); 92ac9f1b55SMasahiro Yamada 93ac9f1b55SMasahiro Yamada uniphier_console_init(base); 94ac9f1b55SMasahiro Yamada } 95