1/* 2 * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7#include <asm_macros.S> 8 9#define UNIPHIER_UART_BASE 0x54006800 10#define UNIPHIER_UART_END 0x54006c00 11#define UNIPHIER_UART_OFFSET 0x100 12 13#define UNIPHIER_UART_RX 0x00 /* In: Receive buffer */ 14#define UNIPHIER_UART_TX 0x00 /* Out: Transmit buffer */ 15 16#define UNIPHIER_UART_FCR 0x0c /* Char/FIFO Control Register */ 17#define UNIPHIER_UART_FCR_ENABLE_FIFO 0x01 /* Enable the FIFO */ 18 19#define UNIPHIER_UART_LCR_MCR 0x10 /* Line/Modem Control Register */ 20#define UNIPHIER_UART_LCR_WLEN8 0x03 /* Wordlength: 8 bits */ 21#define UNIPHIER_UART_LSR 0x14 /* Line Status Register */ 22#define UNIPHIER_UART_LSR_TEMT_BIT 6 /* Transmitter empty */ 23#define UNIPHIER_UART_LSR_THRE_BIT 5 /* Transmit-hold-register empty */ 24#define UNIPHIER_UART_LSR_DR_BIT 0 /* Receiver data ready */ 25#define UNIPHIER_UART_DLR 0x24 /* Divisor Latch Register */ 26 27/* 28 * Uncomment for debug 29 */ 30/* #define UNIPHIER_UART_INIT_DIVISOR */ 31#define UNIPHIER_UART_DEFAULT_BASE (UNIPHIER_UART_BASE) 32#define UNIPHIER_UART_CLK_RATE 58820000 33#define UNIPHIER_UART_DEFAULT_BAUDRATE 115200 34 35/* 36 * In: x0 - console base address 37 * w1 - uart clock in Hz 38 * w2 - baud rate 39 * Out: return 1 on success, or 0 on error 40 */ 41 .globl console_core_init 42func console_core_init 43 cbz x0, 1f 44#ifdef UNIPHIER_UART_INIT_DIVISOR 45 cbz w1, 1f 46 cbz w2, 1f 47 /* divisor = uart_clock / (16 * baud_rate) */ 48 udiv w2, w1, w2 49 lsr w2, w2, #4 50#endif 51 /* Make sure the transmitter is empty before the divisor set/change */ 520: ldr w1, [x0, #UNIPHIER_UART_LSR] 53 tbz w1, #UNIPHIER_UART_LSR_TEMT_BIT, 0b 54#ifdef UNIPHIER_UART_INIT_DIVISOR 55 str w2, [x0, #UNIPHIER_UART_DLR] 56#endif 57 mov w2, #UNIPHIER_UART_FCR_ENABLE_FIFO 58 str w2, [x0, #UNIPHIER_UART_FCR] 59 60 mov w2, #(UNIPHIER_UART_LCR_WLEN8 << 8) 61 str w2, [x0, #UNIPHIER_UART_LCR_MCR] 62 63 mov w0, #1 64 ret 651: mov w0, #0 66 ret 67endfunc console_core_init 68 69/* 70 * In: w0 - character to be printed 71 * x1 - console base address 72 * Out: return the character written, or -1 on error 73 * Clobber: x2 74 */ 75 .globl console_core_putc 76func console_core_putc 77 /* Error out if the console is not initialized */ 78 cbz x1, 2f 79 80 /* Wait until the transmitter FIFO gets empty */ 810: ldr w2, [x1, #UNIPHIER_UART_LSR] 82 tbz w2, #UNIPHIER_UART_LSR_THRE_BIT, 0b 83 84 mov w2, w0 85 861: str w2, [x1, #UNIPHIER_UART_TX] 87 88 cmp w2, #'\n' 89 b.ne 3f 90 mov w2, #'\r' /* Append '\r' to '\n' */ 91 b 1b 922: mov w0, #-1 933: ret 94endfunc console_core_putc 95 96/* 97 * In: x0 - console base address 98 * Out: return the character read 99 * Clobber: x1 100 */ 101 .globl console_core_getc 102func console_core_getc 103 /* Error out if the console is not initialized */ 104 cbz x0, 1f 105 106 /* Wait while the receiver FIFO is empty */ 1070: ldr w1, [x0, #UNIPHIER_UART_LSR] 108 tbz w1, #UNIPHIER_UART_LSR_DR_BIT, 0b 109 110 ldr w0, [x0, #UNIPHIER_UART_RX] 111 112 ret 1131: mov w0, #-1 114 ret 115endfunc console_core_getc 116 117/* 118 * In: x0 - console base address 119 * Out: return 0, or -1 on error 120 * Clobber: x1 121 */ 122 .global console_core_flush 123func console_core_flush 124 /* Error out if the console is not initialized */ 125 cbz x0, 1f 126 127 /* wait until the transmitter gets empty */ 1280: ldr w1, [x0, #UNIPHIER_UART_LSR] 129 tbz w1, #UNIPHIER_UART_LSR_TEMT_BIT, 0b 130 131 mov w0, #0 132 ret 1331: mov w0, #-1 134 ret 135endfunc console_core_flush 136 137/* find initialized UART port */ 138.macro uniphier_console_get_base base, tmpx, tmpw 139 ldr \base, =UNIPHIER_UART_BASE 1400000: ldr \tmpw, [\base, #UNIPHIER_UART_DLR] 141 mvn \tmpw, \tmpw 142 uxth \tmpw, \tmpw 143 cbnz \tmpw, 0001f 144 add \base, \base, #UNIPHIER_UART_OFFSET 145 ldr \tmpx, =UNIPHIER_UART_END 146 cmp \base, \tmpx 147 b.lo 0000b 148 mov \base, #0 1490001: 150.endm 151 152/* 153 * int plat_crash_console_init(void) 154 * Clobber: x0-x2 155 */ 156 .globl plat_crash_console_init 157func plat_crash_console_init 158#ifdef UNIPHIER_UART_INIT_DIVISOR 159 ldr x0, =UNIPHIER_UART_DEFAULT_BASE 160 ldr x1, =UNIPHIER_UART_CLK_RATE 161 ldr x2, =UNIPHIER_UART_DEFAULT_BAUDRATE 162 b console_core_init 163#else 164 ret 165#endif 166endfunc plat_crash_console_init 167 168/* 169 * int plat_crash_console_putc(int c) 170 * Clobber: x1, x2 171 */ 172 .globl plat_crash_console_putc 173func plat_crash_console_putc 174#ifdef UNIPHIER_UART_INIT_DIVISOR 175 ldr x1, =UNIPHIER_UART_DEFAULT_BASE 176#else 177 uniphier_console_get_base x1, x2, w2 178#endif 179 b console_core_putc 180endfunc plat_crash_console_putc 181 182/* 183 * int plat_crash_console_flush(void) 184 * Clobber: x0, x1 185 */ 186 .global plat_crash_console_flush 187func plat_crash_console_flush 188#ifdef UNIPHIER_UART_INIT_DIVISOR 189 ldr x0, =UNIPHIER_UART_DEFAULT_BASE 190#else 191 uniphier_console_get_base x0, x1, w1 192#endif 193 b console_core_flush 194endfunc plat_crash_console_flush 195 196/* 197 * void uniphier_console_setup(void) 198 * Clobber: x0-x2 199 */ 200 .globl uniphier_console_setup 201func uniphier_console_setup 202#ifdef UNIPHIER_UART_INIT_DIVISOR 203 ldr x0, =UNIPHIER_UART_DEFAULT_BASE 204 ldr w1, =UNIPHIER_UART_CLK_RATE 205 ldr w2, =UNIPHIER_UART_DEFAULT_BAUDRATE 206#else 207 uniphier_console_get_base x0, x1, w1 208 mov w1, #0 209 mov w2, #0 210#endif 211 b console_init 212endfunc uniphier_console_setup 213