rockchip/rk3399: sdram: Reset system if switch to index1 fails

Near the end of DDR initialization, the system switches to the index1
configuration. Sometimes this failed and a status bit that coreboot was
waiting for was never set, hanging the system.

Instead, give the system 100ms to reach the new configuration or reboot
it, which generally fixes the issue. Also reset when training the index1
configuration fails.

BUG=chrome-os-partner:57988
BRANCH=None
TEST=The error condition now leads to a reboot of coreboot which
recovers the system, instead of hanging.

Change-Id: Icb4270369102ff7a4ce91b0677e04b4eb10f1204
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: ca250d0628ea3b6b39d5131246eaba68637c5140
Original-Change-Id: Id6e8936d90e54b733ac327f8476d744b45639232
Original-Signed-off-by: Lin Huang <hl@rock-chips.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/399681
Original-Reviewed-by: Julius Werner <jwerner@chromium.org>
Reviewed-on: https://review.coreboot.org/17106
Tested-by: build bot (Jenkins)
Reviewed-by: Martin Roth <martinroth@google.com>
This commit is contained in:
Lin Huang 2016-10-16 13:24:08 -07:00 committed by Patrick Georgi
parent f435f92654
commit 13acd35d6f
1 changed files with 21 additions and 6 deletions

View File

@ -936,23 +936,38 @@ static void switch_to_phy_index1(const struct rk3399_sdram_params *sdram_params)
{
u32 channel;
u32 *denali_phy;
struct stopwatch sw;
u32 ch_count = sdram_params->num_channels;
stopwatch_init_msecs_expire(&sw, 100);
write32(&rk3399_ddr_cic->cic_ctrl0,
RK_CLRSETBITS(0x03 << 4 | 1 << 2 | 1,
1 << 4 | 1 << 2 | 1));
while (!(read32(&rk3399_ddr_cic->cic_status0) & (1 << 2)))
;
while (!(read32(&rk3399_ddr_cic->cic_status0) & (1 << 2))) {
if (stopwatch_expired(&sw)) {
printk(BIOS_ERR,
"index1 frequency change overtime, reset\n");
hard_reset();
}
}
stopwatch_init_msecs_expire(&sw, 100);
write32(&rk3399_ddr_cic->cic_ctrl0, RK_CLRSETBITS(1 << 1, 1 << 1));
while (!(read32(&rk3399_ddr_cic->cic_status0) & (1 << 0)))
;
while (!(read32(&rk3399_ddr_cic->cic_status0) & (1 << 0))) {
if (stopwatch_expired(&sw)) {
printk(BIOS_ERR,
"index1 frequency done overtime, reset\n");
hard_reset();
}
}
for (channel = 0; channel < ch_count; channel++) {
denali_phy = rk3399_ddr_publ[channel]->denali_phy;
clrsetbits_le32(&denali_phy[896], (0x3 << 8) | 1, 1 << 8);
if (data_training(channel, sdram_params, PI_FULL_TARINING))
printk(BIOS_DEBUG, "training failed\n");
if (data_training(channel, sdram_params, PI_FULL_TARINING)) {
printk(BIOS_ERR, "index1 training failed, reset\n");
hard_reset();
}
}
}