[U-Boot] [PATCH v3 02/28] serial: serial_mtk: add non-DM version for SPL

Weijie Gao weijie.gao at mediatek.com
Wed Sep 25 09:45:18 UTC 2019


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 at mediatek.com>
---
 drivers/serial/serial.c     |   2 +
 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
 
-- 
2.17.1



More information about the U-Boot mailing list