summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plat/rockchip/common/pmusram/pmu_sram_cpus_on.S2
-rw-r--r--plat/rockchip/rk3399/drivers/dram/suspend.c48
-rw-r--r--plat/rockchip/rk3399/drivers/dram/suspend.h4
-rw-r--r--plat/rockchip/rk3399/drivers/pmu/pmu.c4
-rw-r--r--plat/rockchip/rk3399/drivers/soc/soc.c5
-rw-r--r--plat/rockchip/rk3399/drivers/soc/soc.h2
6 files changed, 45 insertions, 20 deletions
diff --git a/plat/rockchip/common/pmusram/pmu_sram_cpus_on.S b/plat/rockchip/common/pmusram/pmu_sram_cpus_on.S
index 22bdffca..5a1854b4 100644
--- a/plat/rockchip/common/pmusram/pmu_sram_cpus_on.S
+++ b/plat/rockchip/common/pmusram/pmu_sram_cpus_on.S
@@ -45,7 +45,7 @@ sys_wakeup:
ddr_resume:
ldr x2, =__bl31_sram_stack_end
mov sp, x2
- bl dmc_restore
+ bl dmc_resume
#endif
bl sram_restore
sys_resume:
diff --git a/plat/rockchip/rk3399/drivers/dram/suspend.c b/plat/rockchip/rk3399/drivers/dram/suspend.c
index 68677449..89f0cd38 100644
--- a/plat/rockchip/rk3399/drivers/dram/suspend.c
+++ b/plat/rockchip/rk3399/drivers/dram/suspend.c
@@ -43,6 +43,9 @@
#define SYS_COUNTER_FREQ_IN_MHZ (SYS_COUNTER_FREQ_IN_TICKS / 1000000)
+__pmusramdata uint32_t dpll_data[PLL_CON_COUNT];
+__pmusramdata uint32_t cru_clksel_con6;
+
/*
* Copy @num registers from @src to @dst
*/
@@ -636,24 +639,45 @@ static __pmusramfunc int pctl_start(uint32_t channel_mask,
return 0;
}
-void dmc_save(void)
+__pmusramfunc static void pmusram_restore_pll(int pll_id, uint32_t *src)
+{
+ mmio_write_32((CRU_BASE + CRU_PLL_CON(pll_id, 3)), PLL_SLOW_MODE);
+
+ mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 0), src[0] | REG_SOC_WMSK);
+ mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 1), src[1] | REG_SOC_WMSK);
+ mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 2), src[2]);
+ mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 4), src[4] | REG_SOC_WMSK);
+ mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 5), src[5] | REG_SOC_WMSK);
+
+ mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 3), src[3] | REG_SOC_WMSK);
+
+ while ((mmio_read_32(CRU_BASE + CRU_PLL_CON(pll_id, 2)) &
+ (1 << 31)) == 0x0)
+ ;
+}
+
+void dmc_suspend(void)
{
struct rk3399_sdram_params *sdram_params = &sdram_config;
struct rk3399_ddr_publ_regs *phy_regs;
uint32_t *params_ctl;
uint32_t *params_pi;
uint32_t refdiv, postdiv2, postdiv1, fbdiv;
- uint32_t tmp, ch, byte, i;
+ uint32_t ch, byte, i;
phy_regs = &sdram_params->phy_regs;
params_ctl = sdram_params->pctl_regs.denali_ctl;
params_pi = sdram_params->pi_regs.denali_pi;
- fbdiv = mmio_read_32(CRU_BASE + CRU_PLL_CON(DPLL_ID, 0)) & 0xfff;
- tmp = mmio_read_32(CRU_BASE + CRU_PLL_CON(DPLL_ID, 1));
- postdiv2 = POSTDIV2_DEC(tmp);
- postdiv1 = POSTDIV1_DEC(tmp);
- refdiv = REFDIV_DEC(tmp);
+ /* save dpll register and ddr clock register value to pmusram */
+ cru_clksel_con6 = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON6);
+ for (i = 0; i < PLL_CON_COUNT; i++)
+ dpll_data[i] = mmio_read_32(CRU_BASE + CRU_PLL_CON(DPLL_ID, i));
+
+ fbdiv = dpll_data[0] & 0xfff;
+ postdiv2 = POSTDIV2_DEC(dpll_data[1]);
+ postdiv1 = POSTDIV1_DEC(dpll_data[1]);
+ refdiv = REFDIV_DEC(dpll_data[1]);
sdram_params->ddr_freq = ((fbdiv * 24) /
(refdiv * postdiv1 * postdiv2)) * MHz;
@@ -697,12 +721,20 @@ void dmc_save(void)
phy_regs->phy896[0] &= ~(0x3 << 8);
}
-__pmusramfunc void dmc_restore(void)
+__pmusramfunc void dmc_resume(void)
{
struct rk3399_sdram_params *sdram_params = &sdram_config;
uint32_t channel_mask = 0;
uint32_t channel;
+ /*
+ * we switch ddr clock to abpll when suspend,
+ * we set back to dpll here
+ */
+ mmio_write_32(CRU_BASE + CRU_CLKSEL_CON6,
+ cru_clksel_con6 | REG_SOC_WMSK);
+ pmusram_restore_pll(DPLL_ID, dpll_data);
+
configure_sgrf();
retry:
diff --git a/plat/rockchip/rk3399/drivers/dram/suspend.h b/plat/rockchip/rk3399/drivers/dram/suspend.h
index 77f9c317..a8a86410 100644
--- a/plat/rockchip/rk3399/drivers/dram/suspend.h
+++ b/plat/rockchip/rk3399/drivers/dram/suspend.h
@@ -19,7 +19,7 @@
#define PI_WDQ_LEVELING (1 << 4)
#define PI_FULL_TRAINING (0xff)
-void dmc_save(void);
-__pmusramfunc void dmc_restore(void);
+void dmc_suspend(void);
+__pmusramfunc void dmc_resume(void);
#endif /* __DRAM_H__ */
diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu.c b/plat/rockchip/rk3399/drivers/pmu/pmu.c
index 635dda6a..d97b0463 100644
--- a/plat/rockchip/rk3399/drivers/pmu/pmu.c
+++ b/plat/rockchip/rk3399/drivers/pmu/pmu.c
@@ -1138,7 +1138,7 @@ int rockchip_soc_sys_pwr_dm_suspend(void)
uint32_t status = 0;
ddr_prepare_for_sys_suspend();
- dmc_save();
+ dmc_suspend();
pmu_scu_b_pwrdn();
pmu_power_domains_suspend();
@@ -1269,8 +1269,6 @@ int rockchip_soc_sys_pwr_dm_resume(void)
pmu_scu_b_pwrup();
pmu_power_domains_resume();
- restore_dpll();
- sram_func_set_ddrctl_pll(DPLL_ID);
restore_abpll();
clr_hw_idle(BIT(PMU_CLR_CENTER1) |
diff --git a/plat/rockchip/rk3399/drivers/soc/soc.c b/plat/rockchip/rk3399/drivers/soc/soc.c
index 993b80ad..175d5427 100644
--- a/plat/rockchip/rk3399/drivers/soc/soc.c
+++ b/plat/rockchip/rk3399/drivers/soc/soc.c
@@ -171,11 +171,6 @@ void restore_abpll(void)
restore_pll(ABPLL_ID, slp_data.plls_con[ABPLL_ID]);
}
-void restore_dpll(void)
-{
- restore_pll(DPLL_ID, slp_data.plls_con[DPLL_ID]);
-}
-
void clk_gate_con_save(void)
{
uint32_t i = 0;
diff --git a/plat/rockchip/rk3399/drivers/soc/soc.h b/plat/rockchip/rk3399/drivers/soc/soc.h
index 8d1fd13f..9680beab 100644
--- a/plat/rockchip/rk3399/drivers/soc/soc.h
+++ b/plat/rockchip/rk3399/drivers/soc/soc.h
@@ -196,6 +196,7 @@ struct deepsleep_data_s {
#define GRF_SOC_CON_BASE 0xe200
#define GRF_SOC_CON(n) (GRF_SOC_CON_BASE + (n) * 4)
+#define CRU_CLKSEL_CON6 0x0118
#define PMUCRU_CLKSEL_CON0 0x0080
#define PMUCRU_CLKGATE_CON2 0x0108
#define PMUCRU_SOFTRST_CON0 0x0110
@@ -231,7 +232,6 @@ void enable_dvfs_plls(void);
void enable_nodvfs_plls(void);
void prepare_abpll_for_ddrctrl(void);
void restore_abpll(void);
-void restore_dpll(void);
void clk_gate_con_save(void);
void clk_gate_con_disable(void);
void clk_gate_con_restore(void);