diff options
author | Tom Rini <trini@ti.com> | 2015-06-05 10:21:11 (GMT) |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2015-06-15 14:57:26 (GMT) |
commit | 7c352cd38d0ad7a25f98592182704667dfde37a8 (patch) | |
tree | ab155ec66d04a7a7e7096cb41fdf1eeaa1d200bb /arch/arm/cpu/armv7/am33xx | |
parent | 37be54fd1351a177c061c2c351ffdd53efaebb59 (diff) | |
download | u-boot-7c352cd38d0ad7a25f98592182704667dfde37a8.tar.xz |
am33xx: Re-enable SW levelling for DDR2
The recent changes for hw leveling on am33xx were not intended for
DDR2 boards, only DDR3. Update emif_sdram_type to take a sdram_config
value to check against. This lets us pass in the value we would use to
configure, when we have not yet configured the board yet. In other cases
update the call to be as functional as before and check an already
programmed value in.
Tested-by: Yan Liu <yan-liu@ti.com>
Signed-off-by: Tom Rini <trini@ti.com>
Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
Diffstat (limited to 'arch/arm/cpu/armv7/am33xx')
-rw-r--r-- | arch/arm/cpu/armv7/am33xx/ddr.c | 101 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/am33xx/emif4.c | 5 |
2 files changed, 77 insertions, 29 deletions
diff --git a/arch/arm/cpu/armv7/am33xx/ddr.c b/arch/arm/cpu/armv7/am33xx/ddr.c index f5b16b4..b3fb0c4 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 9cf816c..27fa3fb 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 */ |