summaryrefslogtreecommitdiff
path: root/src/soc/rockchip/rk3399
diff options
context:
space:
mode:
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);