serial: serial_mtk: add non-DM version for SPL

This patch adds non-DM version for mtk hsuart driver and makes it
compatible with ns16550a driver in configuration.
This is needed in SPL with CONFIG_SPL_DM disabled for reducing size.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
This commit is contained in:
Weijie Gao 2019-09-25 17:45:18 +08:00 committed by Daniel Schwierzeck
parent 99ced5331b
commit 44fa676e58
2 changed files with 187 additions and 17 deletions

View File

@ -124,6 +124,7 @@ serial_initfunc(ns16550_serial_initialize);
serial_initfunc(pl01x_serial_initialize);
serial_initfunc(pxa_serial_initialize);
serial_initfunc(sh_serial_initialize);
serial_initfunc(mtk_serial_initialize);
/**
* serial_register() - Register serial driver with serial driver core
@ -177,6 +178,7 @@ void serial_initialize(void)
pl01x_serial_initialize();
pxa_serial_initialize();
sh_serial_initialize();
mtk_serial_initialize();
serial_assign(default_serial_console()->name);
}

View File

@ -140,6 +140,37 @@ static void _mtk_serial_setbrg(struct mtk_serial_priv *priv, int baud)
}
}
static int _mtk_serial_putc(struct mtk_serial_priv *priv, const char ch)
{
if (!(readl(&priv->regs->lsr) & UART_LSR_THRE))
return -EAGAIN;
writel(ch, &priv->regs->thr);
if (ch == '\n')
WATCHDOG_RESET();
return 0;
}
static int _mtk_serial_getc(struct mtk_serial_priv *priv)
{
if (!(readl(&priv->regs->lsr) & UART_LSR_DR))
return -EAGAIN;
return readl(&priv->regs->rbr);
}
static int _mtk_serial_pending(struct mtk_serial_priv *priv, bool input)
{
if (input)
return (readl(&priv->regs->lsr) & UART_LSR_DR) ? 1 : 0;
else
return (readl(&priv->regs->lsr) & UART_LSR_THRE) ? 0 : 1;
}
#if defined(CONFIG_DM_SERIAL) && \
(!defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_DM))
static int mtk_serial_setbrg(struct udevice *dev, int baudrate)
{
struct mtk_serial_priv *priv = dev_get_priv(dev);
@ -153,35 +184,21 @@ static int mtk_serial_putc(struct udevice *dev, const char ch)
{
struct mtk_serial_priv *priv = dev_get_priv(dev);
if (!(readl(&priv->regs->lsr) & UART_LSR_THRE))
return -EAGAIN;
writel(ch, &priv->regs->thr);
if (ch == '\n')
WATCHDOG_RESET();
return 0;
return _mtk_serial_putc(priv, ch);
}
static int mtk_serial_getc(struct udevice *dev)
{
struct mtk_serial_priv *priv = dev_get_priv(dev);
if (!(readl(&priv->regs->lsr) & UART_LSR_DR))
return -EAGAIN;
return readl(&priv->regs->rbr);
return _mtk_serial_getc(priv);
}
static int mtk_serial_pending(struct udevice *dev, bool input)
{
struct mtk_serial_priv *priv = dev_get_priv(dev);
if (input)
return (readl(&priv->regs->lsr) & UART_LSR_DR) ? 1 : 0;
else
return (readl(&priv->regs->lsr) & UART_LSR_THRE) ? 0 : 1;
return _mtk_serial_pending(priv, input);
}
static int mtk_serial_probe(struct udevice *dev)
@ -254,6 +271,157 @@ U_BOOT_DRIVER(serial_mtk) = {
.ops = &mtk_serial_ops,
.flags = DM_FLAG_PRE_RELOC,
};
#else
DECLARE_GLOBAL_DATA_PTR;
#define DECLARE_HSUART_PRIV(port) \
static struct mtk_serial_priv mtk_hsuart##port = { \
.regs = (struct mtk_serial_regs *)CONFIG_SYS_NS16550_COM##port, \
.clock = CONFIG_SYS_NS16550_CLK \
};
#define DECLARE_HSUART_FUNCTIONS(port) \
static int mtk_serial##port##_init(void) \
{ \
writel(0, &mtk_hsuart##port.regs->ier); \
writel(UART_MCRVAL, &mtk_hsuart##port.regs->mcr); \
writel(UART_FCRVAL, &mtk_hsuart##port.regs->fcr); \
_mtk_serial_setbrg(&mtk_hsuart##port, gd->baudrate); \
return 0 ; \
} \
static void mtk_serial##port##_setbrg(void) \
{ \
_mtk_serial_setbrg(&mtk_hsuart##port, gd->baudrate); \
} \
static int mtk_serial##port##_getc(void) \
{ \
int err; \
do { \
err = _mtk_serial_getc(&mtk_hsuart##port); \
if (err == -EAGAIN) \
WATCHDOG_RESET(); \
} while (err == -EAGAIN); \
return err >= 0 ? err : 0; \
} \
static int mtk_serial##port##_tstc(void) \
{ \
return _mtk_serial_pending(&mtk_hsuart##port, true); \
} \
static void mtk_serial##port##_putc(const char c) \
{ \
int err; \
if (c == '\n') \
mtk_serial##port##_putc('\r'); \
do { \
err = _mtk_serial_putc(&mtk_hsuart##port, c); \
} while (err == -EAGAIN); \
} \
static void mtk_serial##port##_puts(const char *s) \
{ \
while (*s) { \
mtk_serial##port##_putc(*s++); \
} \
}
/* Serial device descriptor */
#define INIT_HSUART_STRUCTURE(port, __name) { \
.name = __name, \
.start = mtk_serial##port##_init, \
.stop = NULL, \
.setbrg = mtk_serial##port##_setbrg, \
.getc = mtk_serial##port##_getc, \
.tstc = mtk_serial##port##_tstc, \
.putc = mtk_serial##port##_putc, \
.puts = mtk_serial##port##_puts, \
}
#define DECLARE_HSUART(port, __name) \
DECLARE_HSUART_PRIV(port); \
DECLARE_HSUART_FUNCTIONS(port); \
struct serial_device mtk_hsuart##port##_device = \
INIT_HSUART_STRUCTURE(port, __name);
#if !defined(CONFIG_CONS_INDEX)
#elif (CONFIG_CONS_INDEX < 1) || (CONFIG_CONS_INDEX > 6)
#error "Invalid console index value."
#endif
#if CONFIG_CONS_INDEX == 1 && !defined(CONFIG_SYS_NS16550_COM1)
#error "Console port 1 defined but not configured."
#elif CONFIG_CONS_INDEX == 2 && !defined(CONFIG_SYS_NS16550_COM2)
#error "Console port 2 defined but not configured."
#elif CONFIG_CONS_INDEX == 3 && !defined(CONFIG_SYS_NS16550_COM3)
#error "Console port 3 defined but not configured."
#elif CONFIG_CONS_INDEX == 4 && !defined(CONFIG_SYS_NS16550_COM4)
#error "Console port 4 defined but not configured."
#elif CONFIG_CONS_INDEX == 5 && !defined(CONFIG_SYS_NS16550_COM5)
#error "Console port 5 defined but not configured."
#elif CONFIG_CONS_INDEX == 6 && !defined(CONFIG_SYS_NS16550_COM6)
#error "Console port 6 defined but not configured."
#endif
#if defined(CONFIG_SYS_NS16550_COM1)
DECLARE_HSUART(1, "mtk-hsuart0");
#endif
#if defined(CONFIG_SYS_NS16550_COM2)
DECLARE_HSUART(2, "mtk-hsuart1");
#endif
#if defined(CONFIG_SYS_NS16550_COM3)
DECLARE_HSUART(3, "mtk-hsuart2");
#endif
#if defined(CONFIG_SYS_NS16550_COM4)
DECLARE_HSUART(4, "mtk-hsuart3");
#endif
#if defined(CONFIG_SYS_NS16550_COM5)
DECLARE_HSUART(5, "mtk-hsuart4");
#endif
#if defined(CONFIG_SYS_NS16550_COM6)
DECLARE_HSUART(6, "mtk-hsuart5");
#endif
__weak struct serial_device *default_serial_console(void)
{
#if CONFIG_CONS_INDEX == 1
return &mtk_hsuart1_device;
#elif CONFIG_CONS_INDEX == 2
return &mtk_hsuart2_device;
#elif CONFIG_CONS_INDEX == 3
return &mtk_hsuart3_device;
#elif CONFIG_CONS_INDEX == 4
return &mtk_hsuart4_device;
#elif CONFIG_CONS_INDEX == 5
return &mtk_hsuart5_device;
#elif CONFIG_CONS_INDEX == 6
return &mtk_hsuart6_device;
#else
#error "Bad CONFIG_CONS_INDEX."
#endif
}
void mtk_serial_initialize(void)
{
#if defined(CONFIG_SYS_NS16550_COM1)
serial_register(&mtk_hsuart1_device);
#endif
#if defined(CONFIG_SYS_NS16550_COM2)
serial_register(&mtk_hsuart2_device);
#endif
#if defined(CONFIG_SYS_NS16550_COM3)
serial_register(&mtk_hsuart3_device);
#endif
#if defined(CONFIG_SYS_NS16550_COM4)
serial_register(&mtk_hsuart4_device);
#endif
#if defined(CONFIG_SYS_NS16550_COM5)
serial_register(&mtk_hsuart5_device);
#endif
#if defined(CONFIG_SYS_NS16550_COM6)
serial_register(&mtk_hsuart6_device);
#endif
}
#endif
#ifdef CONFIG_DEBUG_UART_MTK