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>