Add a early_console_setup() for the LS1028A SoC with 32bit, little endian access. If the bootloader does a fixup of the clock-frequency node the baudrate divisor register will automatically be set. Signed-off-by: Michael Walle <michael@xxxxxxxx> --- drivers/tty/serial/fsl_lpuart.c | 51 +++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 8 deletions(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index d5a67e02f06a..e8e5c60e5b71 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -1841,11 +1841,12 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios, spin_unlock_irqrestore(&sport->port.lock, flags); } -static void -lpuart32_serial_setbrg(struct lpuart_port *sport, unsigned int baudrate) +static void __lpuart32_serial_setbrg(struct uart_port *port, + unsigned int baudrate, bool use_rx_dma, + bool use_tx_dma) { u32 sbr, osr, baud_diff, tmp_osr, tmp_sbr, tmp_diff, tmp; - u32 clk = sport->port.uartclk; + u32 clk = port->uartclk; /* * The idea is to use the best OSR (over-sampling rate) possible. @@ -1891,10 +1892,10 @@ lpuart32_serial_setbrg(struct lpuart_port *sport, unsigned int baudrate) /* handle buadrate outside acceptable rate */ if (baud_diff > ((baudrate / 100) * 3)) - dev_warn(sport->port.dev, + dev_warn(port->dev, "unacceptable baud rate difference of more than 3%%\n"); - tmp = lpuart32_read(&sport->port, UARTBAUD); + tmp = lpuart32_read(port, UARTBAUD); if ((osr > 3) && (osr < 8)) tmp |= UARTBAUD_BOTHEDGE; @@ -1905,14 +1906,23 @@ lpuart32_serial_setbrg(struct lpuart_port *sport, unsigned int baudrate) tmp &= ~UARTBAUD_SBR_MASK; tmp |= sbr & UARTBAUD_SBR_MASK; - if (!sport->lpuart_dma_rx_use) + if (!use_rx_dma) tmp &= ~UARTBAUD_RDMAE; - if (!sport->lpuart_dma_tx_use) + if (!use_tx_dma) tmp &= ~UARTBAUD_TDMAE; - lpuart32_write(&sport->port, tmp, UARTBAUD); + lpuart32_write(port, tmp, UARTBAUD); +} + +static void lpuart32_serial_setbrg(struct lpuart_port *sport, + unsigned int baudrate) +{ + __lpuart32_serial_setbrg(&sport->port, baudrate, + sport->lpuart_dma_rx_use, + sport->lpuart_dma_tx_use); } + static void lpuart32_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) @@ -2406,6 +2416,30 @@ static int __init lpuart32_early_console_setup(struct earlycon_device *device, return 0; } +static int __init ls1028a_early_console_setup(struct earlycon_device *device, + const char *opt) +{ + u32 cr; + + if (!device->port.membase) + return -ENODEV; + + device->port.iotype = UPIO_MEM32; + device->con->write = lpuart32_early_write; + + /* set the baudrate */ + if (device->port.uartclk && device->baud) + __lpuart32_serial_setbrg(&device->port, device->baud, + false, false); + + /* enable transmitter */ + cr = lpuart32_read(&device->port, UARTCTRL); + cr |= UARTCTRL_TE; + lpuart32_write(&device->port, cr, UARTCTRL); + + return 0; +} + static int __init lpuart32_imx_early_console_setup(struct earlycon_device *device, const char *opt) { @@ -2420,6 +2454,7 @@ static int __init lpuart32_imx_early_console_setup(struct earlycon_device *devic } OF_EARLYCON_DECLARE(lpuart, "fsl,vf610-lpuart", lpuart_early_console_setup); OF_EARLYCON_DECLARE(lpuart32, "fsl,ls1021a-lpuart", lpuart32_early_console_setup); +OF_EARLYCON_DECLARE(lpuart32, "fsl,ls1028a-lpuart", ls1028a_early_console_setup); OF_EARLYCON_DECLARE(lpuart32, "fsl,imx7ulp-lpuart", lpuart32_imx_early_console_setup); EARLYCON_DECLARE(lpuart, lpuart_early_console_setup); EARLYCON_DECLARE(lpuart32, lpuart32_early_console_setup); -- 2.20.1