blob: e3e0e67d39efab82db3e505b99b189fa2600727c [file] [log] [blame]
Yann Gautier4b0c72a2018-07-16 10:54:09 +02001/*
Yann Gautier376b80b2022-02-28 17:29:49 +01002 * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
Yann Gautier4b0c72a2018-07-16 10:54:09 +02003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6#include <asm_macros.S>
Yann Gautier4518c592018-11-15 09:51:06 +01007#include <assert_macros.S>
Yann Gautier4518c592018-11-15 09:51:06 +01008#include <console_macros.S>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00009#include <drivers/st/stm32_console.h>
10#include <drivers/st/stm32_uart_regs.h>
Yann Gautier4b0c72a2018-07-16 10:54:09 +020011
Yann Gautier69035a82018-07-05 16:48:16 +020012#define USART_TIMEOUT 0x1000
13
Yann Gautier4518c592018-11-15 09:51:06 +010014 /*
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
Yann Gautier4b0c72a2018-07-16 10:54:09 +020027
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 */
Yann Gautier4518c592018-11-15 09:51:06 +010044func console_stm32_core_init
Yann Gautier69035a82018-07-05 16:48:16 +020045 /* Check the input base address */
46 cmp r0, #0
47 beq core_init_fail
Yann Gautier9ee1f9c2021-09-09 17:34:53 +020048#if !defined(IMAGE_BL2)
Yann Gautier61f74bb2022-09-13 13:55:43 +020049#if STM32MP_RECONFIGURE_CONSOLE
50 /* UART clock rate is set to 0 in BL32, skip init in that case */
51 cmp r1, #0
52 beq 1f
53#else /* STM32MP_RECONFIGURE_CONSOLE */
Yann Gautier9ee1f9c2021-09-09 17:34:53 +020054 /* Skip UART initialization if it is already enabled */
55 ldr r3, [r0, #USART_CR1]
56 ands r3, r3, #USART_CR1_UE
57 bne 1f
Yann Gautier61f74bb2022-09-13 13:55:43 +020058#endif /* STM32MP_RECONFIGURE_CONSOLE */
Yann Gautier9ee1f9c2021-09-09 17:34:53 +020059#endif /* IMAGE_BL2 */
Yann Gautier69035a82018-07-05 16:48:16 +020060 /* Check baud rate and uart clock for sanity */
61 cmp r1, #0
62 beq core_init_fail
63 cmp r2, #0
64 beq core_init_fail
65 /* Disable UART */
66 ldr r3, [r0, #USART_CR1]
67 bic r3, r3, #USART_CR1_UE
68 str r3, [r0, #USART_CR1]
69 /* Configure UART */
70 orr r3, r3, #(USART_CR1_TE | USART_CR1_FIFOEN)
71 str r3, [r0, #USART_CR1]
72 ldr r3, [r0, #USART_CR2]
73 bic r3, r3, #USART_CR2_STOP
74 str r3, [r0, #USART_CR2]
75 /* Divisor = (Uart clock + (baudrate / 2)) / baudrate */
Yann Gautier376b80b2022-02-28 17:29:49 +010076 lsr r3, r2, #1
Yann Gautier69035a82018-07-05 16:48:16 +020077 add r3, r1, r3
78 udiv r3, r3, r2
Yann Gautier2934be52022-02-28 18:28:06 +010079 cmp r3, #16
80 bhi 2f
81 /* Oversampling 8 */
82 /* Divisor = (2 * Uart clock + (baudrate / 2)) / baudrate */
83 lsr r3, r2, #1
84 add r3, r3, r1, lsl #1
85 udiv r3, r3, r2
86 and r1, r3, #USART_BRR_DIV_FRACTION
87 lsr r1, r1, #1
88 bic r3, r3, #USART_BRR_DIV_FRACTION
89 orr r3, r3, r1
90 ldr r1, [r0, #USART_CR1]
91 orr r1, r1, #USART_CR1_OVER8
92 str r1, [r0, #USART_CR1]
932:
Yann Gautier69035a82018-07-05 16:48:16 +020094 str r3, [r0, #USART_BRR]
95 /* Enable UART */
96 ldr r3, [r0, #USART_CR1]
97 orr r3, r3, #USART_CR1_UE
98 str r3, [r0, #USART_CR1]
99 /* Check TEACK bit */
100 mov r2, #USART_TIMEOUT
101teack_loop:
102 subs r2, r2, #1
103 beq core_init_fail
104 ldr r3, [r0, #USART_ISR]
105 tst r3, #USART_ISR_TEACK
106 beq teack_loop
Yann Gautier9ee1f9c2021-09-09 17:34:53 +02001071:
Yann Gautier69035a82018-07-05 16:48:16 +0200108 mov r0, #1
109 bx lr
110core_init_fail:
111 mov r0, #0
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200112 bx lr
Yann Gautier4518c592018-11-15 09:51:06 +0100113endfunc console_stm32_core_init
114
Yann Gautier4518c592018-11-15 09:51:06 +0100115 .globl console_stm32_register
116
117 /* -------------------------------------------------------
118 * int console_stm32_register(uintptr_t baseaddr,
119 * uint32_t clock, uint32_t baud,
Andre Przywara678c6fa2020-01-25 00:58:35 +0000120 * console_t *console);
Yann Gautier4518c592018-11-15 09:51:06 +0100121 * Function to initialize and register a new STM32
122 * console. Storage passed in for the console struct
123 * *must* be persistent (i.e. not from the stack).
124 * In: r0 - UART register base address
125 * r1 - UART clock in Hz
126 * r2 - Baud rate
Andre Przywara678c6fa2020-01-25 00:58:35 +0000127 * r3 - pointer to empty console_t struct
Yann Gautier4518c592018-11-15 09:51:06 +0100128 * Out: return 1 on success, 0 on error
129 * Clobber list : r0, r1, r2
130 * -------------------------------------------------------
131 */
132func console_stm32_register
133 push {r4, lr}
134 mov r4, r3
135 cmp r4, #0
136 beq register_fail
Andre Przywara678c6fa2020-01-25 00:58:35 +0000137 str r0, [r4, #CONSOLE_T_BASE]
Yann Gautier4518c592018-11-15 09:51:06 +0100138
139 bl console_stm32_core_init
140 cmp r0, #0
141 beq register_fail
142
143 mov r0, r4
144 pop {r4, lr}
145 finish_console_register stm32 putc=1, getc=0, flush=1
146
147register_fail:
148 pop {r4, pc}
149endfunc console_stm32_register
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200150
151 /* ---------------------------------------------------------------
152 * int console_core_putc(int c, uintptr_t base_addr)
153 *
154 * Function to output a character over the console. It returns the
155 * character printed on success or -1 on error.
156 *
157 * In : r0 - character to be printed
158 * r1 - console base address
159 * Out : return -1 on error else return character.
160 * Clobber list : r2
161 * ---------------------------------------------------------------
162 */
Yann Gautier4518c592018-11-15 09:51:06 +0100163func console_stm32_core_putc
Yann Gautier69035a82018-07-05 16:48:16 +0200164 /* Check the input parameter */
165 cmp r1, #0
166 beq putc_error
Yann Gautiera30e5f72019-09-04 11:55:10 +0200167
Yann Gautier69035a82018-07-05 16:48:16 +0200168 /* Check Transmit Data Register Empty */
Yann Gautiera30e5f72019-09-04 11:55:10 +0200169txe_loop:
Yann Gautier69035a82018-07-05 16:48:16 +0200170 ldr r2, [r1, #USART_ISR]
171 tst r2, #USART_ISR_TXE
Yann Gautiera30e5f72019-09-04 11:55:10 +0200172 beq txe_loop
Yann Gautier69035a82018-07-05 16:48:16 +0200173 str r0, [r1, #USART_TDR]
174 /* Check transmit complete flag */
Yann Gautiera30e5f72019-09-04 11:55:10 +0200175tc_loop:
Yann Gautier69035a82018-07-05 16:48:16 +0200176 ldr r2, [r1, #USART_ISR]
177 tst r2, #USART_ISR_TC
Yann Gautiera30e5f72019-09-04 11:55:10 +0200178 beq tc_loop
Yann Gautier69035a82018-07-05 16:48:16 +0200179 bx lr
180putc_error:
181 mov r0, #-1
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200182 bx lr
Yann Gautier4518c592018-11-15 09:51:06 +0100183endfunc console_stm32_core_putc
184
185 /* ------------------------------------------------------------
Andre Przywara678c6fa2020-01-25 00:58:35 +0000186 * int console_stm32_putc(int c, console_t *console)
Yann Gautier4518c592018-11-15 09:51:06 +0100187 * Function to output a character over the console. It
188 * returns the character printed on success or -1 on error.
189 * In: r0 - character to be printed
190 * r1 - pointer to console_t structure
191 * Out : return -1 on error else return character.
192 * Clobber list: r2
193 * ------------------------------------------------------------
194 */
195func console_stm32_putc
196#if ENABLE_ASSERTIONS
197 cmp r1, #0
198 ASM_ASSERT(ne)
199#endif /* ENABLE_ASSERTIONS */
Andre Przywara678c6fa2020-01-25 00:58:35 +0000200 ldr r1, [r1, #CONSOLE_T_BASE]
Yann Gautier4518c592018-11-15 09:51:06 +0100201 b console_stm32_core_putc
202endfunc console_stm32_putc
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200203
204 /* -----------------------------------------------------------
205 * int console_core_getc(uintptr_t base_addr)
206 *
207 * Function to get a character from the console.
208 * It returns the character grabbed on success or -1 on error.
209 *
210 * In : r0 - console base address
211 * Out : return -1.
212 * Clobber list : r0, r1
213 * -----------------------------------------------------------
214 */
Yann Gautier4518c592018-11-15 09:51:06 +0100215func console_stm32_core_getc
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200216 /* Not supported */
217 mov r0, #-1
218 bx lr
Yann Gautier4518c592018-11-15 09:51:06 +0100219endfunc console_stm32_core_getc
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200220
221 /* ---------------------------------------------------------------
Jimmy Brisson39f9eee2020-08-05 13:44:05 -0500222 * void console_core_flush(uintptr_t base_addr)
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200223 *
224 * Function to force a write of all buffered data that hasn't been
225 * output.
226 *
227 * In : r0 - console base address
Jimmy Brisson39f9eee2020-08-05 13:44:05 -0500228 * Out : void.
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200229 * Clobber list : r0, r1
230 * ---------------------------------------------------------------
231 */
Yann Gautier4518c592018-11-15 09:51:06 +0100232func console_stm32_core_flush
Jimmy Brisson39f9eee2020-08-05 13:44:05 -0500233#if ENABLE_ASSERTIONS
Yann Gautier69035a82018-07-05 16:48:16 +0200234 cmp r0, #0
Jimmy Brisson39f9eee2020-08-05 13:44:05 -0500235 ASM_ASSERT(ne)
236#endif /* ENABLE_ASSERTIONS */
Yann Gautier69035a82018-07-05 16:48:16 +0200237 /* 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
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200242 bx lr
Yann Gautier4518c592018-11-15 09:51:06 +0100243endfunc console_stm32_core_flush
244
245 /* ------------------------------------------------------
Jimmy Brisson39f9eee2020-08-05 13:44:05 -0500246 * void console_stm32_flush(console_t *console)
Yann Gautier4518c592018-11-15 09:51:06 +0100247 * Function to force a write of all buffered
248 * data that hasn't been output.
249 * In : r0 - pointer to console_t structure
Jimmy Brisson39f9eee2020-08-05 13:44:05 -0500250 * Out : void.
Yann Gautier4518c592018-11-15 09:51:06 +0100251 * Clobber list: r0, r1
252 * ------------------------------------------------------
253 */
254func console_stm32_flush
255#if ENABLE_ASSERTIONS
256 cmp r0, #0
257 ASM_ASSERT(ne)
258#endif /* ENABLE_ASSERTIONS */
Andre Przywara678c6fa2020-01-25 00:58:35 +0000259 ldr r0, [r0, #CONSOLE_T_BASE]
Yann Gautier4518c592018-11-15 09:51:06 +0100260 b console_stm32_core_flush
261endfunc console_stm32_flush