blob: c7eb165e62e4392be0633ab57ea75b7f450485e1 [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
Pali Rohár622d5da2021-11-15 10:51:28 +010037 * Clobber list : x1, x2, x3, x4
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +030038 * -----------------------------------------------
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
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +030047 /*
Pali Rohárc0002962021-02-16 11:56:24 +010048 * Wait for the TX (THR and TSR) to be empty. If wait for 3ms, the TX FIFO is
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +030049 * still not empty, TX FIFO will reset by all means.
50 */
Pali Rohár622d5da2021-11-15 10:51:28 +010051 mov w4, #30 /* max time out 30 * 100 us */
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +0300522:
Pali Rohár10d330f2021-01-18 12:52:55 +010053 /* Check whether TX (THR and TSR) is empty */
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +030054 ldr w3, [x0, #UART_STATUS_REG]
Pali Rohár10d330f2021-01-18 12:52:55 +010055 and w3, w3, #UARTLSR_TXEMPTY
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +030056 cmp w3, #0
57 b.ne 4f
58
59 /* Delay */
Pali Rohár622d5da2021-11-15 10:51:28 +010060 mov w3, #60000 /* 60000 cycles of below 3 instructions on 1200 MHz CPU ~~ 100 us */
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +0300613:
Pali Rohár622d5da2021-11-15 10:51:28 +010062 sub w3, w3, #1
63 cmp w3, #0
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +030064 b.ne 3b
65
Pali Rohár46179c32021-02-16 11:49:11 +010066 /* Check whether wait timeout expired */
Pali Rohár622d5da2021-11-15 10:51:28 +010067 sub w4, w4, #1
68 cmp w4, #0
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +030069 b.ne 2b
70
714:
Pali Rohár82602c92021-11-15 12:24:56 +010072 /* Reset UART via North Bridge Peripheral */
73 mov_imm x4, MVEBU_NB_RESET_REG
74 ldr w3, [x4]
75 bic w3, w3, #MVEBU_NB_RESET_UART_N
76 str w3, [x4]
77 orr w3, w3, #MVEBU_NB_RESET_UART_N
78 str w3, [x4]
79
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +030080 /* Reset FIFO */
81 mov w3, #UART_CTRL_RXFIFO_RESET
82 orr w3, w3, #UART_CTRL_TXFIFO_RESET
83 str w3, [x0, #UART_CTRL_REG]
84
85 /* Delay */
Pali Rohár622d5da2021-11-15 10:51:28 +010086 mov w3, #2000
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +0300871:
Pali Rohár622d5da2021-11-15 10:51:28 +010088 sub w3, w3, #1
89 cmp w3, #0
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +030090 b.ne 1b
91
Pali Rohárf658b892021-11-15 10:53:21 +010092 /* Program the baudrate */
93 /* Divisor = Round(Uartclock / (16 * baudrate)) */
94 lsl w2, w2, #4
95 add w1, w1, w2, lsr #1
96 udiv w2, w1, w2
97 and w2, w2, #0x3ff /* clear all other bits to use default clock */
98
99 str w2, [x0, #UART_BAUD_REG]/* set baud rate divisor */
100
101 /* Set UART to default 16X scheme */
102 mov w3, #0
103 str w3, [x0, #UART_POSSR_REG]
104
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +0300105 /* No Parity, 1 Stop */
106 mov w3, #0
107 str w3, [x0, #UART_CTRL_REG]
108
109 mov w0, #1
110 ret
111init_fail:
112 mov w0, #0
113 ret
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200114endfunc console_a3700_core_init
115
116 .globl console_a3700_register
117
118 /* -----------------------------------------------
Andre Przywara0342f402020-01-25 00:58:35 +0000119 * int console_a3700_register(console_t *console,
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200120 uintptr_t base, uint32_t clk, uint32_t baud)
121 * Function to initialize and register a new a3700
122 * console. Storage passed in for the console struct
123 * *must* be persistent (i.e. not from the stack).
124 * In: x0 - UART register base address
125 * w1 - UART clock in Hz
126 * w2 - Baud rate
Andre Przywara0342f402020-01-25 00:58:35 +0000127 * x3 - pointer to empty console_t struct
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200128 * Out: return 1 on success, 0 on error
Pali Rohár622d5da2021-11-15 10:51:28 +0100129 * Clobber list : x0, x1, x2, x3, x4, x6, x7, x14
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200130 * -----------------------------------------------
131 */
132func console_a3700_register
133 mov x7, x30
134 mov x6, x3
135 cbz x6, register_fail
Andre Przywara0342f402020-01-25 00:58:35 +0000136 str x0, [x6, #CONSOLE_T_BASE]
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200137
138 bl console_a3700_core_init
139 cbz x0, register_fail
140
141 mov x0, x6
142 mov x30, x7
143 finish_console_register a3700, putc=1, getc=1, flush=1
144
145register_fail:
146 ret x7
147endfunc console_a3700_register
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +0300148
149 /* --------------------------------------------------------
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200150 * int console_a3700_core_putc(int c, unsigned int base_addr)
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +0300151 * Function to output a character over the console. It
152 * returns the character printed on success or -1 on error.
153 * In : w0 - character to be printed
154 * x1 - console base address
155 * Out : return -1 on error else return character.
156 * Clobber list : x2
157 * --------------------------------------------------------
158 */
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200159func console_a3700_core_putc
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +0300160 /* Check the input parameter */
161 cbz x1, putc_error
162
163 /* Prepend '\r' to '\n' */
164 cmp w0, #0xA
165 b.ne 2f
166 /* Check if the transmit FIFO is full */
1671: ldr w2, [x1, #UART_STATUS_REG]
168 and w2, w2, #UARTLSR_TXFIFOFULL
169 cmp w2, #UARTLSR_TXFIFOFULL
170 b.eq 1b
171 mov w2, #0xD /* '\r' */
172 str w2, [x1, #UART_TX_REG]
173
174 /* Check if the transmit FIFO is full */
1752: ldr w2, [x1, #UART_STATUS_REG]
176 and w2, w2, #UARTLSR_TXFIFOFULL
177 cmp w2, #UARTLSR_TXFIFOFULL
178 b.eq 2b
179 str w0, [x1, #UART_TX_REG]
180 ret
181putc_error:
182 mov w0, #-1
183 ret
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200184endfunc console_a3700_core_putc
185
186 /* --------------------------------------------------------
Andre Przywara0342f402020-01-25 00:58:35 +0000187 * int console_a3700_putc(int c, console_t *console)
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200188 * Function to output a character over the console. It
189 * returns the character printed on success or -1 on error.
190 * In : w0 - character to be printed
191 * x1 - pointer to console_t structure
192 * Out : return -1 on error else return character.
193 * Clobber list : x2
194 * --------------------------------------------------------
195 */
196func console_a3700_putc
Andre Przywara0342f402020-01-25 00:58:35 +0000197 ldr x1, [x1, #CONSOLE_T_BASE]
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200198 b console_a3700_core_putc
199endfunc console_a3700_putc
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +0300200
201 /* ---------------------------------------------
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200202 * int console_a3700_core_getc(void)
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +0300203 * Function to get a character from the console.
204 * It returns the character grabbed on success
Pali Rohár6291f552021-01-18 12:39:25 +0100205 * or -1 if no character is available.
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +0300206 * In : w0 - console base address
Pali Rohár6291f552021-01-18 12:39:25 +0100207 * Out : w0 - character if available, else -1
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +0300208 * Clobber list : x0, x1
209 * ---------------------------------------------
210 */
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200211func console_a3700_core_getc
Pali Rohár6291f552021-01-18 12:39:25 +0100212 /* Check if there is a pending character */
213 ldr w1, [x0, #UART_STATUS_REG]
214 and w1, w1, #UARTLSR_RXRDY
215 cmp w1, #UARTLSR_RXRDY
216 b.ne getc_no_char
217 ldr w0, [x0, #UART_RX_REG]
218 and w0, w0, #0xff
219 ret
220getc_no_char:
221 mov w0, #ERROR_NO_PENDING_CHAR
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +0300222 ret
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200223endfunc console_a3700_core_getc
224
225 /* ---------------------------------------------
Andre Przywara0342f402020-01-25 00:58:35 +0000226 * int console_a3700_getc(console_t *console)
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200227 * Function to get a character from the console.
228 * It returns the character grabbed on success
229 * or -1 on if no character is available.
230 * In : x0 - pointer to console_t structure
231 * Out : w0 - character if available, else -1
232 * Clobber list : x0, x1
233 * ---------------------------------------------
234 */
235func console_a3700_getc
Andre Przywara0342f402020-01-25 00:58:35 +0000236 ldr x0, [x0, #CONSOLE_T_BASE]
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200237 b console_a3700_core_getc
238endfunc console_a3700_getc
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +0300239
240 /* ---------------------------------------------
Jimmy Brisson39f9eee2020-08-05 13:44:05 -0500241 * void console_a3700_core_flush(uintptr_t base_addr)
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +0300242 * Function to force a write of all buffered
243 * data that hasn't been output.
244 * In : x0 - console base address
Jimmy Brisson39f9eee2020-08-05 13:44:05 -0500245 * Out : void.
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +0300246 * Clobber list : x0, x1
247 * ---------------------------------------------
248 */
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200249func console_a3700_core_flush
Pali Rohár10d330f2021-01-18 12:52:55 +0100250 /* Wait for the TX (THR and TSR) to be empty */
Pali Rohárf758ceb2020-12-23 19:23:26 +01002511: ldr w1, [x0, #UART_STATUS_REG]
Pali Rohár10d330f2021-01-18 12:52:55 +0100252 and w1, w1, #UARTLSR_TXEMPTY
253 cmp w1, #UARTLSR_TXEMPTY
Pali Rohárf758ceb2020-12-23 19:23:26 +0100254 b.ne 1b
Konstantin Porotchkinee4fa952018-10-08 16:50:54 +0300255 ret
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200256endfunc console_a3700_core_flush
257
258 /* ---------------------------------------------
Jimmy Brisson39f9eee2020-08-05 13:44:05 -0500259 * void console_a3700_flush(console_t *console)
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200260 * Function to force a write of all buffered
261 * data that hasn't been output.
262 * In : x0 - pointer to console_t structure
Jimmy Brisson39f9eee2020-08-05 13:44:05 -0500263 * Out : void.
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200264 * Clobber list : x0, x1
265 * ---------------------------------------------
266 */
267func console_a3700_flush
Andre Przywara0342f402020-01-25 00:58:35 +0000268 ldr x0, [x0, #CONSOLE_T_BASE]
Konstantin Porotchkind8e39572018-11-14 17:15:08 +0200269 b console_a3700_core_flush
270endfunc console_a3700_flush
271