serial: sh: Add DEBUG_UART support
authorMarek Vasut <marek.vasut+renesas@mailbox.org>
Tue, 28 Feb 2023 21:17:22 +0000 (22:17 +0100)
committerMarek Vasut <marek.vasut+renesas@mailbox.org>
Sat, 18 Mar 2023 11:04:02 +0000 (12:04 +0100)
Add support for debug output very early during boot using the DEBUG_UART
mechanism. This uses a static fixed UART port configuration selected via
Kconfig options and dedicated print functions from debug_uart.h. This is
useful e.g. when debugging problems so early during boot, that not even
the DM is initialized at that point, and thus DM_SERIAL is not available
either.

This functionality is disabled by default. To activate it, define the
following Kconfig options and select SCIF type using CFG_SCI/CFG_SCIF_A/
CFG_HSCIF/<nothing for regular SCIF>:

CONFIG_DEBUG_UART=y
CONFIG_DEBUG_UART_SCIF=y
CONFIG_DEBUG_UART_BASE=0xe6540000
CONFIG_DEBUG_UART_CLOCK=24000000

The later two options define the SCIF physical base address and SCIF
input clock in Hz. Optionally, to validate DEBUG_UART works, enable
the following as well to get early serial output message by default:

CONFIG_DEBUG_UART_ANNOUNCE=y

Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
drivers/serial/Kconfig
drivers/serial/serial_sh.c

index bb50832..10d07da 100644 (file)
@@ -415,6 +415,14 @@ config DEBUG_UART_SEMIHOSTING
          start up driver model. The driver will be available until the real
          driver model serial is running.
 
+config DEBUG_UART_SCIF
+       bool "Renesas SCIF UART"
+       depends on SH || ARCH_RMOBILE
+       help
+         Select this to enable a debug UART using the serial_sh 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_SIFIVE
        bool "SiFive UART"
        depends on SIFIVE_SERIAL
index c3e3f25..e08bdca 100644 (file)
@@ -249,9 +249,40 @@ U_BOOT_DRIVER(serial_sh) = {
 #endif
        .priv_auto      = sizeof(struct uart_port),
 };
+#endif
+
+#if !CONFIG_IS_ENABLED(DM_SERIAL) || IS_ENABLED(CONFIG_DEBUG_UART_SCIF)
 
-#else /* CONFIG_DM_SERIAL */
+#if defined(CFG_SCIF_A)
+       #define SCIF_BASE_PORT  PORT_SCIFA
+#elif defined(CFG_SCI)
+       #define SCIF_BASE_PORT  PORT_SCI
+#else
+       #define SCIF_BASE_PORT  PORT_SCIF
+#endif
+
+static void sh_serial_init_nodm(struct uart_port *port)
+{
+       sh_serial_init_generic(port);
+       serial_setbrg();
+}
+
+static void sh_serial_putc_nondm(struct uart_port *port, const char c)
+{
+       if (c == '\n') {
+               while (1) {
+                       if  (serial_raw_putc(port, '\r') != -EAGAIN)
+                               break;
+               }
+       }
+       while (1) {
+               if  (serial_raw_putc(port, c) != -EAGAIN)
+                       break;
+       }
+}
+#endif
 
+#if !CONFIG_IS_ENABLED(DM_SERIAL)
 #if defined(CONFIG_CONS_SCIF0)
 # define SCIF_BASE     SCIF0_BASE
 #elif defined(CONFIG_CONS_SCIF1)
@@ -274,14 +305,6 @@ U_BOOT_DRIVER(serial_sh) = {
 # error "Default SCIF doesn't set....."
 #endif
 
-#if defined(CFG_SCIF_A)
-       #define SCIF_BASE_PORT  PORT_SCIFA
-#elif defined(CFG_SCI)
-       #define SCIF_BASE_PORT  PORT_SCI
-#else
-       #define SCIF_BASE_PORT  PORT_SCIF
-#endif
-
 static struct uart_port sh_sci = {
        .membase        = (unsigned char *)SCIF_BASE,
        .mapbase        = SCIF_BASE,
@@ -301,28 +324,14 @@ static void sh_serial_setbrg(void)
 
 static int sh_serial_init(void)
 {
-       struct uart_port *port = &sh_sci;
-
-       sh_serial_init_generic(port);
-       serial_setbrg();
+       sh_serial_init_nodm(&sh_sci);
 
        return 0;
 }
 
 static void sh_serial_putc(const char c)
 {
-       struct uart_port *port = &sh_sci;
-
-       if (c == '\n') {
-               while (1) {
-                       if  (serial_raw_putc(port, '\r') != -EAGAIN)
-                               break;
-               }
-       }
-       while (1) {
-               if  (serial_raw_putc(port, c) != -EAGAIN)
-                       break;
-       }
+       sh_serial_putc_nondm(&sh_sci, c);
 }
 
 static int sh_serial_tstc(void)
@@ -367,3 +376,29 @@ __weak struct serial_device *default_serial_console(void)
        return &sh_serial_drv;
 }
 #endif /* CONFIG_DM_SERIAL */
+
+#ifdef CONFIG_DEBUG_UART_SCIF
+#include <debug_uart.h>
+
+static struct uart_port debug_uart_sci = {
+       .membase        = (unsigned char *)CONFIG_DEBUG_UART_BASE,
+       .mapbase        = CONFIG_DEBUG_UART_BASE,
+       .type           = SCIF_BASE_PORT,
+#ifdef CFG_SCIF_USE_EXT_CLK
+       .clk_mode =     EXT_CLK,
+#endif
+};
+
+static inline void _debug_uart_init(void)
+{
+       sh_serial_init_nodm(&debug_uart_sci);
+}
+
+static inline void _debug_uart_putc(int c)
+{
+       sh_serial_putc_nondm(&debug_uart_sci, c);
+}
+
+DEBUG_UART_FUNCS
+
+#endif