Message ID | e333bdd7-4de8-1364-64f3-799cce72f4de@xrpbot.org |
---|---|
State | Deferred |
Delegated to: | Tom Rini |
Headers | show |
Series | serial: zynq: disable TX and RX while changing baud rate | expand |
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, ®s->baud_rate_divider); > - writel(bgen, ®s->baud_rate_gen); > + /* Check if baud rate registers actually need to be changed. */ > + if(readl(®s->baud_rate_divider) != bdiv || > + readl(®s->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, ®s->control); > + writel(ZYNQ_UART_CR_TX_DIS, ®s->control); > + writel(bgen, ®s->baud_rate_gen); > + writel(bdiv, ®s->baud_rate_divider); > + writel(ZYNQ_UART_CR_TXRST | ZYNQ_UART_CR_RXRST, ®s->control); > + writel(ZYNQ_UART_CR_RX_EN, ®s->control); > + writel(ZYNQ_UART_CR_TX_EN, ®s->control); > + } > } > > /* Initialize the UART, with...some settings. */ > Looks good. I have added your SoB line and applied. Thanks, Michal
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, ®s->baud_rate_divider); > > - writel(bgen, ®s->baud_rate_gen); > > + /* Check if baud rate registers actually need to be changed. */ > > + if(readl(®s->baud_rate_divider) != bdiv || > > + readl(®s->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, ®s->control); > > + writel(ZYNQ_UART_CR_TX_DIS, ®s->control); > > + writel(bgen, ®s->baud_rate_gen); > > + writel(bdiv, ®s->baud_rate_divider); > > + writel(ZYNQ_UART_CR_TXRST | ZYNQ_UART_CR_RXRST, ®s->control); > > + writel(ZYNQ_UART_CR_RX_EN, ®s->control); > > + writel(ZYNQ_UART_CR_TX_EN, ®s->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 --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, ®s->baud_rate_divider); - writel(bgen, ®s->baud_rate_gen); + /* Check if baud rate registers actually need to be changed. */ + if(readl(®s->baud_rate_divider) != bdiv || + readl(®s->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, ®s->control); + writel(ZYNQ_UART_CR_TX_DIS, ®s->control); + writel(bgen, ®s->baud_rate_gen); + writel(bdiv, ®s->baud_rate_divider); + writel(ZYNQ_UART_CR_TXRST | ZYNQ_UART_CR_RXRST, ®s->control); + writel(ZYNQ_UART_CR_RX_EN, ®s->control); + writel(ZYNQ_UART_CR_TX_EN, ®s->control); + } } /* Initialize the UART, with...some settings. */