ARM: DRA7: DDR3: Add support for HW leveling
DRA7 EMIF supports Full leveling for DDR3. Adding support for the Full leveling sequence. Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com> Reviewed-by: Tom Rini <trini@konsulko.com>
This commit is contained in:
parent
9d01b7872e
commit
6213db78f4
@ -242,13 +242,122 @@ static void omap5_ddr3_leveling(u32 base, const struct emif_regs *regs)
|
||||
__udelay(130);
|
||||
}
|
||||
|
||||
static void ddr3_leveling(u32 base, const struct emif_regs *regs)
|
||||
static void update_hwleveling_output(u32 base, const struct emif_regs *regs)
|
||||
{
|
||||
if (is_omap54xx())
|
||||
omap5_ddr3_leveling(base, regs);
|
||||
struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
|
||||
u32 *emif_ext_phy_ctrl_reg, *emif_phy_status;
|
||||
u32 reg, i;
|
||||
|
||||
emif_phy_status = (u32 *)&emif->emif_ddr_phy_status[7];
|
||||
|
||||
/* Update PHY_REG_RDDQS_RATIO */
|
||||
emif_ext_phy_ctrl_reg = (u32 *)&emif->emif_ddr_ext_phy_ctrl_7;
|
||||
for (i = 0; i < PHY_RDDQS_RATIO_REGS; i++) {
|
||||
reg = readl(emif_phy_status++);
|
||||
writel(reg, emif_ext_phy_ctrl_reg++);
|
||||
writel(reg, emif_ext_phy_ctrl_reg++);
|
||||
}
|
||||
|
||||
/* Update PHY_REG_FIFO_WE_SLAVE_RATIO */
|
||||
emif_ext_phy_ctrl_reg = (u32 *)&emif->emif_ddr_ext_phy_ctrl_2;
|
||||
for (i = 0; i < PHY_FIFO_WE_SLAVE_RATIO_REGS; i++) {
|
||||
reg = readl(emif_phy_status++);
|
||||
writel(reg, emif_ext_phy_ctrl_reg++);
|
||||
writel(reg, emif_ext_phy_ctrl_reg++);
|
||||
}
|
||||
|
||||
/* Update PHY_REG_WR_DQ/DQS_SLAVE_RATIO */
|
||||
emif_ext_phy_ctrl_reg = (u32 *)&emif->emif_ddr_ext_phy_ctrl_12;
|
||||
for (i = 0; i < PHY_REG_WR_DQ_SLAVE_RATIO_REGS; i++) {
|
||||
reg = readl(emif_phy_status++);
|
||||
writel(reg, emif_ext_phy_ctrl_reg++);
|
||||
writel(reg, emif_ext_phy_ctrl_reg++);
|
||||
}
|
||||
|
||||
/* Disable 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(0x0, &emif->emif_rd_wr_lvl_rmp_ctl);
|
||||
}
|
||||
|
||||
static void ddr3_init(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;
|
||||
|
||||
/* Clear Error Status */
|
||||
clrsetbits_le32(&emif->emif_ddr_ext_phy_ctrl_36,
|
||||
EMIF_REG_PHY_FIFO_WE_IN_MISALINED_CLR,
|
||||
EMIF_REG_PHY_FIFO_WE_IN_MISALINED_CLR);
|
||||
|
||||
clrsetbits_le32(&emif->emif_ddr_ext_phy_ctrl_36_shdw,
|
||||
EMIF_REG_PHY_FIFO_WE_IN_MISALINED_CLR,
|
||||
EMIF_REG_PHY_FIFO_WE_IN_MISALINED_CLR);
|
||||
|
||||
/* Disable refreshed before leveling */
|
||||
clrsetbits_le32(&emif->emif_sdram_ref_ctrl, EMIF_REG_INITREF_DIS_SHIFT,
|
||||
EMIF_REG_INITREF_DIS_SHIFT);
|
||||
|
||||
/* Start Full leveling */
|
||||
writel(DDR3_FULL_LVL, &emif->emif_rd_wr_lvl_ctl);
|
||||
|
||||
__udelay(300);
|
||||
|
||||
/* Check for leveling timeout */
|
||||
if (readl(&emif->emif_status) & EMIF_REG_LEVELING_TO_MASK) {
|
||||
printf("Leveling timeout on EMIF%d\n", emif_num(base));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Enable refreshes after leveling */
|
||||
clrbits_le32(&emif->emif_sdram_ref_ctrl, EMIF_REG_INITREF_DIS_SHIFT);
|
||||
|
||||
debug("HW leveling success\n");
|
||||
/*
|
||||
* Update slave ratios in EXT_PHY_CTRLx registers
|
||||
* as per HW leveling output
|
||||
*/
|
||||
update_hwleveling_output(base, regs);
|
||||
}
|
||||
|
||||
static void dra7_ddr3_init(u32 base, const struct emif_regs *regs)
|
||||
{
|
||||
struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
|
||||
|
||||
if (warm_reset())
|
||||
emif_reset_phy(base);
|
||||
do_ext_phy_settings(base, regs);
|
||||
|
||||
writel(regs->ref_ctrl | EMIF_REG_INITREF_DIS_MASK,
|
||||
&emif->emif_sdram_ref_ctrl);
|
||||
/* Update timing registers */
|
||||
writel(regs->sdram_tim1, &emif->emif_sdram_tim_1);
|
||||
writel(regs->sdram_tim2, &emif->emif_sdram_tim_2);
|
||||
writel(regs->sdram_tim3, &emif->emif_sdram_tim_3);
|
||||
|
||||
writel(EMIF_L3_CONFIG_VAL_SYS_10_MPU_5_LL_0, &emif->emif_l3_config);
|
||||
writel(regs->read_idle_ctrl, &emif->emif_read_idlectrl);
|
||||
writel(regs->zq_config, &emif->emif_zq_config);
|
||||
writel(regs->temp_alert_config, &emif->emif_temp_alert_config);
|
||||
writel(regs->emif_rd_wr_lvl_rmp_ctl, &emif->emif_rd_wr_lvl_rmp_ctl);
|
||||
writel(regs->emif_rd_wr_lvl_ctl, &emif->emif_rd_wr_lvl_ctl);
|
||||
|
||||
writel(regs->emif_ddr_phy_ctlr_1_init, &emif->emif_ddr_phy_ctrl_1);
|
||||
writel(regs->emif_rd_wr_exec_thresh, &emif->emif_rd_wr_exec_thresh);
|
||||
|
||||
writel(regs->ref_ctrl, &emif->emif_sdram_ref_ctrl);
|
||||
|
||||
writel(regs->sdram_config2, &emif->emif_lpddr2_nvm_config);
|
||||
writel(regs->sdram_config_init, &emif->emif_sdram_config);
|
||||
|
||||
__udelay(1000);
|
||||
|
||||
writel(regs->ref_ctrl_final, &emif->emif_sdram_ref_ctrl);
|
||||
|
||||
if (regs->emif_rd_wr_lvl_rmp_ctl & EMIF_REG_RDWRLVL_EN_MASK)
|
||||
dra7_ddr3_leveling(base, regs);
|
||||
}
|
||||
|
||||
static void omap5_ddr3_init(u32 base, const struct emif_regs *regs)
|
||||
{
|
||||
struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
|
||||
|
||||
@ -269,25 +378,20 @@ static void ddr3_init(u32 base, const struct emif_regs *regs)
|
||||
|
||||
writel(regs->read_idle_ctrl, &emif->emif_read_idlectrl);
|
||||
|
||||
/*
|
||||
* The same sequence should work on OMAP5432 as well. But strange that
|
||||
* it is not working
|
||||
*/
|
||||
if (is_dra7xx()) {
|
||||
do_ext_phy_settings(base, regs);
|
||||
writel(regs->ref_ctrl_final, &emif->emif_sdram_ref_ctrl);
|
||||
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);
|
||||
}
|
||||
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);
|
||||
omap5_ddr3_leveling(base, regs);
|
||||
}
|
||||
|
||||
ddr3_leveling(base, regs);
|
||||
static void ddr3_init(u32 base, const struct emif_regs *regs)
|
||||
{
|
||||
if (is_omap54xx())
|
||||
omap5_ddr3_init(base, regs);
|
||||
else
|
||||
dra7_ddr3_init(base, regs);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS
|
||||
@ -1075,7 +1179,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);
|
||||
ddr3_leveling(base, regs);
|
||||
omap5_ddr3_leveling(base, regs);
|
||||
}
|
||||
|
||||
/* Write to the shadow registers */
|
||||
|
@ -421,8 +421,14 @@ const u32 ddr3_ext_phy_ctrl_const_base_es2[] = {
|
||||
0x0
|
||||
};
|
||||
|
||||
/* Ext phy ctrl 1-35 regs */
|
||||
const u32
|
||||
dra_ddr3_ext_phy_ctrl_const_base_es1_emif1[] = {
|
||||
0x10040100,
|
||||
0x00910091,
|
||||
0x00950095,
|
||||
0x009B009B,
|
||||
0x009E009E,
|
||||
0x00980098,
|
||||
0x00340034,
|
||||
0x00350035,
|
||||
@ -441,7 +447,7 @@ dra_ddr3_ext_phy_ctrl_const_base_es1_emif1[] = {
|
||||
0x00500050,
|
||||
0x00000000,
|
||||
0x00600020,
|
||||
0x40010080,
|
||||
0x40011080,
|
||||
0x08102040,
|
||||
0x0,
|
||||
0x0,
|
||||
@ -450,8 +456,14 @@ dra_ddr3_ext_phy_ctrl_const_base_es1_emif1[] = {
|
||||
0x0
|
||||
};
|
||||
|
||||
/* Ext phy ctrl 1-35 regs */
|
||||
const u32
|
||||
dra_ddr3_ext_phy_ctrl_const_base_es1_emif2[] = {
|
||||
0x10040100,
|
||||
0x00910091,
|
||||
0x00950095,
|
||||
0x009B009B,
|
||||
0x009E009E,
|
||||
0x00980098,
|
||||
0x00330033,
|
||||
0x00330033,
|
||||
@ -470,7 +482,7 @@ dra_ddr3_ext_phy_ctrl_const_base_es1_emif2[] = {
|
||||
0x00500050,
|
||||
0x00000000,
|
||||
0x00600020,
|
||||
0x40010080,
|
||||
0x40011080,
|
||||
0x08102040,
|
||||
0x0,
|
||||
0x0,
|
||||
@ -479,8 +491,14 @@ dra_ddr3_ext_phy_ctrl_const_base_es1_emif2[] = {
|
||||
0x0
|
||||
};
|
||||
|
||||
/* Ext phy ctrl 1-35 regs */
|
||||
const u32
|
||||
dra_ddr3_ext_phy_ctrl_const_base_666MHz[] = {
|
||||
0x10040100,
|
||||
0x00A400A4,
|
||||
0x00A900A9,
|
||||
0x00B000B0,
|
||||
0x00B000B0,
|
||||
0x00A400A4,
|
||||
0x00390039,
|
||||
0x00320032,
|
||||
@ -562,7 +580,7 @@ void get_lpddr2_mr_regs(const struct lpddr2_mr_regs **regs)
|
||||
*regs = &mr_regs;
|
||||
}
|
||||
|
||||
void do_ext_phy_settings(u32 base, const struct emif_regs *regs)
|
||||
static void do_ext_phy_settings_omap5(u32 base, const struct emif_regs *regs)
|
||||
{
|
||||
u32 *ext_phy_ctrl_base = 0;
|
||||
u32 *emif_ext_phy_ctrl_base = 0;
|
||||
@ -601,6 +619,58 @@ void do_ext_phy_settings(u32 base, const struct emif_regs *regs)
|
||||
}
|
||||
}
|
||||
|
||||
static void do_ext_phy_settings_dra7(u32 base, const struct emif_regs *regs)
|
||||
{
|
||||
struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
|
||||
u32 *emif_ext_phy_ctrl_base = 0;
|
||||
u32 emif_nr;
|
||||
const u32 *ext_phy_ctrl_const_regs;
|
||||
u32 i, hw_leveling, size;
|
||||
|
||||
emif_nr = (base == EMIF1_BASE) ? 1 : 2;
|
||||
|
||||
hw_leveling = regs->emif_rd_wr_lvl_rmp_ctl >> EMIF_REG_RDWRLVL_EN_SHIFT;
|
||||
|
||||
emif_ext_phy_ctrl_base = (u32 *)&(emif->emif_ddr_ext_phy_ctrl_1);
|
||||
|
||||
emif_get_ext_phy_ctrl_const_regs(emif_nr,
|
||||
&ext_phy_ctrl_const_regs, &size);
|
||||
|
||||
writel(ext_phy_ctrl_const_regs[0], &emif_ext_phy_ctrl_base[0]);
|
||||
writel(ext_phy_ctrl_const_regs[0], &emif_ext_phy_ctrl_base[1]);
|
||||
|
||||
if (!hw_leveling) {
|
||||
/*
|
||||
* Copy the predefined PHY register values
|
||||
* in case of sw leveling
|
||||
*/
|
||||
for (i = 1; i < 25; i++) {
|
||||
writel(ext_phy_ctrl_const_regs[i],
|
||||
&emif_ext_phy_ctrl_base[i * 2]);
|
||||
writel(ext_phy_ctrl_const_regs[i],
|
||||
&emif_ext_phy_ctrl_base[i * 2 + 1]);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Write the init value for HW levling to occur
|
||||
*/
|
||||
for (i = 21; i < 35; i++) {
|
||||
writel(ext_phy_ctrl_const_regs[i],
|
||||
&emif_ext_phy_ctrl_base[i * 2]);
|
||||
writel(ext_phy_ctrl_const_regs[i],
|
||||
&emif_ext_phy_ctrl_base[i * 2 + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void do_ext_phy_settings(u32 base, const struct emif_regs *regs)
|
||||
{
|
||||
if (is_omap54xx())
|
||||
do_ext_phy_settings_omap5(base, regs);
|
||||
else
|
||||
do_ext_phy_settings_dra7(base, regs);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS
|
||||
static const struct lpddr2_ac_timings timings_jedec_532_mhz = {
|
||||
.max_freq = 532000000,
|
||||
|
@ -44,6 +44,8 @@
|
||||
#define EMIF_REG_DUAL_CLK_MODE_MASK (1 << 30)
|
||||
#define EMIF_REG_FAST_INIT_SHIFT 29
|
||||
#define EMIF_REG_FAST_INIT_MASK (1 << 29)
|
||||
#define EMIF_REG_LEVLING_TO_SHIFT 4
|
||||
#define EMIF_REG_LEVELING_TO_MASK (7 << 4)
|
||||
#define EMIF_REG_PHY_DLL_READY_SHIFT 2
|
||||
#define EMIF_REG_PHY_DLL_READY_MASK (1 << 2)
|
||||
|
||||
@ -509,6 +511,13 @@
|
||||
#define EMIF_REG_RDWRLVLINC_RMP_WIN_SHIFT 0
|
||||
#define EMIF_REG_RDWRLVLINC_RMP_WIN_MASK (0x1FFF << 0)
|
||||
|
||||
/* EMIF_PHY_CTRL_36 */
|
||||
#define EMIF_REG_PHY_FIFO_WE_IN_MISALINED_CLR (1 << 8)
|
||||
|
||||
#define PHY_RDDQS_RATIO_REGS 5
|
||||
#define PHY_FIFO_WE_SLAVE_RATIO_REGS 5
|
||||
#define PHY_REG_WR_DQ_SLAVE_RATIO_REGS 10
|
||||
|
||||
/*Leveling Fields */
|
||||
#define DDR3_WR_LVL_INT 0x73
|
||||
#define DDR3_RD_LVL_INT 0x33
|
||||
|
@ -68,7 +68,13 @@ static const struct emif_regs beagle_x15_emif1_ddr3_532mhz_emif_regs = {
|
||||
.emif_rd_wr_exec_thresh = 0x00000305
|
||||
};
|
||||
|
||||
/* Ext phy ctrl regs 1-35 */
|
||||
static const u32 beagle_x15_emif1_ddr3_ext_phy_ctrl_const_regs[] = {
|
||||
0x10040100,
|
||||
0x00740074,
|
||||
0x00780078,
|
||||
0x007c007c,
|
||||
0x007b007b,
|
||||
0x00800080,
|
||||
0x00360036,
|
||||
0x00340034,
|
||||
@ -90,7 +96,7 @@ static const u32 beagle_x15_emif1_ddr3_ext_phy_ctrl_const_regs[] = {
|
||||
|
||||
0x00000000,
|
||||
0x00600020,
|
||||
0x40010080,
|
||||
0x40011080,
|
||||
0x08102040,
|
||||
|
||||
0x00400040,
|
||||
@ -126,6 +132,11 @@ static const struct emif_regs beagle_x15_emif2_ddr3_532mhz_emif_regs = {
|
||||
};
|
||||
|
||||
static const u32 beagle_x15_emif2_ddr3_ext_phy_ctrl_const_regs[] = {
|
||||
0x10040100,
|
||||
0x00820082,
|
||||
0x008b008b,
|
||||
0x00800080,
|
||||
0x007e007e,
|
||||
0x00800080,
|
||||
0x00370037,
|
||||
0x00390039,
|
||||
@ -145,7 +156,7 @@ static const u32 beagle_x15_emif2_ddr3_ext_phy_ctrl_const_regs[] = {
|
||||
|
||||
0x00000000,
|
||||
0x00600020,
|
||||
0x40010080,
|
||||
0x40011080,
|
||||
0x08102040,
|
||||
|
||||
0x00400040,
|
||||
|
Loading…
Reference in New Issue
Block a user