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 | 110 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 111 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..c728bc8f8347eeaa9c6c5e0c8f5905316e9cc077 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,111 @@ U_BOOT_DRIVER(serial_meson) = { .plat_auto = sizeof(struct meson_serial_plat), }; +#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> -- 2.51.0