From: Samuel Holland <[email protected]> Some platforms need the UART clock gates enabled before NS16550 register access. This is required by the downstream Allwinner D1 port used on the MangoPi MQ Pro.
Add CONFIG_NS16550_CLK_ENABLE to enable the UART clocks during probe when explicitly selected by a platform. The option defaults to disabled, preserving the existing behavior on other platforms. The clock-enabling code originates from Samuel Holland's D1 work. This patch makes that behavior optional through Kconfig. Link: https://github.com/smaeul/u-boot/commit/0617377a2555031f02a459b3451fa33ce53e9b74 Signed-off-by: Samuel Holland <[email protected]> Co-developed-by: khaliforce <[email protected]> Signed-off-by: khaliforce <[email protected]> --- Tested on a MangoPi MQ Pro with the downstream D1 port based on U-Boot v2026.10: - With the option enabled, cold boot and warm reboot succeeded through SPL, OpenSBI, U-Boot, GRUB and Linux. - Removing only this patch, without adding diagnostic code, resulted in no UART output at all, not even a single character, and the board did not become reachable over SSH. The standalone patch also builds on current upstream main for RISC-V64, ARM64 and ARM32. An additional RISC-V64 build with CLK and NS16550_CLK_ENABLE enabled passed. With the option disabled, the tested ARM64 and ARM32 NS16550 .text sections were unchanged. Checkpatch reports no errors or warnings. drivers/serial/Kconfig | 7 +++++++ drivers/serial/ns16550.c | 9 +++++++++ 2 files changed, 16 insertions(+) diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index ffc58d663ff..4c5400a3816 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -821,6 +821,13 @@ config SYS_NS16550 be used. It can be a constant or a function to get clock, eg, get_serial_clock(). +config NS16550_CLK_ENABLE + bool "Enable NS16550 clocks during probe" + depends on SYS_NS16550 && DM_SERIAL && CLK + help + Enable all UART clocks before register access. + Select this when firmware does not enable the UART clock gates. + config NS16550_DYNAMIC bool "Allow NS16550 to be configured at runtime" depends on SYS_NS16550 diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c index 10271f46aa6..217a7cf7238 100644 --- a/drivers/serial/ns16550.c +++ b/drivers/serial/ns16550.c @@ -516,6 +516,15 @@ int ns16550_serial_probe(struct udevice *dev) if (!ret) reset_deassert_bulk(&reset_bulk); + if (IS_ENABLED(CONFIG_NS16550_CLK_ENABLE) && + CONFIG_IS_ENABLED(CLK)) { + struct clk_bulk clk_bulk; + + ret = clk_get_bulk(dev, &clk_bulk); + if (!ret) + clk_enable_bulk(&clk_bulk); + } + com_port->plat = dev_get_plat(dev); ns16550_init(com_port, -1);
