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