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