diff --git a/plat/rockchip/rk3399/drivers/dram/suspend.c b/plat/rockchip/rk3399/drivers/dram/suspend.c index 2a80bcb..dd97581 100644 --- a/plat/rockchip/rk3399/drivers/dram/suspend.c +++ b/plat/rockchip/rk3399/drivers/dram/suspend.c @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include #include #include @@ -656,6 +658,30 @@ ; } +__pmusramfunc static void pmusram_enable_watchdog(void) +{ + /* Make the watchdog use the first global reset. */ + mmio_write_32(CRU_BASE + CRU_GLB_RST_CON, 1 << 1); + + /* + * This gives the system ~8 seconds before reset. The pclk for the + * watchdog is 4MHz on reset. The value of 0x9 in WDT_TORR means that + * the watchdog will wait for 0x1ffffff cycles before resetting. + */ + mmio_write_32(WDT0_BASE + 4, 0x9); + + /* Enable the watchdog */ + mmio_setbits_32(WDT0_BASE, 0x1); + + /* Magic reset the watchdog timer value for WDT_CRR. */ + mmio_write_32(WDT0_BASE + 0xc, 0x76); + + secure_watchdog_ungate(); + + /* The watchdog is in PD_ALIVE, so deidle it. */ + mmio_clrbits_32(PMU_BASE + PMU_BUS_CLR, PMU_CLR_ALIVE); +} + void dmc_suspend(void) { struct rk3399_sdram_params *sdram_params = &sdram_config; @@ -726,6 +752,9 @@ uint32_t channel_mask = 0; uint32_t channel; + pmusram_enable_watchdog(); + pmu_sgrf_rst_hld_release(); + restore_pmu_rsthold(); sram_secure_timer_init(); /* diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu.c b/plat/rockchip/rk3399/drivers/pmu/pmu.c index e136bbc..04446d6 100644 --- a/plat/rockchip/rk3399/drivers/pmu/pmu.c +++ b/plat/rockchip/rk3399/drivers/pmu/pmu.c @@ -1368,7 +1368,7 @@ mmio_setbits_32(PMU_BASE + PMU_PWRDN_CON, BIT(PMU_SCU_B_PWRDWN_EN)); wdt_register_save(); - secure_watchdog_disable(); + secure_watchdog_gate(); /* * Disabling PLLs/PWM/DVFS is approaching WFI which is @@ -1397,6 +1397,7 @@ plat_rockchip_restore_gpio(); cru_register_restore(); grf_register_restore(); + wdt_register_restore(); resume_uart(); resume_apio(); resume_gpio(); @@ -1406,10 +1407,8 @@ udelay(300); enable_dvfs_plls(); - secure_watchdog_enable(); secure_sgrf_init(); secure_sgrf_ddr_rgn_init(); - wdt_register_restore(); /* restore clk_ddrc_bpll_src_en gate */ mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(3), @@ -1460,12 +1459,10 @@ udelay(1); } - pmu_sgrf_rst_hld_release(); pmu_scu_b_pwrup(); pmu_power_domains_resume(); restore_abpll(); - restore_pmu_rsthold(); clr_hw_idle(BIT(PMU_CLR_CENTER1) | BIT(PMU_CLR_ALIVE) | BIT(PMU_CLR_MSCH0) | diff --git a/plat/rockchip/rk3399/drivers/secure/secure.c b/plat/rockchip/rk3399/drivers/secure/secure.c index 589d833..1937b13 100644 --- a/plat/rockchip/rk3399/drivers/secure/secure.c +++ b/plat/rockchip/rk3399/drivers/secure/secure.c @@ -77,7 +77,7 @@ BIT_WITH_WMSK(rgn)); } -void secure_watchdog_disable(void) +void secure_watchdog_gate(void) { /** * Disable CA53 and CM0 wdt pclk @@ -89,7 +89,7 @@ BIT_WITH_WMSK(PCLK_WDT_CM0_GATE_SHIFT)); } -void secure_watchdog_enable(void) +__pmusramfunc void secure_watchdog_ungate(void) { /** * Enable CA53 and CM0 wdt pclk diff --git a/plat/rockchip/rk3399/drivers/secure/secure.h b/plat/rockchip/rk3399/drivers/secure/secure.h index 334805d..8e80f2b 100644 --- a/plat/rockchip/rk3399/drivers/secure/secure.h +++ b/plat/rockchip/rk3399/drivers/secure/secure.h @@ -95,8 +95,8 @@ #define PCLK_WDT_CM0_GATE_SHIFT 10 /* export secure operating APIs */ -void secure_watchdog_disable(void); -void secure_watchdog_enable(void); +void secure_watchdog_gate(void); +__pmusramfunc void secure_watchdog_ungate(void); void secure_timer_init(void); void secure_sgrf_init(void); void secure_sgrf_ddr_rgn_init(void); diff --git a/plat/rockchip/rk3399/drivers/soc/soc.c b/plat/rockchip/rk3399/drivers/soc/soc.c index 7dd0b72..741adde 100644 --- a/plat/rockchip/rk3399/drivers/soc/soc.c +++ b/plat/rockchip/rk3399/drivers/soc/soc.c @@ -43,6 +43,9 @@ /* sleep data for pll suspend */ static struct deepsleep_data_s slp_data; +/* sleep data that needs to be accessed from pmusram */ +__pmusramdata struct pmu_sleep_data pmu_slp_data; + static void set_pll_slow_mode(uint32_t pll_id) { if (pll_id == PPLL_ID) @@ -229,9 +232,9 @@ uint32_t rstnhold_cofig0; uint32_t rstnhold_cofig1; - slp_data.pmucru_rstnhold_con0 = mmio_read_32(PMUCRU_BASE + + pmu_slp_data.pmucru_rstnhold_con0 = mmio_read_32(PMUCRU_BASE + PMUCRU_RSTNHOLD_CON0); - slp_data.pmucru_rstnhold_con1 = mmio_read_32(PMUCRU_BASE + + pmu_slp_data.pmucru_rstnhold_con1 = mmio_read_32(PMUCRU_BASE + PMUCRU_RSTNHOLD_CON1); rstnhold_cofig0 = BIT_WITH_WMSK(PRESETN_NOC_PMU_HOLD) | BIT_WITH_WMSK(PRESETN_INTMEM_PMU_HOLD) | @@ -257,12 +260,33 @@ mmio_write_32(PMUCRU_BASE + PMUCRU_RSTNHOLD_CON1, rstnhold_cofig1); } -void restore_pmu_rsthold(void) +void pmu_sgrf_rst_hld(void) +{ + mmio_write_32(PMUCRU_BASE + CRU_PMU_RSTHOLD_CON(1), + CRU_PMU_SGRF_RST_HOLD); +} + +/* + * When system reset in running state, we want the cpus to be reboot + * from maskrom (system reboot), + * the pmusgrf reset-hold bits needs to be released. + * When system wake up from system deep suspend, some soc will be reset + * when waked up, + * we want the bootcpu to be reboot from pmusram, + * the pmusgrf reset-hold bits needs to be held. + */ +__pmusramfunc void pmu_sgrf_rst_hld_release(void) +{ + mmio_write_32(PMUCRU_BASE + CRU_PMU_RSTHOLD_CON(1), + CRU_PMU_SGRF_RST_RLS); +} + +__pmusramfunc void restore_pmu_rsthold(void) { mmio_write_32(PMUCRU_BASE + PMUCRU_RSTNHOLD_CON0, - slp_data.pmucru_rstnhold_con0 | REG_SOC_WMSK); + pmu_slp_data.pmucru_rstnhold_con0 | REG_SOC_WMSK); mmio_write_32(PMUCRU_BASE + PMUCRU_RSTNHOLD_CON1, - slp_data.pmucru_rstnhold_con1 | REG_SOC_WMSK); + pmu_slp_data.pmucru_rstnhold_con1 | REG_SOC_WMSK); } /** diff --git a/plat/rockchip/rk3399/drivers/soc/soc.h b/plat/rockchip/rk3399/drivers/soc/soc.h index 6100d95..bc41933 100644 --- a/plat/rockchip/rk3399/drivers/soc/soc.h +++ b/plat/rockchip/rk3399/drivers/soc/soc.h @@ -134,6 +134,9 @@ uint32_t plls_con[END_PLL_ID][PLL_CON_COUNT]; uint32_t cru_gate_con[CRU_GATE_COUNT]; uint32_t pmucru_gate_con[PMUCRU_GATE_COUNT]; +}; + +struct pmu_sleep_data { uint32_t pmucru_rstnhold_con0; uint32_t pmucru_rstnhold_con1; }; @@ -263,27 +266,6 @@ #define PMUCRU_GATEDIS_CON0 0x0130 #define PMUCRU_SOFTRST_CON(n) (PMUCRU_SOFTRST_CON0 + (n) * 4) -/* - * When system reset in running state, we want the cpus to be reboot - * from maskrom (system reboot), - * the pmusgrf reset-hold bits needs to be released. - * When system wake up from system deep suspend, some soc will be reset - * when waked up, - * we want the bootcpu to be reboot from pmusram, - * the pmusgrf reset-hold bits needs to be held. - */ -static inline void pmu_sgrf_rst_hld_release(void) -{ - mmio_write_32(PMUCRU_BASE + CRU_PMU_RSTHOLD_CON(1), - CRU_PMU_SGRF_RST_RLS); -} - -static inline void pmu_sgrf_rst_hld(void) -{ - mmio_write_32(PMUCRU_BASE + CRU_PMU_RSTHOLD_CON(1), - CRU_PMU_SGRF_RST_HOLD); -} - /* export related and operating SoC APIs */ void __dead2 soc_global_soft_reset(void); void disable_dvfs_plls(void); @@ -296,5 +278,7 @@ void clk_gate_con_disable(void); void clk_gate_con_restore(void); void set_pmu_rsthold(void); -void restore_pmu_rsthold(void); +void pmu_sgrf_rst_hld(void); +__pmusramfunc void pmu_sgrf_rst_hld_release(void); +__pmusramfunc void restore_pmu_rsthold(void); #endif /* __SOC_H__ */