summaryrefslogtreecommitdiff
path: root/src/soc/rockchip
diff options
context:
space:
mode:
authorLin Huang <hl@rock-chips.com>2016-10-16 13:24:08 -0700
committerPatrick Georgi <pgeorgi@google.com>2016-11-02 17:31:03 +0100
commit13acd35d6fa2623dce970acae9296b80a75ed2a3 (patch)
tree12801af615b3eb8a4f9ada22871c549414a2fcdb /src/soc/rockchip
parentf435f92654a18860814187a029657755f1c1d187 (diff)
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>
Diffstat (limited to 'src/soc/rockchip')
-rw-r--r--src/soc/rockchip/rk3399/sdram.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/src/soc/rockchip/rk3399/sdram.c b/src/soc/rockchip/rk3399/sdram.c
index 945c0bca85..9ff1294bcd 100644
--- a/src/soc/rockchip/rk3399/sdram.c
+++ b/src/soc/rockchip/rk3399/sdram.c
@@ -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();
+ }
}
}