summaryrefslogtreecommitdiff
path: root/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'cpu')
-rw-r--r--cpu/arm_cortexa8/mx6/generic.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/cpu/arm_cortexa8/mx6/generic.c b/cpu/arm_cortexa8/mx6/generic.c
index 175cd03..8e5c9a6 100644
--- a/cpu/arm_cortexa8/mx6/generic.c
+++ b/cpu/arm_cortexa8/mx6/generic.c
@@ -889,4 +889,54 @@ int otp_clk_disable(void)
return 0;
}
+#ifdef CONFIG_CMD_IMX_DOWNLOAD_MODE
+#define PERSIST_WATCHDOG_RESET_BOOT (0x10000000)
+/*BOOT_CFG1[7..4] = 0x3 Boot from Serial ROM (I2C/SPI)*/
+#define BOOT_MODE_SERIAL_ROM (0x00000030)
+
+/* this function should call before enter linux, otherwise, you
+ * watchdog reset will enter mfg download mode again, clear this bit
+ * to prevent this behavior */
+void clear_mfgmode_mem(void)
+{
+ u32 reg;
+ reg = readl(SRC_BASE_ADDR + SRC_GPR9);
+
+ reg &= ~BOOT_MODE_SERIAL_ROM;
+ writel(reg, SRC_BASE_ADDR + SRC_GPR9);
+
+ reg = readl(SRC_BASE_ADDR + SRC_GPR10);
+ reg &= ~PERSIST_WATCHDOG_RESET_BOOT;
+ reg = writel(reg, SRC_BASE_ADDR + SRC_GPR10);
+}
+
+void do_switch_mfgmode(void)
+{
+ u32 reg;
+
+ /*
+ * During reset, if GPR10[28] is 1, ROM will copy GPR9[25:0]
+ * to SBMR1, which will determine what is the boot device.
+ * Here SERIAL_ROM mode is selected
+ */
+ reg = readl(SRC_BASE_ADDR + SRC_GPR9);
+ reg |= BOOT_MODE_SERIAL_ROM;
+ writel(reg, SRC_BASE_ADDR + SRC_GPR9);
+
+ reg = readl(SRC_BASE_ADDR + SRC_GPR10);
+ reg |= PERSIST_WATCHDOG_RESET_BOOT;
+ writel(reg, SRC_BASE_ADDR + SRC_GPR10);
+
+ /*
+ * this watchdog reset will let chip enter mfgtool download
+ * mode.
+ */
+ do_reset(NULL, 0, 0, NULL);
+}
+
+U_BOOT_CMD(
+ download_mode, 1, 1, do_switch_mfgmode,
+ "download_mode - enter i.MX serial/usb download mode",
+ "");
+#endif