diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/cpu/armv7/mx6/soc.c | 94 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-mx6/imx-regs.h | 1 | ||||
-rw-r--r-- | arch/arm/include/asm/imx-common/boot_mode.h | 21 | ||||
-rw-r--r-- | arch/arm/lib/board.c | 12 |
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(); |