ARM: DRA: EMIF: Change DDR3 settings to use hw leveling
PATCH 1/1 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.
Boot tested on DRA7 evm, OMAP5 uevm, OMAP4 panda
--- 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(-)
arch/arm/cpu/armv7/omap-common/emif-common.c +50 -46
@@ -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 */
arch/arm/cpu/armv7/omap5/hw_data.c +6 -3
@@ -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 , };
arch/arm/cpu/armv7/omap5/hwinit.c +8 -4
@@ -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 )
arch/arm/cpu/armv7/omap5/sdram.c +85 -61
224 lines not on this page · raw message
arch/arm/include/asm/arch-omap5/omap.h +1 -0
@@ -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__ */
arch/arm/include/asm/emif.h +3 -1
@@ -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 {
Signature · 1 line
1.7.9.5
PATCH 1/1 ARM: DRA: EMIF: Change DDR3 settings to use hw leveling
Quoted 5 lines · Sricharan R
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]
Quoted 1 line
#ifndef
CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS
OK, so this reminds me, should we be printing out something more now then, when we're calculating timings, rather than using precalculated ones? Or is that a different issue I'm thinking of?
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.denx.de/pipermail/u-boot/attachments/20130820/af97ea1b/attachment.pgp>
PATCH 1/1 ARM: DRA: EMIF: Change DDR3 settings to use hw leveling
Hi Tom,
Quoted 7 lines · Tom Rini
Quoted 5 lines · Sricharan R
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.
Quoted 6 lines
[snip]
Quoted 1 line
#ifndef
CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGSOK, so this reminds me, should we be printing out something more now then, when we're calculating timings, rather than using precalculated ones? Or is that a different issue I'm thinking of?
This is not something to do with precalculated timings or auto config.
This patch is specific only to DDR3 memory and EMIF supports auto leveling feature for DDR3. This feature was disabled for DRA7 till now, but this patch enables that.
Regards,
Sricharan
PATCH 1/1 ARM: DRA: EMIF: Change DDR3 settings to use hw leveling
Hi Tom,
Quoted 12 lines · Sricharan R
Hi Tom,
Quoted 9 lines · Tom Rini
Quoted 5 lines · Sricharan R
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]
Quoted 1 line
#ifndef
CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS
Quoted 8 lines
Quoted 4 lines
OK, so this reminds me, should we be printing out something more now then, when we're calculating timings, rather than using precalculated ones? Or is that a different issue I'm thinking of?
This is not something to do with precalculated timings or auto config.
This patch is specific only to DDR3 memory and EMIF supports auto leveling feature for DDR3. This feature was disabled for DRA7 till now, but this patch enables that.
I want to add one more change in patch. So will send V2 for this.
Regards,
Sricharan