diff options
author | Simon Glass <sjg@chromium.org> | 2015-10-18 04:41:22 +0300 |
---|---|---|
committer | Michal Simek <michal.simek@xilinx.com> | 2015-11-04 16:49:52 +0300 |
commit | c54c0a4c1c745a009565ceb2a5c564d4d9418476 (patch) | |
tree | d618bbdabefcc0db7cccbbafdbb2f3b7e04fc75a /drivers/serial/serial_zynq.c | |
parent | bd44758a41b6d38b865e0bc0b1751c6129c1ec2b (diff) | |
download | u-boot-c54c0a4c1c745a009565ceb2a5c564d4d9418476.tar.xz |
arm: zynq: Support the debug UART
Add support for the debug UART to assist with early debugging. Enable it
for Zybo as an example.
Signed-off-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
Diffstat (limited to 'drivers/serial/serial_zynq.c')
-rw-r--r-- | drivers/serial/serial_zynq.c | 77 |
1 files changed, 61 insertions, 16 deletions
diff --git a/drivers/serial/serial_zynq.c b/drivers/serial/serial_zynq.c index 9d84290196..3b12c01538 100644 --- a/drivers/serial/serial_zynq.c +++ b/drivers/serial/serial_zynq.c @@ -6,6 +6,7 @@ */ #include <common.h> +#include <errno.h> #include <fdtdec.h> #include <watchdog.h> #include <asm/io.h> @@ -43,20 +44,16 @@ static struct uart_zynq *uart_zynq_ports[2] = { }; /* Set up the baud rate in gd struct */ -static void uart_zynq_serial_setbrg(const int port) +static void _uart_zynq_serial_setbrg(struct uart_zynq *regs, + unsigned long clock, unsigned long baud) { /* Calculation results. */ unsigned int calc_bauderror, bdiv, bgen; unsigned long calc_baud = 0; - unsigned long baud; - unsigned long clock = get_uart_clk(port); - struct uart_zynq *regs = uart_zynq_ports[port]; /* Covering case where input clock is so slow */ - if (clock < 1000000 && gd->baudrate > 4800) - gd->baudrate = 4800; - - baud = gd->baudrate; + if (clock < 1000000 && baud > 4800) + baud = 4800; /* master clock * Baud rate = ------------------ @@ -87,36 +84,59 @@ static void uart_zynq_serial_setbrg(const int port) writel(bgen, ®s->baud_rate_gen); } -/* Initialize the UART, with...some settings. */ -static int uart_zynq_serial_init(const int port) +/* Set up the baud rate in gd struct */ +static void uart_zynq_serial_setbrg(const int port) { + unsigned long clock = get_uart_clk(port); struct uart_zynq *regs = uart_zynq_ports[port]; - if (!regs) - return -1; + return _uart_zynq_serial_setbrg(regs, clock, gd->baudrate); +} +/* Initialize the UART, with...some settings. */ +static void _uart_zynq_serial_init(struct uart_zynq *regs) +{ /* RX/TX enabled & reset */ writel(ZYNQ_UART_CR_TX_EN | ZYNQ_UART_CR_RX_EN | ZYNQ_UART_CR_TXRST | \ ZYNQ_UART_CR_RXRST, ®s->control); writel(ZYNQ_UART_MR_PARITY_NONE, ®s->mode); /* 8 bit, no parity */ +} + +/* Initialize the UART, with...some settings. */ +static int uart_zynq_serial_init(const int port) +{ + struct uart_zynq *regs = uart_zynq_ports[port]; + + if (!regs) + return -1; + + _uart_zynq_serial_init(regs); uart_zynq_serial_setbrg(port); return 0; } +static int _uart_zynq_serial_putc(struct uart_zynq *regs, const char c) +{ + if (readl(®s->channel_sts) & ZYNQ_UART_SR_TXFULL) + return -EAGAIN; + + writel(c, ®s->tx_rx_fifo); + + return 0; +} + static void uart_zynq_serial_putc(const char c, const int port) { struct uart_zynq *regs = uart_zynq_ports[port]; - while ((readl(®s->channel_sts) & ZYNQ_UART_SR_TXFULL) != 0) + while (_uart_zynq_serial_putc(regs, c) == -EAGAIN) WATCHDOG_RESET(); if (c == '\n') { - writel('\r', ®s->tx_rx_fifo); - while ((readl(®s->channel_sts) & ZYNQ_UART_SR_TXFULL) != 0) + while (_uart_zynq_serial_putc(regs, '\r') == -EAGAIN) WATCHDOG_RESET(); } - writel(c, ®s->tx_rx_fifo); } static void uart_zynq_serial_puts(const char *s, const int port) @@ -218,3 +238,28 @@ void zynq_serial_initialize(void) serial_register(&uart_zynq_serial0_device); serial_register(&uart_zynq_serial1_device); } + +#ifdef CONFIG_DEBUG_UART_ZYNQ + +#include <debug_uart.h> + +void _debug_uart_init(void) +{ + struct uart_zynq *regs = (struct uart_zynq *)CONFIG_DEBUG_UART_BASE; + + _uart_zynq_serial_init(regs); + _uart_zynq_serial_setbrg(regs, CONFIG_DEBUG_UART_CLOCK, + CONFIG_BAUDRATE); +} + +static inline void _debug_uart_putc(int ch) +{ + struct uart_zynq *regs = (struct uart_zynq *)CONFIG_DEBUG_UART_BASE; + + while (_uart_zynq_serial_putc(regs, ch) == -EAGAIN) + WATCHDOG_RESET(); +} + +DEBUG_UART_FUNCS + +#endif |