1/* 2 * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6#include <asm_macros.S> 7#include <console_macros.S> 8 9#define CONSOLE_NUM_BYTES_SHIFT 24 10#define CONSOLE_FLUSH_DATA_TO_PORT (1 << 26) 11#define CONSOLE_RING_DOORBELL (1 << 31) 12#define CONSOLE_IS_BUSY (1 << 31) 13#define CONSOLE_WRITE (CONSOLE_RING_DOORBELL | CONSOLE_FLUSH_DATA_TO_PORT) 14 15 /* 16 * This file contains a driver implementation to make use of the 17 * real console implementation provided by the SPE firmware running 18 * SoCs after Tegra186. 19 * 20 * This console is shared by multiple components and the SPE firmware 21 * finally displays everything on the UART port. 22 */ 23 24 .globl console_spe_core_init 25 .globl console_spe_core_putc 26 .globl console_spe_core_getc 27 .globl console_spe_core_flush 28 .globl console_spe_putc 29 .globl console_spe_getc 30 .globl console_spe_flush 31 .globl console_spe_register 32 33 /* ------------------------------------------------- 34 * int console_spe_register(uintptr_t baseaddr, 35 * uint32_t clock, uint32_t baud, 36 * console_spe_t *console); 37 * Function to initialize and register a new spe 38 * console. Storage passed in for the console struct 39 * *must* be persistent (i.e. not from the stack). 40 * In: x0 - UART register base address 41 * w1 - UART clock in Hz 42 * w2 - Baud rate 43 * x3 - pointer to empty console_spe_t struct 44 * Out: return 1 on success, 0 on error 45 * Clobber list : x0, x1, x2, x6, x7, x14 46 * ------------------------------------------------- 47 */ 48func console_spe_register 49 cbz x3, register_fail 50 str x0, [x3, #CONSOLE_T_DRVDATA] 51 mov x0, x3 52 finish_console_register spe putc=1, getc=1, flush=1 53 54register_fail: 55 mov w0, wzr 56 ret 57endfunc console_spe_register 58 59 /* -------------------------------------------------------- 60 * int console_spe_core_putc(int c, uintptr_t base_addr) 61 * Function to output a character over the console. It 62 * returns the character printed on success or -1 on error. 63 * In : w0 - character to be printed 64 * x1 - console base address 65 * Out : return -1 on error else return character. 66 * Clobber list : x2 67 * -------------------------------------------------------- 68 */ 69func console_spe_core_putc 70 /* Check the input parameter */ 71 cbz x1, putc_error 72 73 /* Prepend '\r' to '\n' */ 74 cmp w0, #0xA 75 b.ne 2f 76 77 /* wait until spe is ready */ 781: ldr w2, [x1] 79 and w2, w2, #CONSOLE_IS_BUSY 80 cbnz w2, 1b 81 82 /* spe is ready */ 83 mov w2, #0xD /* '\r' */ 84 and w2, w2, #0xFF 85 mov w3, #(CONSOLE_WRITE | (1 << CONSOLE_NUM_BYTES_SHIFT)) 86 orr w2, w2, w3 87 str w2, [x1] 88 89 /* wait until spe is ready */ 902: ldr w2, [x1] 91 and w2, w2, #CONSOLE_IS_BUSY 92 cbnz w2, 2b 93 94 /* spe is ready */ 95 mov w2, w0 96 and w2, w2, #0xFF 97 mov w3, #(CONSOLE_WRITE | (1 << CONSOLE_NUM_BYTES_SHIFT)) 98 orr w2, w2, w3 99 str w2, [x1] 100 101 ret 102putc_error: 103 mov w0, #-1 104 ret 105endfunc console_spe_core_putc 106 107 /* -------------------------------------------------------- 108 * int console_spe_putc(int c, console_spe_t *console) 109 * Function to output a character over the console. It 110 * returns the character printed on success or -1 on error. 111 * In : w0 - character to be printed 112 * x1 - pointer to console_t structure 113 * Out : return -1 on error else return character. 114 * Clobber list : x2 115 * -------------------------------------------------------- 116 */ 117func console_spe_putc 118 ldr x1, [x1, #CONSOLE_T_DRVDATA] 119 b console_spe_core_putc 120endfunc console_spe_putc 121 122 /* --------------------------------------------- 123 * int console_spe_getc(console_spe_t *console) 124 * Function to get a character from the console. 125 * It returns the character grabbed on success 126 * or -1 if no character is available. 127 * In : x0 - pointer to console_t structure 128 * Out: w0 - character if available, else -1 129 * Clobber list : x0, x1 130 * --------------------------------------------- 131 */ 132func console_spe_getc 133 mov w0, #-1 134 ret 135endfunc console_spe_getc 136 137 /* ------------------------------------------------- 138 * int console_spe_core_flush(uintptr_t base_addr) 139 * Function to force a write of all buffered 140 * data that hasn't been output. 141 * In : x0 - console base address 142 * Out : return -1 on error else return 0. 143 * Clobber list : x0, x1 144 * ------------------------------------------------- 145 */ 146func console_spe_core_flush 147 cbz x0, flush_error 148 149 /* flush console */ 150 mov w1, #CONSOLE_WRITE 151 str w1, [x0] 152 mov w0, #0 153 ret 154flush_error: 155 mov w0, #-1 156 ret 157endfunc console_spe_core_flush 158 159 /* --------------------------------------------- 160 * int console_spe_flush(console_spe_t *console) 161 * Function to force a write of all buffered 162 * data that hasn't been output. 163 * In : x0 - pointer to console_t structure 164 * Out : return -1 on error else return 0. 165 * Clobber list : x0, x1 166 * --------------------------------------------- 167 */ 168func console_spe_flush 169 ldr x0, [x0, #CONSOLE_T_DRVDATA] 170 b console_spe_core_flush 171endfunc console_spe_flush 172