On 05.08.20 15:34, Marek Vasut wrote: > 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 <ma...@denx.de> > Cc: Fabio Estevam <feste...@gmail.com> > Cc: NXP i.MX U-Boot Team <uboot-...@nxp.com> > Cc: Peng Fan <peng....@nxp.com> > Cc: Stefano Babic <sba...@denx.de> > --- > arch/arm/include/asm/mach-imx/boot_mode.h | 2 ++ > arch/arm/include/asm/mach-imx/sys_proto.h | 2 ++ > arch/arm/mach-imx/init.c | 22 +++++++++++++++------- > arch/arm/mach-imx/mx7/soc.c | 2 ++ > 4 files changed, 21 insertions(+), 7 deletions(-) > > diff --git a/arch/arm/include/asm/mach-imx/boot_mode.h > b/arch/arm/include/asm/mach-imx/boot_mode.h > index 3a483b6afa..6dc5855968 100644 > --- a/arch/arm/include/asm/mach-imx/boot_mode.h > +++ b/arch/arm/include/asm/mach-imx/boot_mode.h > @@ -7,6 +7,8 @@ > #define _ASM_BOOT_MODE_H > #define MAKE_CFGVAL(cfg1, cfg2, cfg3, cfg4) \ > ((cfg4) << 24) | ((cfg3) << 16) | ((cfg2) << 8) | (cfg1) > +#define MAKE_CFGVAL_PRIMARY_BOOT 0xfffffff0 > +#define MAKE_CFGVAL_SECONDARY_BOOT 0xffffffff > > enum boot_device { > WEIM_NOR_BOOT, > diff --git a/arch/arm/include/asm/mach-imx/sys_proto.h > b/arch/arm/include/asm/mach-imx/sys_proto.h > index 2d18b1f56b..15d1cba8e7 100644 > --- a/arch/arm/include/asm/mach-imx/sys_proto.h > +++ b/arch/arm/include/asm/mach-imx/sys_proto.h > @@ -79,6 +79,7 @@ struct bd_info; > > #ifdef CONFIG_MX6 > #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_SHIFT 4 > @@ -128,6 +129,7 @@ void gpr_init(void); > > #ifdef CONFIG_MX7 > #define IMX7_SRC_GPR10_BMODE BIT(28) > +#define IMX7_SRC_GPR10_PERSIST_SECONDARY_BOOT BIT(30) > #endif > > /* address translation table */ > diff --git a/arch/arm/mach-imx/init.c b/arch/arm/mach-imx/init.c > index e30d63b896..ce3eb4b0b8 100644 > --- a/arch/arm/mach-imx/init.c > +++ b/arch/arm/mach-imx/init.c > @@ -104,20 +104,28 @@ void init_src(void) > void boot_mode_apply(unsigned cfg_val) > { > #ifdef CONFIG_MX6 > + const u32 persist_sec = IMX6_SRC_GPR10_PERSIST_SECONDARY_BOOT; > const u32 bmode = IMX6_SRC_GPR10_BMODE; > #elif CONFIG_MX7 > + const u32 persist_sec = IMX7_SRC_GPR10_PERSIST_SECONDARY_BOOT; > const u32 bmode = IMX7_SRC_GPR10_BMODE; > #endif > struct src *psrc = (struct src *)SRC_BASE_ADDR; > unsigned reg; > > - writel(cfg_val, &psrc->gpr9); > - reg = readl(&psrc->gpr10); > - if (cfg_val) > - reg |= bmode; > - else > - reg &= ~bmode; > - writel(reg, &psrc->gpr10); > + if (cfg_val == MAKE_CFGVAL_PRIMARY_BOOT) > + clrbits_le32(&psrc->gpr10, persist_sec); > + else if (cfg_val == MAKE_CFGVAL_SECONDARY_BOOT) > + setbits_le32(&psrc->gpr10, persist_sec); > + else { > + writel(cfg_val, &psrc->gpr9); > + reg = readl(&psrc->gpr10); > + if (cfg_val) > + reg |= bmode; > + else > + reg &= ~bmode; > + writel(reg, &psrc->gpr10); > + } > } > #endif > > diff --git a/arch/arm/mach-imx/mx7/soc.c b/arch/arm/mach-imx/mx7/soc.c > index 2698ae623e..b6fd25a991 100644 > --- a/arch/arm/mach-imx/mx7/soc.c > +++ b/arch/arm/mach-imx/mx7/soc.c > @@ -415,6 +415,8 @@ void s_init(void) > #ifndef CONFIG_SPL_BUILD > const struct boot_mode soc_boot_modes[] = { > {"normal", MAKE_CFGVAL(0x00, 0x00, 0x00, 0x00)}, > + {"primary", MAKE_CFGVAL_PRIMARY_BOOT}, > + {"secondary", MAKE_CFGVAL_SECONDARY_BOOT}, > {NULL, 0}, > }; > #endif >
Reviewed-by: Stefano Babic <sba...@denx.de> Regards, Stefano -- ===================================================================== DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sba...@denx.de =====================================================================