diff options
| -rw-r--r-- | arch/arm/cpu/armv7/omap-common/emif-common.c | 105 | ||||
| -rw-r--r-- | arch/arm/cpu/armv7/omap4/hwinit.c | 5 | ||||
| -rw-r--r-- | arch/arm/cpu/armv7/omap5/hwinit.c | 15 | ||||
| -rw-r--r-- | arch/arm/include/asm/emif.h | 45 | 
4 files changed, 166 insertions, 4 deletions
| diff --git a/arch/arm/cpu/armv7/omap-common/emif-common.c b/arch/arm/cpu/armv7/omap-common/emif-common.c index 389feda71..846511d03 100644 --- a/arch/arm/cpu/armv7/omap-common/emif-common.c +++ b/arch/arm/cpu/armv7/omap-common/emif-common.c @@ -190,7 +190,7 @@ void emif_update_timings(u32 base, const struct emif_regs *regs)  	writel(regs->temp_alert_config, &emif->emif_temp_alert_config);  	writel(regs->emif_ddr_phy_ctlr_1, &emif->emif_ddr_phy_ctrl_1_shdw); -	if (omap_revision() == OMAP5430_ES1_0) { +	if (omap_revision() >= OMAP5430_ES1_0) {  		writel(EMIF_L3_CONFIG_VAL_SYS_10_MPU_5_LL_0,  			&emif->emif_l3_config);  	} else if (omap_revision() >= OMAP4460_ES1_0) { @@ -202,6 +202,101 @@ void emif_update_timings(u32 base, const struct emif_regs *regs)  	}  } +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); + +	/* 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); +} + +static void ddr3_init(u32 base, const struct emif_regs *regs) +{ +	struct emif_reg_struct *emif = (struct emif_reg_struct *)base; +	u32 *ext_phy_ctrl_base = 0; +	u32 *emif_ext_phy_ctrl_base = 0; +	u32 i = 0; + +	/* +	 * Set SDRAM_CONFIG and PHY control registers to locked frequency +	 * and RL =7. As the default values of the Mode Registers are not +	 * defined, contents of mode Registers must be fully initialized. +	 * H/W takes care of this initialization +	 */ +	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 */ +	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(regs->ref_ctrl, &emif->emif_sdram_ref_ctrl); +	writel(regs->read_idle_ctrl, &emif->emif_read_idlectrl); + +	ext_phy_ctrl_base = (u32 *) &(regs->emif_ddr_ext_phy_ctrl_1); +	emif_ext_phy_ctrl_base = (u32 *) &(emif->emif_ddr_ext_phy_ctrl_1); + +	/* Configure external phy control timing registers */ +	for (i = 0; i < EMIF_EXT_PHY_CTRL_TIMING_REG; i++) { +		writel(*ext_phy_ctrl_base, emif_ext_phy_ctrl_base++); +		/* Update shadow registers */ +		writel(*ext_phy_ctrl_base++, emif_ext_phy_ctrl_base++); +	} + +	/* +	 * external phy 6-24 registers do not change with +	 * ddr frequency +	 */ +	for (i = 0; i < EMIF_EXT_PHY_CTRL_CONST_REG; i++) { +		writel(ddr3_ext_phy_ctrl_const_base[i], +					emif_ext_phy_ctrl_base++); +		/* Update shadow registers */ +		writel(ddr3_ext_phy_ctrl_const_base[i], +					emif_ext_phy_ctrl_base++); +	} + +	/* enable leveling */ +	writel(regs->emif_rd_wr_lvl_rmp_ctl, &emif->emif_rd_wr_lvl_rmp_ctl); + +	ddr3_leveling(base, regs); +} +  #ifndef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS  #define print_timing_reg(reg) debug(#reg" - 0x%08x\n", (reg)) @@ -975,8 +1070,12 @@ static void do_sdram_init(u32 base)  	 * Changing the timing registers in EMIF can happen(going from one  	 * OPP to another)  	 */ -	if (!in_sdram) -		lpddr2_init(base, regs); +	if (!in_sdram) { +		if (omap_revision() != OMAP5432_ES1_0) +			lpddr2_init(base, regs); +		else +			ddr3_init(base, regs); +	}  	/* Write to the shadow registers */  	emif_update_timings(base, regs); diff --git a/arch/arm/cpu/armv7/omap4/hwinit.c b/arch/arm/cpu/armv7/omap4/hwinit.c index 187e93887..2c34e48f4 100644 --- a/arch/arm/cpu/armv7/omap4/hwinit.c +++ b/arch/arm/cpu/armv7/omap4/hwinit.c @@ -118,6 +118,11 @@ void do_io_settings(void)  }  #endif +/* dummy fuction for omap4 */ +void config_data_eye_leveling_samples(u32 emif_base) +{ +} +  void init_omap_revision(void)  {  	/* diff --git a/arch/arm/cpu/armv7/omap5/hwinit.c b/arch/arm/cpu/armv7/omap5/hwinit.c index df0b76050..d0c3ff702 100644 --- a/arch/arm/cpu/armv7/omap5/hwinit.c +++ b/arch/arm/cpu/armv7/omap5/hwinit.c @@ -35,6 +35,7 @@  #include <asm/sizes.h>  #include <asm/utils.h>  #include <asm/arch/gpio.h> +#include <asm/emif.h>  DECLARE_GLOBAL_DATA_PTR; @@ -203,6 +204,20 @@ void do_io_settings(void)  }  #endif +void config_data_eye_leveling_samples(u32 emif_base) +{ +	struct omap_sys_ctrl_regs *ioregs_base = +		(struct omap_sys_ctrl_regs *) SYSCTRL_GENERAL_CORE_BASE; + +	/*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, +			&(ioregs_base->control_emif1_sdram_config_ext)); +	else if (emif_base == EMIF2_BASE) +		writel(SDRAM_CONFIG_EXT_RD_LVL_4_SAMPLES, +			&(ioregs_base->control_emif2_sdram_config_ext)); +} +  void init_omap_revision(void)  {  	/* diff --git a/arch/arm/include/asm/emif.h b/arch/arm/include/asm/emif.h index 5d2649e12..c2ad877ab 100644 --- a/arch/arm/include/asm/emif.h +++ b/arch/arm/include/asm/emif.h @@ -471,6 +471,49 @@  #define EMIF_REG_DDR_PHY_CTRL_2_SHIFT		0  #define EMIF_REG_DDR_PHY_CTRL_2_MASK		(0xffffffff << 0) +/*EMIF_READ_WRITE_LEVELING_CONTROL*/ +#define EMIF_REG_RDWRLVLFULL_START_SHIFT	31 +#define EMIF_REG_RDWRLVLFULL_START_MASK		(1 << 31) +#define EMIF_REG_RDWRLVLINC_PRE_SHIFT		24 +#define EMIF_REG_RDWRLVLINC_PRE_MASK		(0x7F << 24) +#define EMIF_REG_RDLVLINC_INT_SHIFT		16 +#define EMIF_REG_RDLVLINC_INT_MASK		(0xFF << 16) +#define EMIF_REG_RDLVLGATEINC_INT_SHIFT		8 +#define EMIF_REG_RDLVLGATEINC_INT_MASK		(0xFF << 8) +#define EMIF_REG_WRLVLINC_INT_SHIFT		0 +#define EMIF_REG_WRLVLINC_INT_MASK		(0xFF << 0) + +/*EMIF_READ_WRITE_LEVELING_RAMP_CONTROL*/ +#define EMIF_REG_RDWRLVL_EN_SHIFT		31 +#define EMIF_REG_RDWRLVL_EN_MASK		(1 << 31) +#define EMIF_REG_RDWRLVLINC_RMP_PRE_SHIFT	24 +#define EMIF_REG_RDWRLVLINC_RMP_PRE_MASK	(0x7F << 24) +#define EMIF_REG_RDLVLINC_RMP_INT_SHIFT		16 +#define EMIF_REG_RDLVLINC_RMP_INT_MASK		(0xFF << 16) +#define EMIF_REG_RDLVLGATEINC_RMP_INT_SHIFT	8 +#define EMIF_REG_RDLVLGATEINC_RMP_INT_MASK	(0xFF << 8) +#define EMIF_REG_WRLVLINC_RMP_INT_SHIFT		0 +#define EMIF_REG_WRLVLINC_RMP_INT_MASK		(0xFF << 0) + +/*EMIF_READ_WRITE_LEVELING_RAMP_WINDOW*/ +#define EMIF_REG_RDWRLVLINC_RMP_WIN_SHIFT	0 +#define EMIF_REG_RDWRLVLINC_RMP_WIN_MASK	(0x1FFF << 0) + +/*Leveling Fields */ +#define DDR3_WR_LVL_INT		0x73 +#define DDR3_RD_LVL_INT		0x33 +#define DDR3_RD_LVL_GATE_INT	0x59 +#define RD_RW_LVL_INC_PRE	0x0 +#define DDR3_FULL_LVL		(1 << EMIF_REG_RDWRLVL_EN_SHIFT) + +#define DDR3_INC_LVL	((DDR3_WR_LVL_INT << EMIF_REG_WRLVLINC_INT_SHIFT)   \ +		| (DDR3_RD_LVL_GATE_INT << EMIF_REG_RDLVLGATEINC_INT_SHIFT) \ +		| (DDR3_RD_LVL_INT << EMIF_REG_RDLVLINC_RMP_INT_SHIFT)      \ +		| (RD_RW_LVL_INC_PRE << EMIF_REG_RDWRLVLINC_RMP_PRE_SHIFT)) + +#define SDRAM_CONFIG_EXT_RD_LVL_11_SAMPLES	0x0000C1A7 +#define SDRAM_CONFIG_EXT_RD_LVL_4_SAMPLES	0x000001A7 +  /* DMM */  #define DMM_BASE			0x4E000040 @@ -1104,5 +1147,5 @@ extern u32 *const T_den;  extern u32 *const emif_sizes;  #endif - +void config_data_eye_leveling_samples(u32 emif_base);  #endif |