1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2016, STMicroelectronics - All Rights Reserved
4 * Author(s): Vikas Manocha, <vikas.manocha@st.com> for STMicroelectronics.
7 #define LOG_CATEGORY UCLASS_SERIAL
17 #include <asm/arch/stm32.h>
18 #include <dm/device_compat.h>
19 #include <linux/bitops.h>
20 #include <linux/delay.h>
21 #include <linux/iopoll.h>
22 #include "serial_stm32.h"
23 #include <dm/device_compat.h>
27 * 1 bit = 1 / 115200 = 8,68 us
29 * 10 bits are needed for worst case (8 bits + 1 start + 1 stop) = 86.806 us
31 #define ONE_BYTE_B115200_US 87
33 static void _stm32_serial_setbrg(fdt_addr_t base
,
34 struct stm32_uart_info
*uart_info
,
38 bool stm32f4
= uart_info
->stm32f4
;
39 u32 int_div
, mantissa
, fraction
, oversampling
;
40 u8 uart_enable_bit
= uart_info
->uart_enable_bit
;
42 /* BRR register must be set when uart is disabled */
43 clrbits_le32(base
+ CR1_OFFSET(stm32f4
), BIT(uart_enable_bit
));
45 int_div
= DIV_ROUND_CLOSEST(clock_rate
, baudrate
);
49 setbits_le32(base
+ CR1_OFFSET(stm32f4
), USART_CR1_OVER8
);
52 clrbits_le32(base
+ CR1_OFFSET(stm32f4
), USART_CR1_OVER8
);
55 mantissa
= (int_div
/ oversampling
) << USART_BRR_M_SHIFT
;
56 fraction
= int_div
% oversampling
;
58 writel(mantissa
| fraction
, base
+ BRR_OFFSET(stm32f4
));
60 setbits_le32(base
+ CR1_OFFSET(stm32f4
), BIT(uart_enable_bit
));
63 static int stm32_serial_setbrg(struct udevice
*dev
, int baudrate
)
65 struct stm32x7_serial_plat
*plat
= dev_get_plat(dev
);
67 _stm32_serial_setbrg(plat
->base
, plat
->uart_info
,
68 plat
->clock_rate
, baudrate
);
73 static int stm32_serial_setconfig(struct udevice
*dev
, uint serial_config
)
75 struct stm32x7_serial_plat
*plat
= dev_get_plat(dev
);
76 bool stm32f4
= plat
->uart_info
->stm32f4
;
77 u8 uart_enable_bit
= plat
->uart_info
->uart_enable_bit
;
78 u32 cr1
= plat
->base
+ CR1_OFFSET(stm32f4
);
80 uint parity
= SERIAL_GET_PARITY(serial_config
);
81 uint bits
= SERIAL_GET_BITS(serial_config
);
82 uint stop
= SERIAL_GET_STOP(serial_config
);
85 * only parity config is implemented, check if other serial settings
86 * are the default one.
87 * (STM32F4 serial IP didn't support parity setting)
89 if (bits
!= SERIAL_8_BITS
|| stop
!= SERIAL_ONE_STOP
|| stm32f4
)
90 return -ENOTSUPP
; /* not supported in driver*/
92 clrbits_le32(cr1
, USART_CR1_RE
| USART_CR1_TE
| BIT(uart_enable_bit
));
93 /* update usart configuration (uart need to be disable)
94 * PCE: parity check enable
95 * PS : '0' : Even / '1' : Odd
96 * M[1:0] = '00' : 8 Data bits
97 * M[1:0] = '01' : 9 Data bits with parity
101 case SERIAL_PAR_NONE
:
105 config
= USART_CR1_PCE
| USART_CR1_PS
| USART_CR1_M0
;
107 case SERIAL_PAR_EVEN
:
108 config
= USART_CR1_PCE
| USART_CR1_M0
;
113 USART_CR1_PCE
| USART_CR1_PS
| USART_CR1_M1
|
116 setbits_le32(cr1
, USART_CR1_RE
| USART_CR1_TE
| BIT(uart_enable_bit
));
121 static int stm32_serial_getc(struct udevice
*dev
)
123 struct stm32x7_serial_plat
*plat
= dev_get_plat(dev
);
124 bool stm32f4
= plat
->uart_info
->stm32f4
;
125 fdt_addr_t base
= plat
->base
;
126 u32 isr
= readl(base
+ ISR_OFFSET(stm32f4
));
128 if ((isr
& USART_ISR_RXNE
) == 0)
131 if (isr
& (USART_ISR_PE
| USART_ISR_ORE
| USART_ISR_FE
)) {
133 setbits_le32(base
+ ICR_OFFSET
,
134 USART_ICR_PCECF
| USART_ICR_ORECF
|
137 readl(base
+ RDR_OFFSET(stm32f4
));
141 return readl(base
+ RDR_OFFSET(stm32f4
));
144 static int _stm32_serial_putc(fdt_addr_t base
,
145 struct stm32_uart_info
*uart_info
,
148 bool stm32f4
= uart_info
->stm32f4
;
150 if ((readl(base
+ ISR_OFFSET(stm32f4
)) & USART_ISR_TXE
) == 0)
153 writel(c
, base
+ TDR_OFFSET(stm32f4
));
158 static int stm32_serial_putc(struct udevice
*dev
, const char c
)
160 struct stm32x7_serial_plat
*plat
= dev_get_plat(dev
);
162 return _stm32_serial_putc(plat
->base
, plat
->uart_info
, c
);
165 static int stm32_serial_pending(struct udevice
*dev
, bool input
)
167 struct stm32x7_serial_plat
*plat
= dev_get_plat(dev
);
168 bool stm32f4
= plat
->uart_info
->stm32f4
;
169 fdt_addr_t base
= plat
->base
;
172 return readl(base
+ ISR_OFFSET(stm32f4
)) &
173 USART_ISR_RXNE
? 1 : 0;
175 return readl(base
+ ISR_OFFSET(stm32f4
)) &
176 USART_ISR_TXE
? 0 : 1;
179 static void _stm32_serial_init(fdt_addr_t base
,
180 struct stm32_uart_info
*uart_info
)
182 bool stm32f4
= uart_info
->stm32f4
;
183 u8 uart_enable_bit
= uart_info
->uart_enable_bit
;
185 /* Disable uart-> enable fifo -> enable uart */
186 clrbits_le32(base
+ CR1_OFFSET(stm32f4
), USART_CR1_RE
| USART_CR1_TE
|
187 BIT(uart_enable_bit
));
188 if (uart_info
->has_fifo
)
189 setbits_le32(base
+ CR1_OFFSET(stm32f4
), USART_CR1_FIFOEN
);
190 setbits_le32(base
+ CR1_OFFSET(stm32f4
), USART_CR1_RE
| USART_CR1_TE
|
191 BIT(uart_enable_bit
));
194 static int stm32_serial_probe(struct udevice
*dev
)
196 struct stm32x7_serial_plat
*plat
= dev_get_plat(dev
);
198 struct reset_ctl reset
;
203 plat
->uart_info
= (struct stm32_uart_info
*)dev_get_driver_data(dev
);
204 stm32f4
= plat
->uart_info
->stm32f4
;
206 ret
= clk_get_by_index(dev
, 0, &clk
);
210 ret
= clk_enable(&clk
);
212 dev_err(dev
, "failed to enable clock\n");
217 * before uart initialization, wait for TC bit (Transmission Complete)
218 * in case there is still chars from previous bootstage to transmit
220 ret
= read_poll_timeout(readl
, isr
, isr
& USART_ISR_TC
, 50,
221 16 * ONE_BYTE_B115200_US
, plat
->base
+ ISR_OFFSET(stm32f4
));
223 dev_dbg(dev
, "FIFO not empty, some character can be lost (%d)\n", ret
);
225 ret
= reset_get_by_index(dev
, 0, &reset
);
227 reset_assert(&reset
);
229 reset_deassert(&reset
);
232 plat
->clock_rate
= clk_get_rate(&clk
);
233 if (!plat
->clock_rate
) {
238 _stm32_serial_init(plat
->base
, plat
->uart_info
);
243 static const struct udevice_id stm32_serial_id
[] = {
244 { .compatible
= "st,stm32-uart", .data
= (ulong
)&stm32f4_info
},
245 { .compatible
= "st,stm32f7-uart", .data
= (ulong
)&stm32f7_info
},
246 { .compatible
= "st,stm32h7-uart", .data
= (ulong
)&stm32h7_info
},
250 static int stm32_serial_of_to_plat(struct udevice
*dev
)
252 struct stm32x7_serial_plat
*plat
= dev_get_plat(dev
);
254 plat
->base
= dev_read_addr(dev
);
255 if (plat
->base
== FDT_ADDR_T_NONE
)
261 static const struct dm_serial_ops stm32_serial_ops
= {
262 .putc
= stm32_serial_putc
,
263 .pending
= stm32_serial_pending
,
264 .getc
= stm32_serial_getc
,
265 .setbrg
= stm32_serial_setbrg
,
266 .setconfig
= stm32_serial_setconfig
269 U_BOOT_DRIVER(serial_stm32
) = {
270 .name
= "serial_stm32",
272 .of_match
= of_match_ptr(stm32_serial_id
),
273 .of_to_plat
= of_match_ptr(stm32_serial_of_to_plat
),
274 .plat_auto
= sizeof(struct stm32x7_serial_plat
),
275 .ops
= &stm32_serial_ops
,
276 .probe
= stm32_serial_probe
,
277 #if !CONFIG_IS_ENABLED(OF_CONTROL)
278 .flags
= DM_FLAG_PRE_RELOC
,
282 #ifdef CONFIG_DEBUG_UART_STM32
283 #include <debug_uart.h>
284 static inline struct stm32_uart_info
*_debug_uart_info(void)
286 struct stm32_uart_info
*uart_info
;
288 #if defined(CONFIG_STM32F4)
289 uart_info
= &stm32f4_info
;
290 #elif defined(CONFIG_STM32F7)
291 uart_info
= &stm32f7_info
;
293 uart_info
= &stm32h7_info
;
298 static inline void _debug_uart_init(void)
300 fdt_addr_t base
= CONFIG_VAL(DEBUG_UART_BASE
);
301 struct stm32_uart_info
*uart_info
= _debug_uart_info();
303 _stm32_serial_init(base
, uart_info
);
304 _stm32_serial_setbrg(base
, uart_info
,
305 CONFIG_DEBUG_UART_CLOCK
,
309 static inline void _debug_uart_putc(int c
)
311 fdt_addr_t base
= CONFIG_VAL(DEBUG_UART_BASE
);
312 struct stm32_uart_info
*uart_info
= _debug_uart_info();
314 while (_stm32_serial_putc(base
, uart_info
, c
) == -EAGAIN
)