Add a configurable Rockchip SPL hotkey feature that checks the
serial console during SPL startup.

Ctrl+B can be used to enter BootROM download (MASKROM) mode and
be widely used. 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.

 arch/arm/mach-rockchip/Kconfig | 13 +++++++++++
 arch/arm/mach-rockchip/spl.c   | 40 ++++++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+)

diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index 1a2e7847c9e..f2d2b5520ef 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -743,6 +743,19 @@ 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 BootROM download mode (MASKROM) with Ctrl+B.
+
+         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..0422415b06e 100644
--- a/arch/arm/mach-rockchip/spl.c
+++ b/arch/arm/mach-rockchip/spl.c
@@ -13,12 +13,15 @@
 #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/bitops.h>
+#include <linux/delay.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -107,6 +110,40 @@ __weak int arch_cpu_init(void)
        return 0;
 }
 
+#if IS_ENABLED(CONFIG_SPL_ROCKCHIP_HOTKEY)
+static void rockchip_reset_from_hotkey(const int code)
+{
+       switch (code) {
+       case 0x02:
+               printf("SPL Hotkey: Ctrl+B: BootROM download!\n");
+               writel(BOOT_BROM_DOWNLOAD, CONFIG_ROCKCHIP_BOOT_MODE_REG);
+               do_reset(NULL, 0, 0, NULL);
+               /*NOTREACHED*/
+       default:
+               if (code <= 0x1a) /* 'z' */
+                       printf("SPL Hotkey: Ctrl+%c\n", code + 'A' - 1);
+               else
+                       printf("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
+               printf("SPL Hotkey: No key pressed, continue\n");
+}
+#endif
+
 void board_init_f(ulong dummy)
 {
        int ret;
@@ -143,6 +180,9 @@ void board_init_f(ulong dummy)
        }
 #endif
        preloader_console_init();
+
+       if (IS_ENABLED(CONFIG_SPL_ROCKCHIP_HOTKEY))
+               spl_hotkey_init();
 }
 
 void spl_board_prepare_for_boot(void)
-- 
2.53.0

Reply via email to