summaryrefslogtreecommitdiff
path: root/arch/arm/cpu/armv7
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/cpu/armv7')
-rw-r--r--arch/arm/cpu/armv7/omap-common/emif-common.c105
-rw-r--r--arch/arm/cpu/armv7/omap4/hwinit.c5
-rw-r--r--arch/arm/cpu/armv7/omap5/hwinit.c15
3 files changed, 122 insertions, 3 deletions
diff --git a/arch/arm/cpu/armv7/omap-common/emif-common.c b/arch/arm/cpu/armv7/omap-common/emif-common.c
index 389feda..846511d 100644
--- a/arch/arm/cpu/armv7/omap-common/emif-common.c
+++ b/arch/arm/cpu/armv7/omap-common/emif-common.c
@@ -190,7 +190,7 @@ void emif_update_timings(u32 base, const struct emif_regs *regs)
writel(regs->temp_alert_config, &emif->emif_temp_alert_config);
writel(regs->emif_ddr_phy_ctlr_1, &emif->emif_ddr_phy_ctrl_1_shdw);
- if (omap_revision() == OMAP5430_ES1_0) {
+ if (omap_revision() >= OMAP5430_ES1_0) {
writel(EMIF_L3_CONFIG_VAL_SYS_10_MPU_5_LL_0,
&emif->emif_l3_config);
} else if (omap_revision() >= OMAP4460_ES1_0) {
@@ -202,6 +202,101 @@ void emif_update_timings(u32 base, const struct emif_regs *regs)
}
}
+static void ddr3_leveling(u32 base, const struct emif_regs *regs)
+{
+ struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
+
+ /* keep sdram in self-refresh */
+ writel(((LP_MODE_SELF_REFRESH << EMIF_REG_LP_MODE_SHIFT)
+ & EMIF_REG_LP_MODE_MASK), &emif->emif_pwr_mgmt_ctrl);
+ __udelay(130);
+
+ /*
+ * Set invert_clkout (if activated)--DDR_PHYCTRL_1
+ * Invert clock adds an additional half cycle delay on the command
+ * interface. The additional half cycle, is usually meant to enable
+ * leveling in the situation that DQS is later than CK on the board.It
+ * also helps provide some additional margin for leveling.
+ */
+ writel(regs->emif_ddr_phy_ctlr_1, &emif->emif_ddr_phy_ctrl_1);
+ writel(regs->emif_ddr_phy_ctlr_1, &emif->emif_ddr_phy_ctrl_1_shdw);
+ __udelay(130);
+
+ writel(((LP_MODE_DISABLE << EMIF_REG_LP_MODE_SHIFT)
+ & EMIF_REG_LP_MODE_MASK), &emif->emif_pwr_mgmt_ctrl);
+
+ /* Launch Full leveling */
+ writel(DDR3_FULL_LVL, &emif->emif_rd_wr_lvl_ctl);
+
+ /* Wait till full leveling is complete */
+ readl(&emif->emif_rd_wr_lvl_ctl);
+ __udelay(130);
+
+ /* Read data eye leveling no of samples */
+ config_data_eye_leveling_samples(base);
+
+ /* Launch 8 incremental WR_LVL- to compensate for PHY limitation */
+ writel(0x2 << EMIF_REG_WRLVLINC_INT_SHIFT, &emif->emif_rd_wr_lvl_ctl);
+ __udelay(130);
+
+ /* Launch Incremental leveling */
+ writel(DDR3_INC_LVL, &emif->emif_rd_wr_lvl_ctl);
+ __udelay(130);
+}
+
+static void ddr3_init(u32 base, const struct emif_regs *regs)
+{
+ struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
+ u32 *ext_phy_ctrl_base = 0;
+ u32 *emif_ext_phy_ctrl_base = 0;
+ u32 i = 0;
+
+ /*
+ * Set SDRAM_CONFIG and PHY control registers to locked frequency
+ * and RL =7. As the default values of the Mode Registers are not
+ * defined, contents of mode Registers must be fully initialized.
+ * H/W takes care of this initialization
+ */
+ writel(regs->sdram_config_init, &emif->emif_sdram_config);
+
+ writel(regs->emif_ddr_phy_ctlr_1_init, &emif->emif_ddr_phy_ctrl_1);
+
+ /* Update timing registers */
+ writel(regs->sdram_tim1, &emif->emif_sdram_tim_1);
+ writel(regs->sdram_tim2, &emif->emif_sdram_tim_2);
+ writel(regs->sdram_tim3, &emif->emif_sdram_tim_3);
+
+ writel(regs->ref_ctrl, &emif->emif_sdram_ref_ctrl);
+ writel(regs->read_idle_ctrl, &emif->emif_read_idlectrl);
+
+ ext_phy_ctrl_base = (u32 *) &(regs->emif_ddr_ext_phy_ctrl_1);
+ emif_ext_phy_ctrl_base = (u32 *) &(emif->emif_ddr_ext_phy_ctrl_1);
+
+ /* Configure external phy control timing registers */
+ for (i = 0; i < EMIF_EXT_PHY_CTRL_TIMING_REG; i++) {
+ writel(*ext_phy_ctrl_base, emif_ext_phy_ctrl_base++);
+ /* Update shadow registers */
+ writel(*ext_phy_ctrl_base++, emif_ext_phy_ctrl_base++);
+ }
+
+ /*
+ * external phy 6-24 registers do not change with
+ * ddr frequency
+ */
+ for (i = 0; i < EMIF_EXT_PHY_CTRL_CONST_REG; i++) {
+ writel(ddr3_ext_phy_ctrl_const_base[i],
+ emif_ext_phy_ctrl_base++);
+ /* Update shadow registers */
+ writel(ddr3_ext_phy_ctrl_const_base[i],
+ emif_ext_phy_ctrl_base++);
+ }
+
+ /* enable leveling */
+ writel(regs->emif_rd_wr_lvl_rmp_ctl, &emif->emif_rd_wr_lvl_rmp_ctl);
+
+ ddr3_leveling(base, regs);
+}
+
#ifndef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS
#define print_timing_reg(reg) debug(#reg" - 0x%08x\n", (reg))
@@ -975,8 +1070,12 @@ static void do_sdram_init(u32 base)
* Changing the timing registers in EMIF can happen(going from one
* OPP to another)
*/
- if (!in_sdram)
- lpddr2_init(base, regs);
+ if (!in_sdram) {
+ if (omap_revision() != OMAP5432_ES1_0)
+ lpddr2_init(base, regs);
+ else
+ ddr3_init(base, regs);
+ }
/* Write to the shadow registers */
emif_update_timings(base, regs);
diff --git a/arch/arm/cpu/armv7/omap4/hwinit.c b/arch/arm/cpu/armv7/omap4/hwinit.c
index 187e938..2c34e48 100644
--- a/arch/arm/cpu/armv7/omap4/hwinit.c
+++ b/arch/arm/cpu/armv7/omap4/hwinit.c
@@ -118,6 +118,11 @@ void do_io_settings(void)
}
#endif
+/* dummy fuction for omap4 */
+void config_data_eye_leveling_samples(u32 emif_base)
+{
+}
+
void init_omap_revision(void)
{
/*
diff --git a/arch/arm/cpu/armv7/omap5/hwinit.c b/arch/arm/cpu/armv7/omap5/hwinit.c
index df0b760..d0c3ff7 100644
--- a/arch/arm/cpu/armv7/omap5/hwinit.c
+++ b/arch/arm/cpu/armv7/omap5/hwinit.c
@@ -35,6 +35,7 @@
#include <asm/sizes.h>
#include <asm/utils.h>
#include <asm/arch/gpio.h>
+#include <asm/emif.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -203,6 +204,20 @@ void do_io_settings(void)
}
#endif
+void config_data_eye_leveling_samples(u32 emif_base)
+{
+ struct omap_sys_ctrl_regs *ioregs_base =
+ (struct omap_sys_ctrl_regs *) SYSCTRL_GENERAL_CORE_BASE;
+
+ /*EMIF_SDRAM_CONFIG_EXT-Read data eye leveling no of samples =4*/
+ if (emif_base == EMIF1_BASE)
+ writel(SDRAM_CONFIG_EXT_RD_LVL_4_SAMPLES,
+ &(ioregs_base->control_emif1_sdram_config_ext));
+ else if (emif_base == EMIF2_BASE)
+ writel(SDRAM_CONFIG_EXT_RD_LVL_4_SAMPLES,
+ &(ioregs_base->control_emif2_sdram_config_ext));
+}
+
void init_omap_revision(void)
{
/*