diff options
author | Lucas Stach <dev@lynxeye.de> | 2020-01-13 20:37:15 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2020-01-14 12:06:59 +0100 |
commit | 49e79ebc95c1adfc1324f450b82ba3bf20b3ee0a (patch) | |
tree | f21511ce4f685d7e12ffacc90acaaeca0405895b | |
parent | 521589d8816432cf2d00f1a9840233075d888024 (diff) | |
download | barebox-49e79ebc95c1adfc1324f450b82ba3bf20b3ee0a.tar.gz barebox-49e79ebc95c1adfc1324f450b82ba3bf20b3ee0a.tar.xz |
serial: cadence: add lowlevel init and putc functions
This allows to use the Cadence serial as a PBL console.
Signed-off-by: Lucas Stach <dev@lynxeye.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r-- | include/serial/cadence.h | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/include/serial/cadence.h b/include/serial/cadence.h index 014fb01203..f08b5b0cba 100644 --- a/include/serial/cadence.h +++ b/include/serial/cadence.h @@ -34,4 +34,59 @@ #define CADENCE_STS_TEMPTY (1 << 3) #define CADENCE_STS_TFUL (1 << 4) +static inline void cadence_uart_init(void __iomem *uartbase) +{ + int baudrate = CONFIG_BAUDRATE; + unsigned int clk = 49999995; + unsigned int gen, div; + + /* disable transmitter and receiver */ + writel(0, uartbase + CADENCE_UART_CONTROL); + + /* calculate and set baud clock generator parameters */ + for (div = 4; div < 256; div++) { + int calc_rate, error; + + gen = clk / (baudrate * (div + 1)); + + if (gen < 1 || gen > 65535) + continue; + + calc_rate = clk / (gen * (div + 1)); + error = baudrate - calc_rate; + if (error < 0) + error *= -1; + if (((error * 100) / baudrate) < 3) + break; + } + + writel(gen, uartbase + CADENCE_UART_BAUD_GEN); + writel(div, uartbase + CADENCE_UART_BAUD_DIV); + + /* soft-reset tx/rx paths */ + writel(CADENCE_CTRL_RXRES | CADENCE_CTRL_TXRES, + uartbase + CADENCE_UART_CONTROL); + + while (readl(uartbase + CADENCE_UART_CONTROL) & + (CADENCE_CTRL_RXRES | CADENCE_CTRL_TXRES)) + ; + + /* enable UART */ + writel(CADENCE_MODE_CLK_REF | CADENCE_MODE_CHRL_8 | + CADENCE_MODE_PAR_NONE, uartbase + CADENCE_UART_MODE); + writel(CADENCE_CTRL_RXEN | CADENCE_CTRL_TXEN, + uartbase + CADENCE_UART_CONTROL); +} + +static inline void cadence_uart_putc(void *base, int c) +{ + if (!(readl(base + CADENCE_UART_CONTROL) & CADENCE_CTRL_TXEN)) + return; + + while ((readl(base + CADENCE_UART_CHANNEL_STS) & CADENCE_STS_TFUL)) + ; + + writel(c, base + CADENCE_UART_RXTXFIFO); +} + #endif /* __CADENCE_UART_H__ */ |