[PATCH v5 2/2] serial: mxc: have putc use the TXFIFO

Pali Rohár pali at kernel.org
Wed Nov 2 18:24:34 CET 2022


On Wednesday 02 November 2022 11:20:44 Fabio Estevam wrote:
> Hi Johannes,
> 
> On 02/11/2022 09:38, SCHNEIDER Johannes wrote:
> 
> > sadly that does not reproduce on imx8mm ... a long print works fine
> > with or without the patch :-S
> 
> Yes, it does happen on imx8mm.
> 
> You need to add the print() inside board_init().
> 
> Here is a reproducer on imx8mm evk:
> 
> diff --git a/board/freescale/imx8mm_evk/imx8mm_evk.c
> b/board/freescale/imx8mm_evk/imx8mm_evk.c
> index e0975fcda705..69ec723c616e 100644
> --- a/board/freescale/imx8mm_evk/imx8mm_evk.c
> +++ b/board/freescale/imx8mm_evk/imx8mm_evk.c
> @@ -50,6 +50,7 @@ int board_init(void)
>         if (IS_ENABLED(CONFIG_FEC_MXC))
>                 setup_fec();
> 
> +
> printf("*******************0123456789012345678901234567890123456789\n");
>         return 0;
>  }
> 
> 
> The result is:
> 
> U-Boot SPL 2022.10-00991-gc8d9ff634fc4-dirty (Nov 02 2022 - 11:15:14 -0300)
> No pmic
> SEC0:  RNG instantiated
> cyclic_register for watchdog at 30280000 failed
> WDT:   Failed to start watchdog at 30280000
> Trying to boot from MMC1
> NOTICE:  BL31: v2.6(release):lf-5.15.32-2.0.0-1-g044ea08c0109
> NOTICE:  BL31: Built : 11:15:02, Nov  2 2022
> 
> 
> U-Boot 2022.10-00991-gc8d9ff634fc4-dirty (Nov 02 2022 - 11:15:14 -0300)
> 
> CPU:   Freescale i.MX8MMQ rev1.0 at 1200 MHz
> Reset cause: POR
> Model: FSL i.MX8MM EVK board
> DRAM:  2 GiB
> *******************0123456789012345678901234567890123n�KW�'$HL�� devices, 23
> uclasses, devicetree: separate
> WDT:   Started watchdog at 30280000 with servicing every 1000ms (60s timeout)
> MMC:   FSL_SDHC: 1, FSL_SDHC: 2
> Loading Environment from MMC... OK
> In:    serial at 30890000
> Out:   serial at 30890000
> Err:   serial at 30890000
> SEC0:  RNG instantiated
> Net:   eth0: ethernet at 30be0000
> Hit any key to stop autoboot:  0
> u-boot=>
> 
> As you can see the corruption is clearly seen.
> 
> > > The RTC line is displayed from drivers/misc/gsc.c and the Core: comes
> > > from dm_announce. Somehow in between the FIFO does not get drained
> > > before dm_announce gets called.
> > 
> > "flushing" shouldn't be an issue, since everything goes through the
> > same set of registers which the imx queues into its fifo...
> > i suspect the rootcause lies someplace else?
> 
> 
> Reverting your change makes the issue disappear.
> 
> Regards,
> 
> Fabio Estevam
> -- 
> DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
> Phone: (+49)-8142-66989-60 Fax: (+49)-8142-66989-80 Email: festevam at denx.de

Hello! This log just cleanly shows that UART TX FIFO is either broken or
something drops its content prior all bytes are properly transmitted.
Dropping HW TX FIFO is on most UARTs possible by resetting registers or
reconfiguring buadrate.

I have an idea, cannot some u-boot code calls some mxc function which
changes parameters of UART and this will cause loosing of FIFO?

For example I see two functions which are doing it. Could you try to add
code which waits until content of FIFO is transmitted prior changing
UART parameters?

diff --git a/drivers/serial/serial_mxc.c b/drivers/serial/serial_mxc.c
index 4cf79c1ca24f..9611d9bc8a00 100644
--- a/drivers/serial/serial_mxc.c
+++ b/drivers/serial/serial_mxc.c
@@ -146,6 +146,9 @@ struct mxc_uart {
 
 static void _mxc_serial_init(struct mxc_uart *base, int use_dte)
 {
+	while (!(readl(&base->ts) & UTS_TXEMPTY))
+		;
+
 	writel(0, &base->cr1);
 	writel(0, &base->cr2);
 
@@ -169,6 +172,9 @@ static void _mxc_serial_setbrg(struct mxc_uart *base, unsigned long clk,
 {
 	u32 tmp;
 
+	while (!(readl(&base->ts) & UTS_TXEMPTY))
+		;
+
 	tmp = RFDIV << UFCR_RFDIV_SHF;
 	if (use_dte)
 		tmp |= UFCR_DCEDTE;



More information about the U-Boot mailing list