diff options
-rw-r--r-- | arch/arm/cpu/armv7/am33xx/ddr.c | 101 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/am33xx/emif4.c | 5 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/omap-common/clocks-common.c | 4 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/omap-common/emif-common.c | 9 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/omap5/hwinit.c | 3 | ||||
-rw-r--r-- | arch/arm/include/asm/emif.h | 9 | ||||
-rw-r--r-- | board/ti/am43xx/board.c | 33 |
7 files changed, 124 insertions, 40 deletions
diff --git a/arch/arm/cpu/armv7/am33xx/ddr.c b/arch/arm/cpu/armv7/am33xx/ddr.c index f5b16b4b72..b3fb0c47ab 100644 --- a/arch/arm/cpu/armv7/am33xx/ddr.c +++ b/arch/arm/cpu/armv7/am33xx/ddr.c @@ -123,30 +123,33 @@ void config_sdram_emif4d5(const struct emif_regs *regs, int nr) writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl); writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl_shdw); - /* Perform hardware leveling. */ - udelay(1000); - writel(readl(&emif_reg[nr]->emif_ddr_ext_phy_ctrl_36) | - 0x100, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36); - writel(readl(&emif_reg[nr]->emif_ddr_ext_phy_ctrl_36_shdw) | - 0x100, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36_shdw); - - writel(0x80000000, &emif_reg[nr]->emif_rd_wr_lvl_rmp_ctl); - - /* Enable read leveling */ - writel(0x80000000, &emif_reg[nr]->emif_rd_wr_lvl_ctl); - - /* - * Enable full read and write leveling. Wait for read and write - * leveling bit to clear RDWRLVLFULL_START bit 31 - */ - while((readl(&emif_reg[nr]->emif_rd_wr_lvl_ctl) & 0x80000000) != 0) - ; - - /* Check the timeout register to see if leveling is complete */ - if((readl(&emif_reg[nr]->emif_status) & 0x70) != 0) - puts("DDR3 H/W leveling incomplete with errors\n"); - - if (emif_sdram_type() == EMIF_SDRAM_TYPE_LPDDR2) { + /* Perform hardware leveling for DDR3 */ + if (emif_sdram_type(regs->sdram_config) == EMIF_SDRAM_TYPE_DDR3) { + udelay(1000); + writel(readl(&emif_reg[nr]->emif_ddr_ext_phy_ctrl_36) | + 0x100, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36); + writel(readl(&emif_reg[nr]->emif_ddr_ext_phy_ctrl_36_shdw) | + 0x100, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36_shdw); + + writel(0x80000000, &emif_reg[nr]->emif_rd_wr_lvl_rmp_ctl); + + /* Enable read leveling */ + writel(0x80000000, &emif_reg[nr]->emif_rd_wr_lvl_ctl); + + /* + * Enable full read and write leveling. Wait for read and write + * leveling bit to clear RDWRLVLFULL_START bit 31 + */ + while ((readl(&emif_reg[nr]->emif_rd_wr_lvl_ctl) & 0x80000000) + != 0) + ; + + /* Check the timeout register to see if leveling is complete */ + if ((readl(&emif_reg[nr]->emif_status) & 0x70) != 0) + puts("DDR3 H/W leveling incomplete with errors\n"); + + } else { + /* DDR2 */ configure_mr(nr, 0); configure_mr(nr, 1); } @@ -183,9 +186,49 @@ void set_sdram_timings(const struct emif_regs *regs, int nr) } /* + * Configure EXT PHY registers for software leveling + */ +static void ext_phy_settings_swlvl(const struct emif_regs *regs, int nr) +{ + u32 *ext_phy_ctrl_base = 0; + u32 *emif_ext_phy_ctrl_base = 0; + __maybe_unused const u32 *ext_phy_ctrl_const_regs; + u32 i = 0; + __maybe_unused u32 size; + + ext_phy_ctrl_base = (u32 *)&(regs->emif_ddr_ext_phy_ctrl_1); + emif_ext_phy_ctrl_base = + (u32 *)&(emif_reg[nr]->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++); + } + +#ifdef CONFIG_AM43XX + /* + * External phy 6-24 registers do not change with ddr frequency. + * These only need to be set on DDR2 on AM43xx. + */ + emif_get_ext_phy_ctrl_const_regs(&ext_phy_ctrl_const_regs, &size); + + if (!size) + return; + + for (i = 0; i < size; i++) { + writel(ext_phy_ctrl_const_regs[i], emif_ext_phy_ctrl_base++); + /* Update shadow registers */ + writel(ext_phy_ctrl_const_regs[i], emif_ext_phy_ctrl_base++); + } +#endif +} + +/* * Configure EXT PHY registers for hardware leveling */ -static void ext_phy_settings(const struct emif_regs *regs, int nr) +static void ext_phy_settings_hwlvl(const struct emif_regs *regs, int nr) { /* * Enable hardware leveling on the EMIF. For details about these @@ -256,8 +299,12 @@ void config_ddr_phy(const struct emif_regs *regs, int nr) writel(regs->emif_ddr_phy_ctlr_1, &emif_reg[nr]->emif_ddr_phy_ctrl_1_shdw); - if (get_emif_rev((u32)emif_reg[nr]) == EMIF_4D5) - ext_phy_settings(regs, nr); + if (get_emif_rev((u32)emif_reg[nr]) == EMIF_4D5) { + if (emif_sdram_type(regs->sdram_config) == EMIF_SDRAM_TYPE_DDR3) + ext_phy_settings_hwlvl(regs, nr); + else + ext_phy_settings_swlvl(regs, nr); + } } /** diff --git a/arch/arm/cpu/armv7/am33xx/emif4.c b/arch/arm/cpu/armv7/am33xx/emif4.c index 9cf816c89a..27fa3fb462 100644 --- a/arch/arm/cpu/armv7/am33xx/emif4.c +++ b/arch/arm/cpu/armv7/am33xx/emif4.c @@ -124,8 +124,9 @@ void config_ddr(unsigned int pll, const struct ctrl_ioregs *ioregs, /* Set CKE to be controlled by EMIF/DDR PHY */ writel(DDR_CKE_CTRL_NORMAL, &ddrctrl->ddrckectrl); - /* Allow EMIF to control DDR_RESET */ - writel(0x00000000, &ddrctrl->ddrioctrl); + if (emif_sdram_type(regs->sdram_config) == EMIF_SDRAM_TYPE_DDR3) + /* Allow EMIF to control DDR_RESET */ + writel(0x00000000, &ddrctrl->ddrioctrl); #endif /* Program EMIF instance */ diff --git a/arch/arm/cpu/armv7/omap-common/clocks-common.c b/arch/arm/cpu/armv7/omap-common/clocks-common.c index fa04bbedf9..c94a807819 100644 --- a/arch/arm/cpu/armv7/omap-common/clocks-common.c +++ b/arch/arm/cpu/armv7/omap-common/clocks-common.c @@ -372,6 +372,7 @@ static void setup_dplls(void) { u32 temp; const struct dpll_params *params; + struct emif_reg_struct *emif = (struct emif_reg_struct *)EMIF1_BASE; debug("setup_dplls\n"); @@ -382,7 +383,8 @@ static void setup_dplls(void) * Core DPLL will be locked after setting up EMIF * using the FREQ_UPDATE method(freq_update_core()) */ - if (emif_sdram_type() == EMIF_SDRAM_TYPE_LPDDR2) + if (emif_sdram_type(readl(&emif->emif_sdram_config)) == + EMIF_SDRAM_TYPE_LPDDR2) do_setup_dpll((*prcm)->cm_clkmode_dpll_core, params, DPLL_NO_LOCK, "core"); else diff --git a/arch/arm/cpu/armv7/omap-common/emif-common.c b/arch/arm/cpu/armv7/omap-common/emif-common.c index 3ee4695ea3..ca22c00601 100644 --- a/arch/arm/cpu/armv7/omap-common/emif-common.c +++ b/arch/arm/cpu/armv7/omap-common/emif-common.c @@ -1171,12 +1171,14 @@ static void do_sdram_init(u32 base) * OPP to another) */ if (!(in_sdram || warm_reset())) { - if (emif_sdram_type() == EMIF_SDRAM_TYPE_LPDDR2) + if (emif_sdram_type(regs->sdram_config) == + EMIF_SDRAM_TYPE_LPDDR2) lpddr2_init(base, regs); else ddr3_init(base, regs); } - if (warm_reset() && (emif_sdram_type() == EMIF_SDRAM_TYPE_DDR3)) { + if (warm_reset() && (emif_sdram_type(regs->sdram_config) == + EMIF_SDRAM_TYPE_DDR3)) { set_lpmode_selfrefresh(base); emif_reset_phy(base); omap5_ddr3_leveling(base, regs); @@ -1398,7 +1400,8 @@ static void do_bug0039_workaround(u32 base) void sdram_init(void) { u32 in_sdram, size_prog, size_detect; - u32 sdram_type = emif_sdram_type(); + struct emif_reg_struct *emif = (struct emif_reg_struct *)EMIF1_BASE; + u32 sdram_type = emif_sdram_type(emif->emif_sdram_config); debug(">>sdram_init()\n"); diff --git a/arch/arm/cpu/armv7/omap5/hwinit.c b/arch/arm/cpu/armv7/omap5/hwinit.c index 222540f9c1..39f8d0d5e2 100644 --- a/arch/arm/cpu/armv7/omap5/hwinit.c +++ b/arch/arm/cpu/armv7/omap5/hwinit.c @@ -122,6 +122,7 @@ static void io_settings_ddr3(void) void do_io_settings(void) { u32 io_settings = 0, mask = 0; + struct emif_reg_struct *emif = (struct emif_reg_struct *)EMIF1_BASE; /* Impedance settings EMMC, C2C 1,2, hsi2 */ mask = (ds_mask << 2) | (ds_mask << 8) | @@ -177,7 +178,7 @@ void do_io_settings(void) (sc_fast << 17) | (sc_fast << 14); writel(io_settings, (*ctrl)->control_smart3io_padconf_1); - if (emif_sdram_type() == EMIF_SDRAM_TYPE_LPDDR2) + if (emif_sdram_type(emif->emif_sdram_config) == EMIF_SDRAM_TYPE_LPDDR2) io_settings_lpddr2(); else io_settings_ddr3(); diff --git a/arch/arm/include/asm/emif.h b/arch/arm/include/asm/emif.h index a97d2fd4ea..7986e6e794 100644 --- a/arch/arm/include/asm/emif.h +++ b/arch/arm/include/asm/emif.h @@ -1209,12 +1209,10 @@ static inline u32 get_emif_rev(u32 base) * which is typically the case. So it is sufficient to get * SDRAM type from EMIF1. */ -static inline u32 emif_sdram_type(void) +static inline u32 emif_sdram_type(u32 sdram_config) { - struct emif_reg_struct *emif = (struct emif_reg_struct *)EMIF1_BASE; - - return (readl(&emif->emif_sdram_config) & - EMIF_REG_SDRAM_TYPE_MASK) >> EMIF_REG_SDRAM_TYPE_SHIFT; + return (sdram_config & EMIF_REG_SDRAM_TYPE_MASK) + >> EMIF_REG_SDRAM_TYPE_SHIFT; } /* assert macros */ @@ -1244,6 +1242,5 @@ extern u32 *const T_den; #endif void config_data_eye_leveling_samples(u32 emif_base); -u32 emif_sdram_type(void); const struct read_write_regs *get_bug_regs(u32 *iterations); #endif diff --git a/board/ti/am43xx/board.c b/board/ti/am43xx/board.c index 4aae230608..d7b9e5af88 100644 --- a/board/ti/am43xx/board.c +++ b/board/ti/am43xx/board.c @@ -148,6 +148,29 @@ static const struct dpll_params idk_dpll_ddr = { 400, 23, 1, -1, 2, -1, -1 }; +static const u32 ext_phy_ctrl_const_base_lpddr2[] = { + 0x00500050, + 0x00350035, + 0x00350035, + 0x00350035, + 0x00350035, + 0x00350035, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x40001000, + 0x08102040 +}; + const struct ctrl_ioregs ioregs_lpddr2 = { .cm0ioctl = LPDDR2_ADDRCTRL_IOCTRL_VALUE, .cm1ioctl = LPDDR2_ADDRCTRL_WD0_IOCTRL_VALUE, @@ -318,6 +341,16 @@ static const struct emif_regs ddr3_idk_emif_regs_400Mhz = { .emif_cos_config = 0x00ffffff }; +void emif_get_ext_phy_ctrl_const_regs(const u32 **regs, u32 *size) +{ + if (board_is_eposevm()) { + *regs = ext_phy_ctrl_const_base_lpddr2; + *size = ARRAY_SIZE(ext_phy_ctrl_const_base_lpddr2); + } + + return; +} + /* * get_sys_clk_index : returns the index of the sys_clk read from * ctrl status register. This value is either |