This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

local variable and code in s_init(), board.c, spl/u-boot, am335x

branch: remotes/rowboat/am335x-v2013.01.01

commit: 0bb4b4e8fb884cf6cc1ae453ef956ec52a672bcd

Author: Steve Kipisz <s-kipisz2@ti.com>  2013-04-26 02:24:18

Committer: Franklin S. Cooper Jr <fcooper@ti.com>  2013-05-07 22:01:52

 

This commit introduced a new local variable 'header' in s_init() function in board.c file. The author claimed this commit was intended to add NOR boot support.

I am confused about the code inside s_init() function. There is already a global/static variable 'header' declared in the same file, and read_eeprom() will fill the struct according to i2c read result. Then what is the point from this commit to use a macro CONFIG_NOR_BOOT to bypass the read_eeprom(), defined a local variable with the same name with the global one, copied the code from read_eeprom() /*almost*/ to fill the local struct and pass it to enable_board_pin_mux(), and use the local struct for branching ddr config. 

My custom board has no eeprom, the code hanged and I must modify code here. I want to fully understand the code here and make sure there are no potential pitfalls.

~~~~~~~~~~~~~ code ~~~~~~~~~~~~~

void s_init(void)
{
+ __maybe_unused struct am335x_baseboard_id header;
+#ifdef CONFIG_NOR_BOOT
+ asm("stmfd sp!, {r2 - r4}");
+ asm("movw r4, #0x8A4");
+ asm("movw r3, #0x44E1");
+ asm("orr r4, r4, r3, lsl #16");
+ asm("mov r2, #9");
+ asm("mov r3, #8");
+ asm("gpmc_mux: str r2, [r4], #4");
+ asm("subs r3, r3, #1");
+ asm("bne gpmc_mux");
+ asm("ldmfd sp!, {r2 - r4}");
+#endif
+
/* WDT1 is already running when the bootloader gets control
* Disable it to avoid "random" resets
*/
@@ -532,7 +546,7 @@ void s_init(void)
while (readl(&wdtimer->wdtwwps) != 0x0)
;

-#ifdef CONFIG_SPL_BUILD
+#if defined(CONFIG_SPL_BUILD) || defined(CONFIG_NOR_BOOT)
/* Setup the PLLs and the clocks for the peripherals */
pll_init();

@@ -573,18 +587,59 @@ void s_init(void)
regVal |= UART_SMART_IDLE_EN;
writel(regVal, &uart_base->uartsyscfg);

+#if defined(CONFIG_NOR_BOOT)
+ gd = (gd_t *) ((CONFIG_SYS_INIT_SP_ADDR) & ~0x07);
+ gd->baudrate = CONFIG_BAUDRATE;
+ serial_init();
+ gd->have_console = 1;
+#else
gd = &gdata;

preloader_console_init();
+#endif

/* Initalize the board header */
enable_i2c0_pin_mux();
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+#ifndef CONFIG_NOR_BOOT
if (read_eeprom() < 0)
puts("Could not get board ID.\n");
+#endif
+
+ /* Check if baseboard eeprom is available */
+ if (i2c_probe(CONFIG_SYS_I2C_EEPROM_ADDR)) {
+ puts("Could not probe the EEPROM; something fundamentally "
+ "wrong on the I2C bus.\n");
+ }
+
+ /* read the eeprom using i2c */
+ if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, 2, (uchar *)&header,
+ sizeof(header))) {
+ puts("Could not read the EEPROM; something fundamentally"
+ " wrong on the I2C bus.\n");
+ }
+
+ if (header.magic != 0xEE3355AA) {
+ /*
+ * read the eeprom using i2c again,
+ * but use only a 1 byte address
+ */
+ if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, 1,
+ (uchar *)&header, sizeof(header))) {
+ puts("Could not read the EEPROM; something "
+ "fundamentally wrong on the I2C bus.\n");
+ hang();
+ }
+
+ if (header.magic != 0xEE3355AA) {
+ printf("Incorrect magic number (0x%x) in EEPROM\n",
+ header.magic);
+ hang();
+ }
+ }

enable_board_pin_mux(&header);
- if (board_is_evm_sk()) {
+ if (!strncmp("A335X_SK", header.name, HDR_NAME_LEN)) {
/*
* EVM SK 1.2A and later use gpio0_7 to enable DDR3.
* This is safe enough to do on older revs.
@@ -593,10 +648,16 @@ void s_init(void)
gpio_direction_output(GPIO_DDR_VTT_EN, 1);
}

- if (board_is_evm_sk() || board_is_bone_lt())
+#ifdef CONFIG_NOR_BOOT
+ am33xx_spl_board_init();
+#endif
+
+ if ((!strncmp("A335X_SK", header.name, HDR_NAME_LEN)) ||
+ (!strncmp("A335BNLT", header.name, 8)))
config_ddr(303, MT41J128MJT125_IOCTRL_VALUE, &ddr3_data,
&ddr3_cmd_ctrl_data, &ddr3_emif_reg_data);
- else if (board_is_evm_15_or_later())
+ else if (!strncmp("A33515BB", header.name, 8) &&
+ strncmp("1.5", header.version, 3) <= 0)
config_ddr(303, MT41J512M8RH125_IOCTRL_VALUE, &ddr3_evm_data,
&ddr3_evm_cmd_ctrl_data, &ddr3_evm_emif_reg_data);
else

 

  • Escalating this to the factory team.

  • That code was added for booting from NOR. When you boot from NOR, the boot ROM only pin muxes 12-bits of address for non-muxed NOR and 16-bits of address for muxed NOR. So some code is not available until after the pin-muxing for the rest of the GPMC address space . That pin-muxing must be done in the first 4k of address space for non-mux NOR or the first 16k of address space for muxed NOR. The assembler code is doing the pin-muxing of the rest of the address space.

    Can you post any changes you made? I should be able to figure out why your board is hanging.

    Steve K.