[U-Boot,v1,1/5] serial: stm32: Add debug uart support

Message ID 1526561446-29004-2-git-send-email-patrice.chotard@st.com
State Accepted
Delegated to: Tom Rini
Headers show
Series
  • Update STM32 serial driver
Related show

Commit Message

Patrice Chotard May 17, 2018, 12:50 p.m.
From: Patrick Delaunay <patrick.delaunay@st.com>

Add support for early debug printf, before the availability of
driver model and device tree support.

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
---

 drivers/serial/Kconfig        |   9 ++++
 drivers/serial/serial_stm32.c | 105 +++++++++++++++++++++++++++++++++---------
 2 files changed, 92 insertions(+), 22 deletions(-)

Comments

Simon Glass May 18, 2018, 1:37 a.m. | #1
On 17 May 2018 at 06:50, Patrice Chotard <patrice.chotard@st.com> wrote:
> From: Patrick Delaunay <patrick.delaunay@st.com>
>
> Add support for early debug printf, before the availability of
> driver model and device tree support.
>
> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
> ---
>
>  drivers/serial/Kconfig        |   9 ++++
>  drivers/serial/serial_stm32.c | 105 +++++++++++++++++++++++++++++++++---------
>  2 files changed, 92 insertions(+), 22 deletions(-)
>

Reviewed-by: Simon Glass <sjg@chromium.org>

One question below.
[..]

> +static inline void _debug_uart_init(void)
> +{
> +       fdt_addr_t base = CONFIG_DEBUG_UART_BASE;
> +       struct stm32_uart_info *uart_info = _debug_uart_info();
> +
> +       _stm32_serial_init(base, uart_info);
> +       _stm32_serial_setbrg(base, uart_info,
> +                            CONFIG_DEBUG_UART_CLOCK,
> +                            CONFIG_BAUDRATE);
> +       printf("DEBUG done\n");

Do you really want this line?

Regards,
Simon
Patrice Chotard May 21, 2018, 7:36 a.m. | #2
Hi Simon

On 05/18/2018 03:37 AM, Simon Glass wrote:
> On 17 May 2018 at 06:50, Patrice Chotard <patrice.chotard@st.com> wrote:
>> From: Patrick Delaunay <patrick.delaunay@st.com>
>>
>> Add support for early debug printf, before the availability of
>> driver model and device tree support.
>>
>> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
>> Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
>> ---
>>
>>   drivers/serial/Kconfig        |   9 ++++
>>   drivers/serial/serial_stm32.c | 105 +++++++++++++++++++++++++++++++++---------
>>   2 files changed, 92 insertions(+), 22 deletions(-)
>>
> 
> Reviewed-by: Simon Glass <sjg@chromium.org>
> 
> One question below.
> [..]
> 
>> +static inline void _debug_uart_init(void)
>> +{
>> +       fdt_addr_t base = CONFIG_DEBUG_UART_BASE;
>> +       struct stm32_uart_info *uart_info = _debug_uart_info();
>> +
>> +       _stm32_serial_init(base, uart_info);
>> +       _stm32_serial_setbrg(base, uart_info,
>> +                            CONFIG_DEBUG_UART_CLOCK,
>> +                            CONFIG_BAUDRATE);
>> +       printf("DEBUG done\n");
> 
> Do you really want this line?

it's a development debug trace, i will remove it.

Thanks

Patrice

> 
> Regards,
> Simon
>
Tom Rini May 28, 2018, 7:13 p.m. | #3
On Thu, May 17, 2018 at 02:50:42PM +0200, Patrice Chotard wrote:

> From: Patrick Delaunay <patrick.delaunay@st.com>
> 
> Add support for early debug printf, before the availability of
> driver model and device tree support.
> 
> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
> Reviewed-by: Simon Glass <sjg@chromium.org>

Applied to u-boot/master, thanks!

Patch

diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 5937910e5bf9..25ac869b0e64 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -315,6 +315,15 @@  config DEBUG_UART_MXC
 	  will need to provide parameters to make this work. The driver will
 	  be available until the real driver model serial is running.
 
+config DEBUG_UART_STM32
+	bool "STMicroelectronics STM32"
+	depends on STM32_SERIAL
+	help
+	  Select this to enable a debug UART using the serial_stm32 driver
+	  You will need to provide parameters to make this work.
+	  The driver will be available until the real driver model
+	  serial is running.
+
 config DEBUG_UART_UNIPHIER
 	bool "UniPhier on-chip UART"
 	depends on ARCH_UNIPHIER
diff --git a/drivers/serial/serial_stm32.c b/drivers/serial/serial_stm32.c
index 6717ffaaa5b9..724d6f967246 100644
--- a/drivers/serial/serial_stm32.c
+++ b/drivers/serial/serial_stm32.c
@@ -7,19 +7,21 @@ 
 #include <common.h>
 #include <clk.h>
 #include <dm.h>
-#include <asm/io.h>
 #include <serial.h>
+#include <watchdog.h>
+#include <asm/io.h>
 #include <asm/arch/stm32.h>
 #include "serial_stm32.h"
 
-static int stm32_serial_setbrg(struct udevice *dev, int baudrate)
+static void _stm32_serial_setbrg(fdt_addr_t base,
+				 struct stm32_uart_info *uart_info,
+				 u32 clock_rate,
+				 int baudrate)
 {
-	struct stm32x7_serial_platdata *plat = dev_get_platdata(dev);
-	bool stm32f4 = plat->uart_info->stm32f4;
-	fdt_addr_t base = plat->base;
+	bool stm32f4 = uart_info->stm32f4;
 	u32 int_div, mantissa, fraction, oversampling;
 
-	int_div = DIV_ROUND_CLOSEST(plat->clock_rate, baudrate);
+	int_div = DIV_ROUND_CLOSEST(clock_rate, baudrate);
 
 	if (int_div < 16) {
 		oversampling = 8;
@@ -33,6 +35,14 @@  static int stm32_serial_setbrg(struct udevice *dev, int baudrate)
 	fraction = int_div % oversampling;
 
 	writel(mantissa | fraction, base + BRR_OFFSET(stm32f4));
+}
+
+static int stm32_serial_setbrg(struct udevice *dev, int baudrate)
+{
+	struct stm32x7_serial_platdata *plat = dev_get_platdata(dev);
+
+	_stm32_serial_setbrg(plat->base, plat->uart_info,
+			     plat->clock_rate, baudrate);
 
 	return 0;
 }
@@ -58,11 +68,11 @@  static int stm32_serial_getc(struct udevice *dev)
 	return readl(base + RDR_OFFSET(stm32f4));
 }
 
-static int stm32_serial_putc(struct udevice *dev, const char c)
+static int _stm32_serial_putc(fdt_addr_t base,
+			      struct stm32_uart_info *uart_info,
+			      const char c)
 {
-	struct stm32x7_serial_platdata *plat = dev_get_platdata(dev);
-	bool stm32f4 = plat->uart_info->stm32f4;
-	fdt_addr_t base = plat->base;
+	bool stm32f4 = uart_info->stm32f4;
 
 	if ((readl(base + ISR_OFFSET(stm32f4)) & USART_ISR_FLAG_TXE) == 0)
 		return -EAGAIN;
@@ -72,6 +82,13 @@  static int stm32_serial_putc(struct udevice *dev, const char c)
 	return 0;
 }
 
+static int stm32_serial_putc(struct udevice *dev, const char c)
+{
+	struct stm32x7_serial_platdata *plat = dev_get_platdata(dev);
+
+	return _stm32_serial_putc(plat->base, plat->uart_info, c);
+}
+
 static int stm32_serial_pending(struct udevice *dev, bool input)
 {
 	struct stm32x7_serial_platdata *plat = dev_get_platdata(dev);
@@ -86,18 +103,28 @@  static int stm32_serial_pending(struct udevice *dev, bool input)
 			USART_ISR_FLAG_TXE ? 0 : 1;
 }
 
+static void _stm32_serial_init(fdt_addr_t base,
+			       struct stm32_uart_info *uart_info)
+{
+	bool stm32f4 = uart_info->stm32f4;
+	u8 uart_enable_bit = uart_info->uart_enable_bit;
+
+	/* Disable uart-> enable fifo -> enable uart */
+	clrbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_RE | USART_CR1_TE |
+		     BIT(uart_enable_bit));
+	if (uart_info->has_fifo)
+		setbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_FIFOEN);
+	setbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_RE | USART_CR1_TE |
+		     BIT(uart_enable_bit));
+}
+
 static int stm32_serial_probe(struct udevice *dev)
 {
 	struct stm32x7_serial_platdata *plat = dev_get_platdata(dev);
 	struct clk clk;
-	fdt_addr_t base = plat->base;
 	int ret;
-	bool stm32f4;
-	u8 uart_enable_bit;
 
 	plat->uart_info = (struct stm32_uart_info *)dev_get_driver_data(dev);
-	stm32f4 = plat->uart_info->stm32f4;
-	uart_enable_bit = plat->uart_info->uart_enable_bit;
 
 	ret = clk_get_by_index(dev, 0, &clk);
 	if (ret < 0)
@@ -115,13 +142,7 @@  static int stm32_serial_probe(struct udevice *dev)
 		return plat->clock_rate;
 	};
 
-	/* Disable uart-> enable fifo-> enable uart */
-	clrbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_RE | USART_CR1_TE |
-		     BIT(uart_enable_bit));
-	if (plat->uart_info->has_fifo)
-		setbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_FIFOEN);
-	setbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_RE | USART_CR1_TE |
-		     BIT(uart_enable_bit));
+	_stm32_serial_init(plat->base, plat->uart_info);
 
 	return 0;
 }
@@ -161,3 +182,43 @@  U_BOOT_DRIVER(serial_stm32) = {
 	.probe = stm32_serial_probe,
 	.flags = DM_FLAG_PRE_RELOC,
 };
+
+#ifdef CONFIG_DEBUG_UART_STM32
+#include <debug_uart.h>
+static inline struct stm32_uart_info *_debug_uart_info(void)
+{
+	struct stm32_uart_info *uart_info;
+
+#if defined(CONFIG_STM32F4)
+	uart_info = &stm32f4_info;
+#elif defined(CONFIG_STM32F7)
+	uart_info = &stm32f7_info;
+#else
+	uart_info = &stm32h7_info;
+#endif
+	return uart_info;
+}
+
+static inline void _debug_uart_init(void)
+{
+	fdt_addr_t base = CONFIG_DEBUG_UART_BASE;
+	struct stm32_uart_info *uart_info = _debug_uart_info();
+
+	_stm32_serial_init(base, uart_info);
+	_stm32_serial_setbrg(base, uart_info,
+			     CONFIG_DEBUG_UART_CLOCK,
+			     CONFIG_BAUDRATE);
+	printf("DEBUG done\n");
+}
+
+static inline void _debug_uart_putc(int c)
+{
+	fdt_addr_t base = CONFIG_DEBUG_UART_BASE;
+	struct stm32_uart_info *uart_info = _debug_uart_info();
+
+	while (_stm32_serial_putc(base, uart_info, c) == -EAGAIN)
+		WATCHDOG_RESET();
+}
+
+DEBUG_UART_FUNCS
+#endif