serial: serial_mtk: add non-DM version for SPL
authorWeijie Gao <weijie.gao@mediatek.com>
Wed, 25 Sep 2019 09:45:18 +0000 (17:45 +0800)
committerDaniel Schwierzeck <daniel.schwierzeck@gmail.com>
Fri, 25 Oct 2019 15:20:43 +0000 (17:20 +0200)
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>
drivers/serial/serial.c
drivers/serial/serial_mtk.c

index b907508dbe5d75c0d29f79871b911ee5402221a0..bf5f39215d1df9521e270399fb69dea5450b7b3f 100644 (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);
 }
index 11892a87405536e8d81101fc598e1653a062395e..18530a4fd15e27b7e5e305b82d59cdc222914bd6 100644 (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