xref: /rk3399_ARM-atf/drivers/st/uart/aarch32/stm32_console.S (revision 8244d2260da69e49e97a6d19aa18c84b4da0a3e4)
14353bb20SYann Gautier/*
24353bb20SYann Gautier * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
34353bb20SYann Gautier *
44353bb20SYann Gautier * SPDX-License-Identifier: BSD-3-Clause
54353bb20SYann Gautier */
64353bb20SYann Gautier#include <asm_macros.S>
7*8244d226SYann Gautier#include <stm32_uart_regs.h>
84353bb20SYann Gautier
9278c34dfSYann Gautier#define USART_TIMEOUT		0x1000
10278c34dfSYann Gautier
114353bb20SYann Gautier	.globl	console_core_init
124353bb20SYann Gautier	.globl	console_core_putc
134353bb20SYann Gautier	.globl	console_core_getc
144353bb20SYann Gautier	.globl	console_core_flush
154353bb20SYann Gautier
164353bb20SYann Gautier	/* -----------------------------------------------------------------
174353bb20SYann Gautier	 * int console_core_init(uintptr_t base_addr,
184353bb20SYann Gautier	 *			 unsigned int uart_clk,
194353bb20SYann Gautier	 *			 unsigned int baud_rate)
204353bb20SYann Gautier	 *
214353bb20SYann Gautier	 * Function to initialize the console without a C Runtime to print
224353bb20SYann Gautier	 * debug information. This function will be accessed by console_init
234353bb20SYann Gautier	 * and crash reporting.
244353bb20SYann Gautier	 *
254353bb20SYann Gautier	 * In: r0 - console base address
264353bb20SYann Gautier	 *     r1 - Uart clock in Hz
274353bb20SYann Gautier	 *     r2 - Baud rate
284353bb20SYann Gautier	 * Out: return 1 on success else 0 on error
294353bb20SYann Gautier	 * Clobber list : r1, r2, r3
304353bb20SYann Gautier	 * -----------------------------------------------------------------
314353bb20SYann Gautier	 */
324353bb20SYann Gautierfunc console_core_init
33278c34dfSYann Gautier	/* Check the input base address */
34278c34dfSYann Gautier	cmp	r0, #0
35278c34dfSYann Gautier	beq	core_init_fail
36278c34dfSYann Gautier#if defined(IMAGE_BL2)
37278c34dfSYann Gautier	/* Check baud rate and uart clock for sanity */
38278c34dfSYann Gautier	cmp	r1, #0
39278c34dfSYann Gautier	beq	core_init_fail
40278c34dfSYann Gautier	cmp	r2, #0
41278c34dfSYann Gautier	beq	core_init_fail
42278c34dfSYann Gautier	/* Disable UART */
43278c34dfSYann Gautier	ldr	r3, [r0, #USART_CR1]
44278c34dfSYann Gautier	bic	r3, r3, #USART_CR1_UE
45278c34dfSYann Gautier	str	r3, [r0, #USART_CR1]
46278c34dfSYann Gautier	/* Configure UART */
47278c34dfSYann Gautier	orr	r3, r3, #(USART_CR1_TE | USART_CR1_FIFOEN)
48278c34dfSYann Gautier	str	r3, [r0, #USART_CR1]
49278c34dfSYann Gautier	ldr	r3, [r0, #USART_CR2]
50278c34dfSYann Gautier	bic	r3, r3, #USART_CR2_STOP
51278c34dfSYann Gautier	str	r3, [r0, #USART_CR2]
52278c34dfSYann Gautier	/* Divisor =  (Uart clock + (baudrate / 2)) / baudrate */
53278c34dfSYann Gautier	lsl	r3, r2, #1
54278c34dfSYann Gautier	add	r3, r1, r3
55278c34dfSYann Gautier	udiv	r3, r3, r2
56278c34dfSYann Gautier	str	r3, [r0, #USART_BRR]
57278c34dfSYann Gautier	/* Enable UART */
58278c34dfSYann Gautier	ldr	r3, [r0, #USART_CR1]
59278c34dfSYann Gautier	orr	r3, r3, #USART_CR1_UE
60278c34dfSYann Gautier	str	r3, [r0, #USART_CR1]
61278c34dfSYann Gautier	/* Check TEACK bit */
62278c34dfSYann Gautier	mov	r2, #USART_TIMEOUT
63278c34dfSYann Gautierteack_loop:
64278c34dfSYann Gautier	subs	r2, r2, #1
65278c34dfSYann Gautier	beq	core_init_fail
66278c34dfSYann Gautier	ldr	r3, [r0, #USART_ISR]
67278c34dfSYann Gautier	tst	r3, #USART_ISR_TEACK
68278c34dfSYann Gautier	beq	teack_loop
69278c34dfSYann Gautier#endif /* IMAGE_BL2 */
70278c34dfSYann Gautier	mov	r0, #1
71278c34dfSYann Gautier	bx	lr
72278c34dfSYann Gautiercore_init_fail:
73278c34dfSYann Gautier	mov	r0, #0
744353bb20SYann Gautier	bx	lr
754353bb20SYann Gautierendfunc console_core_init
764353bb20SYann Gautier
774353bb20SYann Gautier	/* ---------------------------------------------------------------
784353bb20SYann Gautier	 * int console_core_putc(int c, uintptr_t base_addr)
794353bb20SYann Gautier	 *
804353bb20SYann Gautier	 * Function to output a character over the console. It returns the
814353bb20SYann Gautier	 * character printed on success or -1 on error.
824353bb20SYann Gautier	 *
834353bb20SYann Gautier	 * In : r0 - character to be printed
844353bb20SYann Gautier	 *      r1 - console base address
854353bb20SYann Gautier	 * Out : return -1 on error else return character.
864353bb20SYann Gautier	 * Clobber list : r2
874353bb20SYann Gautier	 * ---------------------------------------------------------------
884353bb20SYann Gautier	 */
894353bb20SYann Gautierfunc console_core_putc
90278c34dfSYann Gautier	/* Check the input parameter */
91278c34dfSYann Gautier	cmp	r1, #0
92278c34dfSYann Gautier	beq	putc_error
93278c34dfSYann Gautier	/* Prepend '\r' to '\n' */
94278c34dfSYann Gautier	cmp	r0, #0xA
95278c34dfSYann Gautier	bne	2f
96278c34dfSYann Gautier1:
97278c34dfSYann Gautier	/* Check Transmit Data Register Empty */
98278c34dfSYann Gautiertxe_loop_1:
99278c34dfSYann Gautier	ldr	r2, [r1, #USART_ISR]
100278c34dfSYann Gautier	tst	r2, #USART_ISR_TXE
101278c34dfSYann Gautier	beq	txe_loop_1
102278c34dfSYann Gautier	mov	r2, #0xD
103278c34dfSYann Gautier	str	r2, [r1, #USART_TDR]
104278c34dfSYann Gautier	/* Check transmit complete flag */
105278c34dfSYann Gautiertc_loop_1:
106278c34dfSYann Gautier	ldr	r2, [r1, #USART_ISR]
107278c34dfSYann Gautier	tst	r2, #USART_ISR_TC
108278c34dfSYann Gautier	beq	tc_loop_1
109278c34dfSYann Gautier2:
110278c34dfSYann Gautier	/* Check Transmit Data Register Empty */
111278c34dfSYann Gautiertxe_loop_2:
112278c34dfSYann Gautier	ldr	r2, [r1, #USART_ISR]
113278c34dfSYann Gautier	tst	r2, #USART_ISR_TXE
114278c34dfSYann Gautier	beq	txe_loop_2
115278c34dfSYann Gautier	str	r0, [r1, #USART_TDR]
116278c34dfSYann Gautier	/* Check transmit complete flag */
117278c34dfSYann Gautiertc_loop_2:
118278c34dfSYann Gautier	ldr	r2, [r1, #USART_ISR]
119278c34dfSYann Gautier	tst	r2, #USART_ISR_TC
120278c34dfSYann Gautier	beq	tc_loop_2
121278c34dfSYann Gautier	bx	lr
122278c34dfSYann Gautierputc_error:
123278c34dfSYann Gautier	mov	r0, #-1
1244353bb20SYann Gautier	bx	lr
1254353bb20SYann Gautierendfunc console_core_putc
1264353bb20SYann Gautier
1274353bb20SYann Gautier	/* -----------------------------------------------------------
1284353bb20SYann Gautier	 * int console_core_getc(uintptr_t base_addr)
1294353bb20SYann Gautier	 *
1304353bb20SYann Gautier	 * Function to get a character from the console.
1314353bb20SYann Gautier	 * It returns the character grabbed on success or -1 on error.
1324353bb20SYann Gautier	 *
1334353bb20SYann Gautier	 * In : r0 - console base address
1344353bb20SYann Gautier	 * Out : return -1.
1354353bb20SYann Gautier	 * Clobber list : r0, r1
1364353bb20SYann Gautier	 * -----------------------------------------------------------
1374353bb20SYann Gautier	 */
1384353bb20SYann Gautierfunc console_core_getc
1394353bb20SYann Gautier	/* Not supported */
1404353bb20SYann Gautier	mov	r0, #-1
1414353bb20SYann Gautier	bx	lr
1424353bb20SYann Gautierendfunc console_core_getc
1434353bb20SYann Gautier
1444353bb20SYann Gautier	/* ---------------------------------------------------------------
1454353bb20SYann Gautier	 * int console_core_flush(uintptr_t base_addr)
1464353bb20SYann Gautier	 *
1474353bb20SYann Gautier	 * Function to force a write of all buffered data that hasn't been
1484353bb20SYann Gautier	 * output.
1494353bb20SYann Gautier	 *
1504353bb20SYann Gautier	 * In : r0 - console base address
1514353bb20SYann Gautier	 * Out : return -1 on error else return 0.
1524353bb20SYann Gautier	 * Clobber list : r0, r1
1534353bb20SYann Gautier	 * ---------------------------------------------------------------
1544353bb20SYann Gautier	 */
1554353bb20SYann Gautierfunc console_core_flush
156278c34dfSYann Gautier	cmp	r0, #0
157278c34dfSYann Gautier	beq	flush_error
158278c34dfSYann Gautier	/* Check Transmit Data Register Empty */
159278c34dfSYann Gautiertxe_loop_3:
160278c34dfSYann Gautier	ldr	r1, [r0, #USART_ISR]
161278c34dfSYann Gautier	tst	r1, #USART_ISR_TXE
162278c34dfSYann Gautier	beq	txe_loop_3
163278c34dfSYann Gautier	mov	r0, #0
164278c34dfSYann Gautier	bx	lr
165278c34dfSYann Gautierflush_error:
166278c34dfSYann Gautier	mov	r0, #-1
1674353bb20SYann Gautier	bx	lr
1684353bb20SYann Gautierendfunc console_core_flush
169