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/clk.h>
9 #include <drivers/clk_dt.h>
10 #include <drivers/serial.h>
11 #include <drivers/stm32_gpio.h>
12 #include <drivers/stm32_uart.h>
13 #include <io.h>
14 #include <keep.h>
15 #include <kernel/delay.h>
16 #include <kernel/dt.h>
17 #include <kernel/panic.h>
18 #include <libfdt.h>
19 #include <stm32_util.h>
20 #include <util.h>
21
22 #define UART_REG_CR1 0x00 /* Control register 1 */
23 #define UART_REG_CR2 0x04 /* Control register 2 */
24 #define UART_REG_CR3 0x08 /* Control register 3 */
25 #define UART_REG_BRR 0x0c /* Baud rate register */
26 #define UART_REG_RQR 0x18 /* Request register */
27 #define UART_REG_ISR 0x1c /* Interrupt & status reg. */
28 #define UART_REG_ICR 0x20 /* Interrupt flag clear reg. */
29 #define UART_REG_RDR 0x24 /* Receive data register */
30 #define UART_REG_TDR 0x28 /* Transmit data register */
31 #define UART_REG_PRESC 0x2c /* Prescaler register */
32
33 #define PUTC_TIMEOUT_US 1000
34 #define FLUSH_TIMEOUT_US 16000
35
36 /*
37 * Uart Interrupt & status register bits
38 *
39 * Bit 5 RXNE: Read data register not empty/RXFIFO not empty
40 * Bit 6 TC: Transmission complete
41 * Bit 7 TXE/TXFNF: Transmit data register empty/TXFIFO not full
42 * Bit 23 TXFE: TXFIFO empty
43 */
44 #define USART_ISR_RXNE_RXFNE BIT(5)
45 #define USART_ISR_TC BIT(6)
46 #define USART_ISR_TXE_TXFNF BIT(7)
47 #define USART_ISR_TXFE BIT(23)
48
loc_chip_to_base(struct serial_chip * chip)49 static vaddr_t loc_chip_to_base(struct serial_chip *chip)
50 {
51 struct stm32_uart_pdata *pd = NULL;
52
53 pd = container_of(chip, struct stm32_uart_pdata, chip);
54
55 return io_pa_or_va(&pd->base, 1);
56 }
57
loc_flush(struct serial_chip * chip)58 static void loc_flush(struct serial_chip *chip)
59 {
60 vaddr_t base = loc_chip_to_base(chip);
61 uint64_t timeout = timeout_init_us(FLUSH_TIMEOUT_US);
62
63 while (!(io_read32(base + UART_REG_ISR) & USART_ISR_TXFE))
64 if (timeout_elapsed(timeout))
65 return;
66 }
67
loc_putc(struct serial_chip * chip,int ch)68 static void loc_putc(struct serial_chip *chip, int ch)
69 {
70 vaddr_t base = loc_chip_to_base(chip);
71 uint64_t timeout = timeout_init_us(PUTC_TIMEOUT_US);
72
73 while (!(io_read32(base + UART_REG_ISR) & USART_ISR_TXE_TXFNF))
74 if (timeout_elapsed(timeout))
75 return;
76
77 io_write32(base + UART_REG_TDR, ch);
78 }
79
loc_have_rx_data(struct serial_chip * chip)80 static bool loc_have_rx_data(struct serial_chip *chip)
81 {
82 vaddr_t base = loc_chip_to_base(chip);
83
84 return io_read32(base + UART_REG_ISR) & USART_ISR_RXNE_RXFNE;
85 }
86
loc_getchar(struct serial_chip * chip)87 static int loc_getchar(struct serial_chip *chip)
88 {
89 vaddr_t base = loc_chip_to_base(chip);
90
91 while (!loc_have_rx_data(chip))
92 ;
93
94 return io_read32(base + UART_REG_RDR) & 0xff;
95 }
96
97 static const struct serial_ops stm32_uart_serial_ops = {
98 .flush = loc_flush,
99 .putc = loc_putc,
100 .have_rx_data = loc_have_rx_data,
101 .getchar = loc_getchar,
102
103 };
104 DECLARE_KEEP_PAGER(stm32_uart_serial_ops);
105
stm32_uart_init(struct stm32_uart_pdata * pd,vaddr_t base)106 void stm32_uart_init(struct stm32_uart_pdata *pd, vaddr_t base)
107 {
108 pd->base.pa = base;
109 pd->chip.ops = &stm32_uart_serial_ops;
110 }
111
stm32_uart_init_from_dt_node(void * fdt,int node)112 struct stm32_uart_pdata *stm32_uart_init_from_dt_node(void *fdt, int node)
113 {
114 TEE_Result res = TEE_ERROR_GENERIC;
115 struct stm32_uart_pdata *pd = NULL;
116 struct dt_node_info info = { };
117
118 fdt_fill_device_info(fdt, &info, node);
119
120 if (info.status == DT_STATUS_DISABLED)
121 return NULL;
122
123 assert(info.reg != DT_INFO_INVALID_REG &&
124 info.reg_size != DT_INFO_INVALID_REG_SIZE);
125
126 pd = calloc(1, sizeof(*pd));
127 if (!pd)
128 panic();
129
130 pd->chip.ops = &stm32_uart_serial_ops;
131 pd->base.pa = info.reg;
132
133 res = clk_dt_get_by_index(fdt, node, 0, &pd->clock);
134 if (res) {
135 EMSG("Failed to get clock: %#"PRIx32, res);
136 panic();
137 }
138
139 res = clk_enable(pd->clock);
140 if (res)
141 panic();
142
143 assert(cpu_mmu_enabled());
144 pd->base.va = (vaddr_t)phys_to_virt(pd->base.pa, MEM_AREA_IO_SEC,
145 info.reg_size);
146
147 res = pinctrl_get_state_by_name(fdt, node, "default", &pd->pinctrl);
148 if (res)
149 panic();
150
151 res = pinctrl_get_state_by_name(fdt, node, "sleep", &pd->pinctrl_sleep);
152 if (res && res != TEE_ERROR_ITEM_NOT_FOUND)
153 panic();
154
155 res = pinctrl_apply_state(pd->pinctrl);
156 if (res)
157 panic();
158
159 return pd;
160 }
161