According to the Zynq-7000 TRM (UG585), the UART transmitter and
receiver must be disabled while changing the baud rate. Change
_uart_zynq_serial_setbrg accordingly.
---
 drivers/serial/serial_zynq.c | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/drivers/serial/serial_zynq.c b/drivers/serial/serial_zynq.c
index 0e71cada1b..4f7bab16fa 100644
--- a/drivers/serial/serial_zynq.c
+++ b/drivers/serial/serial_zynq.c
@@ -23,7 +23,9 @@
 #define ZYNQ_UART_SR_TXFULL    BIT(4) /* TX FIFO full */
 #define ZYNQ_UART_SR_RXEMPTY   BIT(1) /* RX FIFO empty */
 
+#define ZYNQ_UART_CR_TX_DIS    BIT(5) /* TX disable */
 #define ZYNQ_UART_CR_TX_EN     BIT(4) /* TX enabled */
+#define ZYNQ_UART_CR_RX_DIS    BIT(3) /* RX disable */
 #define ZYNQ_UART_CR_RX_EN     BIT(2) /* RX enabled */
 #define ZYNQ_UART_CR_TXRST     BIT(1) /* TX logic reset */
 #define ZYNQ_UART_CR_RXRST     BIT(0) /* RX logic reset */
@@ -82,8 +84,26 @@ static void _uart_zynq_serial_setbrg(struct uart_zynq *regs,
                        break;
        }
 
-       writel(bdiv, &regs->baud_rate_divider);
-       writel(bgen, &regs->baud_rate_gen);
+       /* Check if baud rate registers actually need to be changed. */
+       if(readl(&regs->baud_rate_divider) != bdiv ||
+          readl(&regs->baud_rate_gen) != bgen) {
+               /*
+                * Configure the baud rate.
+                *
+                * This follows the procedure from the
+                * Zynq-7000 SoC Technical Reference Manual,
+                * UG585 (v1.12.2),
+                * section 19.3.2, part 2.
+                */
+
+               writel(ZYNQ_UART_CR_RX_DIS, &regs->control);
+               writel(ZYNQ_UART_CR_TX_DIS, &regs->control);
+               writel(bgen, &regs->baud_rate_gen);
+               writel(bdiv, &regs->baud_rate_divider);
+               writel(ZYNQ_UART_CR_TXRST | ZYNQ_UART_CR_RXRST, &regs->control);
+               writel(ZYNQ_UART_CR_RX_EN, &regs->control);
+               writel(ZYNQ_UART_CR_TX_EN, &regs->control);
+       }
 }
 
 /* Initialize the UART, with...some settings. */
-- 
2.17.1


Reply via email to