summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKe Qinghua <qinghua.ke@freescale.com>2014-04-23 17:08:30 +0800
committerKe Qinghua <qinghua.ke@freescale.com>2014-04-23 17:16:45 +0800
commitd782a300614be14690be40ddfd11cba5beb81419 (patch)
treed6f172c4f38b49abd546cbb0965d6f66b6de3946
parent0aa03f145e83640de10ac5899be5a3926d6c1e4b (diff)
ENGR00309837 Failed to enter recovery by command "reboot recovery". 100%
Enable recovery flag setting in SNVS for kernel 3.10 Signed-off-by: Ke Qinghua <qinghua.ke@freescale.com>
-rw-r--r--arch/arm/mach-imx/Kconfig6
-rw-r--r--arch/arm/mach-imx/system.c62
2 files changed, 67 insertions, 1 deletions
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 65d5476679c6..bb8454ba609b 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -889,6 +889,12 @@ config SOC_VF610
help
This enable support for Freescale Vybrid VF610 processor.
+config MXC_REBOOT_MFGMODE
+ bool "MFG mode setting"
+
+config MXC_REBOOT_ANDROID_CMD
+ bool "Android reboot setting"
+
endif
source "arch/arm/mach-imx/devices/Kconfig"
diff --git a/arch/arm/mach-imx/system.c b/arch/arm/mach-imx/system.c
index df3d1ff0c288..b3f48f032a26 100644
--- a/arch/arm/mach-imx/system.c
+++ b/arch/arm/mach-imx/system.c
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999 ARM Limited
* Copyright (C) 2000 Deep Blue Solutions Ltd
- * Copyright (C) 2006-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2006-2014 Freescale Semiconductor, Inc. All Rights Reserved.
* Copyright 2008 Juergen Beisert, kernel@pengutronix.de
* Copyright 2009 Ilya Yanok, Emcraft Systems Ltd, yanok@emcraft.com
*
@@ -31,11 +31,69 @@
#include "common.h"
#include "hardware.h"
+#include "mx6.h"
static void __iomem *wdog_base;
static struct clk *wdog_clk;
static u32 wdog_source = 1; /* use WDOG1 default */
+#ifdef CONFIG_MXC_REBOOT_ANDROID_CMD
+/* This function will set a bit on SNVS_LPGPR[7-8] bits to enter
+ * special boot mode. These bits will not clear by watchdog reset, so
+ * it can be checked by bootloader to choose enter different mode.*/
+
+#define ANDROID_RECOVERY_BOOT (1 << 7)
+#define ANDROID_FASTBOOT_BOOT (1 << 8)
+
+#define AIPS1_ARB_BASE_ADDR 0x02000000
+#define ATZ1_BASE_ADDR AIPS1_ARB_BASE_ADDR
+#define AIPS1_OFF_BASE_ADDR (ATZ1_BASE_ADDR + 0x80000)
+#define MX6_SNVS_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x4C000)
+#define SNVS_LPGPR 0x68
+#define SNVS_SIZE (1024*16)
+void do_switch_recovery(void)
+{
+ u32 reg;
+ u32 addr;
+ addr = ioremap(MX6_SNVS_BASE_ADDR, SNVS_SIZE);
+ if (!addr) {
+ pr_warn("SNVS ioremap failed!\n");
+ return;
+ }
+ reg = __raw_readl(addr + SNVS_LPGPR);
+ reg |= ANDROID_RECOVERY_BOOT;
+ __raw_writel(reg, (addr + SNVS_LPGPR));
+
+ iounmap(addr);
+}
+
+void do_switch_fastboot(void)
+{
+ u32 reg;
+ u32 addr;
+
+ addr = ioremap(MX6_SNVS_BASE_ADDR, SNVS_SIZE);
+ if (!addr) {
+ pr_warn("SNVS ioremap failed!\n");
+ return;
+ }
+
+ reg = __raw_readl(addr + SNVS_LPGPR);
+ reg |= ANDROID_FASTBOOT_BOOT;
+ __raw_writel(reg, addr + SNVS_LPGPR);
+
+ iounmap(addr);
+}
+#endif
+static void arch_reset_special_mode(char mode, const char *cmd)
+{
+#ifdef CONFIG_MXC_REBOOT_ANDROID_CMD
+ if (strcmp(cmd, "recovery") == 0)
+ do_switch_recovery();
+ else if (strcmp(cmd, "fastboot") == 0)
+ do_switch_fastboot();
+#endif
+}
/*
* Reset the system. It is called by machine_restart().
*/
@@ -43,6 +101,8 @@ void mxc_restart(char mode, const char *cmd)
{
unsigned int wcr_enable;
+ arch_reset_special_mode(mode, cmd);
+
if (wdog_clk)
clk_enable(wdog_clk);