From 48cbc3a8761fad6624fb63f1d56f09a30322bfd9 Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Tue, 16 Oct 2012 15:43:15 -0500 Subject: serial/ns16550: don't build serial_ns16550 with MIN_FUNCTIONS CONFIG_NS16550_MIN_FUNCTIONS is used by small SPLs to gain access to basic ns16550 output code without pulling in things not needed by the SPL. This previously only worked with non-MULTI configs. Recently MULTI was made mandatory, and MIN_FUNCTIONS fails like this: drivers/serial/libserial.o: In function `calc_divisor.clone.0': serial_ns16550.c:(.text.calc_divisor.clone.0+0x24): undefined reference to `get_bus_freq' drivers/serial/libserial.o: In function `_serial_getc': (.text._serial_getc+0x30): undefined reference to `NS16550_getc' drivers/serial/libserial.o: In function `_serial_tstc': (.text._serial_tstc+0x30): undefined reference to `NS16550_tstc' drivers/serial/libserial.o: In function `_serial_setbrg': (.text._serial_setbrg+0x3c): undefined reference to `NS16550_reinit' make[1]: *** [/tmp/u-boot/spl/u-boot-spl] Error 1 make: *** [/tmp/u-boot/spl/u-boot-spl.bin] Error 2 With MIN_FUNCTIONS we don't need anything from this file, so don't build it. The conditional needs to be in the file itself rather than the makefile, because the config symbols are only imported to the makefiles once, not separately for the SPL phase of the build. Signed-off-by: Scott Wood --- drivers/serial/serial_ns16550.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/serial') diff --git a/drivers/serial/serial_ns16550.c b/drivers/serial/serial_ns16550.c index c1c0134..fc01a3c 100644 --- a/drivers/serial/serial_ns16550.c +++ b/drivers/serial/serial_ns16550.c @@ -31,6 +31,8 @@ #include +#ifndef CONFIG_NS16550_MIN_FUNCTIONS + DECLARE_GLOBAL_DATA_PTR; #if !defined(CONFIG_CONS_INDEX) @@ -304,3 +306,5 @@ void ns16550_serial_initialize(void) serial_register(&eserial6_device); #endif } + +#endif /* !CONFIG_NS16550_MIN_FUNCTIONS */ -- cgit v1.1 From cb55b3320014b7f6014416c556fe506efbf0a84b Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Tue, 18 Sep 2012 18:19:05 -0500 Subject: serial/ns16550: wait for TEMT before initializing TEMT is set when the transmitter is totally empty and all output has finished. This prevents output problems (including a loss of synchronization observed on p2020 that persisted for quite a while) if SPL has output still on its way out. Signed-off-by: Scott Wood -- v2: fixed typo in subject, and explained what the bit does in the changelog --- drivers/serial/ns16550.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/serial') diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c index 9027781..bbd91ca 100644 --- a/drivers/serial/ns16550.c +++ b/drivers/serial/ns16550.c @@ -36,6 +36,9 @@ void NS16550_init(NS16550_t com_port, int baud_divisor) { + while (!(serial_in(&com_port->lsr) & UART_LSR_TEMT)) + ; + serial_out(CONFIG_SYS_NS16550_IER, &com_port->ier); #if (defined(CONFIG_OMAP) && !defined(CONFIG_OMAP3_ZOOM2)) || \ defined(CONFIG_AM33XX) -- cgit v1.1 From 7c791b3f0a8e42f8012f782ef56ad6e88858e7c4 Mon Sep 17 00:00:00 2001 From: Tetsuyuki Kobayashi Date: Mon, 19 Nov 2012 21:37:38 +0000 Subject: serial: serial_sh: bugfix: autoboot fails if serial console is not connected On kzm9g board (rmobile SoC), autoboot fails if serial console cable is not connected. When serial cable is not connected, serial error occurs and some garbage comes in data register. sh_serial_tstc() in serial_sh.c does not check error status and misunderstand there is some input data. It is the reason that autoboot fails. This patch adds checking error status in sh_serial_tstc(). This patch is based on v2013.01-rc1 tag of u-boot master git. Signed-off-by: Tetsuyuki Kobayashi Signed-off-by: Nobuhiro Iwamatsu --- drivers/serial/serial_sh.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'drivers/serial') diff --git a/drivers/serial/serial_sh.c b/drivers/serial/serial_sh.c index 3c931d0..ee1f2d7 100644 --- a/drivers/serial/serial_sh.c +++ b/drivers/serial/serial_sh.c @@ -117,6 +117,14 @@ static int serial_rx_fifo_level(void) return scif_rxfill(&sh_sci); } +static void handle_error(void) +{ + sci_in(&sh_sci, SCxSR); + sci_out(&sh_sci, SCxSR, SCxSR_ERROR_CLEAR(&sh_sci)); + sci_in(&sh_sci, SCLSR); + sci_out(&sh_sci, SCLSR, 0x00); +} + void serial_raw_putc(const char c) { while (1) { @@ -138,16 +146,14 @@ static void sh_serial_putc(const char c) static int sh_serial_tstc(void) { + if (sci_in(&sh_sci, SCxSR) & SCIF_ERRORS) { + handle_error(); + return 0; + } + return serial_rx_fifo_level() ? 1 : 0; } -void handle_error(void) -{ - sci_in(&sh_sci, SCxSR); - sci_out(&sh_sci, SCxSR, SCxSR_ERROR_CLEAR(&sh_sci)); - sci_in(&sh_sci, SCLSR); - sci_out(&sh_sci, SCLSR, 0x00); -} int serial_getc_check(void) { -- cgit v1.1 From 10501df05e2d2eef501c92483c134d5f7c9da150 Mon Sep 17 00:00:00 2001 From: Joshua Housh Date: Sun, 2 Dec 2012 17:09:26 +0000 Subject: serial_pl011: Set RTS during initialization If the pl011 is connected to another device which has hardware flow-control on, characters are never received by the pl011. Asserting RTS when flow-control is off will have no effect. This is in line with how Linux behaves. Signed-off-by: Joshua Housh Tested-by: Marek Vasut --- drivers/serial/serial_pl01x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/serial') diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c index b331be7..dfdba9f 100644 --- a/drivers/serial/serial_pl01x.c +++ b/drivers/serial/serial_pl01x.c @@ -163,8 +163,8 @@ static int pl01x_serial_init(void) } #endif /* Finally, enable the UART */ - writel(UART_PL011_CR_UARTEN | UART_PL011_CR_TXE | UART_PL011_CR_RXE, - ®s->pl011_cr); + writel(UART_PL011_CR_UARTEN | UART_PL011_CR_TXE | UART_PL011_CR_RXE | + UART_PL011_CR_RTS, ®s->pl011_cr); return 0; } -- cgit v1.1 From 32057717e06a4e703fdf3774671cea14554de76b Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Tue, 11 Dec 2012 22:16:27 -0600 Subject: env: Add a baudrate env handler Remove the hard-coded baudrate handler and use a callback instead Signed-off-by: Joe Hershberger --- drivers/serial/serial.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) (limited to 'drivers/serial') diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c index f5f43a6..1f8955a 100644 --- a/drivers/serial/serial.c +++ b/drivers/serial/serial.c @@ -22,6 +22,7 @@ */ #include +#include #include #include #include @@ -32,6 +33,11 @@ DECLARE_GLOBAL_DATA_PTR; static struct serial_device *serial_devices; static struct serial_device *serial_current; +/* + * Table with supported baudrates (defined in config_xyz.h) + */ +static const unsigned long baudrate_table[] = CONFIG_SYS_BAUDRATE_TABLE; +#define N_BAUDRATES (sizeof(baudrate_table) / sizeof(baudrate_table[0])) /** * serial_null() - Void registration routine of a serial driver @@ -46,6 +52,70 @@ static void serial_null(void) } /** + * 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 < N_BAUDRATES; ++i) { + if (baudrate == baudrate_table[i]) + break; + } + if (i == N_BAUDRATES) { + 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; +#if defined(CONFIG_PPC) || defined(CONFIG_MCF52x2) + gd->bd->bi_baudrate = baudrate; +#endif + + 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); + +/** * serial_initfunc() - Forward declare of driver registration routine * @name: Name of the real driver registration routine. * -- cgit v1.1