xref: /rk3399_ARM-atf/drivers/cadence/uart/aarch64/cdns_console.S (revision 38ba8e9327a3911e8a24ada75346c0765ffffba1)
19c94d3b3SSoby Mathew/*
2ad4c2ec6SAntonio Nino Diaz * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
39c94d3b3SSoby Mathew *
482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause
59c94d3b3SSoby Mathew */
69c94d3b3SSoby Mathew#include <arch.h>
79c94d3b3SSoby Mathew#include <asm_macros.S>
8*38ba8e93SJulius Werner#include <assert_macros.S>
99c94d3b3SSoby Mathew#include <cadence/cdns_uart.h>
109c94d3b3SSoby Mathew
11*38ba8e93SJulius Werner	/*
12*38ba8e93SJulius Werner	 * "core" functions are low-level implementations that don't require
13*38ba8e93SJulius Werner	 * writable memory and are thus safe to call in BL1 crash context.
14*38ba8e93SJulius Werner	 */
15*38ba8e93SJulius Werner	.globl console_cdns_core_init
16*38ba8e93SJulius Werner	.globl console_cdns_core_putc
17*38ba8e93SJulius Werner	.globl console_cdns_core_getc
18*38ba8e93SJulius Werner
19*38ba8e93SJulius Werner	.globl  console_cdns_putc
20*38ba8e93SJulius Werner	.globl  console_cdns_getc
219c94d3b3SSoby Mathew
229c94d3b3SSoby Mathew	/* -----------------------------------------------
23*38ba8e93SJulius Werner	 * int console_cdns_core_init(uintptr_t base_addr)
249c94d3b3SSoby Mathew	 * Function to initialize the console without a
259c94d3b3SSoby Mathew	 * C Runtime to print debug information. This
269c94d3b3SSoby Mathew	 * function will be accessed by console_init and
279c94d3b3SSoby Mathew	 * crash reporting.
289c94d3b3SSoby Mathew	 * We assume that the bootloader already set up
299c94d3b3SSoby Mathew	 * the HW (baud, ...) and only enable the trans-
309c94d3b3SSoby Mathew	 * mitter and receiver here.
319c94d3b3SSoby Mathew	 * In: x0 - console base address
329c94d3b3SSoby Mathew	 * Out: return 1 on success else 0 on error
339c94d3b3SSoby Mathew	 * Clobber list : x1, x2, x3
349c94d3b3SSoby Mathew	 * -----------------------------------------------
359c94d3b3SSoby Mathew	 */
36*38ba8e93SJulius Wernerfunc console_cdns_core_init
379c94d3b3SSoby Mathew	/* Check the input base address */
389c94d3b3SSoby Mathew	cbz	x0, core_init_fail
399c94d3b3SSoby Mathew
409c94d3b3SSoby Mathew	/* RX/TX enabled & reset */
419c94d3b3SSoby Mathew	mov	w3, #(R_UART_CR_TX_EN | R_UART_CR_RX_EN | R_UART_CR_TXRST | R_UART_CR_RXRST)
429c94d3b3SSoby Mathew	str	w3, [x0, #R_UART_CR]
439c94d3b3SSoby Mathew
449c94d3b3SSoby Mathew	mov	w0, #1
459c94d3b3SSoby Mathew	ret
469c94d3b3SSoby Mathewcore_init_fail:
479c94d3b3SSoby Mathew	mov	w0, wzr
489c94d3b3SSoby Mathew	ret
49*38ba8e93SJulius Wernerendfunc console_cdns_core_init
50*38ba8e93SJulius Werner
51*38ba8e93SJulius Werner#if MULTI_CONSOLE_API
52*38ba8e93SJulius Werner	.globl console_cdns_register
53*38ba8e93SJulius Werner
54*38ba8e93SJulius Werner	/* -----------------------------------------------
55*38ba8e93SJulius Werner	 * int console_cdns_register(console_cdns_t *console,
56*38ba8e93SJulius Werner		uintptr_t base, uint32_t clk, uint32_t baud)
57*38ba8e93SJulius Werner	 * Function to initialize and register a new CDNS
58*38ba8e93SJulius Werner	 * console. Storage passed in for the console struct
59*38ba8e93SJulius Werner	 * *must* be persistent (i.e. not from the stack).
60*38ba8e93SJulius Werner	 * In: x0 - UART register base address
61*38ba8e93SJulius Werner	 *     x1 - pointer to empty console_cdns_t struct
62*38ba8e93SJulius Werner	 * Out: return 1 on success, 0 on error
63*38ba8e93SJulius Werner	 * Clobber list : x0, x1, x2, x6, x7, x14
64*38ba8e93SJulius Werner	 * -----------------------------------------------
65*38ba8e93SJulius Werner	 */
66*38ba8e93SJulius Wernerfunc console_cdns_register
67*38ba8e93SJulius Werner	mov	x7, x30
68*38ba8e93SJulius Werner	mov	x6, x1
69*38ba8e93SJulius Werner	cbz	x6, register_fail
70*38ba8e93SJulius Werner	str	x0, [x6, #CONSOLE_T_CDNS_BASE]
71*38ba8e93SJulius Werner
72*38ba8e93SJulius Werner	bl	console_cdns_core_init
73*38ba8e93SJulius Werner	cbz	x0, register_fail
74*38ba8e93SJulius Werner
75*38ba8e93SJulius Werner	mov	x0, x6
76*38ba8e93SJulius Werner	mov	x30, v7
77*38ba8e93SJulius Werner	finish_console_register cdns
78*38ba8e93SJulius Werner
79*38ba8e93SJulius Wernerregister_fail:
80*38ba8e93SJulius Werner	ret	x7
81*38ba8e93SJulius Wernerendfunc console_cdns_register
82*38ba8e93SJulius Werner#else
83*38ba8e93SJulius Werner	.globl console_core_init
84*38ba8e93SJulius Werner	.globl console_core_putc
85*38ba8e93SJulius Werner	.globl console_core_getc
86*38ba8e93SJulius Werner	.globl console_core_flush
87*38ba8e93SJulius Werner	.equ console_core_init,console_cdns_core_init
88*38ba8e93SJulius Werner	.equ console_core_putc,console_cdns_core_putc
89*38ba8e93SJulius Werner	.equ console_core_getc,console_cdns_core_getc
90*38ba8e93SJulius Werner#endif
919c94d3b3SSoby Mathew
929c94d3b3SSoby Mathew	/* --------------------------------------------------------
93*38ba8e93SJulius Werner	 * int console_cdns_core_putc(int c, uintptr_t base_addr)
949c94d3b3SSoby Mathew	 * Function to output a character over the console. It
959c94d3b3SSoby Mathew	 * returns the character printed on success or -1 on error.
969c94d3b3SSoby Mathew	 * In : w0 - character to be printed
979c94d3b3SSoby Mathew	 *      x1 - console base address
989c94d3b3SSoby Mathew	 * Out : return -1 on error else return character.
999c94d3b3SSoby Mathew	 * Clobber list : x2
1009c94d3b3SSoby Mathew	 * --------------------------------------------------------
1019c94d3b3SSoby Mathew	 */
102*38ba8e93SJulius Wernerfunc console_cdns_core_putc
103*38ba8e93SJulius Werner#if ENABLE_ASSERTIONS
104*38ba8e93SJulius Werner	cmp	x1, #0
105*38ba8e93SJulius Werner	ASM_ASSERT(ne)
106*38ba8e93SJulius Werner#endif /* ENABLE_ASSERTIONS */
107*38ba8e93SJulius Werner
1089c94d3b3SSoby Mathew	/* Prepend '\r' to '\n' */
1099c94d3b3SSoby Mathew	cmp	w0, #0xA
1109c94d3b3SSoby Mathew	b.ne	2f
1119c94d3b3SSoby Mathew1:
1129c94d3b3SSoby Mathew	/* Check if the transmit FIFO is full */
1139c94d3b3SSoby Mathew	ldr	w2, [x1, #R_UART_SR]
1149c94d3b3SSoby Mathew	tbnz	w2, #UART_SR_INTR_TFUL_BIT, 1b
1159c94d3b3SSoby Mathew	mov	w2, #0xD
1169c94d3b3SSoby Mathew	str	w2, [x1, #R_UART_TX]
1179c94d3b3SSoby Mathew2:
1189c94d3b3SSoby Mathew	/* Check if the transmit FIFO is full */
1199c94d3b3SSoby Mathew	ldr	w2, [x1, #R_UART_SR]
1209c94d3b3SSoby Mathew	tbnz	w2, #UART_SR_INTR_TFUL_BIT, 2b
1219c94d3b3SSoby Mathew	str	w0, [x1, #R_UART_TX]
1229c94d3b3SSoby Mathew	ret
123*38ba8e93SJulius Wernerendfunc console_cdns_core_putc
124*38ba8e93SJulius Werner
125*38ba8e93SJulius Werner	/* --------------------------------------------------------
126*38ba8e93SJulius Werner	 * int console_cdns_putc(int c, console_cdns_t *cdns)
127*38ba8e93SJulius Werner	 * Function to output a character over the console. It
128*38ba8e93SJulius Werner	 * returns the character printed on success or -1 on error.
129*38ba8e93SJulius Werner	 * In : w0 - character to be printed
130*38ba8e93SJulius Werner	 *      x1 - pointer to console_t structure
131*38ba8e93SJulius Werner	 * Out : return -1 on error else return character.
132*38ba8e93SJulius Werner	 * Clobber list : x2
133*38ba8e93SJulius Werner	 * --------------------------------------------------------
134*38ba8e93SJulius Werner	 */
135*38ba8e93SJulius Wernerfunc console_cdns_putc
136*38ba8e93SJulius Werner#if ENABLE_ASSERTIONS
137*38ba8e93SJulius Werner	cmp	x1, #0
138*38ba8e93SJulius Werner	ASM_ASSERT(ne)
139*38ba8e93SJulius Werner#endif /* ENABLE_ASSERTIONS */
140*38ba8e93SJulius Werner	ldr	x1, [x1, #CONSOLE_T_CDNS_BASE]
141*38ba8e93SJulius Werner	b	console_cdns_core_putc
142*38ba8e93SJulius Wernerendfunc console_cdns_putc
1439c94d3b3SSoby Mathew
1449c94d3b3SSoby Mathew	/* ---------------------------------------------
145*38ba8e93SJulius Werner	 * int console_cdns_core_getc(uintptr_t base_addr)
1469c94d3b3SSoby Mathew	 * Function to get a character from the console.
1479c94d3b3SSoby Mathew	 * It returns the character grabbed on success
148*38ba8e93SJulius Werner	 * or -1 if no character is available.
1499c94d3b3SSoby Mathew	 * In : x0 - console base address
150*38ba8e93SJulius Werner	 * Out: w0 - character if available, else -1
1519c94d3b3SSoby Mathew	 * Clobber list : x0, x1
1529c94d3b3SSoby Mathew	 * ---------------------------------------------
1539c94d3b3SSoby Mathew	 */
154*38ba8e93SJulius Wernerfunc console_cdns_core_getc
155*38ba8e93SJulius Werner#if ENABLE_ASSERTIONS
156*38ba8e93SJulius Werner	cmp	x0, #0
157*38ba8e93SJulius Werner	ASM_ASSERT(ne)
158*38ba8e93SJulius Werner#endif /* ENABLE_ASSERTIONS */
159*38ba8e93SJulius Werner
1609c94d3b3SSoby Mathew	/* Check if the receive FIFO is empty */
1619c94d3b3SSoby Mathew	ldr	w1, [x0, #R_UART_SR]
162*38ba8e93SJulius Werner	tbnz	w1, #UART_SR_INTR_REMPTY_BIT, no_char
1639c94d3b3SSoby Mathew	ldr	w1, [x0, #R_UART_RX]
1649c94d3b3SSoby Mathew	mov	w0, w1
1659c94d3b3SSoby Mathew	ret
166*38ba8e93SJulius Wernerno_char:
167*38ba8e93SJulius Werner	mov	w0, #ERROR_NO_PENDING_CHAR
1689c94d3b3SSoby Mathew	ret
169*38ba8e93SJulius Wernerendfunc console_cdns_core_getc
170*38ba8e93SJulius Werner
171*38ba8e93SJulius Werner	/* ---------------------------------------------
172*38ba8e93SJulius Werner	 * int console_cdns_getc(console_cdns_t *console)
173*38ba8e93SJulius Werner	 * Function to get a character from the console.
174*38ba8e93SJulius Werner	 * It returns the character grabbed on success
175*38ba8e93SJulius Werner	 * or -1 if no character is available.
176*38ba8e93SJulius Werner	 * In : x0 - pointer to console_t structure
177*38ba8e93SJulius Werner	 * Out: w0 - character if available, else -1
178*38ba8e93SJulius Werner	 * Clobber list : x0, x1
179*38ba8e93SJulius Werner	 * ---------------------------------------------
180*38ba8e93SJulius Werner	 */
181*38ba8e93SJulius Wernerfunc console_cdns_getc
182*38ba8e93SJulius Werner#if ENABLE_ASSERTIONS
183*38ba8e93SJulius Werner	cmp	x0, #0
184*38ba8e93SJulius Werner	ASM_ASSERT(ne)
185*38ba8e93SJulius Werner#endif /* ENABLE_ASSERTIONS */
186*38ba8e93SJulius Werner	ldr	x0, [x0, #CONSOLE_T_CDNS_BASE]
187*38ba8e93SJulius Werner	b	console_cdns_core_getc
188*38ba8e93SJulius Wernerendfunc console_cdns_getc
189ad4c2ec6SAntonio Nino Diaz
190ad4c2ec6SAntonio Nino Diaz	/* ---------------------------------------------
191ad4c2ec6SAntonio Nino Diaz	 * int console_core_flush(uintptr_t base_addr)
192*38ba8e93SJulius Werner	 * DEPRECATED: Not used with MULTI_CONSOLE_API!
193ad4c2ec6SAntonio Nino Diaz	 * Function to force a write of all buffered
194ad4c2ec6SAntonio Nino Diaz	 * data that hasn't been output.
195ad4c2ec6SAntonio Nino Diaz	 * In : x0 - console base address
196ad4c2ec6SAntonio Nino Diaz	 * Out : return -1 on error else return 0.
197ad4c2ec6SAntonio Nino Diaz	 * Clobber list : x0, x1
198ad4c2ec6SAntonio Nino Diaz	 * ---------------------------------------------
199ad4c2ec6SAntonio Nino Diaz	 */
200ad4c2ec6SAntonio Nino Diazfunc console_core_flush
201ad4c2ec6SAntonio Nino Diaz	/* Placeholder */
202ad4c2ec6SAntonio Nino Diaz	mov	w0, #0
203ad4c2ec6SAntonio Nino Diaz	ret
204ad4c2ec6SAntonio Nino Diazendfunc console_core_flush
205