1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2017-2018, STMicroelectronics 4 */ 5 6 #include <compiler.h> 7 #include <console.h> 8 #include <drivers/serial.h> 9 #include <drivers/stm32_uart.h> 10 #include <io.h> 11 #include <keep.h> 12 #include <kernel/delay.h> 13 #include <util.h> 14 15 #define UART_REG_CR1 0x00 /* Control register 1 */ 16 #define UART_REG_CR2 0x04 /* Control register 2 */ 17 #define UART_REG_CR3 0x08 /* Control register 3 */ 18 #define UART_REG_BRR 0x0c /* Baud rate register */ 19 #define UART_REG_RQR 0x18 /* Request register */ 20 #define UART_REG_ISR 0x1c /* Interrupt & status reg. */ 21 #define UART_REG_ICR 0x20 /* Interrupt flag clear reg. */ 22 #define UART_REG_RDR 0x24 /* Receive data register */ 23 #define UART_REG_TDR 0x28 /* Transmit data register */ 24 #define UART_REG_PRESC 0x2c /* Prescaler register */ 25 26 #define PUTC_TIMEOUT_US 1000 27 #define FLUSH_TIMEOUT_US 16000 28 29 /* 30 * Uart Interrupt & status register bits 31 * 32 * Bit 5 RXNE: Read data register not empty/RXFIFO not empty 33 * Bit 6 TC: Transmission complete 34 * Bit 7 TXE/TXFNF: Transmit data register empty/TXFIFO not full 35 * Bit 27 TXFE: TXFIFO threshold reached 36 */ 37 #define USART_ISR_RXNE_RXFNE BIT(5) 38 #define USART_ISR_TC BIT(6) 39 #define USART_ISR_TXE_TXFNF BIT(7) 40 #define USART_ISR_TXFE BIT(27) 41 42 static vaddr_t loc_chip_to_base(struct serial_chip *chip) 43 { 44 struct stm32_uart_pdata *pd; 45 46 pd = container_of(chip, struct stm32_uart_pdata, chip); 47 48 return io_pa_or_va(&pd->base); 49 } 50 51 static void loc_flush(struct serial_chip *chip) 52 { 53 vaddr_t base = loc_chip_to_base(chip); 54 uint64_t timeout = timeout_init_us(FLUSH_TIMEOUT_US); 55 56 while (!(read32(base + UART_REG_ISR) & USART_ISR_TXFE)) 57 if (timeout_elapsed(timeout)) 58 return; 59 } 60 61 static void loc_putc(struct serial_chip *chip, int ch) 62 { 63 vaddr_t base = loc_chip_to_base(chip); 64 uint64_t timeout = timeout_init_us(PUTC_TIMEOUT_US); 65 66 while (!(read32(base + UART_REG_ISR) & USART_ISR_TXE_TXFNF)) 67 if (timeout_elapsed(timeout)) 68 return; 69 70 write32(ch, base + UART_REG_TDR); 71 } 72 73 static bool loc_have_rx_data(struct serial_chip *chip) 74 { 75 vaddr_t base = loc_chip_to_base(chip); 76 77 return read32(base + UART_REG_ISR) & USART_ISR_RXNE_RXFNE; 78 } 79 80 static int loc_getchar(struct serial_chip *chip) 81 { 82 vaddr_t base = loc_chip_to_base(chip); 83 84 while (!loc_have_rx_data(chip)) 85 ; 86 87 return read32(base + UART_REG_RDR) & 0xff; 88 } 89 90 static const struct serial_ops stm32_uart_serial_ops = { 91 .flush = loc_flush, 92 .putc = loc_putc, 93 .have_rx_data = loc_have_rx_data, 94 .getchar = loc_getchar, 95 96 }; 97 KEEP_PAGER(stm32_uart_serial_ops); 98 99 void stm32_uart_init(struct stm32_uart_pdata *pd, vaddr_t base) 100 { 101 pd->base.pa = base; 102 pd->chip.ops = &stm32_uart_serial_ops; 103 } 104