[U-Boot] [PATCH 1/2] 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.sricha...@ti.com --- arch/arm/cpu/armv7/omap-common/emif-common.c | 133 +-- 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, 182 insertions(+), 123 deletions(-) diff --git a/arch/arm/cpu/armv7/omap-common/emif-common.c b/arch/arm/cpu/armv7/omap-common/emif-common.c index b0e1caa..c1f5838 100644 --- a/arch/arm/cpu/armv7/omap-common/emif-common.c +++ b/arch/arm/cpu/armv7/omap-common/emif-common.c @@ -210,54 +210,76 @@ 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); + 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); + + /* 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); + } else { + u32 fifo_reg; - /* Wait till full leveling is complete */ - readl(emif-emif_rd_wr_lvl_ctl); - __udelay(130); + fifo_reg = readl(emif-emif_ddr_fifo_misaligned_clear_1); + writel(fifo_reg | 0x0100, + emif-emif_ddr_fifo_misaligned_clear_1); - /* Read data eye leveling no of samples */ - config_data_eye_leveling_samples(base); + fifo_reg = readl(emif-emif_ddr_fifo_misaligned_clear_2); + writel(fifo_reg | 0x0100, + emif-emif_ddr_fifo_misaligned_clear_2); - /* 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 Full leveling */ + writel(DDR3_FULL_LVL, emif-emif_rd_wr_lvl_ctl); - /* Launch Incremental
Re: [U-Boot] [PATCH 1/2] ARM: DRA: EMIF: Change DDR3 settings to use hw leveling
On Thu, Nov 07, 2013 at 08:17:39PM +0530, Sricharan R wrote: 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. [snip] @@ -210,54 +210,76 @@ 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 */ [snip] + if (omap_revision() != DRA752_ES1_0){ + /* keep sdram in self-refresh */ [snip] + } else { + u32 fifo_reg; [snip] + /* Disable leveling */ + writel(0x0, emif-emif_rd_wr_lvl_rmp_ctl); + } Two things here. First, it seems that now ddr3_leveling has one sequence for not DRA752_ES1_0 (so likely to get wrong when used on DRA752 whatever comes after ES1.0) and another for DRA752_ES1_0. This would be because the it's different EMIF blocks and related HW, so it's a different sequence, yes? Second, the comment at the end of this function about Disable leveling seems misleading, but maybe it's just me. We're saying leveling sequence is complete now, yes? For the second issue, we can expand / clarify the comment. For the first issue, maybe we shouldn't have a single ddr3_leveling function but per family ones? There's nothing in common between the two cases here, so we're just gaining an indentation level when we could be excluding code from the final binary instead (either ifdef or maybe just separate files?). -- Tom signature.asc Description: Digital signature ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH 1/2] ARM: DRA: EMIF: Change DDR3 settings to use hw leveling
Hi Tom, On Thursday 07 November 2013 08:33 PM, Tom Rini wrote: On Thu, Nov 07, 2013 at 08:17:39PM +0530, Sricharan R wrote: 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. [snip] @@ -210,54 +210,76 @@ 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 */ [snip] +if (omap_revision() != DRA752_ES1_0){ +/* keep sdram in self-refresh */ [snip] +} else { +u32 fifo_reg; [snip] +/* Disable leveling */ +writel(0x0, emif-emif_rd_wr_lvl_rmp_ctl); +} Two things here. First, it seems that now ddr3_leveling has one sequence for not DRA752_ES1_0 (so likely to get wrong when used on DRA752 whatever comes after ES1.0) and another for DRA752_ES1_0. This would be because the it's different EMIF blocks and related HW, so it's a different sequence, yes? Second, the comment at the end of this function about Disable leveling seems misleading, but maybe it's just me. We're saying leveling sequence is complete now, yes? For the second issue, we can expand / clarify the comment. For the first issue, maybe we shouldn't have a single ddr3_leveling function but per family ones? There's nothing in common between the two cases here, so we're just gaining an indentation level when we could be excluding code from the final binary instead (either ifdef or maybe just separate files?). Yes, i also thought about having a separate function for OMAP5/DRA. I will do that. For the point about disable leveling, it was intentional. After we are done with a leveling once during boot, we do not intend to enable it anymore. We see that the PHY misbehaves by triggering a wrong leveling sequence when EMIF hits idle, which results in wrong delay values if it is left enabled. I will add this comment in V2 Regards, Sricharan ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot