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:
The board have three SD sockets (SD1, SD2 and SD4). The following options are used to select the device:
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),
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
HI Julio
suggest to check SBMR with jtag debugger, setting
BOOT_CFG4[7]=1, this is most accurate way.
Note, SBMR latches data on POR deassertion so
after booting, setting boot pins and reading them in Uboot
may lead to not correct results.
Best regards
igor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Dear Igor,
Thanks for your suggestions.
Unfortunately, I don't have a JTAG tool right now. I will acquire one J-Link for this kind of issues as suggested on other post (Re: J-Link and iMX6).
I have a couples of questions:
My final goal, is to boot from any of the available SD ports (SD1, SD2 and SD4) according with the GPIO settings. Right now, the board can boot from SD1, SD2 and cannot boot from SD4. Because that, I tried to read the SBMR1 and the GPIO to know if everything is OK (boot configuration and hardware).
If you consider this info need a new post (thread), please, let me know.
Thanks
Hi Julio
yes, SBMR latches the GPIO on POR deassertion and after that,
the register should not change the value, provided that power-up
sequence is correct.
You can try to prolong POR up to 1 sec. to see if it helps.
Also it is recommended to check crystal clocks both 24MHz and 32.768 KHz.
Best regards
igor
Hi Igor,
I follow your suggestions.
May I know if you have another suggestion?
Thanks
Hi Julio
what is full processor part marking and
what design you followed, is it Freescale Sabre board ?
Also do you have permanent VDD_SNVS_IN to processor ?
If not, could you try with permanently applied VDD_SNVS_IN.
~igor
Hi Igor,
The problem was solved. I'm embarrassed because the problem was in the code as explain in the previous post.
The answer to your questions at the same order:
Thanks again,
Please, may I know what I need to do? Correct answer? Other action?
Dear Igor, all,
I found where the problem was.
In conclusion, the SBMR1 is returning the correct values after reset and the SD is booting according with the GPIO config (SD1, SD2 and SD4).
Below, the code used to read the SBMR1 and configuration used on this board.
void boot_registers(void)
{
uint BOOT_CFG1, BOOT_CFG2, BOOT_CFG3, BOOT_CFG4;
uint SBMR2_8;
uint SBMR1;
uint SBMR2;
uint FUSE_MAP;
puts("Boot Configuration (SBMR1): \n");
SBMR1 = readl(SRC_BASE_ADDR + 0x4);
BOOT_CFG1 = ((SBMR1 & 0x000000FF) >> 0);
BOOT_CFG2 = ((SBMR1 & 0x0000FF00) >> 8);
BOOT_CFG3 = ((SBMR1 & 0x00FF0000) >> 16);
BOOT_CFG4 = ((SBMR1 & 0xFF000000) >> 24);
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);
puts("Boot Configuration (FUSEMAP): \n");
FUSE_MAP = readl(0x021BC000 + 0x450);
BOOT_CFG1 = ((FUSE_MAP & 0x000000FF) >> 0);
BOOT_CFG2 = ((FUSE_MAP & 0x0000FF00) >> 8);
BOOT_CFG3 = ((FUSE_MAP & 0x00FF0000) >> 16);
BOOT_CFG4 = ((FUSE_MAP & 0xFF000000) >> 24);
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");
}
Thanks for your support