serial: stm32: Wait TC bit before performing initialization
authorPatrice Chotard <patrice.chotard@foss.st.com>
Wed, 31 May 2023 06:01:30 +0000 (08:01 +0200)
committerPatrice Chotard <patrice.chotard@foss.st.com>
Fri, 16 Jun 2023 09:29:29 +0000 (11:29 +0200)
In case there is still chars from previous bootstage to transmit, wait
for TC (Transmission Complete) bit to be set which ensure that the last
data written in the USART_TDR has been transmitted out of the shift
register.

Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com>
Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
drivers/serial/serial_stm32.c
drivers/serial/serial_stm32.h

index 2ba92bf..93f7094 100644 (file)
@@ -18,6 +18,7 @@
 #include <dm/device_compat.h>
 #include <linux/bitops.h>
 #include <linux/delay.h>
+#include <linux/iopoll.h>
 #include "serial_stm32.h"
 #include <dm/device_compat.h>
 
@@ -181,9 +182,12 @@ static int stm32_serial_probe(struct udevice *dev)
        struct stm32x7_serial_plat *plat = dev_get_plat(dev);
        struct clk clk;
        struct reset_ctl reset;
+       u32 isr;
        int ret;
+       bool stm32f4;
 
        plat->uart_info = (struct stm32_uart_info *)dev_get_driver_data(dev);
+       stm32f4 = plat->uart_info->stm32f4;
 
        ret = clk_get_by_index(dev, 0, &clk);
        if (ret < 0)
@@ -195,6 +199,17 @@ static int stm32_serial_probe(struct udevice *dev)
                return ret;
        }
 
+       /*
+        * before uart initialization, wait for TC bit (Transmission Complete)
+        * in case there is still chars from previous bootstage to transmit
+        */
+       ret = read_poll_timeout(readl, isr, isr & USART_ISR_TC, 10, 150,
+                               plat->base + ISR_OFFSET(stm32f4));
+       if (ret) {
+               clk_disable(&clk);
+               return ret;
+       }
+
        ret = reset_get_by_index(dev, 0, &reset);
        if (!ret) {
                reset_assert(&reset);
index 5bee68f..b7e7a90 100644 (file)
@@ -66,6 +66,7 @@ struct stm32x7_serial_plat {
 #define USART_CR3_OVRDIS               BIT(12)
 
 #define USART_ISR_TXE                  BIT(7)
+#define USART_ISR_TC                   BIT(6)
 #define USART_ISR_RXNE                 BIT(5)
 #define USART_ISR_ORE                  BIT(3)
 #define USART_ISR_FE                   BIT(1)