diff options
author | Weijie Gao <weijie.gao@mediatek.com> | 2019-09-25 17:45:18 +0800 |
---|---|---|
committer | Daniel Schwierzeck <daniel.schwierzeck@gmail.com> | 2019-10-25 17:20:43 +0200 |
commit | 44fa676e58e90ad9283995b544f8e1013524161f (patch) | |
tree | e1a2550e4b878f85f29a98154dbd0784f82d8eef /drivers/serial | |
parent | 99ced5331baf1254232e3f73e113fb7ecedebad2 (diff) |
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>
Diffstat (limited to 'drivers/serial')
-rw-r--r-- | drivers/serial/serial.c | 2 | ||||
-rw-r--r-- | drivers/serial/serial_mtk.c | 202 |
2 files changed, 187 insertions, 17 deletions
diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c index b907508dbe..bf5f39215d 100644 --- a/drivers/serial/serial.c +++ b/drivers/serial/serial.c @@ -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); } diff --git a/drivers/serial/serial_mtk.c b/drivers/serial/serial_mtk.c index 11892a8740..18530a4fd1 100644 --- a/drivers/serial/serial_mtk.c +++ b/drivers/serial/serial_mtk.c @@ -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 |