From c41251b17563234371a9b376ed4914efa4bc079b Mon Sep 17 00:00:00 2001 From: Scott Telford Date: Thu, 22 Sep 2016 16:58:16 +0100 Subject: [PATCH] serial: xuartps: Add some register initialisation to cdns_early_console_setup() Add initialisation of control register and baud rate to cdns_early_console_setup(), required when running kernel standalone without a boot loader. Baud rate is only initialised when specified in earlycon command-line option, otherwise it is assumed this has been set by a boot loader. Updated Documentation/kernel-parameters.txt accordingly. Signed-off-by: Scott Telford Signed-off-by: Greg Kroah-Hartman --- Documentation/kernel-parameters.txt | 11 ++++++----- drivers/tty/serial/xilinx_uartps.c | 27 ++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index a4f4d693e2c1..70b51f824a60 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1045,11 +1045,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted. determined by the stdout-path property in device tree's chosen node. - cdns, - Start an early, polled-mode console on a cadence serial - port at the specified address. The cadence serial port - must already be setup and configured. Options are not - yet supported. + cdns,[,options] + Start an early, polled-mode console on a Cadence + (xuartps) serial port at the specified address. Only + supported option is baud rate. If baud rate is not + specified, the serial port must already be setup and + configured. uart[8250],io,[,options] uart[8250],mmio,[,options] diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index 39f41bfd7c22..f37edaa5ac75 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c @@ -1165,9 +1165,34 @@ static void __init cdns_early_write(struct console *con, const char *s, static int __init cdns_early_console_setup(struct earlycon_device *device, const char *opt) { - if (!device->port.membase) + struct uart_port *port = &device->port; + + if (!port->membase) return -ENODEV; + /* initialise control register */ + writel(CDNS_UART_CR_TX_EN|CDNS_UART_CR_TXRST|CDNS_UART_CR_RXRST, + port->membase + CDNS_UART_CR); + + /* only set baud if specified on command line - otherwise + * assume it has been initialized by a boot loader. + */ + if (device->baud) { + u32 cd = 0, bdiv = 0; + u32 mr; + int div8; + + cdns_uart_calc_baud_divs(port->uartclk, device->baud, + &bdiv, &cd, &div8); + mr = CDNS_UART_MR_PARITY_NONE; + if (div8) + mr |= CDNS_UART_MR_CLKSEL; + + writel(mr, port->membase + CDNS_UART_MR); + writel(cd, port->membase + CDNS_UART_BAUDGEN); + writel(bdiv, port->membase + CDNS_UART_BAUDDIV); + } + device->con->write = cdns_early_write; return 0; -- 2.39.2