mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-26 15:28:50 +00:00
ARM: imx: Add support for switching primary/secondary boot mode to bmode
The i.MX6/i.MX7 is capable of booting a secondary "redundant" system image in case the primary one is corrupted. The user can force this boot mode as well by explicitly setting SRC GPR10 bit 30. This can be potentially useful when upgrading the bootloader itself. Expose this functionality to the user. Signed-off-by: Marek Vasut <marex@denx.de> Cc: Fabio Estevam <festevam@gmail.com> Cc: NXP i.MX U-Boot Team <uboot-imx@nxp.com> Cc: Peng Fan <peng.fan@nxp.com> Cc: Stefano Babic <sbabic@denx.de> Reviewed-by: Stefano Babic <sbabic@denx.de>
This commit is contained in:
parent
c72372d38c
commit
5ec83561c4
4 changed files with 21 additions and 7 deletions
|
@ -7,6 +7,8 @@
|
||||||
#define _ASM_BOOT_MODE_H
|
#define _ASM_BOOT_MODE_H
|
||||||
#define MAKE_CFGVAL(cfg1, cfg2, cfg3, cfg4) \
|
#define MAKE_CFGVAL(cfg1, cfg2, cfg3, cfg4) \
|
||||||
((cfg4) << 24) | ((cfg3) << 16) | ((cfg2) << 8) | (cfg1)
|
((cfg4) << 24) | ((cfg3) << 16) | ((cfg2) << 8) | (cfg1)
|
||||||
|
#define MAKE_CFGVAL_PRIMARY_BOOT 0xfffffff0
|
||||||
|
#define MAKE_CFGVAL_SECONDARY_BOOT 0xffffffff
|
||||||
|
|
||||||
enum boot_device {
|
enum boot_device {
|
||||||
WEIM_NOR_BOOT,
|
WEIM_NOR_BOOT,
|
||||||
|
|
|
@ -79,6 +79,7 @@ struct bd_info;
|
||||||
|
|
||||||
#ifdef CONFIG_MX6
|
#ifdef CONFIG_MX6
|
||||||
#define IMX6_SRC_GPR10_BMODE BIT(28)
|
#define IMX6_SRC_GPR10_BMODE BIT(28)
|
||||||
|
#define IMX6_SRC_GPR10_PERSIST_SECONDARY_BOOT BIT(30)
|
||||||
|
|
||||||
#define IMX6_BMODE_MASK GENMASK(7, 0)
|
#define IMX6_BMODE_MASK GENMASK(7, 0)
|
||||||
#define IMX6_BMODE_SHIFT 4
|
#define IMX6_BMODE_SHIFT 4
|
||||||
|
@ -128,6 +129,7 @@ void gpr_init(void);
|
||||||
|
|
||||||
#ifdef CONFIG_MX7
|
#ifdef CONFIG_MX7
|
||||||
#define IMX7_SRC_GPR10_BMODE BIT(28)
|
#define IMX7_SRC_GPR10_BMODE BIT(28)
|
||||||
|
#define IMX7_SRC_GPR10_PERSIST_SECONDARY_BOOT BIT(30)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* address translation table */
|
/* address translation table */
|
||||||
|
|
|
@ -104,20 +104,28 @@ void init_src(void)
|
||||||
void boot_mode_apply(unsigned cfg_val)
|
void boot_mode_apply(unsigned cfg_val)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_MX6
|
#ifdef CONFIG_MX6
|
||||||
|
const u32 persist_sec = IMX6_SRC_GPR10_PERSIST_SECONDARY_BOOT;
|
||||||
const u32 bmode = IMX6_SRC_GPR10_BMODE;
|
const u32 bmode = IMX6_SRC_GPR10_BMODE;
|
||||||
#elif CONFIG_MX7
|
#elif CONFIG_MX7
|
||||||
|
const u32 persist_sec = IMX7_SRC_GPR10_PERSIST_SECONDARY_BOOT;
|
||||||
const u32 bmode = IMX7_SRC_GPR10_BMODE;
|
const u32 bmode = IMX7_SRC_GPR10_BMODE;
|
||||||
#endif
|
#endif
|
||||||
struct src *psrc = (struct src *)SRC_BASE_ADDR;
|
struct src *psrc = (struct src *)SRC_BASE_ADDR;
|
||||||
unsigned reg;
|
unsigned reg;
|
||||||
|
|
||||||
writel(cfg_val, &psrc->gpr9);
|
if (cfg_val == MAKE_CFGVAL_PRIMARY_BOOT)
|
||||||
reg = readl(&psrc->gpr10);
|
clrbits_le32(&psrc->gpr10, persist_sec);
|
||||||
if (cfg_val)
|
else if (cfg_val == MAKE_CFGVAL_SECONDARY_BOOT)
|
||||||
reg |= bmode;
|
setbits_le32(&psrc->gpr10, persist_sec);
|
||||||
else
|
else {
|
||||||
reg &= ~bmode;
|
writel(cfg_val, &psrc->gpr9);
|
||||||
writel(reg, &psrc->gpr10);
|
reg = readl(&psrc->gpr10);
|
||||||
|
if (cfg_val)
|
||||||
|
reg |= bmode;
|
||||||
|
else
|
||||||
|
reg &= ~bmode;
|
||||||
|
writel(reg, &psrc->gpr10);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -414,6 +414,8 @@ void s_init(void)
|
||||||
#ifndef CONFIG_SPL_BUILD
|
#ifndef CONFIG_SPL_BUILD
|
||||||
const struct boot_mode soc_boot_modes[] = {
|
const struct boot_mode soc_boot_modes[] = {
|
||||||
{"normal", MAKE_CFGVAL(0x00, 0x00, 0x00, 0x00)},
|
{"normal", MAKE_CFGVAL(0x00, 0x00, 0x00, 0x00)},
|
||||||
|
{"primary", MAKE_CFGVAL_PRIMARY_BOOT},
|
||||||
|
{"secondary", MAKE_CFGVAL_SECONDARY_BOOT},
|
||||||
{NULL, 0},
|
{NULL, 0},
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Reference in a new issue