blob: ecd494ca7424052fe13105241f27349bc12f2092 [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>
Konstantin Porotchkind8e39572018-11-14 17:15:08 +020010#include <console_macros.S>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000011#include <drivers/marvell/uart/a3700_console.h>
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +030012
Konstantin Porotchkind8e39572018-11-14 17:15:08 +020013 /*
14 * "core" functions are low-level implementations that don't require
15 * writable memory and are thus safe to call in BL1 crash context.
16 */
17 .globl console_a3700_core_putc
18 .globl console_a3700_core_init
19 .globl console_a3700_core_getc
20 .globl console_a3700_core_flush
21
22 .globl console_a3700_putc
23 .globl console_a3700_getc
24 .globl console_a3700_flush
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +030025
26 /* -----------------------------------------------
Konstantin Porotchkind8e39572018-11-14 17:15:08 +020027 * int console_a3700_core_init(unsigned long base_addr,
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +030028 * unsigned int uart_clk, unsigned int baud_rate)
29 * Function to initialize the console without a
30 * C Runtime to print debug information. This
31 * function will be accessed by console_init and
32 * crash reporting.
33 * In: x0 - console base address
34 * w1 - Uart clock in Hz
35 * w2 - Baud rate
36 * Out: return 1 on success
37 * Clobber list : x1, x2, x3
38 * -----------------------------------------------
39 */
Konstantin Porotchkind8e39572018-11-14 17:15:08 +020040func console_a3700_core_init
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +030041 /* Check the input base address */
42 cbz x0, init_fail
43 /* Check baud rate and uart clock for sanity */
44 cbz w1, init_fail
45 cbz w2, init_fail
46
47 /* Program the baudrate */
48 /* Divisor = Uart clock / (16 * baudrate) */
49 lsl w2, w2, #4
50 udiv w2, w1, w2
51 and w2, w2, #0x3ff
52
53 ldr w3, [x0, #UART_BAUD_REG]
54 bic w3, w3, 0x3ff
55 orr w3, w3, w2
56 str w3, [x0, #UART_BAUD_REG]/* set baud rate divisor */
57
58 /* Set UART to default 16X scheme */
59 mov w3, #0
60 str w3, [x0, #UART_POSSR_REG]
61
62 /*
63 * Wait for the TX FIFO to be empty. If wait for 20ms, the TX FIFO is
64 * still not empty, TX FIFO will reset by all means.
65 */
66 mov w1, #20 /* max time out 20ms */
672:
68 /* Check whether TX FIFO is empty */
69 ldr w3, [x0, #UART_STATUS_REG]
70 and w3, w3, #UARTLSR_TXFIFOEMPTY
71 cmp w3, #0
72 b.ne 4f
73
74 /* Delay */
75 mov w2, #30000
763:
77 sub w2, w2, #1
78 cmp w2, #0
79 b.ne 3b
80
81 /* Check whether 10ms is waited */
82 sub w1, w1, #1
83 cmp w1, #0
84 b.ne 2b
85
864:
87 /* Reset FIFO */
88 mov w3, #UART_CTRL_RXFIFO_RESET
89 orr w3, w3, #UART_CTRL_TXFIFO_RESET
90 str w3, [x0, #UART_CTRL_REG]
91
92 /* Delay */
93 mov w2, #2000
941:
95 sub w2, w2, #1
96 cmp w2, #0
97 b.ne 1b
98
99 /* No Parity, 1 Stop */
100 mov w3, #0
101 str w3, [x0, #UART_CTRL_REG]
102
103 mov w0, #1
104 ret
105init_fail:
106 mov w0, #0
107 ret
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200108endfunc console_a3700_core_init
109
110 .globl console_a3700_register
111
112 /* -----------------------------------------------
Andre Przywara0342f402020-01-25 00:58:35 +0000113 * int console_a3700_register(console_t *console,
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200114 uintptr_t base, uint32_t clk, uint32_t baud)
115 * Function to initialize and register a new a3700
116 * console. Storage passed in for the console struct
117 * *must* be persistent (i.e. not from the stack).
118 * In: x0 - UART register base address
119 * w1 - UART clock in Hz
120 * w2 - Baud rate
Andre Przywara0342f402020-01-25 00:58:35 +0000121 * x3 - pointer to empty console_t struct
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200122 * Out: return 1 on success, 0 on error
123 * Clobber list : x0, x1, x2, x6, x7, x14
124 * -----------------------------------------------
125 */
126func console_a3700_register
127 mov x7, x30
128 mov x6, x3
129 cbz x6, register_fail
Andre Przywara0342f402020-01-25 00:58:35 +0000130 str x0, [x6, #CONSOLE_T_BASE]
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200131
132 bl console_a3700_core_init
133 cbz x0, register_fail
134
135 mov x0, x6
136 mov x30, x7
137 finish_console_register a3700, putc=1, getc=1, flush=1
138
139register_fail:
140 ret x7
141endfunc console_a3700_register
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +0300142
143 /* --------------------------------------------------------
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200144 * int console_a3700_core_putc(int c, unsigned int base_addr)
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +0300145 * Function to output a character over the console. It
146 * returns the character printed on success or -1 on error.
147 * In : w0 - character to be printed
148 * x1 - console base address
149 * Out : return -1 on error else return character.
150 * Clobber list : x2
151 * --------------------------------------------------------
152 */
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200153func console_a3700_core_putc
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +0300154 /* Check the input parameter */
155 cbz x1, putc_error
156
157 /* Prepend '\r' to '\n' */
158 cmp w0, #0xA
159 b.ne 2f
160 /* Check if the transmit FIFO is full */
1611: ldr w2, [x1, #UART_STATUS_REG]
162 and w2, w2, #UARTLSR_TXFIFOFULL
163 cmp w2, #UARTLSR_TXFIFOFULL
164 b.eq 1b
165 mov w2, #0xD /* '\r' */
166 str w2, [x1, #UART_TX_REG]
167
168 /* Check if the transmit FIFO is full */
1692: ldr w2, [x1, #UART_STATUS_REG]
170 and w2, w2, #UARTLSR_TXFIFOFULL
171 cmp w2, #UARTLSR_TXFIFOFULL
172 b.eq 2b
173 str w0, [x1, #UART_TX_REG]
174 ret
175putc_error:
176 mov w0, #-1
177 ret
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200178endfunc console_a3700_core_putc
179
180 /* --------------------------------------------------------
Andre Przywara0342f402020-01-25 00:58:35 +0000181 * int console_a3700_putc(int c, console_t *console)
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200182 * Function to output a character over the console. It
183 * returns the character printed on success or -1 on error.
184 * In : w0 - character to be printed
185 * x1 - pointer to console_t structure
186 * Out : return -1 on error else return character.
187 * Clobber list : x2
188 * --------------------------------------------------------
189 */
190func console_a3700_putc
Andre Przywara0342f402020-01-25 00:58:35 +0000191 ldr x1, [x1, #CONSOLE_T_BASE]
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200192 b console_a3700_core_putc
193endfunc console_a3700_putc
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +0300194
195 /* ---------------------------------------------
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200196 * int console_a3700_core_getc(void)
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +0300197 * Function to get a character from the console.
198 * It returns the character grabbed on success
199 * or -1 on error.
200 * In : w0 - console base address
201 * Out : return -1 on error else return character.
202 * Clobber list : x0, x1
203 * ---------------------------------------------
204 */
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200205func console_a3700_core_getc
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +0300206 mov w0, #-1
207 ret
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200208endfunc console_a3700_core_getc
209
210 /* ---------------------------------------------
Andre Przywara0342f402020-01-25 00:58:35 +0000211 * int console_a3700_getc(console_t *console)
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200212 * Function to get a character from the console.
213 * It returns the character grabbed on success
214 * or -1 on if no character is available.
215 * In : x0 - pointer to console_t structure
216 * Out : w0 - character if available, else -1
217 * Clobber list : x0, x1
218 * ---------------------------------------------
219 */
220func console_a3700_getc
Andre Przywara0342f402020-01-25 00:58:35 +0000221 ldr x0, [x0, #CONSOLE_T_BASE]
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200222 b console_a3700_core_getc
223endfunc console_a3700_getc
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +0300224
225 /* ---------------------------------------------
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200226 * int console_a3700_core_flush(uintptr_t base_addr)
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +0300227 * Function to force a write of all buffered
228 * data that hasn't been output.
229 * In : x0 - console base address
230 * Out : return -1 on error else return 0.
231 * Clobber list : x0, x1
232 * ---------------------------------------------
233 */
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200234func console_a3700_core_flush
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +0300235 mov w0, #0
236 ret
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200237endfunc console_a3700_core_flush
238
239 /* ---------------------------------------------
Andre Przywara0342f402020-01-25 00:58:35 +0000240 * int console_a3700_flush(console_t *console)
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200241 * Function to force a write of all buffered
242 * data that hasn't been output.
243 * In : x0 - pointer to console_t structure
244 * Out : return -1 on error else return 0.
245 * Clobber list : x0, x1
246 * ---------------------------------------------
247 */
248func console_a3700_flush
Andre Przywara0342f402020-01-25 00:58:35 +0000249 ldr x0, [x0, #CONSOLE_T_BASE]
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200250 b console_a3700_core_flush
251endfunc console_a3700_flush
252