xref: /optee_os/core/drivers/stm32_uart.c (revision 62f21181c547da3bd098908300e5699e9ae5cca9)
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