Migrating to u-boot 2021.01, TI branch

Started by thom_nic, October 20, 2022, 12:24:06 AM

Previous topic - Next topic

thom_nic

Since the Olimex u-boot release has not been updated in some time I tried to use TI's port from here https://git.ti.com/cgit/ti-u-boot/ti-u-boot/log/?h=08.04.01.005&ofs=800

which is their latest release.  It appears to work great EXCEPT the Olimex does not boot on cold power up - but it boots if I hit the reset button a few seconds later.

Is there some SPL code I need (or boot order pins) that would cause TI's 2021.01 branch to not boot whereas the Olimex 2016 release had always worked?

Thanks in advance.

LubOlimex

It might be related to the fact that our design doesn't use the TI's PMU recommended for the board. You might need to manually adjust the configuration for the voltages. Refer to this post:

https://www.olimex.com/forum/index.php?topic=4291.0
Technical support and documentation manager at Olimex

thom_nic

#2
Thanks very much for the feedback. I'm guessing what I should be looking at is this bit of code in board/olimex/am335x_som/board.c (which by the way I can't find the original Olimex source for.)

#define OSC (V_OSCK/1000000)
const struct dpll_params dpll_ddr = {
400, OSC-1, 1, -1, -1, -1, -1};
// 303, OSC-1, 1, -1, -1, -1, -1};

void am33xx_spl_board_init(void)
{
/* Get the frequency */
dpll_mpu_opp100.m = am335x_get_efuse_mpu_max_freq(cdev);

/* Set CORE Frequencies to OPP100 */
do_setup_dpll(&dpll_core_regs, &dpll_core_opp100);

/* Set MPU Frequency to what we detected now that voltages are set */
do_setup_dpll(&dpll_mpu_regs, &dpll_mpu_opp100);
}

const struct dpll_params *get_dpll_ddr_params(void)
{
return &dpll_ddr;
}


I'm actually basing my config off of the `am335x_evm_mini` board which uses this board.c code and specifically provide an alternate code path in scale_vcores_generic()? 

void scale_vcores_generic(int freq)
{
int sil_rev, mpu_vdd;

/*
* The GP EVM, IDK and EVM SK use a TPS65910 PMIC.  For all
* MPU frequencies we support we use a CORE voltage of
* 1.10V.  For MPU voltage we need to switch based on
* the frequency we are running at.
*/

if (IS_ENABLED(CONFIG_DM_I2C)) {
if (power_tps65910_init(0))
return;
} else {
if (i2c_probe(TPS65910_CTRL_I2C_ADDR))
return;
}

/*
* Depending on MPU clock and PG we will need a different
* VDD to drive at that speed.
*/
sil_rev = readl(&cdev->deviceid) >> 28;
mpu_vdd = am335x_get_tps65910_mpu_vdd(sil_rev, freq);

/* Tell the TPS65910 to use i2c */
tps65910_set_i2c_control();

/* First update MPU voltage. */
if (tps65910_voltage_update(MPU, mpu_vdd))
return;

/* Second, update the CORE voltage. */
if (tps65910_voltage_update(CORE, TPS65910_OP_REG_SEL_1_1_0))
return;
}

That code is setting the core and MPU frequency but I'm not sure I understand where the voltages are set.

I added the following to board_mini.c in the 2021.01 tree but it doesn't seem to have any effect:

void am33xx_spl_board_init(void)
{
/* Get the frequency */
dpll_mpu_opp100.m = am335x_get_efuse_mpu_max_freq(cdev);

/* Set CORE Frequencies to OPP100 */
do_setup_dpll(&dpll_core_regs, &dpll_core_opp100);

/* Set MPU Frequency to what we detected now that voltages are set */
do_setup_dpll(&dpll_mpu_regs, &dpll_mpu_opp100);
}

thom_nic

#3
Actually I think the issue was in sdram_init().  When I replace board_mini.c with this code, cold boot works using am335x_evm_sdk_mini:

static const struct ddr_data ddr3_data = {
.datardsratio0 = MT41K256M16HA125E_RD_DQS,
.datawdsratio0 = MT41K256M16HA125E_WR_DQS,
.datafwsratio0 = MT41K256M16HA125E_PHY_FIFO_WE,
.datawrsratio0 = MT41K256M16HA125E_PHY_WR_DATA,
};

static const struct cmd_control ddr3_cmd_ctrl_data = {
.cmd0csratio = MT41K256M16HA125E_RATIO,
.cmd0iclkout = MT41K256M16HA125E_INVERT_CLKOUT,

.cmd1csratio = MT41K256M16HA125E_RATIO,
.cmd1iclkout = MT41K256M16HA125E_INVERT_CLKOUT,

.cmd2csratio = MT41K256M16HA125E_RATIO,
.cmd2iclkout = MT41K256M16HA125E_INVERT_CLKOUT,
};

static struct emif_regs ddr3_emif_reg_data = {
.sdram_config = MT41J512M8RH125_EMIF_SDCFG,
.ref_ctrl = MT41K256M16HA125E_EMIF_SDREF,
.sdram_tim1 = MT41K256M16HA125E_EMIF_TIM1,
.sdram_tim2 = MT41K256M16HA125E_EMIF_TIM2,
.sdram_tim3 = MT41K256M16HA125E_EMIF_TIM3,
.zq_config = MT41K256M16HA125E_ZQ_CFG,
.emif_ddr_phy_ctlr_1 = MT41K256M16HA125E_EMIF_READ_LATENCY,
};

const struct ctrl_ioregs ioregs = {
.cm0ioctl = MT41K256M16HA125E_IOCTRL_VALUE,
.cm1ioctl = MT41K256M16HA125E_IOCTRL_VALUE,
.cm2ioctl = MT41K256M16HA125E_IOCTRL_VALUE,
.dt0ioctl = MT41K256M16HA125E_IOCTRL_VALUE,
.dt1ioctl = MT41K256M16HA125E_IOCTRL_VALUE,
};

void sdram_init(void)
{
config_ddr(400, &ioregs,
   &ddr3_data,
   &ddr3_cmd_ctrl_data,
   &ddr3_emif_reg_data, 0);

udelay(500);
}

#define OSC (V_OSCK/1000000)
const struct dpll_params dpll_ddr = {
400, OSC-1, 1, -1, -1, -1, -1};
// 303, OSC-1, 1, -1, -1, -1, -1};

const struct dpll_params *get_dpll_ddr_params(void)
{
  return &dpll_ddr;
}

I've have copied board_mini.c and mux_mini.c into board/olimex/am335x_som and added the requisite Makefile and Kconfig changes so it is being built as a custom board, adding the above from the original Olimex board.c.  But editing the am335x_evm_mini config was a fast way to test my changes since it appears to be 99% compatible aside from this one issue.

I wonder if the "fix" isn't actually just from that udelay(500) call...

thom_nic

Can someone at Olimex actually give context to the reason for adding the udelay(500) in sdram_init(void) was necessary?

The reason why I am asking: I ran an automated power cycle test and the board boots 95% of the time on cold boot (power applied) HOWEVER every once in a while the board still DOES NOT boot until you press reset.  So there is still some finicky timing issue, that's exposed somewhere from upgrading to newer u-boot. 

Before I just go randomly changing a delay and hope it fixes it, I'd like to understand *why* it was added in the first place :)

LubOlimex

I can't say for certain but I believe it has something to do with the lack of Texas Instruments power management unit in our design. TI expected everyone would use their chip with their PMU.
Technical support and documentation manager at Olimex