[U-Boot] [PATCH] ARM: DRA: EMIF: Change DDR3 settings to use hw leveling

Sricharan R r.sricharan at ti.com
Tue Aug 20 15:17:36 CEST 2013


Currently the DDR3 memory on DRA7 ES1.0 evm board is enabled using
software leveling. This was done since hardware leveling was not
working. Now that the right sequence to do hw leveling is identified,
use it. This is required for EMIF clockdomain to idle and come back
during lowpower usecases.

Boot tested on DRA7 evm, OMAP5 uevm, OMAP4 panda

Signed-off-by: Sricharan R <r.sricharan at ti.com>
---
 arch/arm/cpu/armv7/omap-common/emif-common.c |   96 +++++++++--------
 arch/arm/cpu/armv7/omap5/hw_data.c           |    9 +-
 arch/arm/cpu/armv7/omap5/hwinit.c            |   12 ++-
 arch/arm/cpu/armv7/omap5/sdram.c             |  146 +++++++++++++++-----------
 arch/arm/include/asm/arch-omap5/omap.h       |    1 +
 arch/arm/include/asm/emif.h                  |    4 +-
 6 files changed, 153 insertions(+), 115 deletions(-)

diff --git a/arch/arm/cpu/armv7/omap-common/emif-common.c b/arch/arm/cpu/armv7/omap-common/emif-common.c
index 9ede3f5..8ff796a 100644
--- a/arch/arm/cpu/armv7/omap-common/emif-common.c
+++ b/arch/arm/cpu/armv7/omap-common/emif-common.c
@@ -226,24 +226,40 @@ 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);
+	if (omap_revision() != DRA752_ES1_0)	{
+		/* 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);
+	} else {
+		u32 fifo_reg;
 
-	/*
-	 * 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);
+		fifo_reg = readl(&emif->emif_ddr_fifo_misaligned_clear_1);
+		writel(fifo_reg | 0x00000100,
+		       &emif->emif_ddr_fifo_misaligned_clear_1);
 
-	writel(((LP_MODE_DISABLE << EMIF_REG_LP_MODE_SHIFT)
-		& EMIF_REG_LP_MODE_MASK), &emif->emif_pwr_mgmt_ctrl);
+		fifo_reg = readl(&emif->emif_ddr_fifo_misaligned_clear_2);
+		writel(fifo_reg | 0x00000100,
+		       &emif->emif_ddr_fifo_misaligned_clear_2);
+	}
 
 	/* Launch Full leveling */
 	writel(DDR3_FULL_LVL, &emif->emif_rd_wr_lvl_ctl);
@@ -255,25 +271,19 @@ static void ddr3_leveling(u32 base, const struct emif_regs *regs)
 	/* 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_sw_leveling(u32 base, const struct emif_regs *regs)
-{
-	struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
-
-	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);
-	config_data_eye_leveling_samples(base);
-
-	writel(regs->emif_rd_wr_lvl_ctl, &emif->emif_rd_wr_lvl_ctl);
-	writel(regs->sdram_config, &emif->emif_sdram_config);
+	if (omap_revision() == DRA752_ES1_0) {
+		/*
+		 * 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)
@@ -286,9 +296,6 @@ static void ddr3_init(u32 base, const struct emif_regs *regs)
 	 * defined, contents of mode Registers must be fully initialized.
 	 * H/W takes care of this initialization
 	 */
-	writel(regs->sdram_config2, &emif->emif_lpddr2_nvm_config);
-	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 */
@@ -299,15 +306,15 @@ static void ddr3_init(u32 base, const struct emif_regs *regs)
 	writel(regs->ref_ctrl, &emif->emif_sdram_ref_ctrl);
 	writel(regs->read_idle_ctrl, &emif->emif_read_idlectrl);
 
+	writel(regs->sdram_config2, &emif->emif_lpddr2_nvm_config);
+	writel(regs->sdram_config_init, &emif->emif_sdram_config);
+
 	do_ext_phy_settings(base, regs);
 
 	/* enable leveling */
 	writel(regs->emif_rd_wr_lvl_rmp_ctl, &emif->emif_rd_wr_lvl_rmp_ctl);
 
-	if (omap_revision() == DRA752_ES1_0)
-		ddr3_sw_leveling(base, regs);
-	else
-		ddr3_leveling(base, regs);
+	ddr3_leveling(base, regs);
 }
 
 #ifndef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS
@@ -1095,10 +1102,7 @@ static void do_sdram_init(u32 base)
 	if (warm_reset() && (emif_sdram_type() == EMIF_SDRAM_TYPE_DDR3)) {
 		set_lpmode_selfrefresh(base);
 		emif_reset_phy(base);
-		if (omap_revision() == DRA752_ES1_0)
-			ddr3_sw_leveling(base, regs);
-		else
-			ddr3_leveling(base, regs);
+		ddr3_leveling(base, regs);
 	}
 
 	/* Write to the shadow registers */
diff --git a/arch/arm/cpu/armv7/omap5/hw_data.c b/arch/arm/cpu/armv7/omap5/hw_data.c
index 07b1108..2b76f42 100644
--- a/arch/arm/cpu/armv7/omap5/hw_data.c
+++ b/arch/arm/cpu/armv7/omap5/hw_data.c
@@ -592,6 +592,7 @@ const struct ctrl_ioregs ioregs_omap5432_es1 = {
 	.ctrl_ddrio_1 = DDR_IO_1_VREF_CELLS_DDR3_VALUE,
 	.ctrl_ddrio_2 = DDR_IO_2_VREF_CELLS_DDR3_VALUE,
 	.ctrl_emif_sdram_config_ext = SDRAM_CONFIG_EXT_RD_LVL_11_SAMPLES,
+	.ctrl_emif_sdram_config_ext_final = SDRAM_CONFIG_EXT_RD_LVL_4_SAMPLES,
 };
 
 const struct ctrl_ioregs ioregs_omap5432_es2 = {
@@ -602,16 +603,18 @@ const struct ctrl_ioregs ioregs_omap5432_es2 = {
 	.ctrl_ddrio_1 = DDR_IO_1_VREF_CELLS_DDR3_VALUE_ES2,
 	.ctrl_ddrio_2 = DDR_IO_2_VREF_CELLS_DDR3_VALUE_ES2,
 	.ctrl_emif_sdram_config_ext = SDRAM_CONFIG_EXT_RD_LVL_11_SAMPLES,
+	.ctrl_emif_sdram_config_ext_final = SDRAM_CONFIG_EXT_RD_LVL_4_SAMPLES,
 };
 
 const struct ctrl_ioregs ioregs_dra7xx_es1 = {
 	.ctrl_ddrch = 0x40404040,
 	.ctrl_lpddr2ch = 0x40404040,
 	.ctrl_ddr3ch = 0x80808080,
-	.ctrl_ddrio_0 = 0xbae8c631,
-	.ctrl_ddrio_1 = 0xb46318d8,
+	.ctrl_ddrio_0 = 0xA2084210,
+	.ctrl_ddrio_1 = 0x84210840,
 	.ctrl_ddrio_2 = 0x84210000,
-	.ctrl_emif_sdram_config_ext = 0xb2c00000,
+	.ctrl_emif_sdram_config_ext = 0x0001C1A7,
+	.ctrl_emif_sdram_config_ext_final = 0x000101A7,
 	.ctrl_ddr_ctrl_ext_0 = 0xA2000000,
 };
 
diff --git a/arch/arm/cpu/armv7/omap5/hwinit.c b/arch/arm/cpu/armv7/omap5/hwinit.c
index 11ba36b..567e54e 100644
--- a/arch/arm/cpu/armv7/omap5/hwinit.c
+++ b/arch/arm/cpu/armv7/omap5/hwinit.c
@@ -313,13 +313,17 @@ void srcomp_enable(void)
 
 void config_data_eye_leveling_samples(u32 emif_base)
 {
+	const struct ctrl_ioregs *ioregs;
+
+	get_ioregs(&ioregs);
+
 	/*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,
-			(*ctrl)->control_emif1_sdram_config_ext);
+		writel(ioregs->ctrl_emif_sdram_config_ext_final,
+		       (*ctrl)->control_emif1_sdram_config_ext);
 	else if (emif_base == EMIF2_BASE)
-		writel(SDRAM_CONFIG_EXT_RD_LVL_4_SAMPLES,
-			(*ctrl)->control_emif2_sdram_config_ext);
+		writel(ioregs->ctrl_emif_sdram_config_ext_final,
+		       (*ctrl)->control_emif2_sdram_config_ext);
 }
 
 void init_omap_revision(void)
diff --git a/arch/arm/cpu/armv7/omap5/sdram.c b/arch/arm/cpu/armv7/omap5/sdram.c
index 1b445a6..d35bb1c 100644
--- a/arch/arm/cpu/armv7/omap5/sdram.c
+++ b/arch/arm/cpu/armv7/omap5/sdram.c
@@ -164,13 +164,13 @@ const struct emif_regs emif_1_regs_ddr3_532_mhz_1cs_dra_es1 = {
 	.read_idle_ctrl                 = 0x00050000,
 	.zq_config                      = 0x0007190B,
 	.temp_alert_config              = 0x00000000,
-	.emif_ddr_phy_ctlr_1_init       = 0x0E20400A,
-	.emif_ddr_phy_ctlr_1            = 0x0E24400A,
-	.emif_ddr_ext_phy_ctrl_1        = 0x04040100,
-	.emif_ddr_ext_phy_ctrl_2        = 0x009E009E,
-	.emif_ddr_ext_phy_ctrl_3        = 0x009E009E,
-	.emif_ddr_ext_phy_ctrl_4        = 0x009E009E,
-	.emif_ddr_ext_phy_ctrl_5        = 0x009E009E,
+	.emif_ddr_phy_ctlr_1_init       = 0x0024400A,
+	.emif_ddr_phy_ctlr_1            = 0x0024400A,
+	.emif_ddr_ext_phy_ctrl_1        = 0x10040100,
+	.emif_ddr_ext_phy_ctrl_2        = 0x00B000B0,
+	.emif_ddr_ext_phy_ctrl_3        = 0x00B000B0,
+	.emif_ddr_ext_phy_ctrl_4        = 0x00B000B0,
+	.emif_ddr_ext_phy_ctrl_5        = 0x00B000B0,
 	.emif_rd_wr_lvl_rmp_win         = 0x00000000,
 	.emif_rd_wr_lvl_rmp_ctl         = 0x80000000,
 	.emif_rd_wr_lvl_ctl             = 0x00000000,
@@ -188,13 +188,13 @@ const struct emif_regs emif_2_regs_ddr3_532_mhz_1cs_dra_es1 = {
 	.read_idle_ctrl                 = 0x00050000,
 	.zq_config                      = 0x0007190B,
 	.temp_alert_config              = 0x00000000,
-	.emif_ddr_phy_ctlr_1_init       = 0x0020400A,
-	.emif_ddr_phy_ctlr_1            = 0x0E24400A,
-	.emif_ddr_ext_phy_ctrl_1        = 0x04040100,
-	.emif_ddr_ext_phy_ctrl_2        = 0x009D009D,
-	.emif_ddr_ext_phy_ctrl_3        = 0x009D009D,
-	.emif_ddr_ext_phy_ctrl_4        = 0x009D009D,
-	.emif_ddr_ext_phy_ctrl_5        = 0x009D009D,
+	.emif_ddr_phy_ctlr_1_init       = 0x0024400A,
+	.emif_ddr_phy_ctlr_1            = 0x0024400A,
+	.emif_ddr_ext_phy_ctrl_1        = 0x10040100,
+	.emif_ddr_ext_phy_ctrl_2        = 0x00B000B0,
+	.emif_ddr_ext_phy_ctrl_3        = 0x00B000B0,
+	.emif_ddr_ext_phy_ctrl_4        = 0x00B000B0,
+	.emif_ddr_ext_phy_ctrl_5        = 0x00B000B0,
 	.emif_rd_wr_lvl_rmp_win         = 0x00000000,
 	.emif_rd_wr_lvl_rmp_ctl         = 0x80000000,
 	.emif_rd_wr_lvl_ctl             = 0x00000000,
@@ -322,7 +322,7 @@ void emif_get_device_details(u32 emif_nr,
 
 #endif /* CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS */
 
-const u32 ext_phy_ctrl_const_base[EMIF_EXT_PHY_CTRL_CONST_REG] = {
+const u32 ext_phy_ctrl_const_base[] = {
 	0x01004010,
 	0x00001004,
 	0x04010040,
@@ -345,7 +345,7 @@ const u32 ext_phy_ctrl_const_base[EMIF_EXT_PHY_CTRL_CONST_REG] = {
 	0x0
 };
 
-const u32 ddr3_ext_phy_ctrl_const_base_es1[EMIF_EXT_PHY_CTRL_CONST_REG] = {
+const u32 ddr3_ext_phy_ctrl_const_base_es1[] = {
 	0x01004010,
 	0x00001004,
 	0x04010040,
@@ -368,7 +368,7 @@ const u32 ddr3_ext_phy_ctrl_const_base_es1[EMIF_EXT_PHY_CTRL_CONST_REG] = {
 	0x0
 };
 
-const u32 ddr3_ext_phy_ctrl_const_base_es2[EMIF_EXT_PHY_CTRL_CONST_REG] = {
+const u32 ddr3_ext_phy_ctrl_const_base_es2[] = {
 	0x50D4350D,
 	0x00000D43,
 	0x04010040,
@@ -392,51 +392,61 @@ const u32 ddr3_ext_phy_ctrl_const_base_es2[EMIF_EXT_PHY_CTRL_CONST_REG] = {
 };
 
 const u32
-dra_ddr3_ext_phy_ctrl_const_base_es1_emif1[EMIF_EXT_PHY_CTRL_CONST_REG] = {
-	0x009E009E,
-	0x002E002E,
-	0x002E002E,
-	0x002E002E,
-	0x002E002E,
-	0x002E002E,
-	0x004D004D,
-	0x004D004D,
-	0x004D004D,
-	0x004D004D,
-	0x004D004D,
-	0x004D004D,
-	0x004D004D,
-	0x004D004D,
-	0x004D004D,
-	0x004D004D,
-	0x0,
-	0x600020,
+dra_ddr3_ext_phy_ctrl_const_base_es1_emif1[] = {
+	0x00B000B0,
+	0x00400040,
+	0x00400040,
+	0x00400040,
+	0x00400040,
+	0x00400040,
+	0x00800080,
+	0x00800080,
+	0x00800080,
+	0x00800080,
+	0x00800080,
+	0x00600060,
+	0x00600060,
+	0x00600060,
+	0x00600060,
+	0x00600060,
+	0x00800080,
+	0x00800080,
 	0x40010080,
-	0x8102040
+	0x08102040,
+	0x0,
+	0x0,
+	0x0,
+	0x0,
+	0x0
 };
 
 const u32
-dra_ddr3_ext_phy_ctrl_const_base_es1_emif2[EMIF_EXT_PHY_CTRL_CONST_REG] = {
-	0x009D009D,
-	0x002D002D,
-	0x002D002D,
-	0x002D002D,
-	0x002D002D,
-	0x002D002D,
-	0x00570057,
-	0x00570057,
-	0x00570057,
-	0x00570057,
-	0x00570057,
-	0x00570057,
-	0x00570057,
-	0x00570057,
-	0x00570057,
-	0x00570057,
+dra_ddr3_ext_phy_ctrl_const_base_es1_emif2[] = {
+	0x00BB00BB,
+	0x00440044,
+	0x00440044,
+	0x00440044,
+	0x00440044,
+	0x00440044,
+	0x007F007F,
+	0x007F007F,
+	0x007F007F,
+	0x007F007F,
+	0x007F007F,
+	0x00600060,
+	0x00600060,
+	0x00600060,
+	0x00600060,
+	0x00600060,
 	0x0,
-	0x600020,
+	0x00600020,
 	0x40010080,
-	0x8102040
+	0x08102040,
+	0x0,
+	0x0,
+	0x0,
+	0x0,
+	0x0
 };
 
 const struct lpddr2_mr_regs mr_regs = {
@@ -447,27 +457,38 @@ const struct lpddr2_mr_regs mr_regs = {
 	.mr16	= MR16_REF_FULL_ARRAY
 };
 
-static void emif_get_ext_phy_ctrl_const_regs(u32 emif_nr, const u32 **regs)
+static void emif_get_ext_phy_ctrl_const_regs(u32 emif_nr,
+					     const u32 **regs,
+					     u32 *size)
 {
 	switch (omap_revision()) {
 	case OMAP5430_ES1_0:
 	case OMAP5430_ES2_0:
 		*regs = ext_phy_ctrl_const_base;
+		*size = ARRAY_SIZE(ext_phy_ctrl_const_base);
 		break;
 	case OMAP5432_ES1_0:
 		*regs = ddr3_ext_phy_ctrl_const_base_es1;
+		*size = ARRAY_SIZE(ddr3_ext_phy_ctrl_const_base_es1);
 		break;
 	case OMAP5432_ES2_0:
 		*regs = ddr3_ext_phy_ctrl_const_base_es2;
+		*size = ARRAY_SIZE(ddr3_ext_phy_ctrl_const_base_es2);
 		break;
 	case DRA752_ES1_0:
-		if (emif_nr == 1)
+		if (emif_nr == 1) {
 			*regs = dra_ddr3_ext_phy_ctrl_const_base_es1_emif1;
-		else
+			*size =
+			ARRAY_SIZE(dra_ddr3_ext_phy_ctrl_const_base_es1_emif1);
+		} else {
 			*regs = dra_ddr3_ext_phy_ctrl_const_base_es1_emif2;
+			*size =
+			ARRAY_SIZE(dra_ddr3_ext_phy_ctrl_const_base_es1_emif2);
+		}
 		break;
 	default:
 		*regs = ddr3_ext_phy_ctrl_const_base_es2;
+		*size = ARRAY_SIZE(ddr3_ext_phy_ctrl_const_base_es2);
 
 	}
 }
@@ -484,6 +505,7 @@ void do_ext_phy_settings(u32 base, const struct emif_regs *regs)
 	u32 emif_nr;
 	const u32 *ext_phy_ctrl_const_regs;
 	u32 i = 0;
+	u32 size;
 
 	emif_nr = (base == EMIF1_BASE) ? 1 : 2;
 
@@ -503,8 +525,10 @@ void do_ext_phy_settings(u32 base, const struct emif_regs *regs)
 	 * external phy 6-24 registers do not change with
 	 * ddr frequency
 	 */
-	emif_get_ext_phy_ctrl_const_regs(emif_nr, &ext_phy_ctrl_const_regs);
-	for (i = 0; i < EMIF_EXT_PHY_CTRL_CONST_REG; i++) {
+	emif_get_ext_phy_ctrl_const_regs(emif_nr,
+					 &ext_phy_ctrl_const_regs, &size);
+
+	for (i = 0; i < size; i++) {
 		writel(ext_phy_ctrl_const_regs[i],
 		       emif_ext_phy_ctrl_base++);
 		/* Update shadow registers */
diff --git a/arch/arm/include/asm/arch-omap5/omap.h b/arch/arm/include/asm/arch-omap5/omap.h
index 5e6d82e..4aad8f2 100644
--- a/arch/arm/include/asm/arch-omap5/omap.h
+++ b/arch/arm/include/asm/arch-omap5/omap.h
@@ -222,6 +222,7 @@ struct ctrl_ioregs {
 	u32 ctrl_ddrio_1;
 	u32 ctrl_ddrio_2;
 	u32 ctrl_emif_sdram_config_ext;
+	u32 ctrl_emif_sdram_config_ext_final;
 	u32 ctrl_ddr_ctrl_ext_0;
 };
 #endif /* __ASSEMBLY__ */
diff --git a/arch/arm/include/asm/emif.h b/arch/arm/include/asm/emif.h
index 1b94a99..c12beea 100644
--- a/arch/arm/include/asm/emif.h
+++ b/arch/arm/include/asm/emif.h
@@ -581,7 +581,6 @@
 	(0xFF << EMIF_SYS_ADDR_SHIFT))
 
 #define EMIF_EXT_PHY_CTRL_TIMING_REG	0x5
-#define EMIF_EXT_PHY_CTRL_CONST_REG	0x14
 
 /* Reg mapping structure */
 struct emif_reg_struct {
@@ -690,6 +689,9 @@ struct emif_reg_struct {
 	u32 emif_ddr_ext_phy_ctrl_23_shdw;
 	u32 emif_ddr_ext_phy_ctrl_24;
 	u32 emif_ddr_ext_phy_ctrl_24_shdw;
+	u32 padding[22];
+	u32 emif_ddr_fifo_misaligned_clear_1;
+	u32 emif_ddr_fifo_misaligned_clear_2;
 };
 
 struct dmm_lisa_map_regs {
-- 
1.7.9.5



More information about the U-Boot mailing list