blob: 25c21cfcd8e1491ed86fc5647a15aa9d0c213e48 [file] [log] [blame]
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +03001/*
2 * Copyright (C) 2016 Marvell International Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 * https://spdx.org/licenses
6 */
7
Konstantin Porotchkind8e39572018-11-14 17:15:08 +02008#include <arch.h>
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +03009#include <asm_macros.S>
10#include <a3700_console.h>
Konstantin Porotchkind8e39572018-11-14 17:15:08 +020011#define USE_FINISH_CONSOLE_REG_2
12#include <console_macros.S>
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +030013
Konstantin Porotchkind8e39572018-11-14 17:15:08 +020014 /*
15 * "core" functions are low-level implementations that don't require
16 * writable memory and are thus safe to call in BL1 crash context.
17 */
18 .globl console_a3700_core_putc
19 .globl console_a3700_core_init
20 .globl console_a3700_core_getc
21 .globl console_a3700_core_flush
22
23 .globl console_a3700_putc
24 .globl console_a3700_getc
25 .globl console_a3700_flush
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +030026
27 /* -----------------------------------------------
Konstantin Porotchkind8e39572018-11-14 17:15:08 +020028 * int console_a3700_core_init(unsigned long base_addr,
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +030029 * unsigned int uart_clk, unsigned int baud_rate)
30 * Function to initialize the console without a
31 * C Runtime to print debug information. This
32 * function will be accessed by console_init and
33 * crash reporting.
34 * In: x0 - console base address
35 * w1 - Uart clock in Hz
36 * w2 - Baud rate
37 * Out: return 1 on success
38 * Clobber list : x1, x2, x3
39 * -----------------------------------------------
40 */
Konstantin Porotchkind8e39572018-11-14 17:15:08 +020041func console_a3700_core_init
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +030042 /* Check the input base address */
43 cbz x0, init_fail
44 /* Check baud rate and uart clock for sanity */
45 cbz w1, init_fail
46 cbz w2, init_fail
47
48 /* Program the baudrate */
49 /* Divisor = Uart clock / (16 * baudrate) */
50 lsl w2, w2, #4
51 udiv w2, w1, w2
52 and w2, w2, #0x3ff
53
54 ldr w3, [x0, #UART_BAUD_REG]
55 bic w3, w3, 0x3ff
56 orr w3, w3, w2
57 str w3, [x0, #UART_BAUD_REG]/* set baud rate divisor */
58
59 /* Set UART to default 16X scheme */
60 mov w3, #0
61 str w3, [x0, #UART_POSSR_REG]
62
63 /*
64 * Wait for the TX FIFO to be empty. If wait for 20ms, the TX FIFO is
65 * still not empty, TX FIFO will reset by all means.
66 */
67 mov w1, #20 /* max time out 20ms */
682:
69 /* Check whether TX FIFO is empty */
70 ldr w3, [x0, #UART_STATUS_REG]
71 and w3, w3, #UARTLSR_TXFIFOEMPTY
72 cmp w3, #0
73 b.ne 4f
74
75 /* Delay */
76 mov w2, #30000
773:
78 sub w2, w2, #1
79 cmp w2, #0
80 b.ne 3b
81
82 /* Check whether 10ms is waited */
83 sub w1, w1, #1
84 cmp w1, #0
85 b.ne 2b
86
874:
88 /* Reset FIFO */
89 mov w3, #UART_CTRL_RXFIFO_RESET
90 orr w3, w3, #UART_CTRL_TXFIFO_RESET
91 str w3, [x0, #UART_CTRL_REG]
92
93 /* Delay */
94 mov w2, #2000
951:
96 sub w2, w2, #1
97 cmp w2, #0
98 b.ne 1b
99
100 /* No Parity, 1 Stop */
101 mov w3, #0
102 str w3, [x0, #UART_CTRL_REG]
103
104 mov w0, #1
105 ret
106init_fail:
107 mov w0, #0
108 ret
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200109endfunc console_a3700_core_init
110
111 .globl console_a3700_register
112
113 /* -----------------------------------------------
114 * int console_a3700_register(console_16550_t *console,
115 uintptr_t base, uint32_t clk, uint32_t baud)
116 * Function to initialize and register a new a3700
117 * console. Storage passed in for the console struct
118 * *must* be persistent (i.e. not from the stack).
119 * In: x0 - UART register base address
120 * w1 - UART clock in Hz
121 * w2 - Baud rate
122 * x3 - pointer to empty console_a3700_t struct
123 * Out: return 1 on success, 0 on error
124 * Clobber list : x0, x1, x2, x6, x7, x14
125 * -----------------------------------------------
126 */
127func console_a3700_register
128 mov x7, x30
129 mov x6, x3
130 cbz x6, register_fail
131 str x0, [x6, #CONSOLE_T_A3700_BASE]
132
133 bl console_a3700_core_init
134 cbz x0, register_fail
135
136 mov x0, x6
137 mov x30, x7
138 finish_console_register a3700, putc=1, getc=1, flush=1
139
140register_fail:
141 ret x7
142endfunc console_a3700_register
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +0300143
144 /* --------------------------------------------------------
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200145 * int console_a3700_core_putc(int c, unsigned int base_addr)
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +0300146 * Function to output a character over the console. It
147 * returns the character printed on success or -1 on error.
148 * In : w0 - character to be printed
149 * x1 - console base address
150 * Out : return -1 on error else return character.
151 * Clobber list : x2
152 * --------------------------------------------------------
153 */
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200154func console_a3700_core_putc
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +0300155 /* Check the input parameter */
156 cbz x1, putc_error
157
158 /* Prepend '\r' to '\n' */
159 cmp w0, #0xA
160 b.ne 2f
161 /* Check if the transmit FIFO is full */
1621: ldr w2, [x1, #UART_STATUS_REG]
163 and w2, w2, #UARTLSR_TXFIFOFULL
164 cmp w2, #UARTLSR_TXFIFOFULL
165 b.eq 1b
166 mov w2, #0xD /* '\r' */
167 str w2, [x1, #UART_TX_REG]
168
169 /* Check if the transmit FIFO is full */
1702: ldr w2, [x1, #UART_STATUS_REG]
171 and w2, w2, #UARTLSR_TXFIFOFULL
172 cmp w2, #UARTLSR_TXFIFOFULL
173 b.eq 2b
174 str w0, [x1, #UART_TX_REG]
175 ret
176putc_error:
177 mov w0, #-1
178 ret
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200179endfunc console_a3700_core_putc
180
181 /* --------------------------------------------------------
182 * int console_a3700_putc(int c, console_a3700_t *console)
183 * Function to output a character over the console. It
184 * returns the character printed on success or -1 on error.
185 * In : w0 - character to be printed
186 * x1 - pointer to console_t structure
187 * Out : return -1 on error else return character.
188 * Clobber list : x2
189 * --------------------------------------------------------
190 */
191func console_a3700_putc
192 ldr x1, [x1, #CONSOLE_T_A3700_BASE]
193 b console_a3700_core_putc
194endfunc console_a3700_putc
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +0300195
196 /* ---------------------------------------------
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200197 * int console_a3700_core_getc(void)
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +0300198 * Function to get a character from the console.
199 * It returns the character grabbed on success
200 * or -1 on error.
201 * In : w0 - console base address
202 * Out : return -1 on error else return character.
203 * Clobber list : x0, x1
204 * ---------------------------------------------
205 */
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200206func console_a3700_core_getc
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +0300207 mov w0, #-1
208 ret
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200209endfunc console_a3700_core_getc
210
211 /* ---------------------------------------------
212 * int console_a3700_getc(console_a3700_t *console)
213 * Function to get a character from the console.
214 * It returns the character grabbed on success
215 * or -1 on if no character is available.
216 * In : x0 - pointer to console_t structure
217 * Out : w0 - character if available, else -1
218 * Clobber list : x0, x1
219 * ---------------------------------------------
220 */
221func console_a3700_getc
222 ldr x0, [x0, #CONSOLE_T_A3700_BASE]
223 b console_a3700_core_getc
224endfunc console_a3700_getc
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +0300225
226 /* ---------------------------------------------
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200227 * int console_a3700_core_flush(uintptr_t base_addr)
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +0300228 * Function to force a write of all buffered
229 * data that hasn't been output.
230 * In : x0 - console base address
231 * Out : return -1 on error else return 0.
232 * Clobber list : x0, x1
233 * ---------------------------------------------
234 */
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200235func console_a3700_core_flush
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +0300236 mov w0, #0
237 ret
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200238endfunc console_a3700_core_flush
239
240 /* ---------------------------------------------
241 * int console_a3700_flush(console_a3700_t *console)
242 * Function to force a write of all buffered
243 * data that hasn't been output.
244 * In : x0 - pointer to console_t structure
245 * Out : return -1 on error else return 0.
246 * Clobber list : x0, x1
247 * ---------------------------------------------
248 */
249func console_a3700_flush
250 ldr x0, [x0, #CONSOLE_T_A3700_BASE]
251 b console_a3700_core_flush
252endfunc console_a3700_flush
253