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 42 func 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 */ 52 0: 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 65 1: mov w0, #0 66 ret 67 endfunc 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 76 func 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 */ 81 0: ldr w2, [x1, #UNIPHIER_UART_LSR] 82 tbz w2, #UNIPHIER_UART_LSR_THRE_BIT, 0b 83 84 mov w2, w0 85 86 1: 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 92 2: mov w0, #-1 93 3: ret 94 endfunc 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 102 func 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 */ 107 0: 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 113 1: mov w0, #-1 114 ret 115 endfunc 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 123 func console_core_flush 124 /* Error out if the console is not initialized */ 125 cbz x0, 1f 126 127 /* wait until the transmitter gets empty */ 128 0: ldr w1, [x0, #UNIPHIER_UART_LSR] 129 tbz w1, #UNIPHIER_UART_LSR_TEMT_BIT, 0b 130 131 mov w0, #0 132 ret 133 1: mov w0, #-1 134 ret 135 endfunc console_core_flush 136 137 /* find initialized UART port */ 138 .macro uniphier_console_get_base base, tmpx, tmpw 139 ldr \base, =UNIPHIER_UART_BASE 140 0000: 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 149 0001: 150 .endm 151 152 /* 153 * int plat_crash_console_init(void) 154 * Clobber: x0-x2 155 */ 156 .globl plat_crash_console_init 157 func 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 166 endfunc 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 173 func 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 180 endfunc plat_crash_console_putc 181 182 /* 183 * int plat_crash_console_flush(void) 184 * Clobber: x0, x1 185 */ 186 .global plat_crash_console_flush 187 func 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 194 endfunc plat_crash_console_flush 195 196 /* 197 * void uniphier_console_setup(void) 198 * Clobber: x0-x2 199 */ 200 .globl uniphier_console_setup 201 func 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 212 endfunc uniphier_console_setup 213