]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - arch/arm/cpu/armv7/am33xx/ddr.c
am33xx: Re-enable SW levelling for DDR2
[karo-tx-uboot.git] / arch / arm / cpu / armv7 / am33xx / ddr.c
index 906cdb0d43695389dace4bf8be9734424c00ab09..311104be43d16e4541afbad5aa17785237fe0b2a 100644 (file)
@@ -126,30 +126,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);
        }
@@ -185,10 +188,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
@@ -259,8 +302,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);
+       }
 }
 
 /**