diff mbox series

serial: zynq: disable TX and RX while changing baud rate

Message ID e333bdd7-4de8-1364-64f3-799cce72f4de@xrpbot.org
State New
Delegated to: Michal Simek
Headers show
Series serial: zynq: disable TX and RX while changing baud rate | expand

Commit Message

Norbert Braun Aug. 24, 2020, 9:57 p.m. UTC
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(-)

Comments

Michal Simek Sept. 14, 2020, 11:42 a.m. UTC | #1
On 24. 08. 20 23:57, Norbert Braun wrote:
> 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. */
> 

Looks good. I have added your SoB line and applied.

Thanks,
Michal
Michal Simek Sept. 23, 2020, 11:56 a.m. UTC | #2
po 14. 9. 2020 v 13:42 odesílatel Michal Simek <monstr@monstr.eu> napsal:
>
>
>
> On 24. 08. 20 23:57, Norbert Braun wrote:
> > 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. */
> >
>
> Looks good. I have added your SoB line and applied.


I am dropping this patch from my queue because it breaks travis and
gitlab CI loop. There is any issue with this patch when we run on
qemu.

Thanks,
Michal
diff mbox series

Patch

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. */