[PATCH v5] arm: rockchip: spl: Add hotkey detection support.

Valentin Liu <[email protected]>
Newsgroups gmane.comp.boot-loaders.u-boot
Message-ID <20260821140629.358500-1-valentinliu__23976.8622721144$1787321644$gmane$org@icloud.com>
Add a configurable Rockchip SPL hotkey feature that checks the
serial console during SPL startup.

Ctrl+B can be used to enter MaskROM mode and be widely used.
Ctrl+D can be used to enter Loader mode, Ctrl+F for Fastboot mode.
We can add more boot mode support in future.

Add CONFIG_SPL_ROCKCHIP_HOTKEY to enable the feature and wait for
the serial port to be ready to receive input before checking for
hotkeys.

Signed-off-by: Valentin Liu <[email protected]>
---
Changes for v2:
- Simplify the dependencies of SPL_ROCKCHIP_HOTKEY.
- Remove the conditions for the newly added includes.
---
Changes for v3:
- Add a dummy spl_hotkey_init() to avoid undefined reference errors
  when building without CONFIG_SPL_ROCKCHIP_HOTKEY.
---
Changes for v4:
- Add condition of CONFIG_ROCKCHIP_BOOT_MODE_REG != 0 to prevent
  SPL hotkey be compiled and used on unsupported platforms.
- Add more hotkey support (Ctrl+D and Ctrl+F).
- Remove prints on the standard path.
- Add some code comment.
---
Changes for v5:
- Fixup the CONFIG_IS_ENABLED() call.

 arch/arm/mach-rockchip/Kconfig | 14 +++++++++
 arch/arm/mach-rockchip/spl.c   | 54 ++++++++++++++++++++++++++++++++++
 2 files changed, 68 insertions(+)

diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index 1a2e7847c9e..0e485e8caf6 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -743,6 +743,20 @@ config TPL_ROCKCHIP_EARLYRETURN_TO_BROM
 config SPL_MMC
 	default y if !SPL_ROCKCHIP_BACK_TO_BROM
 
+config SPL_ROCKCHIP_HOTKEY
+	bool "SPL hotkey support"
+	depends on SPL_DM_RESET && SPL_SERIAL
+	help
+	  Enable hotkey detection during SPL booting stage.
+
+	  When enabled, SPL checks the serial console for a control
+	  character and can execute Rockchip-specific hotkey actions,
+	  such as entering MaskROM mode with Ctrl+B, entering Loader
+	  mode with Ctrl+D, entering Fastboot mode with Ctrl+F.
+
+	  The hotkey is checked after the SPL console has been
+	  initialized.
+
 config ROCKCHIP_SPI_IMAGE
 	bool "Build a SPI image for rockchip"
 	help
diff --git a/arch/arm/mach-rockchip/spl.c b/arch/arm/mach-rockchip/spl.c
index e989c148079..b61ccc30a22 100644
--- a/arch/arm/mach-rockchip/spl.c
+++ b/arch/arm/mach-rockchip/spl.c
@@ -13,11 +13,14 @@
 #include <log.h>
 #include <mapmem.h>
 #include <ram.h>
+#include <serial.h>
 #include <spl.h>
+#include <asm/arch-rockchip/boot_mode.h>
 #include <asm/arch-rockchip/bootrom.h>
 #include <asm/arch-rockchip/timer.h>
 #include <asm/global_data.h>
 #include <asm/io.h>
+#include <linux/delay.h>
 #include <linux/bitops.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -107,6 +110,54 @@ __weak int arch_cpu_init(void)
 	return 0;
 }
 
+#if CONFIG_IS_ENABLED(ROCKCHIP_HOTKEY) && (CONFIG_ROCKCHIP_BOOT_MODE_REG != 0)
+static void rockchip_reset_from_hotkey(const int code)
+{
+	switch (code) {
+	case 0x02: /* Ctrl+B */
+		printf("Ctrl+B pressed, entering download mode...\n");
+		writel(BOOT_BROM_DOWNLOAD, CONFIG_ROCKCHIP_BOOT_MODE_REG);
+		do_reset(NULL, 0, 0, NULL);
+		/* NOTREACHED */
+	case 0x04: /* Ctrl+D */
+		printf("Ctrl+D pressed, entering loader mode...\n");
+		writel(BOOT_LOADER, CONFIG_ROCKCHIP_BOOT_MODE_REG);
+		do_reset(NULL, 0, 0, NULL);
+		/* NOTREACHED */
+	case 0x06: /* Ctrl+F */
+		printf("Ctrl+F pressed, entering fastboot mode...\n");
+		writel(BOOT_FASTBOOT, CONFIG_ROCKCHIP_BOOT_MODE_REG);
+		do_reset(NULL, 0, 0, NULL);
+		/* NOTREACHED */
+	default:
+		if (code <= 0x1a) /* 'z' */
+			log_debug("SPL Hotkey: Ctrl+%c\n", code + 'A' - 1);
+		else
+			log_debug("SPL Hotkey: Unknown code: 0x%x, ignore\n", code);
+	}
+}
+
+static void spl_hotkey_init(void)
+{
+	if (!gd || !(gd->flags & GD_FLG_HAVE_CONSOLE))
+		return;
+	if (gd->flags & GD_FLG_DISABLE_CONSOLE)
+		return;
+
+	/* Wait for the serial port to be ready to receive data. */
+	mdelay(100);
+
+	if (serial_tstc())
+		rockchip_reset_from_hotkey(serial_getc());
+	else
+		log_debug("SPL Hotkey: No key pressed, continue\n");
+}
+#else
+static void spl_hotkey_init(void)
+{
+}
+#endif
+
 void board_init_f(ulong dummy)
 {
 	int ret;
@@ -143,6 +194,9 @@ void board_init_f(ulong dummy)
 	}
 #endif
 	preloader_console_init();
+
+	if (CONFIG_IS_ENABLED(ROCKCHIP_HOTKEY))
+		spl_hotkey_init();
 }
 
 void spl_board_prepare_for_boot(void)
-- 
2.53.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.