[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