mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2025-12-21 17:32:09 +01:00
serial: serial_meson: add minimal non-DM driver
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. Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Signed-off-by: Ferass El Hafidi <funderscore@postmarketos.org> Link: https://patch.msgid.link/20251126-spl-gx-v5-3-6cbffb2451ca@postmarketos.org Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
This commit is contained in:
parent
3eee9c1f61
commit
ec958be7cc
@ -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);
|
||||
|
||||
|
||||
@ -3,9 +3,11 @@
|
||||
* (C) Copyright 2016 Beniamino Galvani <b.galvani@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>
|
||||
@ -25,6 +27,15 @@ struct meson_serial_plat {
|
||||
struct meson_uart *reg;
|
||||
};
|
||||
|
||||
#if !CONFIG_IS_ENABLED(DM_SERIAL)
|
||||
/* UART base address */
|
||||
#if defined(CONFIG_MESON_GX)
|
||||
#define AML_UART_BASE 0xc81004c0
|
||||
#else /* G12A, AXG, ... */
|
||||
#define AML_UART_BASE 0xff803000
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* AML_UART_STATUS bits */
|
||||
#define AML_UART_PARITY_ERR BIT(16)
|
||||
#define AML_UART_FRAME_ERR BIT(17)
|
||||
@ -51,6 +62,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 +257,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 *)AML_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 *)AML_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 *)AML_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 *)AML_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>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user