xref: /rk3399_ARM-atf/drivers/st/uart/aarch32/stm32_console.S (revision be3991c0c31bda7b07f002d733c65c65655eb9ad)
1/*
2 * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6#include <asm_macros.S>
7#include <assert_macros.S>
8#include <console_macros.S>
9#include <drivers/st/stm32_console.h>
10#include <drivers/st/stm32_uart_regs.h>
11
12#define USART_TIMEOUT		0x1000
13
14	/*
15	 * "core" functions are low-level implementations that don't require
16	 * writeable memory and are thus safe to call in BL1 crash context.
17	 */
18	.globl	console_stm32_core_init
19	.globl	console_stm32_core_putc
20	.globl	console_stm32_core_getc
21	.globl	console_stm32_core_flush
22
23	.globl	console_stm32_putc
24	.globl	console_stm32_flush
25
26
27
28	/* -----------------------------------------------------------------
29	 * int console_core_init(uintptr_t base_addr,
30	 *			 unsigned int uart_clk,
31	 *			 unsigned int baud_rate)
32	 *
33	 * Function to initialize the console without a C Runtime to print
34	 * debug information. This function will be accessed by console_init
35	 * and crash reporting.
36	 *
37	 * In: r0 - console base address
38	 *     r1 - Uart clock in Hz
39	 *     r2 - Baud rate
40	 * Out: return 1 on success else 0 on error
41	 * Clobber list : r1, r2, r3
42	 * -----------------------------------------------------------------
43	 */
44func console_stm32_core_init
45	/* Check the input base address */
46	cmp	r0, #0
47	beq	core_init_fail
48#if defined(IMAGE_BL2)
49	/* Check baud rate and uart clock for sanity */
50	cmp	r1, #0
51	beq	core_init_fail
52	cmp	r2, #0
53	beq	core_init_fail
54	/* Disable UART */
55	ldr	r3, [r0, #USART_CR1]
56	bic	r3, r3, #USART_CR1_UE
57	str	r3, [r0, #USART_CR1]
58	/* Configure UART */
59	orr	r3, r3, #(USART_CR1_TE | USART_CR1_FIFOEN)
60	str	r3, [r0, #USART_CR1]
61	ldr	r3, [r0, #USART_CR2]
62	bic	r3, r3, #USART_CR2_STOP
63	str	r3, [r0, #USART_CR2]
64	/* Divisor =  (Uart clock + (baudrate / 2)) / baudrate */
65	lsl	r3, r2, #1
66	add	r3, r1, r3
67	udiv	r3, r3, r2
68	str	r3, [r0, #USART_BRR]
69	/* Enable UART */
70	ldr	r3, [r0, #USART_CR1]
71	orr	r3, r3, #USART_CR1_UE
72	str	r3, [r0, #USART_CR1]
73	/* Check TEACK bit */
74	mov	r2, #USART_TIMEOUT
75teack_loop:
76	subs	r2, r2, #1
77	beq	core_init_fail
78	ldr	r3, [r0, #USART_ISR]
79	tst	r3, #USART_ISR_TEACK
80	beq	teack_loop
81#endif /* IMAGE_BL2 */
82	mov	r0, #1
83	bx	lr
84core_init_fail:
85	mov	r0, #0
86	bx	lr
87endfunc console_stm32_core_init
88
89	.globl console_stm32_register
90
91	/* -------------------------------------------------------
92	 * int console_stm32_register(uintptr_t baseaddr,
93	 *     uint32_t clock, uint32_t baud,
94	 *     struct console_stm32 *console);
95	 * Function to initialize and register a new STM32
96	 * console. Storage passed in for the console struct
97	 * *must* be persistent (i.e. not from the stack).
98	 * In: r0 - UART register base address
99	 *     r1 - UART clock in Hz
100	 *     r2 - Baud rate
101	 *     r3 - pointer to empty console_stm32 struct
102	 * Out: return 1 on success, 0 on error
103	 * Clobber list : r0, r1, r2
104	 * -------------------------------------------------------
105	 */
106func console_stm32_register
107	push	{r4, lr}
108	mov	r4, r3
109	cmp	r4, #0
110	beq	register_fail
111	str	r0, [r4, #CONSOLE_T_STM32_BASE]
112
113	bl console_stm32_core_init
114	cmp	r0, #0
115	beq	register_fail
116
117	mov	r0, r4
118	pop	{r4, lr}
119	finish_console_register stm32 putc=1, getc=0, flush=1
120
121register_fail:
122	pop	{r4, pc}
123endfunc console_stm32_register
124
125	/* ---------------------------------------------------------------
126	 * int console_core_putc(int c, uintptr_t base_addr)
127	 *
128	 * Function to output a character over the console. It returns the
129	 * character printed on success or -1 on error.
130	 *
131	 * In : r0 - character to be printed
132	 *      r1 - console base address
133	 * Out : return -1 on error else return character.
134	 * Clobber list : r2
135	 * ---------------------------------------------------------------
136	 */
137func console_stm32_core_putc
138	/* Check the input parameter */
139	cmp	r1, #0
140	beq	putc_error
141	/* Prepend '\r' to '\n' */
142	cmp	r0, #0xA
143	bne	2f
1441:
145	/* Check Transmit Data Register Empty */
146txe_loop_1:
147	ldr	r2, [r1, #USART_ISR]
148	tst	r2, #USART_ISR_TXE
149	beq	txe_loop_1
150	mov	r2, #0xD
151	str	r2, [r1, #USART_TDR]
152	/* Check transmit complete flag */
153tc_loop_1:
154	ldr	r2, [r1, #USART_ISR]
155	tst	r2, #USART_ISR_TC
156	beq	tc_loop_1
1572:
158	/* Check Transmit Data Register Empty */
159txe_loop_2:
160	ldr	r2, [r1, #USART_ISR]
161	tst	r2, #USART_ISR_TXE
162	beq	txe_loop_2
163	str	r0, [r1, #USART_TDR]
164	/* Check transmit complete flag */
165tc_loop_2:
166	ldr	r2, [r1, #USART_ISR]
167	tst	r2, #USART_ISR_TC
168	beq	tc_loop_2
169	bx	lr
170putc_error:
171	mov	r0, #-1
172	bx	lr
173endfunc console_stm32_core_putc
174
175	/* ------------------------------------------------------------
176	 * int console_stm32_putc(int c, struct console_stm32 *console)
177	 * Function to output a character over the console. It
178	 * returns the character printed on success or -1 on error.
179	 * In: r0 - character to be printed
180	 *     r1 - pointer to console_t structure
181	 * Out : return -1 on error else return character.
182	 * Clobber list: r2
183	 * ------------------------------------------------------------
184	 */
185func console_stm32_putc
186#if ENABLE_ASSERTIONS
187	cmp	r1, #0
188	ASM_ASSERT(ne)
189#endif /* ENABLE_ASSERTIONS */
190	ldr	r1, [r1, #CONSOLE_T_STM32_BASE]
191	b	console_stm32_core_putc
192endfunc console_stm32_putc
193
194	/* -----------------------------------------------------------
195	 * int console_core_getc(uintptr_t base_addr)
196	 *
197	 * Function to get a character from the console.
198	 * It returns the character grabbed on success or -1 on error.
199	 *
200	 * In : r0 - console base address
201	 * Out : return -1.
202	 * Clobber list : r0, r1
203	 * -----------------------------------------------------------
204	 */
205func console_stm32_core_getc
206	/* Not supported */
207	mov	r0, #-1
208	bx	lr
209endfunc console_stm32_core_getc
210
211	/* ---------------------------------------------------------------
212	 * int console_core_flush(uintptr_t base_addr)
213	 *
214	 * Function to force a write of all buffered data that hasn't been
215	 * output.
216	 *
217	 * In : r0 - console base address
218	 * Out : return -1 on error else return 0.
219	 * Clobber list : r0, r1
220	 * ---------------------------------------------------------------
221	 */
222func console_stm32_core_flush
223	cmp	r0, #0
224	beq	flush_error
225	/* Check Transmit Data Register Empty */
226txe_loop_3:
227	ldr	r1, [r0, #USART_ISR]
228	tst	r1, #USART_ISR_TXE
229	beq	txe_loop_3
230	mov	r0, #0
231	bx	lr
232flush_error:
233	mov	r0, #-1
234	bx	lr
235endfunc console_stm32_core_flush
236
237	/* ------------------------------------------------------
238	 * int console_stm32_flush(struct console_stm32 *console)
239	 * Function to force a write of all buffered
240	 * data that hasn't been output.
241	 * In : r0 - pointer to console_t structure
242	 * Out : return -1 on error else return 0.
243	 * Clobber list: r0, r1
244	 * ------------------------------------------------------
245	 */
246func console_stm32_flush
247#if ENABLE_ASSERTIONS
248	cmp	r0, #0
249	ASM_ASSERT(ne)
250#endif /* ENABLE_ASSERTIONS */
251	ldr	r0, [r0, #CONSOLE_T_STM32_BASE]
252	b	console_stm32_core_flush
253endfunc console_stm32_flush
254