AnsweredAssumed Answered

iMX6 boot configuration by GPIO differ from SBMR1 in reset

Question asked by Julio Cruz on May 13, 2015
Latest reply on May 15, 2015 by Julio Cruz

Hi,

 

A custom board with a iMX6 DualLite have the BOOT_MODE equal to "10" (Internal Boot) and the boot flow is controlled by GPIO as below:

hardware config GPIO.png

The board have three SD sockets (SD1, SD2 and SD4). The following options are used to select the device:

 

board configuration.png

For testing purpose, I check the value of the register SBMR1 and SBMR2 in uBoot  as below:

 

  puts("Boot Configuration (SBMR1): \n");
  SBMR1 = readl(SRC_BASE_ADDR + 0x4);
  BOOT_CFG1 = ((SBMR1 & 0x000000FF) >> 0);
  BOOT_CFG2 = ((SBMR1 & 0x0000FF00) >> 4);
  BOOT_CFG3 = ((SBMR1 & 0x00FF0000) >> 8);
  BOOT_CFG4 = ((SBMR1 & 0xFF000000) >> 12);
  printf(" - BOOT_CFG1: "); print_register_bin(BOOT_CFG1);
  printf(" - BOOT_CFG2: "); print_register_bin(BOOT_CFG2);
  printf(" - BOOT_CFG3: "); print_register_bin(BOOT_CFG3);
  printf(" - BOOT_CFG4: "); print_register_bin(BOOT_CFG4)

  puts("Boot Configuration (SBMR2): \n");
  SBMR2 = readl(SRC_BASE_ADDR + 0x1C);
  SBMR2_8 = ((SBMR2 & 0x000000FF) >> 0);
  printf(" - SBMR2[7:0]: "); print_register_bin(SBMR2_8);

 

To print out the values I used the function below:

 

void print_register_bin(uint reg)
{
  if(reg & 0x80)
  printf("1");
  else 
  printf("0");

  if(reg & 0x40)
  printf("1");
  else 
  printf("0");

  if(reg & 0x20)
  printf("1");
  else 
  printf("0");

  if(reg & 0x10)
  printf("1");
  else 
  printf("0");

  if(reg & 0x08)
  printf("1");
  else 
  printf("0");

  if(reg & 0x04)
  printf("1");
  else 
  printf("0");

  if(reg & 0x02)
  printf("1");
  else 
  printf("0");

  if(reg & 0x01)
  printf("1");
  else 
  printf("0");

  printf("\n");
}

 

The testing shows unexpected results because the BOOT_CFG2 (in SBMR1) always have the bits [6 to 4] in zero and only recognize the bit [7] from the GPIO configuration (or dip switch).

 

To validate if the board and fuses are OK (following suggestions from others posts),

 

  1. The GPIO (dip-switch) was read using "gpio_get_value()" function
  2. The FUSES was read using "readl()" function

 

Both testing results was OK.

 

Below the functions used for reference:

 

  puts("Boot Configuration (FUSEMAP): \n");
  FUSE_MAP = readl(0x021BC000 + 0x450);
  BOOT_CFG1 = ((FUSE_MAP & 0x000000FF) >> 0);
  BOOT_CFG2 = ((FUSE_MAP & 0x0000FF00) >> 4);
  BOOT_CFG3 = ((FUSE_MAP & 0x00FF0000) >> 8);
  BOOT_CFG4 = ((FUSE_MAP & 0xFF000000) >> 12);
  printf(" - BOOT_CFG1: "); print_register_bin(BOOT_CFG1);
  printf(" - BOOT_CFG2: "); print_register_bin(BOOT_CFG2);
  printf(" - BOOT_CFG3: "); print_register_bin(BOOT_CFG3);
  printf(" - BOOT_CFG4: "); print_register_bin(BOOT_CFG4);


  puts("Boot Configuration (GPIO):");
  imx_iomux_v3_setup_multiple_pads(boot_cfg2_pads, ARRAY_SIZE(boot_cfg2_pads));
  gpio_direction_input(BOOT_CFG1_4_EIM_DA4);
  gpio_direction_input(BOOT_CFG1_5_EIM_DA5);
  gpio_direction_input(BOOT_CFG1_6_EIM_DA6);
  gpio_direction_input(BOOT_CFG1_7_EIM_DA7);
  gpio_direction_input(BOOT_CFG2_6_EIM_DA14);
  gpio_direction_input(BOOT_CFG2_5_EIM_DA13);
  gpio_direction_input(BOOT_CFG2_4_EIM_DA12);
  gpio_direction_input(BOOT_CFG2_3_EIM_DA11);

  printf("\n - BOOT_CFG1[7]: ");
  if(gpio_get_value(BOOT_CFG1_7_EIM_DA7))
  printf("1");
  else
  printf("0");
  printf("\n - BOOT_CFG1[6]: ");
  if(gpio_get_value(BOOT_CFG1_6_EIM_DA6))
  printf("1");
  else
  printf("0");
  printf("\n - BOOT_CFG1[5]: ");
  if(gpio_get_value(BOOT_CFG1_5_EIM_DA5))
  printf("1");
  else
  printf("0");
  printf("\n - BOOT_CFG1[4]: ");
  if(gpio_get_value(BOOT_CFG1_4_EIM_DA4))
  printf("1");
  else
  printf("0");

  printf("\n - BOOT_CFG2[6]: ");
  if(gpio_get_value(BOOT_CFG2_6_EIM_DA14))
  printf("1");
  else
  printf("0");
  printf("\n - BOOT_CFG2[5]: ");
  if(gpio_get_value(BOOT_CFG2_5_EIM_DA13))
  printf("1");
  else
  printf("0");
  printf("\n - BOOT_CFG2[4]: ");
  if(gpio_get_value(BOOT_CFG2_4_EIM_DA12))
  printf("1");
  else
  printf("0");
  printf("\n - BOOT_CFG2[3]: ");
  if(gpio_get_value(BOOT_CFG2_3_EIM_DA11))
  printf("1");
  else
  printf("0");
  printf("\n");

 

For example, the values of registers SBMR1, SBMR2, GPIO and FUSES, when all the dip-switch are set to use SD1 (BOOT_CFG1[7:4] = 0000, BOOT_CFG2[6:3] = 0100) are (please, refer to text in red color for unexpected results):

 

Boot Configuration (from SBMR1):

- BOOT_CFG1: 00000000

- BOOT_CFG2: 00000000

- BOOT_CFG3: 00000000

- BOOT_CFG4: 00000000

Boot Configuration (SBMR2):

- SBMR2[7:0]: 00000001

Boot Configuration (from FUSEMAP):

- BOOT_CFG1: 00000000

- BOOT_CFG2: 00000000

- BOOT_CFG3: 00000000

- BOOT_CFG4: 00000000

Boot Configuration (from GPIO):

- BOOT_CFG1[7]: 0

- BOOT_CFG1[6]: 0

- BOOT_CFG1[5]: 0

- BOOT_CFG1[4]: 0

- BOOT_CFG2[6]: 0

- BOOT_CFG2[5]: 1

- BOOT_CFG2[4]: 0

- BOOT_CFG2[3]: 0

 

I did another test to validate all the GPIO, when all the dip-switch are set to "1" (please, refer to text in red color for unexpected results):

 

Boot Configuration (from SBMR1):

- BOOT_CFG1: 11110000

- BOOT_CFG2: 10000000

- BOOT_CFG3: 00000000

- BOOT_CFG4: 00000000

Boot Configuration (SBMR2):

- SBMR2[7:0]: 00000001

Boot Configuration (from FUSEMAP):

- BOOT_CFG1: 00000000

- BOOT_CFG2: 00000000

- BOOT_CFG3: 00000000

- BOOT_CFG4: 00000000

Boot Configuration (from GPIO):

- BOOT_CFG1[7]: 1

- BOOT_CFG1[6]: 1

- BOOT_CFG1[5]: 1

- BOOT_CFG1[4]: 1

- BOOT_CFG2[6]: 1

- BOOT_CFG2[5]: 1

- BOOT_CFG2[4]: 1

- BOOT_CFG2[3]: 1

 

In conclusion, the bits BOOT_CFG1[6], BOOT_CFG1[5], BOOT_CFG1[4] are not changing according with the GPIO configuration or dip-switch.

 

Any suggestion?

 

Thanks

Outcomes