[rtems commit] bsps/xilinx-zynqmp: Avoid constant UART reinit

Joel Sherrill joel at rtems.org
Mon Apr 19 15:51:11 UTC 2021


Module:    rtems
Branch:    master
Commit:    3ea43bc9e7e1ace798534fabc40326f69f9b18e8
Changeset: http://git.rtems.org/rtems/commit/?id=3ea43bc9e7e1ace798534fabc40326f69f9b18e8

Author:    Kinsey Moore <kinsey.moore at oarcorp.com>
Date:      Fri Mar 12 09:59:40 2021 -0600

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 84e158d..9886a11 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 442431d..74e7255 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



More information about the vc mailing list