The boot mode can be forced by key press
or by TAMP register, requested in kernel by syscon-reboot-mode

tamp: tamp@5c00a000 {
        compatible = "simple-bus", "syscon", "simple-mfd";
        reg = <0x5c00a000 0x400>;

        reboot-mode {
                compatible = "syscon-reboot-mode";
                offset = <0x150>; /* reg20 */
                mask = <0xff>;
                mode-normal = <0>;
                mode-fastboot = <0x1>;
                mode-recovery = <0x2>;
                mode-stm32cubeprogrammer = <0x3>;
                mode-ums_mmc0 = <0x10>;
                mode-ums_mmc1 = <0x11>;
                mode-ums_mmc2 = <0x12>;
        };
};

Signed-off-by: Patrick Delaunay <patrick.delau...@st.com>
---

 arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi   |  5 +++
 arch/arm/mach-stm32mp/cpu.c                | 36 +++++++++++++++++++--
 arch/arm/mach-stm32mp/include/mach/stm32.h | 11 +++++++
 board/st/stm32mp1/stm32mp1.c               | 51 ++++++++++++++++++++++++++++++
 4 files changed, 100 insertions(+), 3 deletions(-)

diff --git a/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi 
b/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi
index 70bbf66..d22401c 100644
--- a/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi
+++ b/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi
@@ -14,6 +14,11 @@
                i2c3 = &i2c4;
        };
 
+       config {
+               st,fastboot-gpios = <&gpioa 13 GPIO_ACTIVE_LOW>;
+               st,stm32prog-gpios = <&gpioa 14 GPIO_ACTIVE_LOW>;
+       };
+
        led {
                compatible = "gpio-leds";
 
diff --git a/arch/arm/mach-stm32mp/cpu.c b/arch/arm/mach-stm32mp/cpu.c
index 206b82e..305ea6d 100644
--- a/arch/arm/mach-stm32mp/cpu.c
+++ b/arch/arm/mach-stm32mp/cpu.c
@@ -359,12 +359,12 @@ static void setup_boot_mode(void)
        u32 boot_mode =
                (boot_ctx & TAMP_BOOT_MODE_MASK) >> TAMP_BOOT_MODE_SHIFT;
        int instance = (boot_mode & TAMP_BOOT_INSTANCE_MASK) - 1;
+       u32 forced_mode = (boot_ctx & TAMP_BOOT_FORCED_MASK);
        struct udevice *dev;
        int alias;
 
-       pr_debug("%s: boot_ctx=0x%x => boot_mode=%x, instance=%d\n",
-                __func__, boot_ctx, boot_mode, instance);
-
+       pr_debug("%s: boot_ctx=0x%x => boot_mode=%x, instance=%d forced=%x\n",
+                __func__, boot_ctx, boot_mode, instance, forced_mode);
        switch (boot_mode & TAMP_BOOT_DEVICE_MASK) {
        case BOOT_SERIAL_UART:
                if (instance > ARRAY_SIZE(serial_addr))
@@ -409,6 +409,36 @@ static void setup_boot_mode(void)
                pr_debug("unexpected boot mode = %x\n", boot_mode);
                break;
        }
+
+       switch (forced_mode) {
+       case BOOT_FASTBOOT:
+               printf("Enter fastboot!\n");
+               env_set("preboot", "env set preboot; fastboot 0");
+               break;
+       case BOOT_STM32PROG:
+               env_set("boot_device", "usb");
+               env_set("boot_instance", "0");
+               break;
+       case BOOT_UMS_MMC0:
+       case BOOT_UMS_MMC1:
+       case BOOT_UMS_MMC2:
+               printf("Enter UMS!\n");
+               instance = forced_mode - BOOT_UMS_MMC0;
+               sprintf(cmd, "env set preboot; ums 0 mmc %d", instance);
+               env_set("preboot", cmd);
+               break;
+       case BOOT_RECOVERY:
+               env_set("preboot", "env set preboot; run altbootcmd");
+               break;
+       case BOOT_NORMAL:
+               break;
+       default:
+               pr_debug("unexpected forced boot mode = %x\n", forced_mode);
+               break;
+       }
+
+       /* clear TAMP for next reboot */
+       clrsetbits_le32(TAMP_BOOT_CONTEXT, TAMP_BOOT_FORCED_MASK, BOOT_NORMAL);
 }
 
 /*
diff --git a/arch/arm/mach-stm32mp/include/mach/stm32.h 
b/arch/arm/mach-stm32mp/include/mach/stm32.h
index f2ab026..da23af0 100644
--- a/arch/arm/mach-stm32mp/include/mach/stm32.h
+++ b/arch/arm/mach-stm32mp/include/mach/stm32.h
@@ -92,6 +92,17 @@ enum boot_device {
 #define TAMP_BOOT_MODE_SHIFT           8
 #define TAMP_BOOT_DEVICE_MASK          GENMASK(7, 4)
 #define TAMP_BOOT_INSTANCE_MASK                GENMASK(3, 0)
+#define TAMP_BOOT_FORCED_MASK          GENMASK(7, 0)
+
+enum forced_boot_mode {
+       BOOT_NORMAL = 0x00,
+       BOOT_FASTBOOT = 0x01,
+       BOOT_RECOVERY = 0x02,
+       BOOT_STM32PROG = 0x03,
+       BOOT_UMS_MMC0 = 0x10,
+       BOOT_UMS_MMC1 = 0x11,
+       BOOT_UMS_MMC2 = 0x12,
+};
 
 /* offset used for BSEC driver: misc_read and misc_write */
 #define STM32_BSEC_SHADOW_OFFSET       0x0
diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c
index 0d963c2..d13793e 100644
--- a/board/st/stm32mp1/stm32mp1.c
+++ b/board/st/stm32mp1/stm32mp1.c
@@ -67,6 +67,55 @@ int checkboard(void)
        return 0;
 }
 
+static void board_key_check(void)
+{
+#if defined(CONFIG_FASTBOOT) || defined(CONFIG_CMD_STM32PROG)
+       ofnode node;
+       struct gpio_desc gpio;
+       enum forced_boot_mode boot_mode = BOOT_NORMAL;
+
+       node = ofnode_path("/config");
+       if (!ofnode_valid(node)) {
+               debug("%s: no /config node?\n", __func__);
+               return;
+       }
+#ifdef CONFIG_FASTBOOT
+       if (gpio_request_by_name_nodev(node, "st,fastboot-gpios", 0,
+                                      &gpio, GPIOD_IS_IN)) {
+               debug("%s: could not find a /config/st,fastboot-gpios\n",
+                     __func__);
+       } else {
+               if (dm_gpio_get_value(&gpio)) {
+                       puts("Fastboot key pressed, ");
+                       boot_mode = BOOT_FASTBOOT;
+               }
+
+               dm_gpio_free(NULL, &gpio);
+       }
+#endif
+#ifdef CONFIG_CMD_STM32PROG
+       if (gpio_request_by_name_nodev(node, "st,stm32prog-gpios", 0,
+                                      &gpio, GPIOD_IS_IN)) {
+               debug("%s: could not find a /config/st,stm32prog-gpios\n",
+                     __func__);
+       } else {
+               if (dm_gpio_get_value(&gpio)) {
+                       puts("STM32Programmer key pressed, ");
+                       boot_mode = BOOT_STM32PROG;
+               }
+               dm_gpio_free(NULL, &gpio);
+       }
+#endif
+
+       if (boot_mode != BOOT_NORMAL) {
+               puts("entering download mode...\n");
+               clrsetbits_le32(TAMP_BOOT_CONTEXT,
+                               TAMP_BOOT_FORCED_MASK,
+                               boot_mode);
+       }
+#endif
+}
+
 static struct dwc2_plat_otg_data stm32mp_otg_data = {
        .usb_gusbcfg = STM32MP_GUSBCFG,
 };
@@ -227,6 +276,8 @@ int board_init(void)
        /* address of boot parameters */
        gd->bd->bi_boot_params = STM32_DDR_BASE + 0x100;
 
+       board_key_check();
+
        if (IS_ENABLED(CONFIG_LED))
                led_default_state();
 
-- 
2.7.4

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to