xref: /optee_os/core/drivers/stm32_uart.c (revision b99a4a1850c2ce661156ebc25f48d47efa8a41c1)
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 <kernel/dt.h>
14 #include <kernel/panic.h>
15 #include <util.h>
16 
17 #define UART_REG_CR1			0x00	/* Control register 1 */
18 #define UART_REG_CR2			0x04	/* Control register 2 */
19 #define UART_REG_CR3			0x08	/* Control register 3 */
20 #define UART_REG_BRR			0x0c	/* Baud rate register */
21 #define UART_REG_RQR			0x18	/* Request register */
22 #define UART_REG_ISR			0x1c	/* Interrupt & status reg. */
23 #define UART_REG_ICR			0x20	/* Interrupt flag clear reg. */
24 #define UART_REG_RDR			0x24	/* Receive data register */
25 #define UART_REG_TDR			0x28	/* Transmit data register */
26 #define UART_REG_PRESC			0x2c	/* Prescaler register */
27 
28 #define PUTC_TIMEOUT_US			1000
29 #define FLUSH_TIMEOUT_US		16000
30 
31 /*
32  * Uart Interrupt & status register bits
33  *
34  * Bit 5 RXNE: Read data register not empty/RXFIFO not empty
35  * Bit 6 TC: Transmission complete
36  * Bit 7 TXE/TXFNF: Transmit data register empty/TXFIFO not full
37  * Bit 27 TXFE: TXFIFO threshold reached
38  */
39 #define USART_ISR_RXNE_RXFNE		BIT(5)
40 #define USART_ISR_TC			BIT(6)
41 #define USART_ISR_TXE_TXFNF		BIT(7)
42 #define USART_ISR_TXFE			BIT(27)
43 
44 static vaddr_t loc_chip_to_base(struct serial_chip *chip)
45 {
46 	struct stm32_uart_pdata *pd = NULL;
47 
48 	pd = container_of(chip, struct stm32_uart_pdata, chip);
49 
50 	return io_pa_or_va(&pd->base);
51 }
52 
53 static void loc_flush(struct serial_chip *chip)
54 {
55 	vaddr_t base = loc_chip_to_base(chip);
56 	uint64_t timeout = timeout_init_us(FLUSH_TIMEOUT_US);
57 
58 	while (!(io_read32(base + UART_REG_ISR) & USART_ISR_TXFE))
59 		if (timeout_elapsed(timeout))
60 			return;
61 }
62 
63 static void loc_putc(struct serial_chip *chip, int ch)
64 {
65 	vaddr_t base = loc_chip_to_base(chip);
66 	uint64_t timeout = timeout_init_us(PUTC_TIMEOUT_US);
67 
68 	while (!(io_read32(base + UART_REG_ISR) & USART_ISR_TXE_TXFNF))
69 		if (timeout_elapsed(timeout))
70 			return;
71 
72 	io_write32(base + UART_REG_TDR, ch);
73 }
74 
75 static bool loc_have_rx_data(struct serial_chip *chip)
76 {
77 	vaddr_t base = loc_chip_to_base(chip);
78 
79 	return io_read32(base + UART_REG_ISR) & USART_ISR_RXNE_RXFNE;
80 }
81 
82 static int loc_getchar(struct serial_chip *chip)
83 {
84 	vaddr_t base = loc_chip_to_base(chip);
85 
86 	while (!loc_have_rx_data(chip))
87 		;
88 
89 	return io_read32(base + UART_REG_RDR) & 0xff;
90 }
91 
92 static const struct serial_ops stm32_uart_serial_ops = {
93 	.flush = loc_flush,
94 	.putc = loc_putc,
95 	.have_rx_data = loc_have_rx_data,
96 	.getchar = loc_getchar,
97 
98 };
99 KEEP_PAGER(stm32_uart_serial_ops);
100 
101 void stm32_uart_init(struct stm32_uart_pdata *pd, vaddr_t base)
102 {
103 	pd->base.pa = base;
104 	pd->chip.ops = &stm32_uart_serial_ops;
105 }
106 
107 #ifdef CFG_DT
108 struct stm32_uart_pdata *stm32_uart_init_from_dt_node(void *fdt, int node)
109 {
110 	struct stm32_uart_pdata *pd = NULL;
111 	struct dt_node_info info = { };
112 
113 	_fdt_fill_device_info(fdt, &info, node);
114 
115 	if (info.status == DT_STATUS_DISABLED)
116 		return NULL;
117 
118 	assert(info.clock != DT_INFO_INVALID_CLOCK &&
119 	       info.reg != DT_INFO_INVALID_REG);
120 
121 	pd = calloc(1, sizeof(*pd));
122 	if (!pd)
123 		panic();
124 
125 	pd->chip.ops = &stm32_uart_serial_ops;
126 	pd->base.pa = info.reg;
127 	pd->secure = (info.status == DT_STATUS_OK_SEC);
128 	pd->clock = (unsigned int)info.clock;
129 
130 	assert(cpu_mmu_enabled());
131 	pd->base.va = (vaddr_t)phys_to_virt(pd->base.pa,
132 					    pd->secure ? MEM_AREA_IO_SEC :
133 					    MEM_AREA_IO_NSEC);
134 
135 	return pd;
136 }
137 #endif /*CFG_DT*/
138