diff options
author | Ke Qinghua <qinghua.ke@freescale.com> | 2014-04-23 17:08:30 +0800 |
---|---|---|
committer | Ke Qinghua <qinghua.ke@freescale.com> | 2014-04-23 17:16:45 +0800 |
commit | d782a300614be14690be40ddfd11cba5beb81419 (patch) | |
tree | d6f172c4f38b49abd546cbb0965d6f66b6de3946 | |
parent | 0aa03f145e83640de10ac5899be5a3926d6c1e4b (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/Kconfig | 6 | ||||
-rw-r--r-- | arch/arm/mach-imx/system.c | 62 |
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); |