blob: a8584ef83acfd9a5242065813fe54c69554f3f7b [file] [log] [blame]
Varun Wadekar91535cd2020-03-12 14:32:44 -07001/*
2 * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <asm_macros.S>
8#include <drivers/console.h>
9
10#define CONSOLE_NUM_BYTES_SHIFT 24
11#define CONSOLE_FLUSH_DATA_TO_PORT (1 << 26)
12#define CONSOLE_RING_DOORBELL (1 << 31)
13#define CONSOLE_IS_BUSY (1 << 31)
14#define CONSOLE_TIMEOUT 0xC000 /* 50 ms */
15
16 /*
17 * This file contains a driver implementation to make use of the
18 * real console implementation provided by the SPE firmware running
19 * SoCs after Tegra186.
20 *
21 * This console is shared by multiple components and the SPE firmware
22 * finally displays everything on the UART port.
23 */
24
25 .globl console_init
26 .globl console_putc
27 .globl console_getc
28 .globl console_try_getc
29 .globl console_flush
30
31.macro check_if_console_is_ready base, tmp1, tmp2, label
32 /* wait until spe is ready or timeout expires */
331: ldr \tmp1, [\base]
34 and \tmp1, \tmp1, #CONSOLE_IS_BUSY
35 cbnz \tmp1, 1b
36.endm
37
38 /*
39 * The console base is in the data section and not in .bss
40 * even though it is zero-init. In particular, this allows
41 * the console functions to start using this variable before
42 * the runtime memory is initialized for images which do not
43 * need to copy the .data section from ROM to RAM.
44 */
45 .section .data.console_base
46 .align 3
47console_base:
48 .quad 0x0
49
50 /* -----------------------------------------------
51 * int console_init(uintptr_t base_addr,
52 * unsigned int uart_clk,
53 * unsigned int baud_rate)
54 *
55 * Clobber list : x1 - x3
56 * -----------------------------------------------
57 */
58func console_init
59 /* Check the input base address */
60 cbz x0, register_fail
61
62 /* save base address */
63 adr x3, console_base
64 str x0, [x3]
65
66 /* Dont use clock or baud rate, so ok to overwrite them */
67 check_if_console_is_ready x0, x1, x2, register_fail
68
69register_fail:
70 mov w0, wzr
71 ret
72endfunc console_init
73
74 /* --------------------------------------------------------
75 * int console_spe_core_putc(int c, uintptr_t base_addr)
76 * Function to output a character over the console. It
77 * returns the character printed on success or -1 on error.
78 * In : w0 - character to be printed
79 * x1 - console base address
80 * Out : return -1 on error else return character.
81 * Clobber list : x2, x3
82 * --------------------------------------------------------
83 */
84func console_spe_core_putc
85 /* Check the input parameter */
86 cbz x1, putc_error
87
88 /* Prepend '\r' to '\n' */
89 cmp w0, #0xA
90 b.ne not_eol
91
92 check_if_console_is_ready x1, x2, x3, putc_error
93
94 /* spe is ready */
95 mov w2, #0xD /* '\r' */
96 and w2, w2, #0xFF
97 mov w3, #(CONSOLE_RING_DOORBELL | (1 << CONSOLE_NUM_BYTES_SHIFT))
98 orr w2, w2, w3
99 str w2, [x1]
100
101not_eol:
102 check_if_console_is_ready x1, x2, x3, putc_error
103
104 /* spe is ready */
105 mov w2, w0
106 and w2, w2, #0xFF
107 mov w3, #(CONSOLE_RING_DOORBELL | (1 << CONSOLE_NUM_BYTES_SHIFT))
108 orr w2, w2, w3
109 str w2, [x1]
110
111 ret
112putc_error:
113 mov w0, #-1
114 ret
115endfunc console_spe_core_putc
116
117 /* ---------------------------------------------
118 * int console_putc(int c)
119 *
120 * Clobber list : x1, x2
121 * ---------------------------------------------
122 */
123func console_putc
124 adr x1, console_base
125 ldr x1, [x1]
126 b console_spe_core_putc
127endfunc console_putc
128
129 /* ---------------------------------------------
130 * int console_getc(void)
131 *
132 * Clobber list : x0 - x3
133 * ---------------------------------------------
134 */
135func console_getc
136 mov w0, #-1
137 ret
138endfunc console_getc
139
140 /* ---------------------------------------------
141 * int console_try_getc(void)
142 *
143 * Clobber list : x0, x1
144 * ---------------------------------------------
145 */
146func console_try_getc
147 mov w0, #-1
148 ret
149endfunc console_try_getc
150
151 /* -------------------------------------------------
152 * int console_spe_core_flush(uintptr_t base_addr)
153 * Function to force a write of all buffered
154 * data that hasn't been output.
155 * In : x0 - console base address
156 * Out : return -1 on error else return 0.
157 * Clobber list : x0, x1
158 * -------------------------------------------------
159 */
160func console_spe_core_flush
161 cbz x0, flush_error
162
163 /* flush console */
164 mov w1, #(CONSOLE_RING_DOORBELL | CONSOLE_FLUSH_DATA_TO_PORT)
165 str w1, [x0]
166 mov w0, #0
167 ret
168flush_error:
169 mov w0, #-1
170 ret
171endfunc console_spe_core_flush
172
173 /* ---------------------------------------------
174 * int console_flush(void)
175 *
176 * Clobber list : x0, x1
177 * ---------------------------------------------
178 */
179func console_flush
180 adr x0, console_base
181 ldr x0, [x0]
182 b console_spe_core_flush
183endfunc console_flush