Merge remote-tracking branch 'u-boot-sh/rmobile'
[oweals/u-boot.git] / drivers / ddr / fsl / mpc85xx_ddr_gen3.c
index c8050864163a30a0c6e25380c22fe405dbf3b141..4d5572ef21b65b0d68c3524bc8f48038b0a261cc 100644 (file)
@@ -15,6 +15,7 @@
 #error Invalid setting for CONFIG_CHIP_SELECTS_PER_CTRL
 #endif
 
+DECLARE_GLOBAL_DATA_PTR;
 
 /*
  * regs has the to-be-set values for DDR controller registers
@@ -43,6 +44,16 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
        u32 save1, save2;
 #endif
 
+#ifdef CONFIG_DEEP_SLEEP
+       const ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+       bool sleep_flag = 0;
+#endif
+
+#ifdef CONFIG_DEEP_SLEEP
+       if (in_be32(&gur->scrtsr[0]) & (1 << 3))
+               sleep_flag = 1;
+#endif
+
        switch (ctrl_num) {
        case 0:
                ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
@@ -119,7 +130,13 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
        out_be32(&ddr->timing_cfg_0, regs->timing_cfg_0);
        out_be32(&ddr->timing_cfg_1, regs->timing_cfg_1);
        out_be32(&ddr->timing_cfg_2, regs->timing_cfg_2);
-       out_be32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2);
+#ifdef CONFIG_DEEP_SLEEP
+       if (sleep_flag)
+               out_be32(&ddr->sdram_cfg_2,
+                        regs->ddr_sdram_cfg_2 & ~SDRAM_CFG2_D_INIT);
+       else
+#endif
+               out_be32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2);
        out_be32(&ddr->sdram_mode, regs->ddr_sdram_mode);
        out_be32(&ddr->sdram_mode_2, regs->ddr_sdram_mode_2);
        out_be32(&ddr->sdram_mode_3, regs->ddr_sdram_mode_3);
@@ -132,8 +149,16 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
        out_be32(&ddr->sdram_interval, regs->ddr_sdram_interval);
        out_be32(&ddr->sdram_data_init, regs->ddr_data_init);
        out_be32(&ddr->sdram_clk_cntl, regs->ddr_sdram_clk_cntl);
-       out_be32(&ddr->init_addr, regs->ddr_init_addr);
-       out_be32(&ddr->init_ext_addr, regs->ddr_init_ext_addr);
+#ifdef CONFIG_DEEP_SLEEP
+       if (sleep_flag) {
+               out_be32(&ddr->init_addr, 0);
+               out_be32(&ddr->init_ext_addr, (1 << 31));
+       } else
+#endif
+       {
+               out_be32(&ddr->init_addr, regs->ddr_init_addr);
+               out_be32(&ddr->init_ext_addr, regs->ddr_init_ext_addr);
+       }
 
        out_be32(&ddr->timing_cfg_4, regs->timing_cfg_4);
        out_be32(&ddr->timing_cfg_5, regs->timing_cfg_5);
@@ -374,8 +399,22 @@ step2:
        udelay(500);
        asm volatile("sync;isync");
 
+#ifdef CONFIG_DEEP_SLEEP
+       if (sleep_flag) {
+               /* enter self-refresh */
+               setbits_be32(&ddr->sdram_cfg_2, (1 << 31));
+               /* do board specific memory setup */
+               board_mem_sleep_setup();
+       }
+#endif
+
        /* Let the controller go */
-       temp_sdram_cfg = in_be32(&ddr->sdram_cfg) & ~SDRAM_CFG_BI;
+#ifdef CONFIG_DEEP_SLEEP
+       if (sleep_flag)
+               temp_sdram_cfg = (in_be32(&ddr->sdram_cfg) | SDRAM_CFG_BI);
+       else
+#endif
+               temp_sdram_cfg = (in_be32(&ddr->sdram_cfg) & ~SDRAM_CFG_BI);
        out_be32(&ddr->sdram_cfg, temp_sdram_cfg | SDRAM_CFG_MEM_EN);
        asm volatile("sync;isync");
 
@@ -526,4 +565,9 @@ step2:
                clrbits_be32(&ddr->sdram_cfg, 0x2);
        }
 #endif /* CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134 */
+#ifdef CONFIG_DEEP_SLEEP
+       if (sleep_flag)
+               /* exit self-refresh */
+               clrbits_be32(&ddr->sdram_cfg_2, (1 << 31));
+#endif
 }