2018-04-20 12:45:36

by Stefan Agner

[permalink] [raw]
Subject: [PATCH v2] serial: imx: fix cached UCR2 read on software reset

To reset the UART the SRST needs be cleared (low active). According
to the documentation the bit will remain active for 4 module clocks
until it is cleared (set to 1).

Hence the real register need to be read in case the cached register
indicates that the SRST bit is zero.

This bug lead to wrong baudrate because the baud rate register got
restored before reset completed in imx_flush_buffer.

Fixes: 3a0ab62f43de ("serial: imx: implement shadow registers for UCRx and UFCR")
Signed-off-by: Stefan Agner <[email protected]>
Reviewed-by: Fabio Estevam <[email protected]>
Reviewed-by: Uwe Kleine-König <[email protected]>
---
Hi Greg,

Since this fixes a regression it should go into v4.17...

--
Stefan


drivers/tty/serial/imx.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 91f3a1a5cb7f..4ff6bd6eb9ab 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -316,7 +316,7 @@ static u32 imx_uart_readl(struct imx_port *sport, u32 offset)
* differ from the value that was last written. As it only
* clears after being set, reread conditionally.
*/
- if (sport->ucr2 & UCR2_SRST)
+ if (!(sport->ucr2 & UCR2_SRST))
sport->ucr2 = readl(sport->port.membase + offset);
return sport->ucr2;
break;
--
2.17.0



2018-06-07 07:59:35

by Uwe Kleine-König

[permalink] [raw]
Subject: Re: [PATCH v2] serial: imx: fix cached UCR2 read on software reset

On Fri, Apr 20, 2018 at 02:44:07PM +0200, Stefan Agner wrote:
> To reset the UART the SRST needs be cleared (low active). According
> to the documentation the bit will remain active for 4 module clocks
> until it is cleared (set to 1).
>
> Hence the real register need to be read in case the cached register
> indicates that the SRST bit is zero.
>
> This bug lead to wrong baudrate because the baud rate register got
> restored before reset completed in imx_flush_buffer.
>
> Fixes: 3a0ab62f43de ("serial: imx: implement shadow registers for UCRx and UFCR")
> Signed-off-by: Stefan Agner <[email protected]>
> Reviewed-by: Fabio Estevam <[email protected]>
> Reviewed-by: Uwe Kleine-K?nig <[email protected]>

For the record, there is a customer of mine who reports that this commit
breaks rs485 communication on i.MX25 because RTS stops to toggle as
intended.

(Some details: uart3, fsl,uart-has-rtscts, fsl,dte-mode,
linux,rs485-enabled-at-boot-time, native RTS.)

I didn't debug this yet.

Best regards
Uwe

--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |

2018-06-12 12:12:29

by Stefan Agner

[permalink] [raw]
Subject: Re: [PATCH v2] serial: imx: fix cached UCR2 read on software reset

On 07.06.2018 09:56, Uwe Kleine-König wrote:
> On Fri, Apr 20, 2018 at 02:44:07PM +0200, Stefan Agner wrote:
>> To reset the UART the SRST needs be cleared (low active). According
>> to the documentation the bit will remain active for 4 module clocks
>> until it is cleared (set to 1).
>>
>> Hence the real register need to be read in case the cached register
>> indicates that the SRST bit is zero.
>>
>> This bug lead to wrong baudrate because the baud rate register got
>> restored before reset completed in imx_flush_buffer.
>>
>> Fixes: 3a0ab62f43de ("serial: imx: implement shadow registers for UCRx and UFCR")
>> Signed-off-by: Stefan Agner <[email protected]>
>> Reviewed-by: Fabio Estevam <[email protected]>
>> Reviewed-by: Uwe Kleine-König <[email protected]>
>
> For the record, there is a customer of mine who reports that this commit
> breaks rs485 communication on i.MX25 because RTS stops to toggle as
> intended.
>
> (Some details: uart3, fsl,uart-has-rtscts, fsl,dte-mode,
> linux,rs485-enabled-at-boot-time, native RTS.)
>
> I didn't debug this yet.

I have seen your patch today "serial: imx: fix comment about UCR2_SRST
and its handling for shadowing" so I assume you looked into this issue?

Was it related to that change?

--
Stefan

2018-06-12 12:29:48

by Uwe Kleine-König

[permalink] [raw]
Subject: Re: [PATCH v2] serial: imx: fix cached UCR2 read on software reset

On Tue, Jun 12, 2018 at 02:11:44PM +0200, Stefan Agner wrote:
> On 07.06.2018 09:56, Uwe Kleine-K?nig wrote:
> > On Fri, Apr 20, 2018 at 02:44:07PM +0200, Stefan Agner wrote:
> >> To reset the UART the SRST needs be cleared (low active). According
> >> to the documentation the bit will remain active for 4 module clocks
> >> until it is cleared (set to 1).
> >>
> >> Hence the real register need to be read in case the cached register
> >> indicates that the SRST bit is zero.
> >>
> >> This bug lead to wrong baudrate because the baud rate register got
> >> restored before reset completed in imx_flush_buffer.
> >>
> >> Fixes: 3a0ab62f43de ("serial: imx: implement shadow registers for UCRx and UFCR")
> >> Signed-off-by: Stefan Agner <[email protected]>
> >> Reviewed-by: Fabio Estevam <[email protected]>
> >> Reviewed-by: Uwe Kleine-K?nig <[email protected]>
> >
> > For the record, there is a customer of mine who reports that this commit
> > breaks rs485 communication on i.MX25 because RTS stops to toggle as
> > intended.
> >
> > (Some details: uart3, fsl,uart-has-rtscts, fsl,dte-mode,
> > linux,rs485-enabled-at-boot-time, native RTS.)
> >
> > I didn't debug this yet.
>
> I have seen your patch today "serial: imx: fix comment about UCR2_SRST
> and its handling for shadowing" so I assume you looked into this issue?
>
> Was it related to that change?

I started looking into this issue, but didn't find the culprit yet.

My work in progress patch looks as follows:

diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 758a67f3c8b3..5270173721c6 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -1357,6 +1357,12 @@ static int imx_uart_startup(struct uart_port *port)
while (!(imx_uart_readl(sport, UCR2) & UCR2_SRST) && (--i > 0))
udelay(1);

+ if (imx_uart_readl(sport, UCR2) & UCR2_SRST) {
+ spin_unlock_irqrestore(&sport->port.lock, flags);
+ dev_warn(port->dev, "SRST didn't go away\n");
+ return -EIO;
+ }
+
/*
* Finally, clear and enable interrupts
*/

which seems to trigger on both i.MX25 and i.MX6 at least occasionally.

Maybe 100 us is too short?

Best regards
Uwe

--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |