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(smh_serial_initialize);
|
||||||
serial_initfunc(sh_serial_initialize);
|
serial_initfunc(sh_serial_initialize);
|
||||||
serial_initfunc(mtk_serial_initialize);
|
serial_initfunc(mtk_serial_initialize);
|
||||||
|
serial_initfunc(meson_serial_initialize);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* serial_register() - Register serial driver with serial driver core
|
* serial_register() - Register serial driver with serial driver core
|
||||||
@ -167,6 +168,7 @@ int serial_initialize(void)
|
|||||||
smh_serial_initialize();
|
smh_serial_initialize();
|
||||||
sh_serial_initialize();
|
sh_serial_initialize();
|
||||||
mtk_serial_initialize();
|
mtk_serial_initialize();
|
||||||
|
meson_serial_initialize();
|
||||||
|
|
||||||
serial_assign(default_serial_console()->name);
|
serial_assign(default_serial_console()->name);
|
||||||
|
|
||||||
|
|||||||
@ -3,9 +3,11 @@
|
|||||||
* (C) Copyright 2016 Beniamino Galvani <b.galvani@gmail.com>
|
* (C) Copyright 2016 Beniamino Galvani <b.galvani@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if CONFIG_IS_ENABLED(DM_SERIAL)
|
||||||
#include <dm.h>
|
#include <dm.h>
|
||||||
#include <errno.h>
|
|
||||||
#include <fdtdec.h>
|
#include <fdtdec.h>
|
||||||
|
#endif
|
||||||
|
#include <errno.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/bitops.h>
|
#include <linux/bitops.h>
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
@ -25,6 +27,15 @@ struct meson_serial_plat {
|
|||||||
struct meson_uart *reg;
|
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 */
|
/* AML_UART_STATUS bits */
|
||||||
#define AML_UART_PARITY_ERR BIT(16)
|
#define AML_UART_PARITY_ERR BIT(16)
|
||||||
#define AML_UART_FRAME_ERR BIT(17)
|
#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_USE_NEW_BAUD BIT(23) /* default 1 (use new baud rate register) */
|
||||||
#define AML_UART_REG5_BAUD_MASK 0x7fffff
|
#define AML_UART_REG5_BAUD_MASK 0x7fffff
|
||||||
|
|
||||||
|
#if CONFIG_IS_ENABLED(DM_SERIAL)
|
||||||
static u32 meson_calc_baud_divisor(ulong src_rate, u32 baud)
|
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),
|
.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
|
#ifdef CONFIG_DEBUG_UART_MESON
|
||||||
|
|
||||||
#include <debug_uart.h>
|
#include <debug_uart.h>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user