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