summaryrefslogtreecommitdiff
path: root/src/soc/rockchip/rk3399
diff options
context:
space:
mode:
authorLin Huang <hl@rock-chips.com>2016-10-10 20:57:09 -0700
committerPatrick Georgi <pgeorgi@google.com>2016-10-25 17:08:58 +0200
commitdf3321aa34cab80a67a00d86e86f7dea93b43067 (patch)
treedbd2d12e099228abbd50656e2103edfc631c9604 /src/soc/rockchip/rk3399
parent65a9462a73bd9c5e1054ea315b51574b4bf2f270 (diff)
rockchip/rk3399: reset system if DDR init fails
We found sdram may fail in pctl_cfg(), so we check the status in this function. If it exceeds 100ms still in this function, we will restart the system. We also found there are rare chances DDR training fails, so also restart system in that case. BUG=chrome-os-partner:57988 BRANCH=None TEST=coreboot resets on failure and eventually the system comes up Change-Id: Icc0688da028a8f4f81eafe36bbaa79fdf2bcea74 Signed-off-by: Patrick Georgi <pgeorgi@chromium.org> Original-Commit-Id: 89e45f8352f62e19a203316330aba14ccc5c8b11 Original-Change-Id: If4e78983abcfdfe1e0e26847448d86169e598700 Original-Signed-off-by: Lin Huang <hl@rock-chips.com> Original-Reviewed-on: https://chromium-review.googlesource.com/397439 Original-Reviewed-by: Julius Werner <jwerner@chromium.org> Reviewed-on: https://review.coreboot.org/17045 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth <martinroth@google.com>
Diffstat (limited to 'src/soc/rockchip/rk3399')
-rw-r--r--src/soc/rockchip/rk3399/sdram.c38
1 files changed, 27 insertions, 11 deletions
diff --git a/src/soc/rockchip/rk3399/sdram.c b/src/soc/rockchip/rk3399/sdram.c
index ed13a82d38..ee980339a1 100644
--- a/src/soc/rockchip/rk3399/sdram.c
+++ b/src/soc/rockchip/rk3399/sdram.c
@@ -16,12 +16,14 @@
#include <arch/io.h>
#include <console/console.h>
#include <delay.h>
+#include <reset.h>
#include <soc/addressmap.h>
#include <soc/clock.h>
#include <soc/sdram.h>
#include <soc/grf.h>
#include <soc/soc.h>
#include <string.h>
+#include <timer.h>
#include <types.h>
#define DDR_PI_OFFSET 0x800
@@ -466,8 +468,8 @@ static void phy_io_config(u32 channel,
clrsetbits_le32(&denali_phy[939], 0x3 << 17, speed << 17);
}
-static void pctl_cfg(u32 channel,
- const struct rk3399_sdram_params *sdram_params)
+static int pctl_cfg(u32 channel,
+ const struct rk3399_sdram_params *sdram_params)
{
u32 *denali_ctl = rk3399_ddr_pctl[channel]->denali_ctl;
u32 *denali_pi = rk3399_ddr_pi[channel]->denali_pi;
@@ -476,6 +478,7 @@ static void pctl_cfg(u32 channel,
const u32 *params_phy = sdram_params->phy_regs.denali_phy;
u32 tmp, tmp1, tmp2;
u32 pwrup_srefresh_exit;
+ struct stopwatch sw;
/*
* work around controller bug:
@@ -554,14 +557,16 @@ static void pctl_cfg(u32 channel,
/* PHY_DLL_RST_EN */
clrsetbits_le32(&denali_phy[957], 0x3 << 24, 0x2 << 24);
- /*
- * FIXME:
- * need to care ERROR bit
- */
- while (!(read32(&denali_ctl[203]) & (1 << 3)))
- ;
+ /* FIXME: need to care ERROR bit */
+ stopwatch_init_msecs_expire(&sw, 100);
+ while (!(read32(&denali_ctl[203]) & (1 << 3))) {
+ if (stopwatch_expired(&sw))
+ return -1;
+ }
+
clrsetbits_le32(&denali_ctl[68], PWRUP_SREFRESH_EXIT,
pwrup_srefresh_exit);
+ return 0;
}
static void select_per_cs_training_index(u32 channel, u32 rank)
@@ -987,14 +992,25 @@ void sdram_init(const struct rk3399_sdram_params *sdram_params)
if (channel >= sdram_params->num_channels)
continue;
- pctl_cfg(channel, sdram_params);
+ /*
+ * TODO: we need to find the root cause why this
+ * step may fail, before that, we just reset the
+ * system, and start again.
+ */
+ if (pctl_cfg(channel, sdram_params) != 0) {
+ printk(BIOS_ERR, "pctl_cfg fail, reset\n");
+ hard_reset();
+ }
/* LPDDR2/LPDDR3 need to wait DAI complete, max 10us */
if (dramtype == LPDDR3)
udelay(10);
- if (data_training(channel, sdram_params, PI_FULL_TARINING))
- die("SDRAM initialization failed!");
+ if (data_training(channel, sdram_params, PI_FULL_TARINING)) {
+ printk(BIOS_ERR,
+ "SDRAM initialization failed, reset\n");
+ hard_reset();
+ }
set_ddrconfig(sdram_params, channel,
sdram_params->ch[channel].ddrconfig);