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