From 3ea43bc9e7e1ace798534fabc40326f69f9b18e8 Mon Sep 17 00:00:00 2001 From: Kinsey Moore Date: Fri, 12 Mar 2021 09:59:40 -0600 Subject: bsps/xilinx-zynqmp: Avoid constant UART reinit Constantly reinitializing the Cadence UART on every character output causes data corruption/loss on some ZynqMP hardware. Only initialize the UART once for early output and give it a kick on startup. --- bsps/aarch64/xilinx-zynqmp/console/console.c | 6 ++++++ bsps/shared/dev/serial/zynq-uart-polled.c | 9 ++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/bsps/aarch64/xilinx-zynqmp/console/console.c b/bsps/aarch64/xilinx-zynqmp/console/console.c index 84e158d3f6..9886a117dc 100644 --- a/bsps/aarch64/xilinx-zynqmp/console/console.c +++ b/bsps/aarch64/xilinx-zynqmp/console/console.c @@ -112,6 +112,12 @@ static void zynqmp_debug_console_early_init(char c) &zynqmp_uart_instances[BSP_CONSOLE_MINOR].base; zynq_uart_initialize(base); + BSP_output_char = zynqmp_debug_console_out; + /* + * Some ZynqMP UARTs have a hardware bug that causes TX/RX logic restarts to + * require a kick after baud rate registers are initialized. + */ + zynqmp_debug_console_out(0); zynqmp_debug_console_out(c); } diff --git a/bsps/shared/dev/serial/zynq-uart-polled.c b/bsps/shared/dev/serial/zynq-uart-polled.c index 442431d502..74e7255ec2 100644 --- a/bsps/shared/dev/serial/zynq-uart-polled.c +++ b/bsps/shared/dev/serial/zynq-uart-polled.c @@ -128,14 +128,17 @@ void zynq_uart_initialize(rtems_termios_device_context *base) regs->control &= ~(ZYNQ_UART_CONTROL_RXEN | ZYNQ_UART_CONTROL_TXEN); regs->control = ZYNQ_UART_CONTROL_RXDIS - | ZYNQ_UART_CONTROL_TXDIS - | ZYNQ_UART_CONTROL_RXRES - | ZYNQ_UART_CONTROL_TXRES; + | ZYNQ_UART_CONTROL_TXDIS; regs->mode = ZYNQ_UART_MODE_CHMODE(ZYNQ_UART_MODE_CHMODE_NORMAL) | ZYNQ_UART_MODE_PAR(ZYNQ_UART_MODE_PAR_NONE) | ZYNQ_UART_MODE_CHRL(ZYNQ_UART_MODE_CHRL_8); regs->baud_rate_gen = ZYNQ_UART_BAUD_RATE_GEN_CD(brgr); regs->baud_rate_div = ZYNQ_UART_BAUD_RATE_DIV_BDIV(bauddiv); + /* A Tx/Rx logic reset must be issued after baud rate manipulation */ + regs->control = ZYNQ_UART_CONTROL_RXDIS + | ZYNQ_UART_CONTROL_TXDIS + | ZYNQ_UART_CONTROL_RXRES + | ZYNQ_UART_CONTROL_TXRES; regs->rx_fifo_trg_lvl = ZYNQ_UART_RX_FIFO_TRG_LVL_RTRIG(0); regs->rx_timeout = ZYNQ_UART_RX_TIMEOUT_RTO(0); regs->control = ZYNQ_UART_CONTROL_RXEN -- cgit v1.2.3