xref: /rk3399_ARM-atf/drivers/st/uart/aarch32/stm32_console.S (revision c3cf06f1a3a9b9ee8ac7a0ae505f95c45f7dca84)
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
8#define USART_TIMEOUT		0x1000
9
10#define USART_CR1		0x00
11#define USART_CR1_UE		0x00000001
12#define USART_CR1_TE		0x00000008
13#define USART_CR1_FIFOEN	0x20000000
14
15#define USART_CR2		0x04
16#define USART_CR2_STOP		0x00003000
17
18#define USART_BRR		0x0C
19
20#define USART_ISR		0x1C
21#define USART_ISR_TC		0x00000040
22#define USART_ISR_TXE		0x00000080
23#define USART_ISR_TEACK		0x00200000
24
25#define USART_TDR		0x28
26
27	.globl	console_core_init
28	.globl	console_core_putc
29	.globl	console_core_getc
30	.globl	console_core_flush
31
32	/* -----------------------------------------------------------------
33	 * int console_core_init(uintptr_t base_addr,
34	 *			 unsigned int uart_clk,
35	 *			 unsigned int baud_rate)
36	 *
37	 * Function to initialize the console without a C Runtime to print
38	 * debug information. This function will be accessed by console_init
39	 * and crash reporting.
40	 *
41	 * In: r0 - console base address
42	 *     r1 - Uart clock in Hz
43	 *     r2 - Baud rate
44	 * Out: return 1 on success else 0 on error
45	 * Clobber list : r1, r2, r3
46	 * -----------------------------------------------------------------
47	 */
48func console_core_init
49	/* Check the input base address */
50	cmp	r0, #0
51	beq	core_init_fail
52#if defined(IMAGE_BL2)
53	/* Check baud rate and uart clock for sanity */
54	cmp	r1, #0
55	beq	core_init_fail
56	cmp	r2, #0
57	beq	core_init_fail
58	/* Disable UART */
59	ldr	r3, [r0, #USART_CR1]
60	bic	r3, r3, #USART_CR1_UE
61	str	r3, [r0, #USART_CR1]
62	/* Configure UART */
63	orr	r3, r3, #(USART_CR1_TE | USART_CR1_FIFOEN)
64	str	r3, [r0, #USART_CR1]
65	ldr	r3, [r0, #USART_CR2]
66	bic	r3, r3, #USART_CR2_STOP
67	str	r3, [r0, #USART_CR2]
68	/* Divisor =  (Uart clock + (baudrate / 2)) / baudrate */
69	lsl	r3, r2, #1
70	add	r3, r1, r3
71	udiv	r3, r3, r2
72	str	r3, [r0, #USART_BRR]
73	/* Enable UART */
74	ldr	r3, [r0, #USART_CR1]
75	orr	r3, r3, #USART_CR1_UE
76	str	r3, [r0, #USART_CR1]
77	/* Check TEACK bit */
78	mov	r2, #USART_TIMEOUT
79teack_loop:
80	subs	r2, r2, #1
81	beq	core_init_fail
82	ldr	r3, [r0, #USART_ISR]
83	tst	r3, #USART_ISR_TEACK
84	beq	teack_loop
85#endif /* IMAGE_BL2 */
86	mov	r0, #1
87	bx	lr
88core_init_fail:
89	mov	r0, #0
90	bx	lr
91endfunc console_core_init
92
93	/* ---------------------------------------------------------------
94	 * int console_core_putc(int c, uintptr_t base_addr)
95	 *
96	 * Function to output a character over the console. It returns the
97	 * character printed on success or -1 on error.
98	 *
99	 * In : r0 - character to be printed
100	 *      r1 - console base address
101	 * Out : return -1 on error else return character.
102	 * Clobber list : r2
103	 * ---------------------------------------------------------------
104	 */
105func console_core_putc
106	/* Check the input parameter */
107	cmp	r1, #0
108	beq	putc_error
109	/* Prepend '\r' to '\n' */
110	cmp	r0, #0xA
111	bne	2f
1121:
113	/* Check Transmit Data Register Empty */
114txe_loop_1:
115	ldr	r2, [r1, #USART_ISR]
116	tst	r2, #USART_ISR_TXE
117	beq	txe_loop_1
118	mov	r2, #0xD
119	str	r2, [r1, #USART_TDR]
120	/* Check transmit complete flag */
121tc_loop_1:
122	ldr	r2, [r1, #USART_ISR]
123	tst	r2, #USART_ISR_TC
124	beq	tc_loop_1
1252:
126	/* Check Transmit Data Register Empty */
127txe_loop_2:
128	ldr	r2, [r1, #USART_ISR]
129	tst	r2, #USART_ISR_TXE
130	beq	txe_loop_2
131	str	r0, [r1, #USART_TDR]
132	/* Check transmit complete flag */
133tc_loop_2:
134	ldr	r2, [r1, #USART_ISR]
135	tst	r2, #USART_ISR_TC
136	beq	tc_loop_2
137	bx	lr
138putc_error:
139	mov	r0, #-1
140	bx	lr
141endfunc console_core_putc
142
143	/* -----------------------------------------------------------
144	 * int console_core_getc(uintptr_t base_addr)
145	 *
146	 * Function to get a character from the console.
147	 * It returns the character grabbed on success or -1 on error.
148	 *
149	 * In : r0 - console base address
150	 * Out : return -1.
151	 * Clobber list : r0, r1
152	 * -----------------------------------------------------------
153	 */
154func console_core_getc
155	/* Not supported */
156	mov	r0, #-1
157	bx	lr
158endfunc console_core_getc
159
160	/* ---------------------------------------------------------------
161	 * int console_core_flush(uintptr_t base_addr)
162	 *
163	 * Function to force a write of all buffered data that hasn't been
164	 * output.
165	 *
166	 * In : r0 - console base address
167	 * Out : return -1 on error else return 0.
168	 * Clobber list : r0, r1
169	 * ---------------------------------------------------------------
170	 */
171func console_core_flush
172	cmp	r0, #0
173	beq	flush_error
174	/* Check Transmit Data Register Empty */
175txe_loop_3:
176	ldr	r1, [r0, #USART_ISR]
177	tst	r1, #USART_ISR_TXE
178	beq	txe_loop_3
179	mov	r0, #0
180	bx	lr
181flush_error:
182	mov	r0, #-1
183	bx	lr
184endfunc console_core_flush
185