[U-Boot] [PATCH 1/1] ARM: mxs: get boot mode from OTP
Stefano Babic
sbabic at denx.de
Thu Mar 26 13:31:54 CET 2015
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 at embedded.rocks>
> Cc: Stefano Babic <sbabic at 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 <sbabic at 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: sbabic at denx.de
=====================================================================
More information about the U-Boot
mailing list