14353bb20SYann Gautier/* 2*ebf851edSYann Gautier * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. 34353bb20SYann Gautier * 44353bb20SYann Gautier * SPDX-License-Identifier: BSD-3-Clause 54353bb20SYann Gautier */ 64353bb20SYann Gautier#include <asm_macros.S> 76d264afcSYann Gautier#include <assert_macros.S> 86d264afcSYann Gautier#include <console_macros.S> 909d40e0eSAntonio Nino Diaz#include <drivers/st/stm32_console.h> 1009d40e0eSAntonio Nino Diaz#include <drivers/st/stm32_uart_regs.h> 114353bb20SYann Gautier 12278c34dfSYann Gautier#define USART_TIMEOUT 0x1000 13278c34dfSYann Gautier 146d264afcSYann Gautier /* 156d264afcSYann Gautier * "core" functions are low-level implementations that don't require 166d264afcSYann Gautier * writeable memory and are thus safe to call in BL1 crash context. 176d264afcSYann Gautier */ 186d264afcSYann Gautier .globl console_stm32_core_init 196d264afcSYann Gautier .globl console_stm32_core_putc 206d264afcSYann Gautier .globl console_stm32_core_getc 216d264afcSYann Gautier .globl console_stm32_core_flush 226d264afcSYann Gautier 236d264afcSYann Gautier .globl console_stm32_putc 246d264afcSYann Gautier .globl console_stm32_flush 256d264afcSYann Gautier 266d264afcSYann Gautier 274353bb20SYann Gautier 284353bb20SYann Gautier /* ----------------------------------------------------------------- 294353bb20SYann Gautier * int console_core_init(uintptr_t base_addr, 304353bb20SYann Gautier * unsigned int uart_clk, 314353bb20SYann Gautier * unsigned int baud_rate) 324353bb20SYann Gautier * 334353bb20SYann Gautier * Function to initialize the console without a C Runtime to print 344353bb20SYann Gautier * debug information. This function will be accessed by console_init 354353bb20SYann Gautier * and crash reporting. 364353bb20SYann Gautier * 374353bb20SYann Gautier * In: r0 - console base address 384353bb20SYann Gautier * r1 - Uart clock in Hz 394353bb20SYann Gautier * r2 - Baud rate 404353bb20SYann Gautier * Out: return 1 on success else 0 on error 414353bb20SYann Gautier * Clobber list : r1, r2, r3 424353bb20SYann Gautier * ----------------------------------------------------------------- 434353bb20SYann Gautier */ 446d264afcSYann Gautierfunc console_stm32_core_init 45278c34dfSYann Gautier /* Check the input base address */ 46278c34dfSYann Gautier cmp r0, #0 47278c34dfSYann Gautier beq core_init_fail 48278c34dfSYann Gautier#if defined(IMAGE_BL2) 49278c34dfSYann Gautier /* Check baud rate and uart clock for sanity */ 50278c34dfSYann Gautier cmp r1, #0 51278c34dfSYann Gautier beq core_init_fail 52278c34dfSYann Gautier cmp r2, #0 53278c34dfSYann Gautier beq core_init_fail 54278c34dfSYann Gautier /* Disable UART */ 55278c34dfSYann Gautier ldr r3, [r0, #USART_CR1] 56278c34dfSYann Gautier bic r3, r3, #USART_CR1_UE 57278c34dfSYann Gautier str r3, [r0, #USART_CR1] 58278c34dfSYann Gautier /* Configure UART */ 59278c34dfSYann Gautier orr r3, r3, #(USART_CR1_TE | USART_CR1_FIFOEN) 60278c34dfSYann Gautier str r3, [r0, #USART_CR1] 61278c34dfSYann Gautier ldr r3, [r0, #USART_CR2] 62278c34dfSYann Gautier bic r3, r3, #USART_CR2_STOP 63278c34dfSYann Gautier str r3, [r0, #USART_CR2] 64278c34dfSYann Gautier /* Divisor = (Uart clock + (baudrate / 2)) / baudrate */ 65278c34dfSYann Gautier lsl r3, r2, #1 66278c34dfSYann Gautier add r3, r1, r3 67278c34dfSYann Gautier udiv r3, r3, r2 68278c34dfSYann Gautier str r3, [r0, #USART_BRR] 69278c34dfSYann Gautier /* Enable UART */ 70278c34dfSYann Gautier ldr r3, [r0, #USART_CR1] 71278c34dfSYann Gautier orr r3, r3, #USART_CR1_UE 72278c34dfSYann Gautier str r3, [r0, #USART_CR1] 73278c34dfSYann Gautier /* Check TEACK bit */ 74278c34dfSYann Gautier mov r2, #USART_TIMEOUT 75278c34dfSYann Gautierteack_loop: 76278c34dfSYann Gautier subs r2, r2, #1 77278c34dfSYann Gautier beq core_init_fail 78278c34dfSYann Gautier ldr r3, [r0, #USART_ISR] 79278c34dfSYann Gautier tst r3, #USART_ISR_TEACK 80278c34dfSYann Gautier beq teack_loop 81278c34dfSYann Gautier#endif /* IMAGE_BL2 */ 82278c34dfSYann Gautier mov r0, #1 83278c34dfSYann Gautier bx lr 84278c34dfSYann Gautiercore_init_fail: 85278c34dfSYann Gautier mov r0, #0 864353bb20SYann Gautier bx lr 876d264afcSYann Gautierendfunc console_stm32_core_init 886d264afcSYann Gautier 896d264afcSYann Gautier .globl console_stm32_register 906d264afcSYann Gautier 916d264afcSYann Gautier /* ------------------------------------------------------- 926d264afcSYann Gautier * int console_stm32_register(uintptr_t baseaddr, 936d264afcSYann Gautier * uint32_t clock, uint32_t baud, 946d264afcSYann Gautier * struct console_stm32 *console); 956d264afcSYann Gautier * Function to initialize and register a new STM32 966d264afcSYann Gautier * console. Storage passed in for the console struct 976d264afcSYann Gautier * *must* be persistent (i.e. not from the stack). 986d264afcSYann Gautier * In: r0 - UART register base address 996d264afcSYann Gautier * r1 - UART clock in Hz 1006d264afcSYann Gautier * r2 - Baud rate 1016d264afcSYann Gautier * r3 - pointer to empty console_stm32 struct 1026d264afcSYann Gautier * Out: return 1 on success, 0 on error 1036d264afcSYann Gautier * Clobber list : r0, r1, r2 1046d264afcSYann Gautier * ------------------------------------------------------- 1056d264afcSYann Gautier */ 1066d264afcSYann Gautierfunc console_stm32_register 1076d264afcSYann Gautier push {r4, lr} 1086d264afcSYann Gautier mov r4, r3 1096d264afcSYann Gautier cmp r4, #0 1106d264afcSYann Gautier beq register_fail 1116d264afcSYann Gautier str r0, [r4, #CONSOLE_T_STM32_BASE] 1126d264afcSYann Gautier 1136d264afcSYann Gautier bl console_stm32_core_init 1146d264afcSYann Gautier cmp r0, #0 1156d264afcSYann Gautier beq register_fail 1166d264afcSYann Gautier 1176d264afcSYann Gautier mov r0, r4 1186d264afcSYann Gautier pop {r4, lr} 1196d264afcSYann Gautier finish_console_register stm32 putc=1, getc=0, flush=1 1206d264afcSYann Gautier 1216d264afcSYann Gautierregister_fail: 1226d264afcSYann Gautier pop {r4, pc} 1236d264afcSYann Gautierendfunc console_stm32_register 1244353bb20SYann Gautier 1254353bb20SYann Gautier /* --------------------------------------------------------------- 1264353bb20SYann Gautier * int console_core_putc(int c, uintptr_t base_addr) 1274353bb20SYann Gautier * 1284353bb20SYann Gautier * Function to output a character over the console. It returns the 1294353bb20SYann Gautier * character printed on success or -1 on error. 1304353bb20SYann Gautier * 1314353bb20SYann Gautier * In : r0 - character to be printed 1324353bb20SYann Gautier * r1 - console base address 1334353bb20SYann Gautier * Out : return -1 on error else return character. 1344353bb20SYann Gautier * Clobber list : r2 1354353bb20SYann Gautier * --------------------------------------------------------------- 1364353bb20SYann Gautier */ 1376d264afcSYann Gautierfunc console_stm32_core_putc 138278c34dfSYann Gautier /* Check the input parameter */ 139278c34dfSYann Gautier cmp r1, #0 140278c34dfSYann Gautier beq putc_error 141*ebf851edSYann Gautier 142278c34dfSYann Gautier /* Check Transmit Data Register Empty */ 143*ebf851edSYann Gautiertxe_loop: 144278c34dfSYann Gautier ldr r2, [r1, #USART_ISR] 145278c34dfSYann Gautier tst r2, #USART_ISR_TXE 146*ebf851edSYann Gautier beq txe_loop 147278c34dfSYann Gautier str r0, [r1, #USART_TDR] 148278c34dfSYann Gautier /* Check transmit complete flag */ 149*ebf851edSYann Gautiertc_loop: 150278c34dfSYann Gautier ldr r2, [r1, #USART_ISR] 151278c34dfSYann Gautier tst r2, #USART_ISR_TC 152*ebf851edSYann Gautier beq tc_loop 153278c34dfSYann Gautier bx lr 154278c34dfSYann Gautierputc_error: 155278c34dfSYann Gautier mov r0, #-1 1564353bb20SYann Gautier bx lr 1576d264afcSYann Gautierendfunc console_stm32_core_putc 1586d264afcSYann Gautier 1596d264afcSYann Gautier /* ------------------------------------------------------------ 1606d264afcSYann Gautier * int console_stm32_putc(int c, struct console_stm32 *console) 1616d264afcSYann Gautier * Function to output a character over the console. It 1626d264afcSYann Gautier * returns the character printed on success or -1 on error. 1636d264afcSYann Gautier * In: r0 - character to be printed 1646d264afcSYann Gautier * r1 - pointer to console_t structure 1656d264afcSYann Gautier * Out : return -1 on error else return character. 1666d264afcSYann Gautier * Clobber list: r2 1676d264afcSYann Gautier * ------------------------------------------------------------ 1686d264afcSYann Gautier */ 1696d264afcSYann Gautierfunc console_stm32_putc 1706d264afcSYann Gautier#if ENABLE_ASSERTIONS 1716d264afcSYann Gautier cmp r1, #0 1726d264afcSYann Gautier ASM_ASSERT(ne) 1736d264afcSYann Gautier#endif /* ENABLE_ASSERTIONS */ 1746d264afcSYann Gautier ldr r1, [r1, #CONSOLE_T_STM32_BASE] 1756d264afcSYann Gautier b console_stm32_core_putc 1766d264afcSYann Gautierendfunc console_stm32_putc 1774353bb20SYann Gautier 1784353bb20SYann Gautier /* ----------------------------------------------------------- 1794353bb20SYann Gautier * int console_core_getc(uintptr_t base_addr) 1804353bb20SYann Gautier * 1814353bb20SYann Gautier * Function to get a character from the console. 1824353bb20SYann Gautier * It returns the character grabbed on success or -1 on error. 1834353bb20SYann Gautier * 1844353bb20SYann Gautier * In : r0 - console base address 1854353bb20SYann Gautier * Out : return -1. 1864353bb20SYann Gautier * Clobber list : r0, r1 1874353bb20SYann Gautier * ----------------------------------------------------------- 1884353bb20SYann Gautier */ 1896d264afcSYann Gautierfunc console_stm32_core_getc 1904353bb20SYann Gautier /* Not supported */ 1914353bb20SYann Gautier mov r0, #-1 1924353bb20SYann Gautier bx lr 1936d264afcSYann Gautierendfunc console_stm32_core_getc 1944353bb20SYann Gautier 1954353bb20SYann Gautier /* --------------------------------------------------------------- 1964353bb20SYann Gautier * int console_core_flush(uintptr_t base_addr) 1974353bb20SYann Gautier * 1984353bb20SYann Gautier * Function to force a write of all buffered data that hasn't been 1994353bb20SYann Gautier * output. 2004353bb20SYann Gautier * 2014353bb20SYann Gautier * In : r0 - console base address 2024353bb20SYann Gautier * Out : return -1 on error else return 0. 2034353bb20SYann Gautier * Clobber list : r0, r1 2044353bb20SYann Gautier * --------------------------------------------------------------- 2054353bb20SYann Gautier */ 2066d264afcSYann Gautierfunc console_stm32_core_flush 207278c34dfSYann Gautier cmp r0, #0 208278c34dfSYann Gautier beq flush_error 209278c34dfSYann Gautier /* Check Transmit Data Register Empty */ 210278c34dfSYann Gautiertxe_loop_3: 211278c34dfSYann Gautier ldr r1, [r0, #USART_ISR] 212278c34dfSYann Gautier tst r1, #USART_ISR_TXE 213278c34dfSYann Gautier beq txe_loop_3 214278c34dfSYann Gautier mov r0, #0 215278c34dfSYann Gautier bx lr 216278c34dfSYann Gautierflush_error: 217278c34dfSYann Gautier mov r0, #-1 2184353bb20SYann Gautier bx lr 2196d264afcSYann Gautierendfunc console_stm32_core_flush 2206d264afcSYann Gautier 2216d264afcSYann Gautier /* ------------------------------------------------------ 2226d264afcSYann Gautier * int console_stm32_flush(struct console_stm32 *console) 2236d264afcSYann Gautier * Function to force a write of all buffered 2246d264afcSYann Gautier * data that hasn't been output. 2256d264afcSYann Gautier * In : r0 - pointer to console_t structure 2266d264afcSYann Gautier * Out : return -1 on error else return 0. 2276d264afcSYann Gautier * Clobber list: r0, r1 2286d264afcSYann Gautier * ------------------------------------------------------ 2296d264afcSYann Gautier */ 2306d264afcSYann Gautierfunc console_stm32_flush 2316d264afcSYann Gautier#if ENABLE_ASSERTIONS 2326d264afcSYann Gautier cmp r0, #0 2336d264afcSYann Gautier ASM_ASSERT(ne) 2346d264afcSYann Gautier#endif /* ENABLE_ASSERTIONS */ 2356d264afcSYann Gautier ldr r0, [r0, #CONSOLE_T_STM32_BASE] 2366d264afcSYann Gautier b console_stm32_core_flush 2376d264afcSYann Gautierendfunc console_stm32_flush 238