aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrice Chotard <patrice.chotard@foss.st.com>2023-05-31 08:01:30 +0200
committerPatrice Chotard <patrice.chotard@foss.st.com>2023-06-16 11:29:29 +0200
commitb4dbc5d65a67456db9cfe874d123e1c87860301d (patch)
tree7ad910087de646219df5e2a460ae0ecebc888acc
parent6d9f86571d10309f00dc9a7f3d8b9882cfd23ce4 (diff)
downloadu-boot-b4dbc5d65a67456db9cfe874d123e1c87860301d.zip
u-boot-b4dbc5d65a67456db9cfe874d123e1c87860301d.tar.gz
u-boot-b4dbc5d65a67456db9cfe874d123e1c87860301d.tar.bz2
serial: stm32: Wait TC bit before performing initialization
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>
-rw-r--r--drivers/serial/serial_stm32.c15
-rw-r--r--drivers/serial/serial_stm32.h1
2 files changed, 16 insertions, 0 deletions
diff --git a/drivers/serial/serial_stm32.c b/drivers/serial/serial_stm32.c
index 2ba92bf..93f7094 100644
--- a/drivers/serial/serial_stm32.c
+++ b/drivers/serial/serial_stm32.c
@@ -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);
diff --git a/drivers/serial/serial_stm32.h b/drivers/serial/serial_stm32.h
index 5bee68f..b7e7a90 100644
--- a/drivers/serial/serial_stm32.h
+++ b/drivers/serial/serial_stm32.h
@@ -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)