Hi Jörg, On 26/03/2015 10:39, Jörg Krause wrote: > Reading the GPIOs for getting the boot mode does not show the correct result > for USB boot mode in case the recovery switch, eg. BM2 for switching from NAND > to USB boot mode, is hold down while plugging in USB and released before > U-Boot > is loaded by mxsldr. > > This state is stored in the HW_OCOTP_ROM0 register. HW_OCOTP_ROM0[27:24] maps > to > BM3-BM0, HW_OCOTP_ROM0[28] maps to voltage selector. > > For using mxs_wait_mask_clr() add imx-common/misc.o to the SPL build. >
As far as I understand from the manual, bootmode is *always* copied fromt the OTP after a reset. Then, I agree that is better to use OCOTP as the GPIOs. GPIOs were already sampled by ROM at reset and their value could be different when evaluated by SPL. > Signed-off-by: Jörg Krause <joerg.krause@embedded.rocks> > Cc: Stefano Babic <sba...@denx.de> > --- > arch/arm/Makefile | 2 +- > arch/arm/cpu/arm926ejs/mxs/spl_boot.c | 73 > +++++------------------------- > arch/arm/include/asm/arch-mxs/regs-ocotp.h | 2 + > drivers/misc/mxs_ocotp.c | 2 - > 4 files changed, 14 insertions(+), 65 deletions(-) > > diff --git a/arch/arm/Makefile b/arch/arm/Makefile > index 08946de..55fe509 100644 > --- a/arch/arm/Makefile > +++ b/arch/arm/Makefile > @@ -37,7 +37,7 @@ libs-y += arch/arm/cpu/ > libs-y += arch/arm/lib/ > > ifeq ($(CONFIG_SPL_BUILD),y) > -ifneq (,$(CONFIG_MX23)$(CONFIG_MX35)$(filter $(SOC), mx25 mx27 mx5 mx6 mx31 > mx35)) > +ifneq (,$(CONFIG_MX23)$(CONFIG_MX35)$(filter $(SOC), mx25 mx27 mx5 mx6 mx31 > mx35 mxs)) > libs-y += arch/arm/imx-common/ > endif > else > diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c > b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c > index d7956e5..c5bf3c4 100644 > --- a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c > +++ b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c > @@ -40,73 +40,22 @@ void early_delay(int delay) > ; > } > > -#define MUX_CONFIG_BOOTMODE_PAD (MXS_PAD_3V3 | MXS_PAD_4MA | > MXS_PAD_NOPULL) > -static const iomux_cfg_t iomux_boot[] = { > -#if defined(CONFIG_MX23) > - MX23_PAD_LCD_D00__GPIO_1_0 | MUX_CONFIG_BOOTMODE_PAD, > - MX23_PAD_LCD_D01__GPIO_1_1 | MUX_CONFIG_BOOTMODE_PAD, > - MX23_PAD_LCD_D02__GPIO_1_2 | MUX_CONFIG_BOOTMODE_PAD, > - MX23_PAD_LCD_D03__GPIO_1_3 | MUX_CONFIG_BOOTMODE_PAD, > - MX23_PAD_LCD_D04__GPIO_1_4 | MUX_CONFIG_BOOTMODE_PAD, > - MX23_PAD_LCD_D05__GPIO_1_5 | MUX_CONFIG_BOOTMODE_PAD, > -#elif defined(CONFIG_MX28) > - MX28_PAD_LCD_D00__GPIO_1_0 | MUX_CONFIG_BOOTMODE_PAD, > - MX28_PAD_LCD_D01__GPIO_1_1 | MUX_CONFIG_BOOTMODE_PAD, > - MX28_PAD_LCD_D02__GPIO_1_2 | MUX_CONFIG_BOOTMODE_PAD, > - MX28_PAD_LCD_D03__GPIO_1_3 | MUX_CONFIG_BOOTMODE_PAD, > - MX28_PAD_LCD_D04__GPIO_1_4 | MUX_CONFIG_BOOTMODE_PAD, > - MX28_PAD_LCD_D05__GPIO_1_5 | MUX_CONFIG_BOOTMODE_PAD, > -#endif > -}; > - > static uint8_t mxs_get_bootmode_index(void) > { > - uint8_t bootmode = 0; > - int i; > - uint8_t masked; > - > - /* Setup IOMUX of bootmode pads to GPIO */ > - mxs_iomux_setup_multiple_pads(iomux_boot, ARRAY_SIZE(iomux_boot)); > - > -#if defined(CONFIG_MX23) > - /* Setup bootmode pins as GPIO input */ > - gpio_direction_input(MX23_PAD_LCD_D00__GPIO_1_0); > - gpio_direction_input(MX23_PAD_LCD_D01__GPIO_1_1); > - gpio_direction_input(MX23_PAD_LCD_D02__GPIO_1_2); > - gpio_direction_input(MX23_PAD_LCD_D03__GPIO_1_3); > - gpio_direction_input(MX23_PAD_LCD_D05__GPIO_1_5); > - > - /* Read bootmode pads */ > - bootmode |= (gpio_get_value(MX23_PAD_LCD_D00__GPIO_1_0) ? 1 : 0) << 0; > - bootmode |= (gpio_get_value(MX23_PAD_LCD_D01__GPIO_1_1) ? 1 : 0) << 1; > - bootmode |= (gpio_get_value(MX23_PAD_LCD_D02__GPIO_1_2) ? 1 : 0) << 2; > - bootmode |= (gpio_get_value(MX23_PAD_LCD_D03__GPIO_1_3) ? 1 : 0) << 3; > - bootmode |= (gpio_get_value(MX23_PAD_LCD_D05__GPIO_1_5) ? 1 : 0) << 5; > -#elif defined(CONFIG_MX28) > - /* Setup bootmode pins as GPIO input */ > - gpio_direction_input(MX28_PAD_LCD_D00__GPIO_1_0); > - gpio_direction_input(MX28_PAD_LCD_D01__GPIO_1_1); > - gpio_direction_input(MX28_PAD_LCD_D02__GPIO_1_2); > - gpio_direction_input(MX28_PAD_LCD_D03__GPIO_1_3); > - gpio_direction_input(MX28_PAD_LCD_D04__GPIO_1_4); > - gpio_direction_input(MX28_PAD_LCD_D05__GPIO_1_5); > - > - /* Read bootmode pads */ > - bootmode |= (gpio_get_value(MX28_PAD_LCD_D00__GPIO_1_0) ? 1 : 0) << 0; > - bootmode |= (gpio_get_value(MX28_PAD_LCD_D01__GPIO_1_1) ? 1 : 0) << 1; > - bootmode |= (gpio_get_value(MX28_PAD_LCD_D02__GPIO_1_2) ? 1 : 0) << 2; > - bootmode |= (gpio_get_value(MX28_PAD_LCD_D03__GPIO_1_3) ? 1 : 0) << 3; > - bootmode |= (gpio_get_value(MX28_PAD_LCD_D04__GPIO_1_4) ? 1 : 0) << 4; > - bootmode |= (gpio_get_value(MX28_PAD_LCD_D05__GPIO_1_5) ? 1 : 0) << 5; > -#endif > + struct mxs_ocotp_regs *ocotp_regs = > + (struct mxs_ocotp_regs *)MXS_OCOTP_BASE; > + uint32_t data; > + > + writel(OCOTP_CTRL_RD_BANK_OPEN, &ocotp_regs->hw_ocotp_ctrl_set); > > - for (i = 0; i < ARRAY_SIZE(mxs_boot_modes); i++) { > - masked = bootmode & mxs_boot_modes[i].boot_mask; > - if (masked == mxs_boot_modes[i].boot_pads) > - break; > + if (mxs_wait_mask_clr(&ocotp_regs->hw_ocotp_ctrl_reg, OCOTP_CTRL_BUSY, > + MXS_OCOTP_TIMEOUT)) { > + printf("MXS: Can't get boot mode from OCOTP\n"); > + return 0; > } > > - return i; > + data = readl(&ocotp_regs->hw_ocotp_rom0) >> 24; > + return (uint8_t) data; > } > > static void mxs_spl_fixup_vectors(void) > diff --git a/arch/arm/include/asm/arch-mxs/regs-ocotp.h > b/arch/arm/include/asm/arch-mxs/regs-ocotp.h > index bd80ac7..9057dc1 100644 > --- a/arch/arm/include/asm/arch-mxs/regs-ocotp.h > +++ b/arch/arm/include/asm/arch-mxs/regs-ocotp.h > @@ -63,6 +63,8 @@ struct mxs_ocotp_regs { > }; > #endif > > +#define MXS_OCOTP_TIMEOUT 100000 > + > #define OCOTP_CTRL_WR_UNLOCK_MASK (0xffff << 16) > #define OCOTP_CTRL_WR_UNLOCK_OFFSET 16 > #define OCOTP_CTRL_WR_UNLOCK_KEY (0x3e77 << 16) > diff --git a/drivers/misc/mxs_ocotp.c b/drivers/misc/mxs_ocotp.c > index 6f0a1d3..6ef4f92 100644 > --- a/drivers/misc/mxs_ocotp.c > +++ b/drivers/misc/mxs_ocotp.c > @@ -20,8 +20,6 @@ > #include <asm/arch/imx-regs.h> > #include <asm/arch/sys_proto.h> > > -#define MXS_OCOTP_TIMEOUT 100000 > - > static struct mxs_ocotp_regs *ocotp_regs = > (struct mxs_ocotp_regs *)MXS_OCOTP_BASE; > static struct mxs_power_regs *power_regs = > Acked-by: Stefano Babic <sba...@denx.de> Jörg, the only issue is that the release is next, and your patch cannot maybe be tested on most boards. I will tend to put it into -next and merge into -master after release. Best regards, Stefano Babic -- ===================================================================== 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 ===================================================================== _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot