summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorNitin Garg <nitin.garg@freescale.com>2014-05-27 17:20:51 -0500
committerNitin Garg <nitin.garg@freescale.com>2014-06-13 10:16:14 -0500
commit624f876980209f9073e6fb834541efa89192d484 (patch)
tree21af710dcf8d5166c06647387b3aedb841ec3518 /arch
parentb79371410aa44972dea53d5c19d256170928dcbd (diff)
downloadu-boot-imx-624f876980209f9073e6fb834541efa89192d484.zip
u-boot-imx-624f876980209f9073e6fb834541efa89192d484.tar.gz
u-boot-imx-624f876980209f9073e6fb834541efa89192d484.tar.bz2
ENGR00315499-10 ARM:imx6:sabresd/sabreauto Add android fastboot supporting
Support android features: fastboot, booti command and recovery for sabresd SD, sabresd eMMC, sabreauto SD, sabreauto NAND. For all booting media (SD, eMMC, NAND), inherits the partitions layout from v2009.08. Fastboot will detect the booting media to replace hardcoding fastboot device. SATA is not supported. FDT is supported to use the "unused" fields in bootimg header which requires the FDT to be combined into the boot.img. For non-FDT boot.img, the "unused" fields should left to NULL and is compatible to boot. Signed-off-by: Ye.Li <B37916@freescale.com> Signed-off-by: Nitin Garg <nitin.garg@freescale.com>
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();