summaryrefslogtreecommitdiff
path: root/drivers/serial
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/Makefile3
-rw-r--r--drivers/serial/atmel_usart.c116
-rw-r--r--drivers/serial/ns16550.c40
-rw-r--r--drivers/serial/serial-uclass.c112
-rw-r--r--drivers/serial/serial.c140
-rw-r--r--drivers/serial/serial_dw.c (renamed from drivers/serial/serial_coreboot.c)15
-rw-r--r--drivers/serial/serial_pl01x.c49
-rw-r--r--drivers/serial/serial_sh.h12
-rw-r--r--drivers/serial/serial_tegra.c16
-rw-r--r--drivers/serial/serial_uniphier.c51
-rw-r--r--drivers/serial/serial_x86.c44
-rw-r--r--drivers/serial/usbtty.c2
12 files changed, 438 insertions, 162 deletions
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 2c19ebc288..4cc00cd2f8 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_ALTERA_UART) += altera_uart.o
obj-$(CONFIG_ALTERA_JTAG_UART) += altera_jtag_uart.o
obj-$(CONFIG_ARM_DCC) += arm_dcc.o
obj-$(CONFIG_ATMEL_USART) += atmel_usart.o
+obj-$(CONFIG_DW_SERIAL) += serial_dw.o
obj-$(CONFIG_LPC32XX_HSUART) += lpc32xx_hsuart.o
obj-$(CONFIG_MCFUART) += mcfuart.o
obj-$(CONFIG_OPENCORES_YANU) += opencores_yanu.o
@@ -42,7 +43,7 @@ obj-$(CONFIG_ARC_SERIAL) += serial_arc.o
obj-$(CONFIG_TEGRA_SERIAL) += serial_tegra.o
obj-$(CONFIG_UNIPHIER_SERIAL) += serial_uniphier.o
obj-$(CONFIG_OMAP_SERIAL) += serial_omap.o
-obj-$(CONFIG_COREBOOT_SERIAL) += serial_coreboot.o
+obj-$(CONFIG_X86_SERIAL) += serial_x86.o
ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_USB_TTY) += usbtty.o
diff --git a/drivers/serial/atmel_usart.c b/drivers/serial/atmel_usart.c
index 8f0e3489a0..4fe992bf2b 100644
--- a/drivers/serial/atmel_usart.c
+++ b/drivers/serial/atmel_usart.c
@@ -7,11 +7,16 @@
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
+#include <dm.h>
+#include <errno.h>
#include <watchdog.h>
#include <serial.h>
#include <linux/compiler.h>
#include <asm/io.h>
+#ifdef CONFIG_DM_SERIAL
+#include <asm/arch/atmel_serial.h>
+#endif
#include <asm/arch/clk.h>
#include <asm/arch/hardware.h>
@@ -19,9 +24,9 @@
DECLARE_GLOBAL_DATA_PTR;
-static void atmel_serial_setbrg(void)
+static void atmel_serial_setbrg_internal(atmel_usart3_t *usart, int id,
+ int baudrate)
{
- atmel_usart3_t *usart = (atmel_usart3_t *)CONFIG_USART_BASE;
unsigned long divisor;
unsigned long usart_hz;
@@ -30,15 +35,13 @@ static void atmel_serial_setbrg(void)
* Baud Rate = --------------
* 16 * CD
*/
- usart_hz = get_usart_clk_rate(CONFIG_USART_ID);
- divisor = (usart_hz / 16 + gd->baudrate / 2) / gd->baudrate;
+ usart_hz = get_usart_clk_rate(id);
+ divisor = (usart_hz / 16 + baudrate / 2) / baudrate;
writel(USART3_BF(CD, divisor), &usart->brgr);
}
-static int atmel_serial_init(void)
+static void atmel_serial_init_internal(atmel_usart3_t *usart)
{
- atmel_usart3_t *usart = (atmel_usart3_t *)CONFIG_USART_BASE;
-
/*
* Just in case: drain transmitter register
* 1000us is enough for baudrate >= 9600
@@ -47,9 +50,10 @@ static int atmel_serial_init(void)
__udelay(1000);
writel(USART3_BIT(RSTRX) | USART3_BIT(RSTTX), &usart->cr);
+}
- serial_setbrg();
-
+static void atmel_serial_activate(atmel_usart3_t *usart)
+{
writel((USART3_BF(USART_MODE, USART3_USART_MODE_NORMAL)
| USART3_BF(USCLKS, USART3_USCLKS_MCK)
| USART3_BF(CHRL, USART3_CHRL_8)
@@ -59,6 +63,22 @@ static int atmel_serial_init(void)
writel(USART3_BIT(RXEN) | USART3_BIT(TXEN), &usart->cr);
/* 100us is enough for the new settings to be settled */
__udelay(100);
+}
+
+#ifndef CONFIG_DM_SERIAL
+static void atmel_serial_setbrg(void)
+{
+ atmel_serial_setbrg_internal((atmel_usart3_t *)CONFIG_USART_BASE,
+ CONFIG_USART_ID, gd->baudrate);
+}
+
+static int atmel_serial_init(void)
+{
+ atmel_usart3_t *usart = (atmel_usart3_t *)CONFIG_USART_BASE;
+
+ atmel_serial_init_internal(usart);
+ serial_setbrg();
+ atmel_serial_activate(usart);
return 0;
}
@@ -109,3 +129,81 @@ __weak struct serial_device *default_serial_console(void)
{
return &atmel_serial_drv;
}
+#endif
+
+#ifdef CONFIG_DM_SERIAL
+
+struct atmel_serial_priv {
+ atmel_usart3_t *usart;
+};
+
+int atmel_serial_setbrg(struct udevice *dev, int baudrate)
+{
+ struct atmel_serial_priv *priv = dev_get_priv(dev);
+
+ atmel_serial_setbrg_internal(priv->usart, 0 /* ignored */, baudrate);
+ atmel_serial_activate(priv->usart);
+
+ return 0;
+}
+
+static int atmel_serial_getc(struct udevice *dev)
+{
+ struct atmel_serial_priv *priv = dev_get_priv(dev);
+
+ if (!(readl(&priv->usart->csr) & USART3_BIT(RXRDY)))
+ return -EAGAIN;
+
+ return readl(&priv->usart->rhr);
+}
+
+static int atmel_serial_putc(struct udevice *dev, const char ch)
+{
+ struct atmel_serial_priv *priv = dev_get_priv(dev);
+
+ if (!(readl(&priv->usart->csr) & USART3_BIT(TXRDY)))
+ return -EAGAIN;
+
+ writel(ch, &priv->usart->thr);
+
+ return 0;
+}
+
+static int atmel_serial_pending(struct udevice *dev, bool input)
+{
+ struct atmel_serial_priv *priv = dev_get_priv(dev);
+ uint32_t csr = readl(&priv->usart->csr);
+
+ if (input)
+ return csr & USART3_BIT(RXRDY) ? 1 : 0;
+ else
+ return csr & USART3_BIT(TXEMPTY) ? 0 : 1;
+}
+
+static const struct dm_serial_ops atmel_serial_ops = {
+ .putc = atmel_serial_putc,
+ .pending = atmel_serial_pending,
+ .getc = atmel_serial_getc,
+ .setbrg = atmel_serial_setbrg,
+};
+
+static int atmel_serial_probe(struct udevice *dev)
+{
+ struct atmel_serial_platdata *plat = dev->platdata;
+ struct atmel_serial_priv *priv = dev_get_priv(dev);
+
+ priv->usart = (atmel_usart3_t *)plat->base_addr;
+ atmel_serial_init_internal(priv->usart);
+
+ return 0;
+}
+
+U_BOOT_DRIVER(serial_atmel) = {
+ .name = "serial_atmel",
+ .id = UCLASS_SERIAL,
+ .probe = atmel_serial_probe,
+ .ops = &atmel_serial_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+ .priv_auto_alloc_size = sizeof(struct atmel_serial_priv),
+};
+#endif
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index 8f051914f5..70c946249f 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -132,11 +132,12 @@ static void NS16550_setbrg(NS16550_t com_port, int baud_divisor)
void NS16550_init(NS16550_t com_port, int baud_divisor)
{
-#if (defined(CONFIG_SPL_BUILD) && defined(CONFIG_OMAP34XX))
+#if (defined(CONFIG_SPL_BUILD) && \
+ (defined(CONFIG_OMAP34XX) || defined(CONFIG_OMAP44XX)))
/*
- * On some OMAP3 devices when UART3 is configured for boot mode before
- * SPL starts only THRE bit is set. We have to empty the transmitter
- * before initialization starts.
+ * On some OMAP3/OMAP4 devices when UART3 is configured for boot mode
+ * before SPL starts only THRE bit is set. We have to empty the
+ * transmitter before initialization starts.
*/
if ((serial_in(&com_port->lsr) & (UART_LSR_TEMT | UART_LSR_THRE))
== UART_LSR_THRE) {
@@ -288,7 +289,38 @@ int ns16550_serial_ofdata_to_platdata(struct udevice *dev)
struct ns16550_platdata *plat = dev->platdata;
fdt_addr_t addr;
+ /* try Processor Local Bus device first */
addr = fdtdec_get_addr(gd->fdt_blob, dev->of_offset, "reg");
+#ifdef CONFIG_PCI
+ if (addr == FDT_ADDR_T_NONE) {
+ /* then try pci device */
+ struct fdt_pci_addr pci_addr;
+ u32 bar;
+ int ret;
+
+ /* we prefer to use a memory-mapped register */
+ ret = fdtdec_get_pci_addr(gd->fdt_blob, dev->of_offset,
+ FDT_PCI_SPACE_MEM32, "reg",
+ &pci_addr);
+ if (ret) {
+ /* try if there is any i/o-mapped register */
+ ret = fdtdec_get_pci_addr(gd->fdt_blob,
+ dev->of_offset,
+ FDT_PCI_SPACE_IO,
+ "reg", &pci_addr);
+ if (ret)
+ return ret;
+ }
+
+ ret = fdtdec_get_pci_bar32(gd->fdt_blob, dev->of_offset,
+ &pci_addr, &bar);
+ if (ret)
+ return ret;
+
+ addr = bar;
+ }
+#endif
+
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
index 71f1a5cb91..d1b5777cec 100644
--- a/drivers/serial/serial-uclass.c
+++ b/drivers/serial/serial-uclass.c
@@ -6,6 +6,7 @@
#include <common.h>
#include <dm.h>
+#include <environment.h>
#include <errno.h>
#include <fdtdec.h>
#include <os.h>
@@ -19,8 +20,10 @@
DECLARE_GLOBAL_DATA_PTR;
-/* The currently-selected console serial device */
-struct udevice *cur_dev __attribute__ ((section(".data")));
+/*
+ * Table with supported baudrates (defined in config_xyz.h)
+ */
+static const unsigned long baudrate_table[] = CONFIG_SYS_BAUDRATE_TABLE;
#ifndef CONFIG_SYS_MALLOC_F_LEN
#error "Serial is required before relocation - define CONFIG_SYS_MALLOC_F_LEN to make this work"
@@ -28,25 +31,30 @@ struct udevice *cur_dev __attribute__ ((section(".data")));
static void serial_find_console_or_panic(void)
{
+ struct udevice *dev;
+
#ifdef CONFIG_OF_CONTROL
int node;
/* Check for a chosen console */
node = fdtdec_get_chosen_node(gd->fdt_blob, "stdout-path");
if (node < 0)
- node = fdtdec_get_alias_node(gd->fdt_blob, "console");
- if (!uclass_get_device_by_of_offset(UCLASS_SERIAL, node, &cur_dev))
+ node = fdt_path_offset(gd->fdt_blob, "console");
+ if (!uclass_get_device_by_of_offset(UCLASS_SERIAL, node, &dev)) {
+ gd->cur_serial_dev = dev;
return;
+ }
/*
* If the console is not marked to be bound before relocation, bind
* it anyway.
*/
if (node > 0 &&
- !lists_bind_fdt(gd->dm_root, gd->fdt_blob, node, &cur_dev)) {
- if (!device_probe(cur_dev))
+ !lists_bind_fdt(gd->dm_root, gd->fdt_blob, node, &dev)) {
+ if (!device_probe(dev)) {
+ gd->cur_serial_dev = dev;
return;
- cur_dev = NULL;
+ }
}
#endif
/*
@@ -61,11 +69,12 @@ static void serial_find_console_or_panic(void)
#else
#define INDEX 0
#endif
- if (uclass_get_device_by_seq(UCLASS_SERIAL, INDEX, &cur_dev) &&
- uclass_get_device(UCLASS_SERIAL, INDEX, &cur_dev) &&
- (uclass_first_device(UCLASS_SERIAL, &cur_dev) || !cur_dev))
+ if (uclass_get_device_by_seq(UCLASS_SERIAL, INDEX, &dev) &&
+ uclass_get_device(UCLASS_SERIAL, INDEX, &dev) &&
+ (uclass_first_device(UCLASS_SERIAL, &dev) || !dev))
panic("No serial driver found");
#undef INDEX
+ gd->cur_serial_dev = dev;
}
/* Called prior to relocation */
@@ -127,40 +136,42 @@ static int _serial_tstc(struct udevice *dev)
void serial_putc(char ch)
{
- _serial_putc(cur_dev, ch);
+ _serial_putc(gd->cur_serial_dev, ch);
}
void serial_puts(const char *str)
{
- _serial_puts(cur_dev, str);
+ _serial_puts(gd->cur_serial_dev, str);
}
int serial_getc(void)
{
- return _serial_getc(cur_dev);
+ return _serial_getc(gd->cur_serial_dev);
}
int serial_tstc(void)
{
- return _serial_tstc(cur_dev);
+ return _serial_tstc(gd->cur_serial_dev);
}
void serial_setbrg(void)
{
- struct dm_serial_ops *ops = serial_get_ops(cur_dev);
+ struct dm_serial_ops *ops = serial_get_ops(gd->cur_serial_dev);
if (ops->setbrg)
- ops->setbrg(cur_dev, gd->baudrate);
+ ops->setbrg(gd->cur_serial_dev, gd->baudrate);
}
void serial_stdio_init(void)
{
}
+#ifdef CONFIG_DM_STDIO
static void serial_stub_putc(struct stdio_dev *sdev, const char ch)
{
_serial_putc(sdev->priv, ch);
}
+#endif
void serial_stub_puts(struct stdio_dev *sdev, const char *str)
{
@@ -177,11 +188,74 @@ int serial_stub_tstc(struct stdio_dev *sdev)
return _serial_tstc(sdev->priv);
}
+/**
+ * on_baudrate() - Update the actual baudrate when the env var changes
+ *
+ * This will check for a valid baudrate and only apply it if valid.
+ */
+static int on_baudrate(const char *name, const char *value, enum env_op op,
+ int flags)
+{
+ int i;
+ int baudrate;
+
+ switch (op) {
+ case env_op_create:
+ case env_op_overwrite:
+ /*
+ * Switch to new baudrate if new baudrate is supported
+ */
+ baudrate = simple_strtoul(value, NULL, 10);
+
+ /* Not actually changing */
+ if (gd->baudrate == baudrate)
+ return 0;
+
+ for (i = 0; i < ARRAY_SIZE(baudrate_table); ++i) {
+ if (baudrate == baudrate_table[i])
+ break;
+ }
+ if (i == ARRAY_SIZE(baudrate_table)) {
+ if ((flags & H_FORCE) == 0)
+ printf("## Baudrate %d bps not supported\n",
+ baudrate);
+ return 1;
+ }
+ if ((flags & H_INTERACTIVE) != 0) {
+ printf("## Switch baudrate to %d bps and press ENTER ...\n",
+ baudrate);
+ udelay(50000);
+ }
+
+ gd->baudrate = baudrate;
+
+ serial_setbrg();
+
+ udelay(50000);
+
+ if ((flags & H_INTERACTIVE) != 0)
+ while (1) {
+ if (getc() == '\r')
+ break;
+ }
+
+ return 0;
+ case env_op_delete:
+ printf("## Baudrate may not be deleted\n");
+ return 1;
+ default:
+ return 0;
+ }
+}
+U_BOOT_ENV_CALLBACK(baudrate, on_baudrate);
+
static int serial_post_probe(struct udevice *dev)
{
- struct stdio_dev sdev;
struct dm_serial_ops *ops = serial_get_ops(dev);
+#ifdef CONFIG_DM_STDIO
struct serial_dev_priv *upriv = dev->uclass_priv;
+ struct stdio_dev sdev;
+#endif
int ret;
/* Set the baud rate */
@@ -191,9 +265,9 @@ static int serial_post_probe(struct udevice *dev)
return ret;
}
+#ifdef CONFIG_DM_STDIO
if (!(gd->flags & GD_FLG_RELOC))
return 0;
-
memset(&sdev, '\0', sizeof(sdev));
strncpy(sdev.name, dev->name, sizeof(sdev.name));
@@ -204,7 +278,7 @@ static int serial_post_probe(struct udevice *dev)
sdev.getc = serial_stub_getc;
sdev.tstc = serial_stub_tstc;
stdio_register_dev(&sdev, &upriv->sdev);
-
+#endif
return 0;
}
diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c
index 18e41b2302..95c992a5a3 100644
--- a/drivers/serial/serial.c
+++ b/drivers/serial/serial.c
@@ -109,54 +109,54 @@ U_BOOT_ENV_CALLBACK(baudrate, on_baudrate);
void name(void) \
__attribute__((weak, alias("serial_null")));
-serial_initfunc(mpc8xx_serial_initialize);
-serial_initfunc(ns16550_serial_initialize);
-serial_initfunc(pxa_serial_initialize);
-serial_initfunc(s3c24xx_serial_initialize);
-serial_initfunc(s5p_serial_initialize);
-serial_initfunc(zynq_serial_initialize);
-serial_initfunc(bfin_serial_initialize);
-serial_initfunc(bfin_jtag_initialize);
-serial_initfunc(mpc512x_serial_initialize);
-serial_initfunc(uartlite_serial_initialize);
-serial_initfunc(au1x00_serial_initialize);
-serial_initfunc(asc_serial_initialize);
-serial_initfunc(jz_serial_initialize);
-serial_initfunc(mpc5xx_serial_initialize);
-serial_initfunc(mpc8260_scc_serial_initialize);
-serial_initfunc(mpc8260_smc_serial_initialize);
-serial_initfunc(mpc85xx_serial_initialize);
-serial_initfunc(iop480_serial_initialize);
-serial_initfunc(leon2_serial_initialize);
-serial_initfunc(leon3_serial_initialize);
-serial_initfunc(marvell_serial_initialize);
+serial_initfunc(altera_jtag_serial_initialize);
+serial_initfunc(altera_serial_initialize);
serial_initfunc(amirix_serial_initialize);
+serial_initfunc(arc_serial_initialize);
+serial_initfunc(arm_dcc_initialize);
+serial_initfunc(asc_serial_initialize);
+serial_initfunc(atmel_serial_initialize);
+serial_initfunc(au1x00_serial_initialize);
+serial_initfunc(bfin_jtag_initialize);
+serial_initfunc(bfin_serial_initialize);
serial_initfunc(bmw_serial_initialize);
+serial_initfunc(clps7111_serial_initialize);
serial_initfunc(cogent_serial_initialize);
serial_initfunc(cpci750_serial_initialize);
serial_initfunc(evb64260_serial_initialize);
-serial_initfunc(ml2_serial_initialize);
-serial_initfunc(sconsole_serial_initialize);
-serial_initfunc(p3mx_serial_initialize);
-serial_initfunc(altera_jtag_serial_initialize);
-serial_initfunc(altera_serial_initialize);
-serial_initfunc(atmel_serial_initialize);
-serial_initfunc(lpc32xx_serial_initialize);
-serial_initfunc(mcf_serial_initialize);
-serial_initfunc(oc_serial_initialize);
-serial_initfunc(sandbox_serial_initialize);
-serial_initfunc(clps7111_serial_initialize);
serial_initfunc(imx_serial_initialize);
+serial_initfunc(iop480_serial_initialize);
+serial_initfunc(jz_serial_initialize);
serial_initfunc(ks8695_serial_initialize);
+serial_initfunc(leon2_serial_initialize);
+serial_initfunc(leon3_serial_initialize);
serial_initfunc(lh7a40x_serial_initialize);
+serial_initfunc(lpc32xx_serial_initialize);
+serial_initfunc(marvell_serial_initialize);
serial_initfunc(max3100_serial_initialize);
+serial_initfunc(mcf_serial_initialize);
+serial_initfunc(ml2_serial_initialize);
+serial_initfunc(mpc512x_serial_initialize);
+serial_initfunc(mpc5xx_serial_initialize);
+serial_initfunc(mpc8260_scc_serial_initialize);
+serial_initfunc(mpc8260_smc_serial_initialize);
+serial_initfunc(mpc85xx_serial_initialize);
+serial_initfunc(mpc8xx_serial_initialize);
serial_initfunc(mxc_serial_initialize);
+serial_initfunc(mxs_auart_initialize);
+serial_initfunc(ns16550_serial_initialize);
+serial_initfunc(oc_serial_initialize);
+serial_initfunc(p3mx_serial_initialize);
serial_initfunc(pl01x_serial_initialize);
+serial_initfunc(pxa_serial_initialize);
+serial_initfunc(s3c24xx_serial_initialize);
+serial_initfunc(s5p_serial_initialize);
serial_initfunc(sa1100_serial_initialize);
+serial_initfunc(sandbox_serial_initialize);
+serial_initfunc(sconsole_serial_initialize);
serial_initfunc(sh_serial_initialize);
-serial_initfunc(arm_dcc_initialize);
-serial_initfunc(mxs_auart_initialize);
-serial_initfunc(arc_serial_initialize);
+serial_initfunc(uartlite_serial_initialize);
+serial_initfunc(zynq_serial_initialize);
/**
* serial_register() - Register serial driver with serial driver core
@@ -202,54 +202,54 @@ void serial_register(struct serial_device *dev)
*/
void serial_initialize(void)
{
- mpc8xx_serial_initialize();
- ns16550_serial_initialize();
- pxa_serial_initialize();
- s3c24xx_serial_initialize();
- s5p_serial_initialize();
- mpc512x_serial_initialize();
- bfin_serial_initialize();
- bfin_jtag_initialize();
- uartlite_serial_initialize();
- zynq_serial_initialize();
- au1x00_serial_initialize();
- asc_serial_initialize();
- jz_serial_initialize();
- mpc5xx_serial_initialize();
- mpc8260_scc_serial_initialize();
- mpc8260_smc_serial_initialize();
- mpc85xx_serial_initialize();
- iop480_serial_initialize();
- leon2_serial_initialize();
- leon3_serial_initialize();
- marvell_serial_initialize();
+ altera_jtag_serial_initialize();
+ altera_serial_initialize();
amirix_serial_initialize();
+ arc_serial_initialize();
+ arm_dcc_initialize();
+ asc_serial_initialize();
+ atmel_serial_initialize();
+ au1x00_serial_initialize();
+ bfin_jtag_initialize();
+ bfin_serial_initialize();
bmw_serial_initialize();
+ clps7111_serial_initialize();
cogent_serial_initialize();
cpci750_serial_initialize();
evb64260_serial_initialize();
- ml2_serial_initialize();
- sconsole_serial_initialize();
- p3mx_serial_initialize();
- altera_jtag_serial_initialize();
- altera_serial_initialize();
- atmel_serial_initialize();
- lpc32xx_serial_initialize();
- mcf_serial_initialize();
- oc_serial_initialize();
- sandbox_serial_initialize();
- clps7111_serial_initialize();
imx_serial_initialize();
+ iop480_serial_initialize();
+ jz_serial_initialize();
ks8695_serial_initialize();
+ leon2_serial_initialize();
+ leon3_serial_initialize();
lh7a40x_serial_initialize();
+ lpc32xx_serial_initialize();
+ marvell_serial_initialize();
max3100_serial_initialize();
+ mcf_serial_initialize();
+ ml2_serial_initialize();
+ mpc512x_serial_initialize();
+ mpc5xx_serial_initialize();
+ mpc8260_scc_serial_initialize();
+ mpc8260_smc_serial_initialize();
+ mpc85xx_serial_initialize();
+ mpc8xx_serial_initialize();
mxc_serial_initialize();
+ mxs_auart_initialize();
+ ns16550_serial_initialize();
+ oc_serial_initialize();
+ p3mx_serial_initialize();
pl01x_serial_initialize();
+ pxa_serial_initialize();
+ s3c24xx_serial_initialize();
+ s5p_serial_initialize();
sa1100_serial_initialize();
+ sandbox_serial_initialize();
+ sconsole_serial_initialize();
sh_serial_initialize();
- arm_dcc_initialize();
- mxs_auart_initialize();
- arc_serial_initialize();
+ uartlite_serial_initialize();
+ zynq_serial_initialize();
serial_assign(default_serial_console()->name);
}
diff --git a/drivers/serial/serial_coreboot.c b/drivers/serial/serial_dw.c
index 5c6a76c59c..a348f2956a 100644
--- a/drivers/serial/serial_coreboot.c
+++ b/drivers/serial/serial_dw.c
@@ -9,12 +9,12 @@
#include <ns16550.h>
#include <serial.h>
-static const struct udevice_id coreboot_serial_ids[] = {
- { .compatible = "coreboot-uart" },
+static const struct udevice_id dw_serial_ids[] = {
+ { .compatible = "snps,dw-apb-uart" },
{ }
};
-static int coreboot_serial_ofdata_to_platdata(struct udevice *dev)
+static int dw_serial_ofdata_to_platdata(struct udevice *dev)
{
struct ns16550_platdata *plat = dev_get_platdata(dev);
int ret;
@@ -22,15 +22,16 @@ static int coreboot_serial_ofdata_to_platdata(struct udevice *dev)
ret = ns16550_serial_ofdata_to_platdata(dev);
if (ret)
return ret;
- plat->clock = 1843200;
+ plat->clock = CONFIG_SYS_NS16550_CLK;
return 0;
}
+
U_BOOT_DRIVER(serial_ns16550) = {
- .name = "serial_coreboot",
+ .name = "serial_dw",
.id = UCLASS_SERIAL,
- .of_match = coreboot_serial_ids,
- .ofdata_to_platdata = coreboot_serial_ofdata_to_platdata,
+ .of_match = dw_serial_ids,
+ .ofdata_to_platdata = dw_serial_ofdata_to_platdata,
.platdata_auto_alloc_size = sizeof(struct ns16550_platdata),
.priv_auto_alloc_size = sizeof(struct NS16550),
.probe = ns16550_serial_probe,
diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c
index 38dda91021..75eb6bd729 100644
--- a/drivers/serial/serial_pl01x.c
+++ b/drivers/serial/serial_pl01x.c
@@ -72,30 +72,39 @@ static int pl01x_tstc(struct pl01x_regs *regs)
static int pl01x_generic_serial_init(struct pl01x_regs *regs,
enum pl01x_type type)
{
- unsigned int lcr;
-
+ switch (type) {
+ case TYPE_PL010:
+ /* disable everything */
+ writel(0, &regs->pl010_cr);
+ break;
+ case TYPE_PL011:
#ifdef CONFIG_PL011_SERIAL_FLUSH_ON_INIT
- if (type == TYPE_PL011) {
/* Empty RX fifo if necessary */
if (readl(&regs->pl011_cr) & UART_PL011_CR_UARTEN) {
while (!(readl(&regs->fr) & UART_PL01x_FR_RXFE))
readl(&regs->dr);
}
- }
#endif
+ /* disable everything */
+ writel(0, &regs->pl011_cr);
+ break;
+ default:
+ return -EINVAL;
+ }
- /* First, disable everything */
- writel(0, &regs->pl010_cr);
+ return 0;
+}
- /* Set the UART to be 8 bits, 1 stop bit, no parity, fifo enabled */
+static int set_line_control(struct pl01x_regs *regs)
+{
+ unsigned int lcr;
+ /*
+ * Internal update of baud rate register require line
+ * control register write
+ */
lcr = UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN;
- writel(lcr, &regs->pl011_lcrh);
-
- switch (type) {
- case TYPE_PL010:
- break;
- case TYPE_PL011: {
#ifdef CONFIG_PL011_SERIAL_RLCR
+ {
int i;
/*
@@ -107,15 +116,9 @@ static int pl01x_generic_serial_init(struct pl01x_regs *regs,
writel(lcr, &regs->fr);
writel(lcr, &regs->pl011_rlcr);
- /* lcrh needs to be set again for change to be effective */
- writel(lcr, &regs->pl011_lcrh);
-#endif
- break;
- }
- default:
- return -EINVAL;
}
-
+#endif
+ writel(lcr, &regs->pl011_lcrh);
return 0;
}
@@ -175,6 +178,7 @@ static int pl01x_generic_setbrg(struct pl01x_regs *regs, enum pl01x_type type,
writel(divider, &regs->pl011_ibrd);
writel(fraction, &regs->pl011_fbrd);
+ set_line_control(regs);
/* Finally, enable the UART */
writel(UART_PL011_CR_UARTEN | UART_PL011_CR_TXE |
UART_PL011_CR_RXE | UART_PL011_CR_RTS, &regs->pl011_cr);
@@ -201,7 +205,7 @@ static void pl01x_serial_init_baud(int baudrate)
base_regs = (struct pl01x_regs *)port[CONFIG_CONS_INDEX];
pl01x_generic_serial_init(base_regs, pl01x_type);
- pl01x_generic_setbrg(base_regs, TYPE_PL010, clock, baudrate);
+ pl01x_generic_setbrg(base_regs, pl01x_type, clock, baudrate);
}
/*
@@ -344,6 +348,7 @@ U_BOOT_DRIVER(serial_pl01x) = {
.probe = pl01x_serial_probe,
.ops = &pl01x_serial_ops,
.flags = DM_FLAG_PRE_RELOC,
+ .priv_auto_alloc_size = sizeof(struct pl01x_priv),
};
#endif
diff --git a/drivers/serial/serial_sh.h b/drivers/serial/serial_sh.h
index fe8cde4ded..ef88c8f273 100644
--- a/drivers/serial/serial_sh.h
+++ b/drivers/serial/serial_sh.h
@@ -227,7 +227,7 @@ struct uart_port {
# define SCIF_ORER 0x0001 /* Overrun error bit */
# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
#elif defined(CONFIG_R8A7790) || defined(CONFIG_R8A7791) || \
- defined(CONFIG_R8A7794)
+ defined(CONFIG_R8A7793) || defined(CONFIG_R8A7794)
# define SCIF_ORER 0x0001
# define SCSCR_INIT(port) 0x32 /* TIE=0,RIE=0,TE=1,RE=1,REIE=0, */
#else
@@ -304,7 +304,8 @@ struct uart_port {
/* SH7763 SCIF2 support */
# define SCIF2_RFDC_MASK 0x001f
# define SCIF2_TXROOM_MAX 16
-#elif defined(CONFIG_R8A7790) || defined(CONFIG_R8A7791)
+#elif defined(CONFIG_R8A7790) || defined(CONFIG_R8A7791) || \
+ defined(CONFIG_R8A7793) || defined(CONFIG_R8A7794)
# define SCIF_ERRORS (SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK)
# define SCIF_RFDC_MASK 0x003f
#else
@@ -432,7 +433,7 @@ static inline void sci_##name##_out(struct uart_port *port,\
SCI_OUT(sci_size, sci_offset, value);\
}
-#if defined(CONFIG_SH3) || \
+#if defined(CONFIG_CPU_SH3) || \
defined(CONFIG_ARCH_SH7367) || \
defined(CONFIG_ARCH_SH7377) || \
defined(CONFIG_ARCH_SH7372) || \
@@ -589,7 +590,7 @@ SCIF_FNS(SCSPTR, 0, 0, 0, 0)
SCIF_FNS(SCSPTR, 0, 0, 0x20, 16)
#endif
#if defined(CONFIG_R8A7790) || defined(CONFIG_R8A7791) || \
- defined(CONFIG_R8A7794)
+ defined(CONFIG_R8A7793) || defined(CONFIG_R8A7794)
SCIF_FNS(DL, 0, 0, 0x30, 16)
SCIF_FNS(CKS, 0, 0, 0x34, 16)
#endif
@@ -734,7 +735,8 @@ static inline int scbrr_calc(struct uart_port port, int bps, int clk)
#define SCBRR_VALUE(bps, clk) scbrr_calc(sh_sci, bps, clk)
#elif defined(__H8300H__) || defined(__H8300S__)
#define SCBRR_VALUE(bps, clk) (((clk*1000/32)/bps)-1)
-#elif defined(CONFIG_R8A7790) || defined(CONFIG_R8A7791)
+#elif defined(CONFIG_R8A7790) || defined(CONFIG_R8A7791) || \
+ defined(CONFIG_R8A7793) || defined(CONFIG_R8A7794)
#define DL_VALUE(bps, clk) (clk / bps / 16) /* External Clock */
#define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(32*bps)-1) /* Internal Clock */
#else /* Generic SH */
diff --git a/drivers/serial/serial_tegra.c b/drivers/serial/serial_tegra.c
index 7eb70e1de1..b9227f0563 100644
--- a/drivers/serial/serial_tegra.c
+++ b/drivers/serial/serial_tegra.c
@@ -9,6 +9,7 @@
#include <ns16550.h>
#include <serial.h>
+#ifdef CONFIG_OF_CONTROL
static const struct udevice_id tegra_serial_ids[] = {
{ .compatible = "nvidia,tegra20-uart" },
{ }
@@ -26,13 +27,28 @@ static int tegra_serial_ofdata_to_platdata(struct udevice *dev)
return 0;
}
+#else
+struct ns16550_platdata tegra_serial = {
+ .base = CONFIG_SYS_NS16550_COM1,
+ .reg_shift = 2,
+ .clock = V_NS16550_CLK,
+};
+
+U_BOOT_DEVICE(ns16550_serial) = {
+ "serial_tegra20", &tegra_serial
+};
+#endif
+
U_BOOT_DRIVER(serial_ns16550) = {
.name = "serial_tegra20",
.id = UCLASS_SERIAL,
+#ifdef CONFIG_OF_CONTROL
.of_match = tegra_serial_ids,
.ofdata_to_platdata = tegra_serial_ofdata_to_platdata,
.platdata_auto_alloc_size = sizeof(struct ns16550_platdata),
+#endif
.priv_auto_alloc_size = sizeof(struct NS16550),
.probe = ns16550_serial_probe,
.ops = &ns16550_serial_ops,
+ .flags = DM_FLAG_PRE_RELOC,
};
diff --git a/drivers/serial/serial_uniphier.c b/drivers/serial/serial_uniphier.c
index 9114b3ed60..e8a1608b99 100644
--- a/drivers/serial/serial_uniphier.c
+++ b/drivers/serial/serial_uniphier.c
@@ -5,12 +5,13 @@
* SPDX-License-Identifier: GPL-2.0+
*/
-#include <common.h>
+#include <linux/serial_reg.h>
#include <asm/io.h>
#include <asm/errno.h>
#include <dm/device.h>
#include <dm/platform_data/serial-uniphier.h>
#include <serial.h>
+#include <fdtdec.h>
#define UART_REG(x) \
u8 x; \
@@ -37,17 +38,6 @@ struct uniphier_serial {
#define thr rbr
-/*
- * These are the definitions for the Line Control Register
- */
-#define UART_LCR_WLS_8 0x03 /* 8 bit character length */
-
-/*
- * These are the definitions for the Line Status Register
- */
-#define UART_LSR_DR 0x01 /* Data ready */
-#define UART_LSR_THRE 0x20 /* Xmit holding register empty */
-
struct uniphier_serial_private_data {
struct uniphier_serial __iomem *membase;
};
@@ -55,14 +45,14 @@ struct uniphier_serial_private_data {
#define uniphier_serial_port(dev) \
((struct uniphier_serial_private_data *)dev_get_priv(dev))->membase
-int uniphier_serial_setbrg(struct udevice *dev, int baudrate)
+static int uniphier_serial_setbrg(struct udevice *dev, int baudrate)
{
struct uniphier_serial_platform_data *plat = dev_get_platdata(dev);
struct uniphier_serial __iomem *port = uniphier_serial_port(dev);
const unsigned int mode_x_div = 16;
unsigned int divisor;
- writeb(UART_LCR_WLS_8, &port->lcr);
+ writeb(UART_LCR_WLEN8, &port->lcr);
divisor = DIV_ROUND_CLOSEST(plat->uartclk, mode_x_div * baudrate);
@@ -93,7 +83,17 @@ static int uniphier_serial_putc(struct udevice *dev, const char c)
return 0;
}
-int uniphier_serial_probe(struct udevice *dev)
+static int uniphier_serial_pending(struct udevice *dev, bool input)
+{
+ struct uniphier_serial __iomem *port = uniphier_serial_port(dev);
+
+ if (input)
+ return readb(&port->lsr) & UART_LSR_DR;
+ else
+ return !(readb(&port->lsr) & UART_LSR_THRE);
+}
+
+static int uniphier_serial_probe(struct udevice *dev)
{
struct uniphier_serial_private_data *priv = dev_get_priv(dev);
struct uniphier_serial_platform_data *plat = dev_get_platdata(dev);
@@ -106,7 +106,7 @@ int uniphier_serial_probe(struct udevice *dev)
return 0;
}
-int uniphier_serial_remove(struct udevice *dev)
+static int uniphier_serial_remove(struct udevice *dev)
{
unmap_sysmem(uniphier_serial_port(dev));
@@ -114,19 +114,21 @@ int uniphier_serial_remove(struct udevice *dev)
}
#ifdef CONFIG_OF_CONTROL
-static const struct udevice_id uniphier_uart_of_match = {
- { .compatible = "panasonic,uniphier-uart"},
+static const struct udevice_id uniphier_uart_of_match[] = {
+ { .compatible = "panasonic,uniphier-uart" },
{},
};
static int uniphier_serial_ofdata_to_platdata(struct udevice *dev)
{
- /*
- * TODO: Masahiro Yamada (yamada.m@jp.panasonic.com)
- *
- * Implement conversion code from DTB to platform data
- * when supporting CONFIG_OF_CONTROL on UniPhir platform.
- */
+ struct uniphier_serial_platform_data *plat = dev_get_platdata(dev);
+ DECLARE_GLOBAL_DATA_PTR;
+
+ plat->base = fdtdec_get_addr(gd->fdt_blob, dev->of_offset, "reg");
+ plat->uartclk = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+ "clock-frequency", 0);
+
+ return 0;
}
#endif
@@ -134,6 +136,7 @@ static const struct dm_serial_ops uniphier_serial_ops = {
.setbrg = uniphier_serial_setbrg,
.getc = uniphier_serial_getc,
.putc = uniphier_serial_putc,
+ .pending = uniphier_serial_pending,
};
U_BOOT_DRIVER(uniphier_serial) = {
diff --git a/drivers/serial/serial_x86.c b/drivers/serial/serial_x86.c
new file mode 100644
index 0000000000..4bf6062c64
--- /dev/null
+++ b/drivers/serial/serial_x86.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <ns16550.h>
+#include <serial.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static const struct udevice_id x86_serial_ids[] = {
+ { .compatible = "x86-uart" },
+ { }
+};
+
+static int x86_serial_ofdata_to_platdata(struct udevice *dev)
+{
+ struct ns16550_platdata *plat = dev_get_platdata(dev);
+ int ret;
+
+ ret = ns16550_serial_ofdata_to_platdata(dev);
+ if (ret)
+ return ret;
+
+ plat->clock = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+ "clock-frequency", 1843200);
+
+ return 0;
+}
+
+U_BOOT_DRIVER(serial_ns16550) = {
+ .name = "serial_x86",
+ .id = UCLASS_SERIAL,
+ .of_match = x86_serial_ids,
+ .ofdata_to_platdata = x86_serial_ofdata_to_platdata,
+ .platdata_auto_alloc_size = sizeof(struct ns16550_platdata),
+ .priv_auto_alloc_size = sizeof(struct NS16550),
+ .probe = ns16550_serial_probe,
+ .ops = &ns16550_serial_ops,
+};
diff --git a/drivers/serial/usbtty.c b/drivers/serial/usbtty.c
index 7fb0b92078..75f0ec31bb 100644
--- a/drivers/serial/usbtty.c
+++ b/drivers/serial/usbtty.c
@@ -882,7 +882,7 @@ static int write_buffer (circbuf_t * buf)
space_avail =
current_urb->buffer_length -
current_urb->actual_length;
- popnum = min(space_avail, buf->size);
+ popnum = min(space_avail, (int)buf->size);
if (popnum == 0)
break;