aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLokesh Vutla <lokeshvutla@ti.com>2012-05-29 19:26:43 +0000
committerAlbert ARIBAUD <albert.u.boot@aribaud.net>2012-07-07 14:07:35 +0200
commit38f25b125e446ab4a64a54e9aa2c10023d8eccc3 (patch)
treeb2f9d6a45735cd89f68b7d72f24532c06da0ae0c
parent784229cc25feee0bb3f2bba6c1318f4d73c293e0 (diff)
downloadu-boot-linaro-stable-38f25b125e446ab4a64a54e9aa2c10023d8eccc3.tar.gz
OMAP4+: Force DDR in self-refresh after warm reset
Errata ID:i727 Description: The refresh rate is programmed in the EMIF_SDRAM_REF_CTRL[15:0] REG_REFRESH_RATE parameter taking into account frequency of the device. When a warm reset is applied on the system, the OMAP processor restarts with another OPP and so frequency is not the same. Due to this frequency change, the refresh rate will be too low and could result in an unexpected behavior on the memory side. Workaround: The workaround is to force self-refresh when coming back from the warm reset with the following sequence: • Set EMIF_PWR_MGMT_CTRL[10:8] REG_LP_MODE to 0x2 • Set EMIF_PWR_MGMT_CTRL[7:4] REG_SR_TIM to 0x0 • Do a dummy read (loads automatically new value of sr_tim) This will reduce the risk of memory content corruption, but memory content can't be guaranteed after a warm reset. This errata is impacted on OMAP4430: 1.0, 2.0, 2.1, 2.2, 2.3 OMAP4460: 1.0, 1.1 OMAP4470: 1.0 OMAP5430: 1.0 Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com> Signed-off-by: R Sricharan <r.sricharan@ti.com> Signed-off-by: Senthilvadivu Guruswamy <svadivu@ti.com>
-rw-r--r--arch/arm/cpu/armv7/omap-common/emif-common.c21
-rw-r--r--arch/arm/cpu/armv7/omap-common/hwinit-common.c4
-rw-r--r--arch/arm/include/asm/arch-omap4/sys_proto.h1
-rw-r--r--arch/arm/include/asm/arch-omap5/sys_proto.h1
4 files changed, 27 insertions, 0 deletions
diff --git a/arch/arm/cpu/armv7/omap-common/emif-common.c b/arch/arm/cpu/armv7/omap-common/emif-common.c
index edc63fa9c..64427e61d 100644
--- a/arch/arm/cpu/armv7/omap-common/emif-common.c
+++ b/arch/arm/cpu/armv7/omap-common/emif-common.c
@@ -32,6 +32,27 @@
#include <asm/omap_common.h>
#include <asm/utils.h>
+void set_lpmode_selfrefresh(u32 base)
+{
+ struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
+ u32 reg;
+
+ reg = readl(&emif->emif_pwr_mgmt_ctrl);
+ reg &= ~EMIF_REG_LP_MODE_MASK;
+ reg |= LP_MODE_SELF_REFRESH << EMIF_REG_LP_MODE_SHIFT;
+ reg &= ~EMIF_REG_SR_TIM_MASK;
+ writel(reg, &emif->emif_pwr_mgmt_ctrl);
+
+ /* dummy read for the new SR_TIM to be loaded */
+ readl(&emif->emif_pwr_mgmt_ctrl);
+}
+
+void force_emif_self_refresh()
+{
+ set_lpmode_selfrefresh(EMIF1_BASE);
+ set_lpmode_selfrefresh(EMIF2_BASE);
+}
+
inline u32 emif_num(u32 base)
{
if (base == EMIF1_BASE)
diff --git a/arch/arm/cpu/armv7/omap-common/hwinit-common.c b/arch/arm/cpu/armv7/omap-common/hwinit-common.c
index 660032330..459ebb55e 100644
--- a/arch/arm/cpu/armv7/omap-common/hwinit-common.c
+++ b/arch/arm/cpu/armv7/omap-common/hwinit-common.c
@@ -111,6 +111,10 @@ static void init_boot_params(void)
void s_init(void)
{
init_omap_revision();
+#ifdef CONFIG_SPL_BUILD
+ if (warm_reset() && (omap_revision() <= OMAP5430_ES1_0))
+ force_emif_self_refresh();
+#endif
watchdog_init();
set_mux_conf_regs();
#ifdef CONFIG_SPL_BUILD
diff --git a/arch/arm/include/asm/arch-omap4/sys_proto.h b/arch/arm/include/asm/arch-omap4/sys_proto.h
index 4f0a29da7..d633573c2 100644
--- a/arch/arm/include/asm/arch-omap4/sys_proto.h
+++ b/arch/arm/include/asm/arch-omap4/sys_proto.h
@@ -58,6 +58,7 @@ void do_io_settings(void);
void omap_vc_init(u16 speed_khz);
int omap_vc_bypass_send_value(u8 sa, u8 reg_addr, u8 reg_data);
u32 warm_reset(void);
+void force_emif_self_refresh(void);
/*
* This is used to verify if the configuration header
* was executed by Romcode prior to control of transfer
diff --git a/arch/arm/include/asm/arch-omap5/sys_proto.h b/arch/arm/include/asm/arch-omap5/sys_proto.h
index b3bbdb7cd..74feb9027 100644
--- a/arch/arm/include/asm/arch-omap5/sys_proto.h
+++ b/arch/arm/include/asm/arch-omap5/sys_proto.h
@@ -58,6 +58,7 @@ void do_io_settings(void);
void omap_vc_init(u16 speed_khz);
int omap_vc_bypass_send_value(u8 sa, u8 reg_addr, u8 reg_data);
u32 warm_reset(void);
+void force_emif_self_refresh(void);
/*
* This is used to verify if the configuration header