I need to read from (and write to) a device connected to uart1 in U-Boot to complete board initialization.
For this purpose I'm using the following code (simplified form given):
struct udevice *dev = uclass_get_device_by_name(UCLASS_SERIAL, "serial at 30860000", &dev);
struct dm_serial_ops *ops = serial_get_ops(dev);
ops->setbrg(dev, 115200);
ops->putc(dev, 'f');
Unfortunately this causes a CPU reset in putc() (serial_mxc.c) when performing writel() on the UART TX register (0x30860040):
"Error" handler, esr 0xbf000002
elr: 00000000402605f0 lr : 00000000402610f8 (reloc)
elr: 00000000bff865f0 lr : 00000000bff870f8
x0 : 000000000000006d x1 : 000000000000081a
x2 : 00000000bffabf00 x3 : 00000000bdf1c630
x4 : 00000000bdf1cf20 x5 : 00000000bdf21804
x6 : 000000000000000f x7 : 00000000bdf1cf50
x8 : 00000000bdf1ce80 x9 : 00000000ffffffd0
x10: 0000000000000002 x11: 00000000ffffffff
x12: 00000000bdf1d080 x13: 0000000000004884
x14: 0000000000000000 x15: 00000000bdf1c6a8
x16: 0000000040234dc4 x17: 000000000000aa80
x18: 00000000bdf25d80 x19: 00000000bdf1cf20
x20: 00000000bdf1c670 x21: 00000000ffffffc8
x22: 00000000bdf1ce8a x23: 00000000bdf1cf20
x24: 00000000bdf1c670 x25: 000000000000081a
x26: 00000000bff9c000 x27: 00000000bffabf00
x28: 0000000000000000 x29: 00000000bdf1c560
Code: d00000ba 91263340 f90037e0 39400360 (350001a0)
Resetting CPU ...
Via trial-and-error I have found out that the problem occurs with uart1, uart3 and uart4 but not with uart2. In case of the latter there is at least no CPU reset, but given that uart2 is the U-Boot console device I cannot do anything else with it.
It also seems that it's only writing to the TX register causes the issue. Reading from the UART seems to work fine as well as setting the baud rate or reading the TXFULL register.
Any suggestions what I might be doing wrong here? Is UART2 special in any way compared to the others?
Thanks in advance!
Solved! Go to Solution.
Hello,
I checked the repository, drivers/serial/serial_mxc.c doesn't set up the clocks and there is no uart node in https://github.com/u-boot/u-boot/blob/v2024.01/drivers/clk/imx/clk-imx8mm.c.
We don't recommend you use mainline uboot, please use uboot-imx.
https://github.com/nxp-imx/uboot-imx
https://github.com/nxp-imx/uboot-imx/blob/lf_v2022.04/board/freescale/imx8mm_evk/imx8mm_evk.c
Best Regards,
Zhiming
Hello,
The clock and pad property of uart2 will be set in board/freescale/imx8mm_evk/imx8mm_evk.c, you need check your board file.
Then try to add pads config and init_uart_clk(0) for UART1.
Best Regards,
Zhiming
Hi Zhiming,
thank you for your response!
For my platform, which is indeed very close to the i.MX8MM EVK, I am using CONFIG_DM_SERIAL so I don't need to set up the pads or clocks manually.
This is all done via device tree (.dts) and automatically picked up by drivers/serial/serial_mxc.c.
For reference, here is how the i.MX8MM EVK is set up in my U-Boot version:
https://github.com/u-boot/u-boot/blob/v2024.01/board/freescale/imx8mm_evk/imx8mm_evk.c
This is working fine for UART2 but not for UART1, UART3 and UART4.
Can you tell me if there's a difference between those UARTs? I've noticed that some of them have SDMA definitions and some don't. Could this be the issue?
Best regards
Alex
Hello,
I checked the repository, drivers/serial/serial_mxc.c doesn't set up the clocks and there is no uart node in https://github.com/u-boot/u-boot/blob/v2024.01/drivers/clk/imx/clk-imx8mm.c.
We don't recommend you use mainline uboot, please use uboot-imx.
https://github.com/nxp-imx/uboot-imx
https://github.com/nxp-imx/uboot-imx/blob/lf_v2022.04/board/freescale/imx8mm_evk/imx8mm_evk.c
Best Regards,
Zhiming
Hi Zhiming,
thank you very much for taking the time to look at the code base.
You were right, there was indeed a missing clock initialization. All I needed to add was a simple call during board init:
init_uart_clk(0);
It is now working fine
I understand your recommendation towards u-boot-imx but we prefer to stay as close to upstream as possible as we have some additional modules that rely on DM which u-boot-imx seems to be missing.
Thanks again and best regards,
Alex