How to Support Recovery Mode for POR Reboot Based on i.MX6 Android R13.4.1

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to Support Recovery Mode for POR Reboot Based on i.MX6 Android R13.4.1

No ratings

How to Support Recovery Mode for POR Reboot Based on i.MX6 Android R13.4.1


Overview

This purpose of this document is to introduce how to support recovery mode for POR reboot event based on MX6 Android R13.4.1.

Background

If you boot Android R13.4.1 on MX6 SabreSD board, the reboot reason is Watchdog. But if the reboot reason is changed from Watchdog to POR, the recovery mode is failed to enter after factory reset.

In R13.4.1, the bit 8 of SRC_GPR10 is used as the persistent bit of recovery mode. This bit is expected to be kept after reboot so that U-boot can use this bit to distinguish what mode should enter. However all SRC registers will be reset on POR sequence according to i.MX6DQRM Section 59.4.1.2.3 IPP_RESET_B (POR). So when the reboot reason is POR, the persistent bit of recovery mode is cleared even if the software set it before reboot. It causes the bootloader won't enter recovery mode after reboot.

Software Changes

According to i.MX6DQRM, the SNVS_LP General Purpose Register provides a 32 bit read write register, which can be used by any application for retaining 32 bit data during a power-down mode. So to support recovery mode for POR event, the SNVS_LP register can be used to store the persistent bit of recovery mode. The following changes are reqiured to apply (See patches.tar.gz)

  • Apply for Uboot patch bootable/bootloader/uboot-imx/0001-ENGR00235817-mx6-use-SNVS-LPGPR-register-to-store-bo.patch.

diff --git a/cpu/arm_cortexa8/mx6/generic.c b/cpu/arm_cortexa8/mx6/generic.c

index 257c930..bd47130 100644

--- a/cpu/arm_cortexa8/mx6/generic.c

+++ b/cpu/arm_cortexa8/mx6/generic.c

@@ -1146,14 +1146,14 @@ int check_and_clean_recovery_flag(void)

{

  int flag_set = 0;

  u32 reg;

- reg = readl(SRC_BASE_ADDR + SRC_GPR10);

+ reg = readl(SNVS_BASE_ADDR + SNVS_LPGPR);

  flag_set = !!(reg & ANDROID_RECOVERY_BOOT);

  /* clean it in case looping infinite here.... */

  if (flag_set) {

   reg &= ~ANDROID_RECOVERY_BOOT;

-  writel(reg, SRC_BASE_ADDR + SRC_GPR10);

+  writel(reg, SNVS_BASE_ADDR + SNVS_LPGPR);

  }

  return flag_set;

@@ -1168,14 +1168,15 @@ int fastboot_check_and_clean_flag(void)

{

  int flag_set = 0;

  u32 reg;

- reg = readl(SRC_BASE_ADDR + SRC_GPR10);

+

+ reg = readl(SNVS_BASE_ADDR + SNVS_LPGPR);

  flag_set = !!(reg & ANDROID_FASTBOOT_BOOT);

  /* clean it in case looping infinite here.... */

  if (flag_set) {

   reg &= ~ANDROID_FASTBOOT_BOOT;

-  writel(reg, SRC_BASE_ADDR + SRC_GPR10);

+  writel(reg, SNVS_BASE_ADDR + SNVS_LPGPR);

  }

  return flag_set;

diff --git a/include/asm-arm/arch-mx6/mx6.h b/include/asm-arm/arch-mx6/mx6.h

index efb90c2..45381e2 100644

--- a/include/asm-arm/arch-mx6/mx6.h

+++ b/include/asm-arm/arch-mx6/mx6.h

@@ -732,6 +732,8 @@

#define SRC_GPR9  0x40

#define SRC_GPR10  0x44

+#define SNVS_LPGPR              0x68

+

/* Get Board ID */

#define board_is_rev(system_rev, rev) (((system_rev & 0x0F00) == rev) ? 1 : 0)

#define chip_is_type(system_rev, rev) \

  • Apply for kernel patch kernel_imx/0001-ENGR00235817-mx6-use-SNVS-LPGPR-register-to-store-bo.patch

diff --git a/arch/arm/mach-mx6/system.c b/arch/arm/mach-mx6/system.c

index 6d24f22..61649c5 100644

--- a/arch/arm/mach-mx6/system.c

+++ b/arch/arm/mach-mx6/system.c

@@ -563,7 +563,7 @@ void mxc_clear_mfgmode(void)

#endif

#ifdef CONFIG_MXC_REBOOT_ANDROID_CMD

-/* This function will set a bit on SRC_GPR10[7-8] bits to enter

+/* 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.*/

@@ -574,18 +574,18 @@ void do_switch_recovery(void)

{

  u32 reg;

- reg = __raw_readl(SRC_BASE_ADDR + SRC_GPR10);

+ reg = __raw_readl(MX6Q_SNVS_BASE_ADDR + SNVS_LPGPR);

  reg |= ANDROID_RECOVERY_BOOT;

- __raw_writel(reg, SRC_BASE_ADDR + SRC_GPR10);

+ __raw_writel(reg, MX6Q_SNVS_BASE_ADDR + SNVS_LPGPR);

}

void do_switch_fastboot(void)

{

  u32 reg;

- reg = __raw_readl(SRC_BASE_ADDR + SRC_GPR10);

+ reg = __raw_readl(MX6Q_SNVS_BASE_ADDR + SNVS_LPGPR);

  reg |= ANDROID_FASTBOOT_BOOT;

- __raw_writel(reg, SRC_BASE_ADDR + SRC_GPR10);

+ __raw_writel(reg, MX6Q_SNVS_BASE_ADDR + SNVS_LPGPR);

}

#endif

diff --git a/arch/arm/plat-mxc/include/mach/mx6.h b/arch/arm/plat-mxc/include/mach/mx6.h

index 48b04b1..bb22de0 100644

--- a/arch/arm/plat-mxc/include/mach/mx6.h

+++ b/arch/arm/plat-mxc/include/mach/mx6.h

@@ -302,6 +302,8 @@

#define SRC_GPR9   0x40

#define SRC_GPR10   0x44

+#define SNVS_LPGPR   0x68

+

/* GPC offsets */

#define MXC_GPC_CNTR_OFFSET  0x0

Labels (2)
Attachments
Version history
Last update:
‎01-15-2013 11:07 PM
Updated by: