summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/cpu/armv7/mx6/soc.c94
-rw-r--r--arch/arm/include/asm/arch-mx6/imx-regs.h1
-rw-r--r--arch/arm/include/asm/imx-common/boot_mode.h21
-rw-r--r--arch/arm/lib/board.c12
4 files changed, 128 insertions, 0 deletions
diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c
index a386e03..0106385 100644
--- a/arch/arm/cpu/armv7/mx6/soc.c
+++ b/arch/arm/cpu/armv7/mx6/soc.c
@@ -21,6 +21,11 @@
#include <stdbool.h>
#include <asm/arch/mxc_hdmi.h>
#include <asm/arch/crm_regs.h>
+#ifdef CONFIG_FASTBOOT
+#ifdef CONFIG_ANDROID_RECOVERY
+#include <recovery.h>
+#endif
+#endif
#ifdef CONFIG_IMX_UDC
#include <asm/arch/mx6_usbphy.h>
#include <usb/imx_udc.h>
@@ -460,6 +465,49 @@ const struct boot_mode soc_boot_modes[] = {
{NULL, 0},
};
+enum boot_device get_boot_device(void)
+{
+ enum boot_device boot_dev = UNKNOWN_BOOT;
+ uint soc_sbmr = readl(SRC_BASE_ADDR + 0x4);
+ uint bt_mem_ctl = (soc_sbmr & 0x000000FF) >> 4 ;
+ uint bt_mem_type = (soc_sbmr & 0x00000008) >> 3;
+ uint bt_dev_port = (soc_sbmr & 0x00001800) >> 11;
+
+ switch (bt_mem_ctl) {
+ case 0x0:
+ if (bt_mem_type)
+ boot_dev = ONE_NAND_BOOT;
+ else
+ boot_dev = WEIM_NOR_BOOT;
+ break;
+ case 0x2:
+ boot_dev = SATA_BOOT;
+ break;
+ case 0x3:
+ if (bt_mem_type)
+ boot_dev = I2C_BOOT;
+ else
+ boot_dev = SPI_NOR_BOOT;
+ break;
+ case 0x4:
+ case 0x5:
+ boot_dev = bt_dev_port + SD1_BOOT;
+ break;
+ case 0x6:
+ case 0x7:
+ boot_dev = bt_dev_port + MMC1_BOOT;
+ break;
+ case 0x8 ... 0xf:
+ boot_dev = NAND_BOOT;
+ break;
+ default:
+ boot_dev = UNKNOWN_BOOT;
+ break;
+ }
+
+ return boot_dev;
+}
+
void s_init(void)
{
struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
@@ -658,6 +706,52 @@ void v7_outer_cache_disable(void)
}
#endif /* !CONFIG_SYS_L2CACHE_OFF */
+#ifdef CONFIG_FASTBOOT
+
+#ifdef CONFIG_ANDROID_RECOVERY
+#define ANDROID_RECOVERY_BOOT (1 << 7)
+/* check if the recovery bit is set by kernel, it can be set by kernel
+ * issue a command '# reboot recovery' */
+int recovery_check_and_clean_flag(void)
+{
+ int flag_set = 0;
+ u32 reg;
+ reg = readl(SNVS_BASE_ADDR + SNVS_LPGPR);
+
+ flag_set = !!(reg & ANDROID_RECOVERY_BOOT);
+ printf("check_and_clean: reg %x, flag_set %d\n", reg, flag_set);
+ /* clean it in case looping infinite here.... */
+ if (flag_set) {
+ reg &= ~ANDROID_RECOVERY_BOOT;
+ writel(reg, SNVS_BASE_ADDR + SNVS_LPGPR);
+ }
+
+ return flag_set;
+}
+#endif /*CONFIG_ANDROID_RECOVERY*/
+
+#define ANDROID_FASTBOOT_BOOT (1 << 8)
+/* check if the recovery bit is set by kernel, it can be set by kernel
+ * issue a command '# reboot fastboot' */
+int fastboot_check_and_clean_flag(void)
+{
+ int flag_set = 0;
+ u32 reg;
+
+ 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, SNVS_BASE_ADDR + SNVS_LPGPR);
+ }
+
+ return flag_set;
+}
+#endif /*CONFIG_FASTBOOT*/
+
#ifdef CONFIG_IMX_UDC
void set_usboh3_clk(void)
{
diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h
index dd91a81..0485407 100644
--- a/arch/arm/include/asm/arch-mx6/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx6/imx-regs.h
@@ -231,6 +231,7 @@
#define CHIP_REV_1_5 0x15
#define IRAM_SIZE 0x00040000
#define FEC_QUIRK_ENET_MAC
+#define SNVS_LPGPR 0x68
#if !(defined(__KERNEL_STRICT_NAMES) || defined(__ASSEMBLY__))
#include <asm/types.h>
diff --git a/arch/arm/include/asm/imx-common/boot_mode.h b/arch/arm/include/asm/imx-common/boot_mode.h
index de0205c..b3b75cd 100644
--- a/arch/arm/include/asm/imx-common/boot_mode.h
+++ b/arch/arm/include/asm/imx-common/boot_mode.h
@@ -9,6 +9,26 @@
#define MAKE_CFGVAL(cfg1, cfg2, cfg3, cfg4) \
((cfg4) << 24) | ((cfg3) << 16) | ((cfg2) << 8) | (cfg1)
+enum boot_device {
+ WEIM_NOR_BOOT,
+ ONE_NAND_BOOT,
+ PATA_BOOT,
+ SATA_BOOT,
+ I2C_BOOT,
+ SPI_NOR_BOOT,
+ SD1_BOOT,
+ SD2_BOOT,
+ SD3_BOOT,
+ SD4_BOOT,
+ MMC1_BOOT,
+ MMC2_BOOT,
+ MMC3_BOOT,
+ MMC4_BOOT,
+ NAND_BOOT,
+ UNKNOWN_BOOT,
+ BOOT_DEV_NUM = UNKNOWN_BOOT,
+};
+
struct boot_mode {
const char *name;
unsigned cfg_val;
@@ -16,5 +36,6 @@ struct boot_mode {
void add_board_boot_modes(const struct boot_mode *p);
void boot_mode_apply(unsigned cfg_val);
+enum boot_device get_boot_device(void);
extern const struct boot_mode soc_boot_modes[];
#endif
diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c
index 92e85c4..e962241 100644
--- a/arch/arm/lib/board.c
+++ b/arch/arm/lib/board.c
@@ -44,6 +44,10 @@
#include <miiphy.h>
#endif
+#ifdef CONFIG_FASTBOOT
+#include <fastboot.h>
+#endif
+
DECLARE_GLOBAL_DATA_PTR;
ulong monitor_flash_len;
@@ -655,6 +659,10 @@ void board_init_r(gd_t *id, ulong dest_addr)
board_late_init();
#endif
+#ifdef CONFIG_FASTBOOT
+ fastboot_setup();
+#endif
+
#ifdef CONFIG_BITBANGMII
bb_miiphy_init();
#endif
@@ -694,6 +702,10 @@ void board_init_r(gd_t *id, ulong dest_addr)
}
#endif
+#ifdef CONFIG_FASTBOOT
+ check_fastboot();
+#endif
+
/* main_loop() can return to retry autoboot, if so just run it again. */
for (;;) {
main_loop();