summaryrefslogtreecommitdiff
path: root/drivers/serial
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/Kconfig22
-rw-r--r--drivers/serial/arm_dcc.c13
-rw-r--r--drivers/serial/lpc32xx_hsuart.c103
-rw-r--r--drivers/serial/serial_pl01x.c28
4 files changed, 115 insertions, 51 deletions
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 04541c9..92084a2 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -127,6 +127,22 @@ config DEBUG_UART_APBUART
will need to provide parameters to make this work. The driver will
be available until the real driver model serial is running.
+config DEBUG_UART_PL010
+ bool "pl010"
+ help
+ Select this to enable a debug UART using the pl01x driver with the
+ PL010 UART type. You will need to provide parameters to make this
+ work. The driver will be available until the real driver model
+ serial is running.
+
+config DEBUG_UART_PL011
+ bool "pl011"
+ help
+ Select this to enable a debug UART using the pl01x driver with the
+ PL011 UART type. You will need to provide parameters to make this
+ work. The driver will be available until the real driver model
+ serial is running.
+
endchoice
config DEBUG_UART_BASE
@@ -180,6 +196,12 @@ config DEBUG_UART_ANNOUNCE
debug_uart_init()). This can be useful just as a check that
everything is working.
+config DEBUG_UART_SKIP_INIT
+ bool "Skip UART initialization"
+ help
+ Select this if the UART you want to use for debug output is already
+ initialized by the time U-Boot starts its execution.
+
config ALTERA_JTAG_UART
bool "Altera JTAG UART support"
depends on DM_SERIAL
diff --git a/drivers/serial/arm_dcc.c b/drivers/serial/arm_dcc.c
index df7eb05..4624666 100644
--- a/drivers/serial/arm_dcc.c
+++ b/drivers/serial/arm_dcc.c
@@ -2,18 +2,7 @@
* Copyright (C) 2004-2007 ARM Limited.
* Copyright (C) 2008 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * SPDX-License-Identifier: GPL-2.0
*
* As a special exception, if other files instantiate templates or use macros
* or inline functions from this file, or you compile this file and link it
diff --git a/drivers/serial/lpc32xx_hsuart.c b/drivers/serial/lpc32xx_hsuart.c
index c8926a8..b425375 100644
--- a/drivers/serial/lpc32xx_hsuart.c
+++ b/drivers/serial/lpc32xx_hsuart.c
@@ -1,89 +1,114 @@
/*
- * Copyright (C) 2011 Vladimir Zapolskiy <vz@mleia.com>
+ * Copyright (C) 2011-2015 Vladimir Zapolskiy <vz@mleia.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
-#include <asm/arch/cpu.h>
-#include <asm/arch/clk.h>
-#include <asm/arch/uart.h>
-#include <asm/io.h>
+#include <dm.h>
#include <serial.h>
+#include <dm/platform_data/lpc32xx_hsuart.h>
+
+#include <asm/arch/uart.h>
#include <linux/compiler.h>
DECLARE_GLOBAL_DATA_PTR;
-static struct hsuart_regs *hsuart = (struct hsuart_regs *)HS_UART_BASE;
+struct lpc32xx_hsuart_priv {
+ struct hsuart_regs *hsuart;
+};
-static void lpc32xx_serial_setbrg(void)
+static int lpc32xx_serial_setbrg(struct udevice *dev, int baudrate)
{
+ struct lpc32xx_hsuart_priv *priv = dev_get_priv(dev);
+ struct hsuart_regs *hsuart = priv->hsuart;
u32 div;
/* UART rate = PERIPH_CLK / ((HSU_RATE + 1) x 14) */
- div = (get_serial_clock() / 14 + gd->baudrate / 2) / gd->baudrate - 1;
+ div = (get_serial_clock() / 14 + baudrate / 2) / baudrate - 1;
if (div > 255)
div = 255;
writel(div, &hsuart->rate);
+
+ return 0;
}
-static int lpc32xx_serial_getc(void)
+static int lpc32xx_serial_getc(struct udevice *dev)
{
- while (!(readl(&hsuart->level) & HSUART_LEVEL_RX))
- /* NOP */;
+ struct lpc32xx_hsuart_priv *priv = dev_get_priv(dev);
+ struct hsuart_regs *hsuart = priv->hsuart;
+
+ if (!(readl(&hsuart->level) & HSUART_LEVEL_RX))
+ return -EAGAIN;
return readl(&hsuart->rx) & HSUART_RX_DATA;
}
-static void lpc32xx_serial_putc(const char c)
+static int lpc32xx_serial_putc(struct udevice *dev, const char c)
{
- if (c == '\n')
- serial_putc('\r');
+ struct lpc32xx_hsuart_priv *priv = dev_get_priv(dev);
+ struct hsuart_regs *hsuart = priv->hsuart;
+
+ /* Wait for empty FIFO */
+ if (readl(&hsuart->level) & HSUART_LEVEL_TX)
+ return -EAGAIN;
writel(c, &hsuart->tx);
- /* Wait for character to be sent */
- while (readl(&hsuart->level) & HSUART_LEVEL_TX)
- /* NOP */;
+ return 0;
}
-static int lpc32xx_serial_tstc(void)
+static int lpc32xx_serial_pending(struct udevice *dev, bool input)
{
- if (readl(&hsuart->level) & HSUART_LEVEL_RX)
- return 1;
+ struct lpc32xx_hsuart_priv *priv = dev_get_priv(dev);
+ struct hsuart_regs *hsuart = priv->hsuart;
+
+ if (input) {
+ if (readl(&hsuart->level) & HSUART_LEVEL_RX)
+ return 1;
+ } else {
+ if (readl(&hsuart->level) & HSUART_LEVEL_TX)
+ return 1;
+ }
return 0;
}
-static int lpc32xx_serial_init(void)
+static int lpc32xx_serial_init(struct hsuart_regs *hsuart)
{
- lpc32xx_serial_setbrg();
-
/* Disable hardware RTS and CTS flow control, set up RX and TX FIFO */
writel(HSUART_CTRL_TMO_16 | HSUART_CTRL_HSU_OFFSET(20) |
HSUART_CTRL_HSU_RX_TRIG_32 | HSUART_CTRL_HSU_TX_TRIG_0,
&hsuart->ctrl);
+
return 0;
}
-static struct serial_device lpc32xx_serial_drv = {
- .name = "lpc32xx_serial",
- .start = lpc32xx_serial_init,
- .stop = NULL,
+static int lpc32xx_hsuart_probe(struct udevice *dev)
+{
+ struct lpc32xx_hsuart_platdata *platdata = dev_get_platdata(dev);
+ struct lpc32xx_hsuart_priv *priv = dev_get_priv(dev);
+
+ priv->hsuart = (struct hsuart_regs *)platdata->base;
+
+ lpc32xx_serial_init(priv->hsuart);
+
+ return 0;
+}
+
+static const struct dm_serial_ops lpc32xx_hsuart_ops = {
.setbrg = lpc32xx_serial_setbrg,
- .putc = lpc32xx_serial_putc,
- .puts = default_serial_puts,
.getc = lpc32xx_serial_getc,
- .tstc = lpc32xx_serial_tstc,
+ .putc = lpc32xx_serial_putc,
+ .pending = lpc32xx_serial_pending,
};
-void lpc32xx_serial_initialize(void)
-{
- serial_register(&lpc32xx_serial_drv);
-}
-
-__weak struct serial_device *default_serial_console(void)
-{
- return &lpc32xx_serial_drv;
-}
+U_BOOT_DRIVER(lpc32xx_hsuart) = {
+ .name = "lpc32xx_hsuart",
+ .id = UCLASS_SERIAL,
+ .probe = lpc32xx_hsuart_probe,
+ .ops = &lpc32xx_hsuart_ops,
+ .priv_auto_alloc_size = sizeof(struct lpc32xx_hsuart_priv),
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c
index 3a5c1d0..552c945 100644
--- a/drivers/serial/serial_pl01x.c
+++ b/drivers/serial/serial_pl01x.c
@@ -367,3 +367,31 @@ U_BOOT_DRIVER(serial_pl01x) = {
};
#endif
+
+#if defined(CONFIG_DEBUG_UART_PL010) || defined(CONFIG_DEBUG_UART_PL011)
+
+#include <debug_uart.h>
+
+static void _debug_uart_init(void)
+{
+#ifndef CONFIG_DEBUG_UART_SKIP_INIT
+ struct pl01x_regs *regs = (struct pl01x_regs *)CONFIG_DEBUG_UART_BASE;
+ enum pl01x_type type = CONFIG_IS_ENABLED(DEBUG_UART_PL011) ?
+ TYPE_PL011 : TYPE_PL010;
+
+ pl01x_generic_serial_init(regs, type);
+ pl01x_generic_setbrg(regs, type,
+ CONFIG_DEBUG_UART_CLOCK, CONFIG_BAUDRATE);
+#endif
+}
+
+static inline void _debug_uart_putc(int ch)
+{
+ struct pl01x_regs *regs = (struct pl01x_regs *)CONFIG_DEBUG_UART_BASE;
+
+ pl01x_putc(regs, ch);
+}
+
+DEBUG_UART_FUNCS
+
+#endif