am33xx: Re-enable SW levelling for DDR2
authorTom Rini <trini@ti.com>
Fri, 5 Jun 2015 10:21:11 +0000 (15:51 +0530)
committerTom Rini <trini@konsulko.com>
Mon, 15 Jun 2015 14:57:26 +0000 (10:57 -0400)
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>
arch/arm/cpu/armv7/am33xx/ddr.c
arch/arm/cpu/armv7/am33xx/emif4.c
arch/arm/cpu/armv7/omap-common/clocks-common.c
arch/arm/cpu/armv7/omap-common/emif-common.c
arch/arm/cpu/armv7/omap5/hwinit.c
arch/arm/include/asm/emif.h
board/ti/am43xx/board.c

index f5b16b4b722605729997892d41007580690ddb58..b3fb0c47ab2dfba7d393c4a3b9d5717031b030af 100644 (file)
@@ -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);
        }
@@ -182,10 +185,50 @@ void set_sdram_timings(const struct emif_regs *regs, int nr)
        writel(regs->sdram_tim3, &emif_reg[nr]->emif_sdram_tim_3_shdw);
 }
 
+/*
+ * 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);
+       }
 }
 
 /**
index 9cf816c89a627b32230f5b03d00c2e5ba3b01069..27fa3fb4628bbfa08ff38a29386d09144e799668 100644 (file)
@@ -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 */
index fa04bbedf9ea780841f7b96fc37d79f2351581ee..c94a807819310fb2a3b00e7a79d45ce3074a3eb0 100644 (file)
@@ -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
index 3ee4695ea31755486be60441c00417e676fbfccb..ca22c0060182d776c3240e7632b0e4544e9697b2 100644 (file)
@@ -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");
 
index 222540f9c1f189b7fdaeed0a69764f1ee2d6201e..39f8d0d5e20013d7a269e29682db436fbc18f8af 100644 (file)
@@ -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();
index a97d2fd4eade83e3bdcccb9ffa81d2841d55adf7..7986e6e7949094d23995977f87f78c29435cf466 100644 (file)
@@ -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
index 4aae2306086bda50724e227543857d9837768648..d7b9e5af88fc8ed6bf3a2f1a1d8d4a48cf12db87 100644 (file)
@@ -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