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:
Lokesh Vutla 2015-06-03 14:43:21 +05:30 committed by Tom Rini
parent 9d01b7872e
commit 6213db78f4
4 changed files with 220 additions and 26 deletions

View File

@ -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 */

View File

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

View File

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

View File

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