On 07/09/2025 16:36, Ferass El Hafidi wrote:
It is very limited and minimal, only implements putc/puts.
This minimal driver is intended to be used in SPL, and other
size-constrained situations.

Signed-off-by: Ferass El Hafidi <fundersc...@postmarketos.org>
---
  drivers/serial/serial.c       |   2 +
  drivers/serial/serial_meson.c | 112 +++++++++++++++++++++++++++++++++++++++++-
  2 files changed, 113 insertions(+), 1 deletion(-)

diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c
index 
e10ca6eef768502ea32bf39a41ae2e3ccd168c66..c0b1eb3056181b95e1861f1ce08fcd82ff81eb71
 100644
--- a/drivers/serial/serial.c
+++ b/drivers/serial/serial.c
@@ -129,6 +129,7 @@ serial_initfunc(pxa_serial_initialize);
  serial_initfunc(smh_serial_initialize);
  serial_initfunc(sh_serial_initialize);
  serial_initfunc(mtk_serial_initialize);
+serial_initfunc(meson_serial_initialize);
/**
   * serial_register() - Register serial driver with serial driver core
@@ -167,6 +168,7 @@ int serial_initialize(void)
        smh_serial_initialize();
        sh_serial_initialize();
        mtk_serial_initialize();
+       meson_serial_initialize();
serial_assign(default_serial_console()->name); diff --git a/drivers/serial/serial_meson.c b/drivers/serial/serial_meson.c
index 
bb79b9729579a661084425d6b3c5357da31dc3c0..981ea5e159062b7d13885325e17b833145281158
 100644
--- a/drivers/serial/serial_meson.c
+++ b/drivers/serial/serial_meson.c
@@ -3,9 +3,11 @@
   * (C) Copyright 2016 Beniamino Galvani <b.galv...@gmail.com>
   */
+#if CONFIG_IS_ENABLED(DM_SERIAL)
  #include <dm.h>
-#include <errno.h>
  #include <fdtdec.h>
+#endif
+#include <errno.h>
  #include <linux/kernel.h>
  #include <linux/bitops.h>
  #include <linux/compiler.h>
@@ -51,6 +53,7 @@ struct meson_serial_plat {
  #define AML_UART_REG5_USE_NEW_BAUD    BIT(23) /* default 1 (use new baud rate 
register) */
  #define AML_UART_REG5_BAUD_MASK               0x7fffff
+#if CONFIG_IS_ENABLED(DM_SERIAL)
  static u32 meson_calc_baud_divisor(ulong src_rate, u32 baud)
  {
        /*
@@ -245,6 +248,113 @@ U_BOOT_DRIVER(serial_meson) = {
        .plat_auto      = sizeof(struct meson_serial_plat),
  };
+DM_DRIVER_ALIAS(serial_meson, amlogic_meson_gx_uart);

Why is this needed ?

+
+#else
+
+static int meson_serial_init(void)
+{
+       struct meson_uart *const uart = (struct meson_uart 
*)CONFIG_VAL(DEBUG_UART_BASE);
+       u32 val;
+
+       val = readl(&uart->control);
+       val |= (AML_UART_RX_RST | AML_UART_TX_RST | AML_UART_CLR_ERR);
+       writel(val, &uart->control);
+       val &= ~(AML_UART_RX_RST | AML_UART_TX_RST | AML_UART_CLR_ERR);
+       writel(val, &uart->control);
+       val |= (AML_UART_RX_EN | AML_UART_TX_EN);
+       writel(val, &uart->control);
+
+       return 0;
+}
+
+static int meson_serial_stop(void)
+{
+       return 0;
+}
+
+static void meson_serial_setbrg(void)
+{
+}
+
+static void meson_serial_putc(const char ch)
+{
+       struct meson_uart *uart = (struct meson_uart 
*)CONFIG_VAL(DEBUG_UART_BASE);
+
+       /* On '\n' also do '\r' */
+       if (ch == '\n')
+               meson_serial_putc('\r');
+
+       while (readl(&uart->status) & AML_UART_TX_FULL)
+               ;
+
+       writel(ch, &uart->wfifo);
+}
+
+static void meson_serial_puts(const char *s)
+{
+       while (*s)
+               meson_serial_putc(*s++);
+}
+
+static int meson_serial_getc(void)
+{
+       struct meson_uart *const uart = (struct meson_uart 
*)CONFIG_VAL(DEBUG_UART_BASE);
+       uint32_t status = readl(&uart->status);
+
+       if (status & AML_UART_RX_EMPTY)
+               return -EAGAIN;
+
+       if (status & AML_UART_ERR) {
+               u32 val = readl(&uart->control);
+
+               /* Clear error */
+               val |= AML_UART_CLR_ERR;
+               writel(val, &uart->control);
+               val &= ~AML_UART_CLR_ERR;
+               writel(val, &uart->control);
+
+               /* Remove spurious byte from fifo */
+               readl(&uart->rfifo);
+               return -EIO;
+       }
+
+       return readl(&uart->rfifo) & 0xff;
+}
+
+static int meson_serial_tstc(void)
+{
+       struct meson_uart *const uart = (struct meson_uart 
*)CONFIG_VAL(DEBUG_UART_BASE);
+       uint32_t status = readl(&uart->status);
+
+       if (status & AML_UART_RX_EMPTY)
+               return 0;
+       return 1;
+}
+
+struct serial_device meson_serial_device = {
+       .name   = "meson_serial",
+       .start  = meson_serial_init,
+       .stop   = meson_serial_stop,
+       .setbrg = meson_serial_setbrg,
+       .getc   = meson_serial_getc,
+       .tstc   = meson_serial_tstc,
+       .putc   = meson_serial_putc,
+       .puts   = meson_serial_puts,
+};
+
+void meson_serial_initialize(void)
+{
+       serial_register(&meson_serial_device);
+}
+
+__weak struct serial_device *default_serial_console(void)
+{
+       return &meson_serial_device;
+}
+
+#endif
+
  #ifdef CONFIG_DEBUG_UART_MESON
#include <debug_uart.h>


Reply via email to