[PATCH v3 1/2] serial: mxc: Wait for TX completion before reset

Loic Poulain loic.poulain at linaro.org
Wed Jan 11 08:53:30 CET 2023


On Wed, 11 Jan 2023 at 00:53, Pali Rohár <pali at kernel.org> wrote:
>
> On Tuesday 10 January 2023 20:24:06 Loic Poulain wrote:
> > The u-boot console may show some corrupted characters when
> > printing in board_init() due to reset of the UART (probe)
> > before the TX FIFO has been completely drained.
> >
> > To fix this issue, and in case UART is still running, we now
> > try to flush the FIFO before proceeding to UART reinitialization.
> > For this we're waiting for Transmitter Complete bit, indicating
> > that the FIFO and the shift register are empty.
> >
> > flushing has a 4ms timeout guard, which is normally more than
> > enough to consume the FIFO @ low baudrate (9600bps).
> >
> > Signed-off-by: Loic Poulain <loic.poulain at linaro.org>
> > Tested-by: Lothar Waßmann <LW at KARO-electronics.de>
>
> Hello! Last time when I looked at this driver I was in impression that
> also _mxc_serial_setbrg() function requires calling some flush function
> at the beginning. Could you please check if it is needed or not? I'm
> really not sure.

_mxc_serial_setbrg is usually called after init, which now includes that flush.

>
> > ---
> >  v2: Add this commit to the series
> >  v3: Fix typo & reordering commits for good bisectability
> >
> >  drivers/serial/serial_mxc.c | 24 +++++++++++++++++++++++-
> >  1 file changed, 23 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/serial/serial_mxc.c b/drivers/serial/serial_mxc.c
> > index 82c0d84628..3c89781f2c 100644
> > --- a/drivers/serial/serial_mxc.c
> > +++ b/drivers/serial/serial_mxc.c
> > @@ -13,6 +13,7 @@
> >  #include <dm/platform_data/serial_mxc.h>
> >  #include <serial.h>
> >  #include <linux/compiler.h>
> > +#include <linux/delay.h>
> >
> >  /* UART Control Register Bit Fields.*/
> >  #define URXD_CHARRDY (1<<15)
> > @@ -144,8 +145,22 @@ struct mxc_uart {
> >       u32 ts;
> >  };
> >
> > +static void _mxc_serial_flush(struct mxc_uart *base)
> > +{
> > +     unsigned int timeout = 4000;
> > +
> > +     if (!(readl(&base->cr1) & UCR1_UARTEN) ||
> > +         !(readl(&base->cr2) & UCR2_TXEN))
> > +             return;
> > +
> > +     while (!(readl(&base->sr2) & USR2_TXDC) && --timeout)
> > +             udelay(1);
> > +}
> > +
> >  static void _mxc_serial_init(struct mxc_uart *base, int use_dte)
> >  {
> > +     _mxc_serial_flush(base);
> > +
> >       writel(0, &base->cr1);
> >       writel(0, &base->cr2);
> >
> > @@ -252,10 +267,17 @@ static int mxc_serial_init(void)
> >       return 0;
> >  }
> >
> > +static int mxc_serial_stop(void)
> > +{
> > +     _mxc_serial_flush(mxc_base);
> > +
> > +     return 0;
> > +}
> > +
> >  static struct serial_device mxc_serial_drv = {
> >       .name   = "mxc_serial",
> >       .start  = mxc_serial_init,
> > -     .stop   = NULL,
> > +     .stop   = mxc_serial_stop,
> >       .setbrg = mxc_serial_setbrg,
> >       .putc   = mxc_serial_putc,
> >       .puts   = default_serial_puts,
>
> Anyway, this code touches _only_ non-DM version of the driver. So same
> fix should be implemented also for DM version because non-DM is now
> legacy and will be removed in the future from U-Boot. Please look at the
> DM version too.

This code impacts both DM and non-DM, as _mxc_serial_init is a common version,
and was the main issue (several init() leading to corrupted char).

Regards,
Loic


More information about the U-Boot mailing list