ARM: DRA: EMIF: Change DDR3 settings to use hw leveling

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.

Signed-off-by: Sricharan R <r.sricharan@ti.com>
diff --git a/arch/arm/cpu/armv7/omap-common/emif-common.c b/arch/arm/cpu/armv7/omap-common/emif-common.c
index b0e1caa..dc1ea1d 100644
--- a/arch/arm/cpu/armv7/omap-common/emif-common.c
+++ b/arch/arm/cpu/armv7/omap-common/emif-common.c
@@ -206,7 +206,7 @@
 	}
 }
 
-static void ddr3_leveling(u32 base, const struct emif_regs *regs)
+static void omap5_ddr3_leveling(u32 base, const struct emif_regs *regs)
 {
 	struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
 
@@ -217,47 +217,86 @@
 
 	/*
 	 * 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.
+	 * 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);
+	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);
+	       & 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);
+	      __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);
+	/*
+	 * 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);
+	       __udelay(130);
 }
 
-static void ddr3_sw_leveling(u32 base, const struct emif_regs *regs)
+static void dra7_ddr3_leveling(u32 base, const struct emif_regs *regs)
 {
 	struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
 
+	u32 fifo_reg;
+
-	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);
+	fifo_reg = readl(&emif->emif_ddr_fifo_misaligned_clear_1);
+	writel(fifo_reg | 0x00000100,
+	       &emif->emif_ddr_fifo_misaligned_clear_1);
+
+	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);
+
+	/* 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);
 
+	/*
+	 * Disable leveling. This is because if leveling is kept
+	 * enabled, then PHY triggers a false leveling during
+	 * EMIF-idle scenario which results in wrong delay
+	 * values getting updated. After this the EMIF becomes
+	 * unaccessible. So disable it after the first time
+	 */
+	writel(0x0, &emif->emif_rd_wr_lvl_rmp_ctl);
+}
+
-	writel(regs->emif_rd_wr_lvl_ctl, &emif->emif_rd_wr_lvl_ctl);
-	writel(regs->sdram_config, &emif->emif_sdram_config);
+static void ddr3_leveling(u32 base, const struct emif_regs *regs)
+{
+	if (is_omap54xx())
+		omap5_ddr3_leveling(base, regs);
+	else
+		dra7_ddr3_leveling(base, regs);
 }
 
 static void ddr3_init(u32 base, const struct emif_regs *regs)
@@ -270,9 +309,6 @@
 	 * 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 */
@@ -283,15 +319,24 @@
 	writel(regs->ref_ctrl, &emif->emif_sdram_ref_ctrl);
 	writel(regs->read_idle_ctrl, &emif->emif_read_idlectrl);
 
-	do_ext_phy_settings(base, regs);
+	/*
+	 * The same sequence should work on OMAP5432 as well. But strange that
+	 * it is not working
+	 */
+	if (omap_revision() == DRA752_ES1_0) {
+		do_ext_phy_settings(base, regs);
+		writel(regs->sdram_config2, &emif->emif_lpddr2_nvm_config);
+		writel(regs->sdram_config_init, &emif->emif_sdram_config);
+	} else {
+		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
@@ -1079,10 +1124,7 @@
 	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 */