303d6bac7551fe8bd6f7b2fb349f76ef847d8f2e
[project/bcm63xx/atf.git] / drivers / st / uart / aarch32 / stm32_console.S
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 */
45 func 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
76 teack_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
85 core_init_fail:
86 mov r0, #0
87 bx lr
88 endfunc console_stm32_core_init
89
90 .globl console_stm32_register
91
92 /* -------------------------------------------------------
93 * int console_stm32_register(uintptr_t baseaddr,
94 * uint32_t clock, uint32_t baud,
95 * struct console_stm32 *console);
96 * Function to initialize and register a new STM32
97 * console. Storage passed in for the console struct
98 * *must* be persistent (i.e. not from the stack).
99 * In: r0 - UART register base address
100 * r1 - UART clock in Hz
101 * r2 - Baud rate
102 * r3 - pointer to empty console_stm32 struct
103 * Out: return 1 on success, 0 on error
104 * Clobber list : r0, r1, r2
105 * -------------------------------------------------------
106 */
107 func console_stm32_register
108 push {r4, lr}
109 mov r4, r3
110 cmp r4, #0
111 beq register_fail
112 str r0, [r4, #CONSOLE_T_STM32_BASE]
113
114 bl console_stm32_core_init
115 cmp r0, #0
116 beq register_fail
117
118 mov r0, r4
119 pop {r4, lr}
120 finish_console_register stm32 putc=1, getc=0, flush=1
121
122 register_fail:
123 pop {r4, pc}
124 endfunc console_stm32_register
125
126 /* ---------------------------------------------------------------
127 * int console_core_putc(int c, uintptr_t base_addr)
128 *
129 * Function to output a character over the console. It returns the
130 * character printed on success or -1 on error.
131 *
132 * In : r0 - character to be printed
133 * r1 - console base address
134 * Out : return -1 on error else return character.
135 * Clobber list : r2
136 * ---------------------------------------------------------------
137 */
138 func console_stm32_core_putc
139 /* Check the input parameter */
140 cmp r1, #0
141 beq putc_error
142 /* Prepend '\r' to '\n' */
143 cmp r0, #0xA
144 bne 2f
145 1:
146 /* Check Transmit Data Register Empty */
147 txe_loop_1:
148 ldr r2, [r1, #USART_ISR]
149 tst r2, #USART_ISR_TXE
150 beq txe_loop_1
151 mov r2, #0xD
152 str r2, [r1, #USART_TDR]
153 /* Check transmit complete flag */
154 tc_loop_1:
155 ldr r2, [r1, #USART_ISR]
156 tst r2, #USART_ISR_TC
157 beq tc_loop_1
158 2:
159 /* Check Transmit Data Register Empty */
160 txe_loop_2:
161 ldr r2, [r1, #USART_ISR]
162 tst r2, #USART_ISR_TXE
163 beq txe_loop_2
164 str r0, [r1, #USART_TDR]
165 /* Check transmit complete flag */
166 tc_loop_2:
167 ldr r2, [r1, #USART_ISR]
168 tst r2, #USART_ISR_TC
169 beq tc_loop_2
170 bx lr
171 putc_error:
172 mov r0, #-1
173 bx lr
174 endfunc console_stm32_core_putc
175
176 /* ------------------------------------------------------------
177 * int console_stm32_putc(int c, struct console_stm32 *console)
178 * Function to output a character over the console. It
179 * returns the character printed on success or -1 on error.
180 * In: r0 - character to be printed
181 * r1 - pointer to console_t structure
182 * Out : return -1 on error else return character.
183 * Clobber list: r2
184 * ------------------------------------------------------------
185 */
186 func console_stm32_putc
187 #if ENABLE_ASSERTIONS
188 cmp r1, #0
189 ASM_ASSERT(ne)
190 #endif /* ENABLE_ASSERTIONS */
191 ldr r1, [r1, #CONSOLE_T_STM32_BASE]
192 b console_stm32_core_putc
193 endfunc console_stm32_putc
194
195 /* -----------------------------------------------------------
196 * int console_core_getc(uintptr_t base_addr)
197 *
198 * Function to get a character from the console.
199 * It returns the character grabbed on success or -1 on error.
200 *
201 * In : r0 - console base address
202 * Out : return -1.
203 * Clobber list : r0, r1
204 * -----------------------------------------------------------
205 */
206 func console_stm32_core_getc
207 /* Not supported */
208 mov r0, #-1
209 bx lr
210 endfunc console_stm32_core_getc
211
212 /* ---------------------------------------------------------------
213 * int console_core_flush(uintptr_t base_addr)
214 *
215 * Function to force a write of all buffered data that hasn't been
216 * output.
217 *
218 * In : r0 - console base address
219 * Out : return -1 on error else return 0.
220 * Clobber list : r0, r1
221 * ---------------------------------------------------------------
222 */
223 func console_stm32_core_flush
224 cmp r0, #0
225 beq flush_error
226 /* Check Transmit Data Register Empty */
227 txe_loop_3:
228 ldr r1, [r0, #USART_ISR]
229 tst r1, #USART_ISR_TXE
230 beq txe_loop_3
231 mov r0, #0
232 bx lr
233 flush_error:
234 mov r0, #-1
235 bx lr
236 endfunc console_stm32_core_flush
237
238 /* ------------------------------------------------------
239 * int console_stm32_flush(struct console_stm32 *console)
240 * Function to force a write of all buffered
241 * data that hasn't been output.
242 * In : r0 - pointer to console_t structure
243 * Out : return -1 on error else return 0.
244 * Clobber list: r0, r1
245 * ------------------------------------------------------
246 */
247 func console_stm32_flush
248 #if ENABLE_ASSERTIONS
249 cmp r0, #0
250 ASM_ASSERT(ne)
251 #endif /* ENABLE_ASSERTIONS */
252 ldr r0, [r0, #CONSOLE_T_STM32_BASE]
253 b console_stm32_core_flush
254 endfunc console_stm32_flush