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>
This commit is contained in:
SRICHARAN R 2013-11-08 17:40:37 +05:30 committed by Tom Rini
parent 39302dcd30
commit 6c70935d75
6 changed files with 174 additions and 98 deletions

View file

@ -206,7 +206,7 @@ void emif_update_timings(u32 base, const struct emif_regs *regs)
}
}
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 @@ static void ddr3_leveling(u32 base, const struct emif_regs *regs)
/*
* 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;
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);
u32 fifo_reg;
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);
writel(regs->emif_rd_wr_lvl_ctl, &emif->emif_rd_wr_lvl_ctl);
writel(regs->sdram_config, &emif->emif_sdram_config);
/*
* 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);
}
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 @@ 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 */
@ -283,15 +319,24 @@ 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);
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 @@ 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 */

View file

@ -600,6 +600,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 = {
@ -610,16 +611,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,
};

View file

@ -297,13 +297,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)

View file

@ -148,13 +148,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,
@ -172,13 +172,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,
@ -306,7 +306,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,
@ -329,7 +329,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,
@ -352,7 +352,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,
@ -376,51 +376,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 = {
@ -431,27 +441,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);
}
}
@ -468,6 +489,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;
@ -487,8 +509,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 */

View file

@ -239,6 +239,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;
};

View file

@ -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 {