I am developing a Yocto kernel for a custom device based on the i.MX6Q. This board works fine when powered cold. If I try to reboot the board form the kernel or reset it from the u-boot prompt, it will almost always lock up at the "Starting kernel ..." message. Occasionally it will reboot successfully. Using an emulator, I have determined that the kernel jumps to the panic function but not always from the same spot in the code. Any one seen this issue before?
Is DDR re-initialized after each reset?
Here is my output:
U-Boot 2014.04 (Jan 14 2016 - 09:35:26)
CPU: Freescale i.MX6Q rev1.2 at 792 MHz
CPU: Temperature 38 C, calibration data: 0x5534cc69
Reset cause: POR
Board: SBC35-C398Q
Boot Device: SD
I2C: ready
DRAM: 2 GiB
MMC: FSL_SDHC: 0, FSL_SDHC: 1
*** Warning - bad CRC, using default environment
Unable to allocate framebuffer memory
In: serial
Out: serial
Err: serial
mmc0 is current device
Net: Phy not found
FEC
Normal Boot
Hit any key to stop autoboot: 0
reading zImage
5938056 bytes read in 279 ms (20.3 MiB/s)
reading imx6q-c398.dtb
40261 bytes read in 21 ms (1.8 MiB/s)
Kernel image @ 0x10800000 [ 0x000000 - 0x5a9b88 ]
## Flattened Device Tree blob at 18000000
Booting using the fdt blob at 0x18000000
Using Device Tree in place at 18000000, end 1800cd44
Starting kernel ...
Hi Paul
DDR is initialized at each reset, it is shown in Table 60-4. SRC reset functionality
http://cache.freescale.com/files/32bit/doc/ref_manual/IMX6DQRM.pdf
When ldo bypass (by default LDO bypass is enabled.) is used then
after reset processor will start with lower power supply voltages, than needed.
After reset processor ldos are enabled, while pmic stays in ldo bypass
configuration. For that reason recommended to reset also pmic using PWRON.
Best regards
igor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
We are using an external PMPF0100 regulator. Its reset is tied to the same POR reset for the i.MX6Q processor. How should I handle the LDO Bypass when I have an external PMIC?
could you clarify your description "If I try to reboot the board
form the kernel or reset it from the u-boot prompt" .
Is POR&pmic_PWRON are asserted ? On Sabre board spf-27392
it is done with U507 Wdog signal.
~igor
Igor,
Where did you go? Are you out of ideas?
OK I have resolved this problem by adding the following ldo_mode_set function. Unfortunately I can no longer save my environment variables to the MMC. If I back this function out of the code, I can save my environment variables but cannot reboot. Obviously I am on the right track, but where is the sweet spot where I can do both???
void ldo_mode_set(int ldo_bypass)
{
unsigned char value;
int is_400M;
unsigned char vddarm;
// increase VDDARM/VDDSOC to support 1.2G chip
if (check_1_2G()) {
ldo_bypass = 0; // ldo_enable on 1.2G chip
printf("1.2G chip, increase VDDARM_IN/VDDSOC_IN\n");
// increase VDDARM to 1.425V
if (i2c_read(0x8, 0x20, 1, &value, 1)) {
printf("Read SW1AB error!\n");
return;
}
value &= ~0x3f;
value |= 0x2d;
if (i2c_write(0x8, 0x20, 1, &value, 1)) {
printf("Set SW1AB error!\n");
return;
}
// increase VDDSOC to 1.425V
if (i2c_read(0x8, 0x2e, 1, &value, 1)) {
printf("Read SW1C error!\n");
return;
}
value &= ~0x3f;
value |= 0x2d;
if (i2c_write(0x8, 0x2e, 1, &value, 1)) {
printf("Set SW1C error!\n");
return;
}
}
// switch to ldo_bypass mode, boot on 800Mhz
if (ldo_bypass) {
prep_anatop_bypass();
// decrease VDDARM for 400Mhz DQ:1.1V, DL:1.275V
if (i2c_read(0x8, 0x20, 1, &value, 1)) {
printf("Read SW1AB error!\n");
return;
}
value &= ~0x3f;
#if defined(CONFIG_MX6DL)
value |= 0x27;
#else
value |= 0x20;
#endif
if (i2c_write(0x8, 0x20, 1, &value, 1)) {
printf("Set SW1AB error!\n");
return;
}
// increase VDDSOC to 1.3V
if (i2c_read(0x8, 0x2e, 1, &value, 1)) {
printf("Read SW1C error!\n");
return;
}
value &= ~0x3f;
value |= 0x28;
if (i2c_write(0x8, 0x2e, 1, &value, 1)) {
printf("Set SW1C error!\n");
return;
}
// MX6Q:
// VDDARM:1.15V@800M; VDDSOC:1.175V@800M
// VDDARM:0.975V@400M; VDDSOC:1.175V@400M
// MX6DL:
// VDDARM:1.175V@800M; VDDSOC:1.175V@800M
// VDDARM:1.075V@400M; VDDSOC:1.175V@400M
is_400M = set_anatop_bypass(2);
if (is_400M)
#if defined(CONFIG_MX6DL)
vddarm = 0x1f;
#else
vddarm = 0x1b;
#endif
else
#if defined(CONFIG_MX6DL)
vddarm = 0x23;
#else
vddarm = 0x22;
#endif
if (i2c_read(0x8, 0x20, 1, &value, 1)) {
printf("Read SW1AB error!\n");
return;
}
value &= ~0x3f;
value |= vddarm;
if (i2c_write(0x8, 0x20, 1, &value, 1)) {
printf("Set SW1AB error!\n");
return;
}
// decrease VDDSOC to 1.175V
if (i2c_read(0x8, 0x2e, 1, &value, 1)) {
printf("Read SW1C error!\n");
return;
}
value &= ~0x3f;
value |= 0x23;
if (i2c_write(0x8, 0x2e, 1, &value, 1)) {
printf("Set SW1C error!\n");
return;
}
finish_anatop_bypass();
printf("switch to ldo_bypass mode!\n");
}
}
When I start the board with a power cycle, it will boot successfully 100% of the time. When I reset the board in the following manners, it will boot successfully about 5% of the time. All other attempts stop at the "Starting kernel ..." message.
I would like to point out that we have a Linux build for this same device using the LTIB tool that works correctly. We are in the process of transitioning to Yocto. It is the Yocto version that does not work.
Is there possibly an issue with our device tree? I have modeled it like the Sabre Auto device. I have the following in our device tree:
&gpc {
fsl,ldo-bypass = <0>;
fsl,wdog-reset = <1>;
};