xref: /rk3399_ARM-atf/drivers/cadence/uart/aarch64/cdns_console.S (revision bf719f66a7f2261b69b397072cec5ad99c573891)
1/*
2 * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6#include <arch.h>
7#include <asm_macros.S>
8#include <assert_macros.S>
9#include <console_macros.S>
10#include <drivers/cadence/cdns_uart.h>
11
12	/*
13	 * "core" functions are low-level implementations that don't require
14	 * writable memory and are thus safe to call in BL1 crash context.
15	 */
16	.globl console_cdns_core_init
17	.globl console_cdns_core_putc
18	.globl console_cdns_core_getc
19	.globl console_cdns_core_flush
20
21	.globl  console_cdns_putc
22	.globl  console_cdns_getc
23	.globl  console_cdns_flush
24
25	/* -----------------------------------------------
26	 * int console_cdns_core_init(uintptr_t base_addr)
27	 * Function to initialize the console without a
28	 * C Runtime to print debug information. This
29	 * function will be accessed by console_init and
30	 * crash reporting.
31	 * We assume that the bootloader already set up
32	 * the HW (baud, ...) and only enable the trans-
33	 * mitter and receiver here.
34	 * In: x0 - console base address
35	 * Out: return 1 on success else 0 on error
36	 * Clobber list : x1, x2, x3
37	 * -----------------------------------------------
38	 */
39func console_cdns_core_init
40	/* Check the input base address */
41	cbz	x0, core_init_fail
42
43	/* RX/TX enabled & reset */
44	mov	w3, #(R_UART_CR_TX_EN | R_UART_CR_RX_EN | R_UART_CR_TXRST | R_UART_CR_RXRST)
45	str	w3, [x0, #R_UART_CR]
46
47	mov	w0, #1
48	ret
49core_init_fail:
50	mov	w0, wzr
51	ret
52endfunc console_cdns_core_init
53
54#if MULTI_CONSOLE_API
55	.globl console_cdns_register
56
57	/* -----------------------------------------------
58	 * int console_cdns_register(uintptr_t baseaddr,
59	 *     uint32_t clock, uint32_t baud,
60	 *     console_cdns_t *console);
61	 * Function to initialize and register a new CDNS
62	 * console. Storage passed in for the console struct
63	 * *must* be persistent (i.e. not from the stack).
64	 * In: x0 - UART register base address
65	 *     w1 - UART clock in Hz
66	 *     w2 - Baud rate
67	 *     x3 - pointer to empty console_16550_t struct
68	 * Out: return 1 on success, 0 on error
69	 * Clobber list : x0, x1, x2, x6, x7, x14
70	 * -----------------------------------------------
71	 */
72func console_cdns_register
73	mov	x7, x30
74	mov	x6, x3
75	cbz	x6, register_fail
76	str	x0, [x6, #CONSOLE_T_CDNS_BASE]
77
78	bl	console_cdns_core_init
79	cbz	x0, register_fail
80
81	mov	x0, x6
82	mov	x30, x7
83	finish_console_register cdns putc=1, getc=1, flush=1
84
85register_fail:
86	ret	x7
87endfunc console_cdns_register
88#else
89	.globl console_core_init
90	.globl console_core_putc
91	.globl console_core_getc
92	.globl console_core_flush
93	.equ console_core_init,console_cdns_core_init
94	.equ console_core_putc,console_cdns_core_putc
95	.equ console_core_getc,console_cdns_core_getc
96	.equ console_core_flush,console_cdns_core_flush
97#endif
98
99	/* --------------------------------------------------------
100	 * int console_cdns_core_putc(int c, uintptr_t base_addr)
101	 * Function to output a character over the console. It
102	 * returns the character printed on success or -1 on error.
103	 * In : w0 - character to be printed
104	 *      x1 - console base address
105	 * Out : return -1 on error else return character.
106	 * Clobber list : x2
107	 * --------------------------------------------------------
108	 */
109func console_cdns_core_putc
110#if ENABLE_ASSERTIONS
111	cmp	x1, #0
112	ASM_ASSERT(ne)
113#endif /* ENABLE_ASSERTIONS */
114
115	/* Prepend '\r' to '\n' */
116	cmp	w0, #0xA
117	b.ne	2f
1181:
119	/* Check if the transmit FIFO is full */
120	ldr	w2, [x1, #R_UART_SR]
121	tbnz	w2, #UART_SR_INTR_TFUL_BIT, 1b
122	mov	w2, #0xD
123	str	w2, [x1, #R_UART_TX]
1242:
125	/* Check if the transmit FIFO is full */
126	ldr	w2, [x1, #R_UART_SR]
127	tbnz	w2, #UART_SR_INTR_TFUL_BIT, 2b
128	str	w0, [x1, #R_UART_TX]
129	ret
130endfunc console_cdns_core_putc
131
132	/* --------------------------------------------------------
133	 * int console_cdns_putc(int c, console_cdns_t *cdns)
134	 * Function to output a character over the console. It
135	 * returns the character printed on success or -1 on error.
136	 * In : w0 - character to be printed
137	 *      x1 - pointer to console_t structure
138	 * Out : return -1 on error else return character.
139	 * Clobber list : x2
140	 * --------------------------------------------------------
141	 */
142func console_cdns_putc
143#if ENABLE_ASSERTIONS
144	cmp	x1, #0
145	ASM_ASSERT(ne)
146#endif /* ENABLE_ASSERTIONS */
147	ldr	x1, [x1, #CONSOLE_T_CDNS_BASE]
148	b	console_cdns_core_putc
149endfunc console_cdns_putc
150
151	/* ---------------------------------------------
152	 * int console_cdns_core_getc(uintptr_t base_addr)
153	 * Function to get a character from the console.
154	 * It returns the character grabbed on success
155	 * or -1 if no character is available.
156	 * In : x0 - console base address
157	 * Out: w0 - character if available, else -1
158	 * Clobber list : x0, x1
159	 * ---------------------------------------------
160	 */
161func console_cdns_core_getc
162#if ENABLE_ASSERTIONS
163	cmp	x0, #0
164	ASM_ASSERT(ne)
165#endif /* ENABLE_ASSERTIONS */
166
167	/* Check if the receive FIFO is empty */
168	ldr	w1, [x0, #R_UART_SR]
169	tbnz	w1, #UART_SR_INTR_REMPTY_BIT, no_char
170	ldr	w1, [x0, #R_UART_RX]
171	mov	w0, w1
172	ret
173no_char:
174	mov	w0, #ERROR_NO_PENDING_CHAR
175	ret
176endfunc console_cdns_core_getc
177
178	/* ---------------------------------------------
179	 * int console_cdns_getc(console_cdns_t *console)
180	 * Function to get a character from the console.
181	 * It returns the character grabbed on success
182	 * or -1 if no character is available.
183	 * In : x0 - pointer to console_t structure
184	 * Out: w0 - character if available, else -1
185	 * Clobber list : x0, x1
186	 * ---------------------------------------------
187	 */
188func console_cdns_getc
189#if ENABLE_ASSERTIONS
190	cmp	x0, #0
191	ASM_ASSERT(ne)
192#endif /* ENABLE_ASSERTIONS */
193	ldr	x0, [x0, #CONSOLE_T_CDNS_BASE]
194	b	console_cdns_core_getc
195endfunc console_cdns_getc
196
197	/* ---------------------------------------------
198	 * int console_cdns_core_flush(uintptr_t base_addr)
199	 * Function to force a write of all buffered
200	 * data that hasn't been output.
201	 * In : x0 - console base address
202	 * Out : return -1 on error else return 0.
203	 * Clobber list : x0, x1
204	 * ---------------------------------------------
205	 */
206func console_cdns_core_flush
207#if ENABLE_ASSERTIONS
208	cmp	x0, #0
209	ASM_ASSERT(ne)
210#endif /* ENABLE_ASSERTIONS */
211	/* Placeholder */
212	mov	w0, #0
213	ret
214endfunc console_cdns_core_flush
215
216	/* ---------------------------------------------
217	 * int console_cdns_flush(console_pl011_t *console)
218	 * Function to force a write of all buffered
219	 * data that hasn't been output.
220	 * In : x0 - pointer to console_t structure
221	 * Out : return -1 on error else return 0.
222	 * Clobber list : x0, x1
223	 * ---------------------------------------------
224	 */
225func console_cdns_flush
226#if ENABLE_ASSERTIONS
227	cmp	x0, #0
228	ASM_ASSERT(ne)
229#endif /* ENABLE_ASSERTIONS */
230	ldr	x0, [x0, #CONSOLE_T_CDNS_BASE]
231	b	console_cdns_core_flush
232endfunc console_cdns_flush
233