From 74c3d79dc2ce8c04cf45dcb709199926fa162f29 Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Fri, 16 Jun 2017 10:43:40 +0800 Subject: [PATCH 1/7] rockchip/rk3399: reinitilize debug uart when resume when shutdown logic power rail, the uart register value will reset, so need to reinitilize debug uart. Change-Id: I48d3535c0068fd671dea6ea32e908612992faf62 Signed-off-by: Lin Huang Signed-off-by: Caesar Wang --- plat/rockchip/rk3399/drivers/pmu/pmu.c | 58 ++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu.c b/plat/rockchip/rk3399/drivers/pmu/pmu.c index 6b420c24ce..635dda6ad8 100644 --- a/plat/rockchip/rk3399/drivers/pmu/pmu.c +++ b/plat/rockchip/rk3399/drivers/pmu/pmu.c @@ -1076,6 +1076,62 @@ void sram_restore(void) incbin_size); } +struct uart_debug { + uint32_t uart_dll; + uint32_t uart_dlh; + uint32_t uart_ier; + uint32_t uart_fcr; + uint32_t uart_mcr; + uint32_t uart_lcr; +}; + +#define UART_DLL 0x00 +#define UART_DLH 0x04 +#define UART_IER 0x04 +#define UART_FCR 0x08 +#define UART_LCR 0x0c +#define UART_MCR 0x10 +#define UARTSRR 0x88 + +#define UART_RESET BIT(0) +#define UARTFCR_FIFOEN BIT(0) +#define RCVR_FIFO_RESET BIT(1) +#define XMIT_FIFO_RESET BIT(2) +#define DIAGNOSTIC_MODE BIT(4) +#define UARTLCR_DLAB BIT(7) + +static struct uart_debug uart_save; + +void suspend_uart(void) +{ + uart_save.uart_lcr = mmio_read_32(PLAT_RK_UART_BASE + UART_LCR); + uart_save.uart_ier = mmio_read_32(PLAT_RK_UART_BASE + UART_IER); + uart_save.uart_mcr = mmio_read_32(PLAT_RK_UART_BASE + UART_MCR); + mmio_write_32(PLAT_RK_UART_BASE + UART_LCR, + uart_save.uart_lcr | UARTLCR_DLAB); + uart_save.uart_dll = mmio_read_32(PLAT_RK_UART_BASE + UART_DLL); + uart_save.uart_dlh = mmio_read_32(PLAT_RK_UART_BASE + UART_DLH); + mmio_write_32(PLAT_RK_UART_BASE + UART_LCR, uart_save.uart_lcr); +} + +void resume_uart(void) +{ + uint32_t uart_lcr; + + mmio_write_32(PLAT_RK_UART_BASE + UARTSRR, + XMIT_FIFO_RESET | RCVR_FIFO_RESET | UART_RESET); + + uart_lcr = mmio_read_32(PLAT_RK_UART_BASE + UART_LCR); + mmio_write_32(PLAT_RK_UART_BASE + UART_MCR, DIAGNOSTIC_MODE); + mmio_write_32(PLAT_RK_UART_BASE + UART_LCR, uart_lcr | UARTLCR_DLAB); + mmio_write_32(PLAT_RK_UART_BASE + UART_DLL, uart_save.uart_dll); + mmio_write_32(PLAT_RK_UART_BASE + UART_DLH, uart_save.uart_dlh); + mmio_write_32(PLAT_RK_UART_BASE + UART_LCR, uart_save.uart_lcr); + mmio_write_32(PLAT_RK_UART_BASE + UART_IER, uart_save.uart_ier); + mmio_write_32(PLAT_RK_UART_BASE + UART_FCR, UARTFCR_FIFOEN); + mmio_write_32(PLAT_RK_UART_BASE + UART_MCR, uart_save.uart_mcr); +} + int rockchip_soc_sys_pwr_dm_suspend(void) { uint32_t wait_cnt = 0; @@ -1139,6 +1195,7 @@ int rockchip_soc_sys_pwr_dm_suspend(void) suspend_apio(); suspend_gpio(); + suspend_uart(); sram_save(); return 0; @@ -1149,6 +1206,7 @@ int rockchip_soc_sys_pwr_dm_resume(void) uint32_t wait_cnt = 0; uint32_t status = 0; + resume_uart(); resume_apio(); resume_gpio(); enable_nodvfs_plls(); From 9aadf25c2251d3fe66ea743b97cf32e1728b3ae4 Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Wed, 17 May 2017 16:14:37 +0800 Subject: [PATCH 2/7] rockchip/rk3399: set ddr clock source back to dpll when ddr resume when logic power rail shutdown, CRU register will back to reset value, ddr use abpll as clock source when do suspend, we need to save and dpll value in pmusram, then set back these ddr clock back to dpll when dddr resume. Change-Id: I95dc0173649e8515859cfa46b40a606e0cc2fe3f Signed-off-by: Lin Huang --- .../common/pmusram/pmu_sram_cpus_on.S | 2 +- plat/rockchip/rk3399/drivers/dram/suspend.c | 48 +++++++++++++++---- plat/rockchip/rk3399/drivers/dram/suspend.h | 4 +- plat/rockchip/rk3399/drivers/pmu/pmu.c | 4 +- plat/rockchip/rk3399/drivers/soc/soc.c | 5 -- plat/rockchip/rk3399/drivers/soc/soc.h | 2 +- 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 22bdffcae1..5a1854b421 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 6867744982..89f0cd3888 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 77f9c317b1..a8a8641089 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 635dda6ad8..d97b0463b1 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 993b80ad48..175d542756 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 8d1fd13ff9..9680beab5b 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); From 2adcad64dc44959e0c1a84654a2c2464af083e99 Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Thu, 18 May 2017 18:04:25 +0800 Subject: [PATCH 3/7] rockchip/rk3399: save and restore pd_alive register pd_alive control cru, grf, timer, gpio and wdt, when turn off logic power rail, these register value will back to reset value, we need to save them value in suspend and restore them when resuem, since timer will reinitial in kernel, so it not need to save/restore. Change-Id: I0fc2a011d3cdc04b66ffbf728e769eb28b51ee38 Signed-off-by: Lin Huang --- plat/rockchip/common/include/plat_private.h | 2 + .../rk3399/drivers/gpio/rk3399_gpio.c | 114 ++++++++++- plat/rockchip/rk3399/drivers/pmu/pmu.c | 183 +++++++++++++++++- plat/rockchip/rk3399/drivers/soc/soc.h | 21 ++ .../rk3399/include/shared/addressmap_shared.h | 3 + 5 files changed, 321 insertions(+), 2 deletions(-) diff --git a/plat/rockchip/common/include/plat_private.h b/plat/rockchip/common/include/plat_private.h index 290811a265..545677352f 100644 --- a/plat/rockchip/common/include/plat_private.h +++ b/plat/rockchip/common/include/plat_private.h @@ -90,6 +90,8 @@ struct gpio_info *plat_get_rockchip_gpio_poweroff(void); struct gpio_info *plat_get_rockchip_suspend_gpio(uint32_t *count); struct apio_info *plat_get_rockchip_suspend_apio(void); void plat_rockchip_gpio_init(void); +void plat_rockchip_save_gpio(void); +void plat_rockchip_restore_gpio(void); int rockchip_soc_cores_pwr_dm_on(unsigned long mpidr, uint64_t entrypoint); int rockchip_soc_hlvl_pwr_dm_off(uint32_t lvl, diff --git a/plat/rockchip/rk3399/drivers/gpio/rk3399_gpio.c b/plat/rockchip/rk3399/drivers/gpio/rk3399_gpio.c index d5a2660932..e74c4d91a7 100644 --- a/plat/rockchip/rk3399/drivers/gpio/rk3399_gpio.c +++ b/plat/rockchip/rk3399/drivers/gpio/rk3399_gpio.c @@ -22,10 +22,29 @@ uint32_t gpio_port[] = { GPIO4_BASE, }; +struct { + uint32_t swporta_dr; + uint32_t swporta_ddr; + uint32_t inten; + uint32_t intmask; + uint32_t inttype_level; + uint32_t int_polarity; + uint32_t debounce; + uint32_t ls_sync; +} store_gpio[3]; + +static uint32_t store_grf_gpio[(GRF_GPIO2D_HE - GRF_GPIO2A_IOMUX) / 4 + 1]; + #define SWPORTA_DR 0x00 #define SWPORTA_DDR 0x04 -#define EXT_PORTA 0x50 +#define INTEN 0x30 +#define INTMASK 0x34 +#define INTTYPE_LEVEL 0x38 +#define INT_POLARITY 0x3c +#define DEBOUNCE 0x48 +#define LS_SYNC 0x60 +#define EXT_PORTA 0x50 #define PMU_GPIO_PORT0 0 #define PMU_GPIO_PORT1 1 #define GPIO_PORT2 2 @@ -290,6 +309,99 @@ static void set_value(int gpio, int value) gpio_put_clock(gpio, clock_state); } +void plat_rockchip_save_gpio(void) +{ + int i; + uint32_t cru_gate_save; + + cru_gate_save = mmio_read_32(CRU_BASE + CRU_CLKGATE_CON(31)); + + /* + * when shutdown logic, we need to save gpio2 ~ gpio4 register, + * we need to enable gpio2 ~ gpio4 clock here, since it may be gating, + * and we do not care gpio0 and gpio1 clock gate, since we never + * gating them + */ + mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(31), + BITS_WITH_WMASK(0, 0x07, PCLK_GPIO2_GATE_SHIFT)); + + /* + * since gpio0, gpio1 are pmugpio, they will keep ther value + * when shutdown logic power rail, so only need to save gpio2 ~ gpio4 + * register value + */ + for (i = 2; i < 5; i++) { + store_gpio[i - 2].swporta_dr = + mmio_read_32(gpio_port[i] + SWPORTA_DR); + store_gpio[i - 2].swporta_ddr = + mmio_read_32(gpio_port[i] + SWPORTA_DDR); + store_gpio[i - 2].inten = + mmio_read_32(gpio_port[i] + INTEN); + store_gpio[i - 2].intmask = + mmio_read_32(gpio_port[i] + INTMASK); + store_gpio[i - 2].inttype_level = + mmio_read_32(gpio_port[i] + INTTYPE_LEVEL); + store_gpio[i - 2].int_polarity = + mmio_read_32(gpio_port[i] + INT_POLARITY); + store_gpio[i - 2].debounce = + mmio_read_32(gpio_port[i] + DEBOUNCE); + store_gpio[i - 2].ls_sync = + mmio_read_32(gpio_port[i] + LS_SYNC); + } + mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(31), + cru_gate_save | REG_SOC_WMSK); + + /* + * gpio0, gpio1 in pmuiomux, they will keep ther value + * when shutdown logic power rail, so only need to save gpio2 ~ gpio4 + * iomux register value + */ + for (i = 0; i < ARRAY_SIZE(store_grf_gpio); i++) + store_grf_gpio[i] = + mmio_read_32(GRF_BASE + GRF_GPIO2A_IOMUX + i * 4); +} + +void plat_rockchip_restore_gpio(void) +{ + int i; + uint32_t cru_gate_save; + + for (i = 0; i < ARRAY_SIZE(store_grf_gpio); i++) + mmio_write_32(GRF_BASE + GRF_GPIO2A_IOMUX + i * 4, + REG_SOC_WMSK | store_grf_gpio[i]); + + cru_gate_save = mmio_read_32(CRU_BASE + CRU_CLKGATE_CON(31)); + + /* + * when shutdown logic, we need to save gpio2 ~ gpio4 register, + * we need to enable gpio2 ~ gpio4 clock here, since it may be gating, + * and we do not care gpio0 and gpio1 clock gate, since we never + * gating them + */ + mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(31), + BITS_WITH_WMASK(0, 0x07, PCLK_GPIO2_GATE_SHIFT)); + + for (i = 2; i < 5; i++) { + mmio_write_32(gpio_port[i] + SWPORTA_DR, + store_gpio[i - 2].swporta_dr); + mmio_write_32(gpio_port[i] + SWPORTA_DDR, + store_gpio[i - 2].swporta_ddr); + mmio_write_32(gpio_port[i] + INTEN, store_gpio[i - 2].inten); + mmio_write_32(gpio_port[i] + INTMASK, + store_gpio[i - 2].intmask); + mmio_write_32(gpio_port[i] + INTTYPE_LEVEL, + store_gpio[i - 2].inttype_level); + mmio_write_32(gpio_port[i] + INT_POLARITY, + store_gpio[i - 2].int_polarity); + mmio_write_32(gpio_port[i] + DEBOUNCE, + store_gpio[i - 2].debounce); + mmio_write_32(gpio_port[i] + LS_SYNC, + store_gpio[i - 2].ls_sync); + } + mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(31), + cru_gate_save | REG_SOC_WMSK); +} + const gpio_ops_t rk3399_gpio_ops = { .get_direction = get_direction, .set_direction = set_direction, diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu.c b/plat/rockchip/rk3399/drivers/pmu/pmu.c index d97b0463b1..7f246c2fd4 100644 --- a/plat/rockchip/rk3399/drivers/pmu/pmu.c +++ b/plat/rockchip/rk3399/drivers/pmu/pmu.c @@ -32,6 +32,19 @@ DEFINE_BAKERY_LOCK(rockchip_pd_lock); static uint32_t cpu_warm_boot_addr; static char store_sram[SRAM_BIN_LIMIT + SRAM_TEXT_LIMIT + SRAM_DATA_LIMIT]; +static uint32_t store_cru[CRU_SDIO0_CON1 / 4]; +static uint32_t store_usbphy0[7]; +static uint32_t store_usbphy1[7]; +static uint32_t store_grf_io_vsel; +static uint32_t store_grf_soc_con0; +static uint32_t store_grf_soc_con1; +static uint32_t store_grf_soc_con2; +static uint32_t store_grf_soc_con3; +static uint32_t store_grf_soc_con4; +static uint32_t store_grf_soc_con7; +static uint32_t store_grf_ddrc_con[4]; +static uint32_t store_wdt0[2]; +static uint32_t store_wdt1[2]; /* * There are two ways to powering on or off on core. @@ -1132,6 +1145,161 @@ void resume_uart(void) mmio_write_32(PLAT_RK_UART_BASE + UART_MCR, uart_save.uart_mcr); } +void save_usbphy(void) +{ + store_usbphy0[0] = mmio_read_32(GRF_BASE + GRF_USBPHY0_CTRL0); + store_usbphy0[1] = mmio_read_32(GRF_BASE + GRF_USBPHY0_CTRL2); + store_usbphy0[2] = mmio_read_32(GRF_BASE + GRF_USBPHY0_CTRL3); + store_usbphy0[3] = mmio_read_32(GRF_BASE + GRF_USBPHY0_CTRL12); + store_usbphy0[4] = mmio_read_32(GRF_BASE + GRF_USBPHY0_CTRL13); + store_usbphy0[5] = mmio_read_32(GRF_BASE + GRF_USBPHY0_CTRL15); + store_usbphy0[6] = mmio_read_32(GRF_BASE + GRF_USBPHY0_CTRL16); + + store_usbphy1[0] = mmio_read_32(GRF_BASE + GRF_USBPHY1_CTRL0); + store_usbphy1[1] = mmio_read_32(GRF_BASE + GRF_USBPHY1_CTRL2); + store_usbphy1[2] = mmio_read_32(GRF_BASE + GRF_USBPHY1_CTRL3); + store_usbphy1[3] = mmio_read_32(GRF_BASE + GRF_USBPHY1_CTRL12); + store_usbphy1[4] = mmio_read_32(GRF_BASE + GRF_USBPHY1_CTRL13); + store_usbphy1[5] = mmio_read_32(GRF_BASE + GRF_USBPHY1_CTRL15); + store_usbphy1[6] = mmio_read_32(GRF_BASE + GRF_USBPHY1_CTRL16); +} + +void restore_usbphy(void) +{ + mmio_write_32(GRF_BASE + GRF_USBPHY0_CTRL0, + REG_SOC_WMSK | store_usbphy0[0]); + mmio_write_32(GRF_BASE + GRF_USBPHY0_CTRL2, + REG_SOC_WMSK | store_usbphy0[1]); + mmio_write_32(GRF_BASE + GRF_USBPHY0_CTRL3, + REG_SOC_WMSK | store_usbphy0[2]); + mmio_write_32(GRF_BASE + GRF_USBPHY0_CTRL12, + REG_SOC_WMSK | store_usbphy0[3]); + mmio_write_32(GRF_BASE + GRF_USBPHY0_CTRL13, + REG_SOC_WMSK | store_usbphy0[4]); + mmio_write_32(GRF_BASE + GRF_USBPHY0_CTRL15, + REG_SOC_WMSK | store_usbphy0[5]); + mmio_write_32(GRF_BASE + GRF_USBPHY0_CTRL16, + REG_SOC_WMSK | store_usbphy0[6]); + + mmio_write_32(GRF_BASE + GRF_USBPHY1_CTRL0, + REG_SOC_WMSK | store_usbphy1[0]); + mmio_write_32(GRF_BASE + GRF_USBPHY1_CTRL2, + REG_SOC_WMSK | store_usbphy1[1]); + mmio_write_32(GRF_BASE + GRF_USBPHY1_CTRL3, + REG_SOC_WMSK | store_usbphy1[2]); + mmio_write_32(GRF_BASE + GRF_USBPHY1_CTRL12, + REG_SOC_WMSK | store_usbphy1[3]); + mmio_write_32(GRF_BASE + GRF_USBPHY1_CTRL13, + REG_SOC_WMSK | store_usbphy1[4]); + mmio_write_32(GRF_BASE + GRF_USBPHY1_CTRL15, + REG_SOC_WMSK | store_usbphy1[5]); + mmio_write_32(GRF_BASE + GRF_USBPHY1_CTRL16, + REG_SOC_WMSK | store_usbphy1[6]); +} + +void grf_register_save(void) +{ + int i; + + store_grf_soc_con0 = mmio_read_32(GRF_BASE + GRF_SOC_CON(0)); + store_grf_soc_con1 = mmio_read_32(GRF_BASE + GRF_SOC_CON(1)); + store_grf_soc_con2 = mmio_read_32(GRF_BASE + GRF_SOC_CON(2)); + store_grf_soc_con3 = mmio_read_32(GRF_BASE + GRF_SOC_CON(3)); + store_grf_soc_con4 = mmio_read_32(GRF_BASE + GRF_SOC_CON(4)); + store_grf_soc_con7 = mmio_read_32(GRF_BASE + GRF_SOC_CON(7)); + + for (i = 0; i < 4; i++) + store_grf_ddrc_con[i] = + mmio_read_32(GRF_BASE + GRF_DDRC0_CON0 + i * 4); + + store_grf_io_vsel = mmio_read_32(GRF_BASE + GRF_IO_VSEL); +} + +void grf_register_restore(void) +{ + int i; + + mmio_write_32(GRF_BASE + GRF_SOC_CON(0), + REG_SOC_WMSK | store_grf_soc_con0); + mmio_write_32(GRF_BASE + GRF_SOC_CON(1), + REG_SOC_WMSK | store_grf_soc_con1); + mmio_write_32(GRF_BASE + GRF_SOC_CON(2), + REG_SOC_WMSK | store_grf_soc_con2); + mmio_write_32(GRF_BASE + GRF_SOC_CON(3), + REG_SOC_WMSK | store_grf_soc_con3); + mmio_write_32(GRF_BASE + GRF_SOC_CON(4), + REG_SOC_WMSK | store_grf_soc_con4); + mmio_write_32(GRF_BASE + GRF_SOC_CON(7), + REG_SOC_WMSK | store_grf_soc_con7); + + for (i = 0; i < 4; i++) + mmio_write_32(GRF_BASE + GRF_DDRC0_CON0 + i * 4, + REG_SOC_WMSK | store_grf_ddrc_con[i]); + + mmio_write_32(GRF_BASE + GRF_IO_VSEL, REG_SOC_WMSK | store_grf_io_vsel); +} + +void cru_register_save(void) +{ + int i; + + for (i = 0; i <= CRU_SDIO0_CON1; i = i + 4) + store_cru[i / 4] = mmio_read_32(CRU_BASE + i); +} + +void cru_register_restore(void) +{ + int i; + + for (i = 0; i <= CRU_SDIO0_CON1; i = i + 4) { + + /* + * since DPLL, CRU_CLKSEL_CON6 have been restore in + * dmc_resume, ABPLL will resote later, so skip them + */ + if ((i == CRU_CLKSEL_CON6) || + (i >= CRU_PLL_CON(ABPLL_ID, 0) && + i <= CRU_PLL_CON(DPLL_ID, 5))) + continue; + + if ((i == CRU_PLL_CON(ALPLL_ID, 2)) || + (i == CRU_PLL_CON(CPLL_ID, 2)) || + (i == CRU_PLL_CON(GPLL_ID, 2)) || + (i == CRU_PLL_CON(NPLL_ID, 2)) || + (i == CRU_PLL_CON(VPLL_ID, 2))) + mmio_write_32(CRU_BASE + i, store_cru[i / 4]); + /* + * CRU_GLB_CNT_TH and CRU_CLKSEL_CON97~CRU_CLKSEL_CON107 + * not need do high 16bit mask + */ + else if ((i > 0x27c && i < 0x2b0) || (i == 0x508)) + mmio_write_32(CRU_BASE + i, store_cru[i / 4]); + else + mmio_write_32(CRU_BASE + i, + REG_SOC_WMSK | store_cru[i / 4]); + } +} + +void wdt_register_save(void) +{ + int i; + + for (i = 0; i < 2; i++) { + store_wdt0[i] = mmio_read_32(WDT0_BASE + i * 4); + store_wdt1[i] = mmio_read_32(WDT1_BASE + i * 4); + } +} + +void wdt_register_restore(void) +{ + int i; + + for (i = 0; i < 2; i++) { + mmio_write_32(WDT0_BASE + i * 4, store_wdt0[i]); + mmio_write_32(WDT1_BASE + i * 4, store_wdt1[i]); + } +} + int rockchip_soc_sys_pwr_dm_suspend(void) { uint32_t wait_cnt = 0; @@ -1141,6 +1309,9 @@ int rockchip_soc_sys_pwr_dm_suspend(void) dmc_suspend(); pmu_scu_b_pwrdn(); + /* need to save usbphy before shutdown PERIHP PD */ + save_usbphy(); + pmu_power_domains_suspend(); set_hw_idle(BIT(PMU_CLR_CENTER1) | BIT(PMU_CLR_ALIVE) | @@ -1196,8 +1367,12 @@ int rockchip_soc_sys_pwr_dm_suspend(void) suspend_apio(); suspend_gpio(); suspend_uart(); - + grf_register_save(); + cru_register_save(); + wdt_register_save(); sram_save(); + plat_rockchip_save_gpio(); + return 0; } @@ -1206,6 +1381,10 @@ int rockchip_soc_sys_pwr_dm_resume(void) uint32_t wait_cnt = 0; uint32_t status = 0; + plat_rockchip_restore_gpio(); + wdt_register_restore(); + cru_register_restore(); + grf_register_restore(); resume_uart(); resume_apio(); resume_gpio(); @@ -1285,6 +1464,8 @@ int rockchip_soc_sys_pwr_dm_resume(void) plat_rockchip_gic_cpuif_enable(); m0_stop(); + restore_usbphy(); + ddr_prepare_for_sys_resume(); return 0; diff --git a/plat/rockchip/rk3399/drivers/soc/soc.h b/plat/rockchip/rk3399/drivers/soc/soc.h index 9680beab5b..c418337313 100644 --- a/plat/rockchip/rk3399/drivers/soc/soc.h +++ b/plat/rockchip/rk3399/drivers/soc/soc.h @@ -189,14 +189,35 @@ struct deepsleep_data_s { #define PWM_ENABLE (1 << 0) /* grf reg offset */ +#define GRF_USBPHY0_CTRL0 0x4480 +#define GRF_USBPHY0_CTRL2 0x4488 +#define GRF_USBPHY0_CTRL3 0x448c +#define GRF_USBPHY0_CTRL12 0x44b0 +#define GRF_USBPHY0_CTRL13 0x44b4 +#define GRF_USBPHY0_CTRL15 0x44bc +#define GRF_USBPHY0_CTRL16 0x44c0 + +#define GRF_USBPHY1_CTRL0 0x4500 +#define GRF_USBPHY1_CTRL2 0x4508 +#define GRF_USBPHY1_CTRL3 0x450c +#define GRF_USBPHY1_CTRL12 0x4530 +#define GRF_USBPHY1_CTRL13 0x4534 +#define GRF_USBPHY1_CTRL15 0x453c +#define GRF_USBPHY1_CTRL16 0x4540 + +#define GRF_GPIO2A_IOMUX 0xe000 +#define GRF_GPIO2D_HE 0xe18c #define GRF_DDRC0_CON0 0xe380 #define GRF_DDRC0_CON1 0xe384 #define GRF_DDRC1_CON0 0xe388 #define GRF_DDRC1_CON1 0xe38c #define GRF_SOC_CON_BASE 0xe200 #define GRF_SOC_CON(n) (GRF_SOC_CON_BASE + (n) * 4) +#define GRF_IO_VSEL 0xe640 +#define CRU_CLKSEL_CON0 0x0100 #define CRU_CLKSEL_CON6 0x0118 +#define CRU_SDIO0_CON1 0x058c #define PMUCRU_CLKSEL_CON0 0x0080 #define PMUCRU_CLKGATE_CON2 0x0108 #define PMUCRU_SOFTRST_CON0 0x0110 diff --git a/plat/rockchip/rk3399/include/shared/addressmap_shared.h b/plat/rockchip/rk3399/include/shared/addressmap_shared.h index fe23e56909..dc5c8d5685 100644 --- a/plat/rockchip/rk3399/include/shared/addressmap_shared.h +++ b/plat/rockchip/rk3399/include/shared/addressmap_shared.h @@ -40,6 +40,9 @@ #define GPIO2_BASE (MMIO_BASE + 0x07780000) #define GPIO3_BASE (MMIO_BASE + 0x07788000) #define GPIO4_BASE (MMIO_BASE + 0x07790000) +#define WDT1_BASE (MMIO_BASE + 0x07840000) +#define WDT0_BASE (MMIO_BASE + 0x07848000) +#define TIMER_BASE (MMIO_BASE + 0x07850000) #define STIME_BASE (MMIO_BASE + 0x07860000) #define SRAM_BASE (MMIO_BASE + 0x078C0000) #define SERVICE_NOC_0_BASE (MMIO_BASE + 0x07A50000) From a109ec92344fa443e39cc77c8b3de4527b8c1c4c Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Mon, 22 May 2017 10:29:59 +0800 Subject: [PATCH 4/7] rockchip/rk3399: disable more powerdomain prepare for shutdown logic rail Change-Id: Ia59adf48cf14eb627721264765bce50cb31065ef Signed-off-by: Lin Huang --- plat/rockchip/rk3399/drivers/pmu/pmu.c | 22 ++++++++++++-- plat/rockchip/rk3399/drivers/soc/soc.c | 41 +++++++++++++++++++++++++ plat/rockchip/rk3399/drivers/soc/soc.h | 42 +++++++++++++++++++++++++- 3 files changed, 102 insertions(+), 3 deletions(-) diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu.c b/plat/rockchip/rk3399/drivers/pmu/pmu.c index 7f246c2fd4..b1c373f7d5 100644 --- a/plat/rockchip/rk3399/drivers/pmu/pmu.c +++ b/plat/rockchip/rk3399/drivers/pmu/pmu.c @@ -336,6 +336,11 @@ static void pmu_power_domains_suspend(void) pmu_set_power_domain(PD_RGA, pmu_pd_off); pmu_set_power_domain(PD_VCODEC, pmu_pd_off); pmu_set_power_domain(PD_VDU, pmu_pd_off); + pmu_set_power_domain(PD_USB3, pmu_pd_off); + pmu_set_power_domain(PD_EMMC, pmu_pd_off); + pmu_set_power_domain(PD_VIO, pmu_pd_off); + pmu_set_power_domain(PD_SD, pmu_pd_off); + pmu_set_power_domain(PD_PERIHP, pmu_pd_off); clk_gate_con_restore(); } @@ -371,6 +376,16 @@ static void pmu_power_domains_resume(void) pmu_set_power_domain(PD_TCPD0, pmu_pd_on); if (!(pmu_powerdomain_state & BIT(PD_GPU))) pmu_set_power_domain(PD_GPU, pmu_pd_on); + if (!(pmu_powerdomain_state & BIT(PD_USB3))) + pmu_set_power_domain(PD_USB3, pmu_pd_on); + if (!(pmu_powerdomain_state & BIT(PD_EMMC))) + pmu_set_power_domain(PD_EMMC, pmu_pd_on); + if (!(pmu_powerdomain_state & BIT(PD_VIO))) + pmu_set_power_domain(PD_VIO, pmu_pd_on); + if (!(pmu_powerdomain_state & BIT(PD_SD))) + pmu_set_power_domain(PD_SD, pmu_pd_on); + if (!(pmu_powerdomain_state & BIT(PD_PERIHP))) + pmu_set_power_domain(PD_PERIHP, pmu_pd_on); qos_restore(); clk_gate_con_restore(); } @@ -828,6 +843,7 @@ static void sys_slp_config(void) BIT_WITH_WMSK(PMU_CLR_GIC2_CORE_L_HW)); slp_mode_cfg = BIT(PMU_PWR_MODE_EN) | + BIT(PMU_INPUT_CLAMP_EN) | BIT(PMU_POWER_OFF_REQ_CFG) | BIT(PMU_CPU0_PD_EN) | BIT(PMU_L2_FLUSH_EN) | @@ -841,7 +857,9 @@ static void sys_slp_config(void) BIT(PMU_DDRC0_GATING_EN) | BIT(PMU_DDRC1_GATING_EN) | BIT(PMU_DDRIO0_RET_EN) | + BIT(PMU_DDRIO0_RET_DE_REQ) | BIT(PMU_DDRIO1_RET_EN) | + BIT(PMU_DDRIO1_RET_DE_REQ) | BIT(PMU_DDRIO_RET_HW_DE_REQ) | BIT(PMU_CENTER_PD_EN) | BIT(PMU_PERILP_PD_EN) | @@ -1323,7 +1341,7 @@ int rockchip_soc_sys_pwr_dm_suspend(void) BIT(PMU_CLR_PERILP) | BIT(PMU_CLR_PERILPM0) | BIT(PMU_CLR_GIC)); - + set_pmu_rsthold(); sys_slp_config(); m0_configure_suspend(); @@ -1449,7 +1467,7 @@ int rockchip_soc_sys_pwr_dm_resume(void) 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/soc/soc.c b/plat/rockchip/rk3399/drivers/soc/soc.c index 175d542756..7dd0b72e25 100644 --- a/plat/rockchip/rk3399/drivers/soc/soc.c +++ b/plat/rockchip/rk3399/drivers/soc/soc.c @@ -224,6 +224,47 @@ static void _pll_resume(uint32_t pll_id) set_pll_normal_mode(pll_id); } +void set_pmu_rsthold(void) +{ + uint32_t rstnhold_cofig0; + uint32_t rstnhold_cofig1; + + slp_data.pmucru_rstnhold_con0 = mmio_read_32(PMUCRU_BASE + + PMUCRU_RSTNHOLD_CON0); + 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) | + BIT_WITH_WMSK(HRESETN_CM0S_PMU_HOLD) | + BIT_WITH_WMSK(HRESETN_CM0S_NOC_PMU_HOLD) | + BIT_WITH_WMSK(DRESETN_CM0S_PMU_HOLD) | + BIT_WITH_WMSK(POESETN_CM0S_PMU_HOLD) | + BIT_WITH_WMSK(PRESETN_TIMER_PMU_0_1_HOLD) | + BIT_WITH_WMSK(RESETN_TIMER_PMU_0_HOLD) | + BIT_WITH_WMSK(RESETN_TIMER_PMU_1_HOLD) | + BIT_WITH_WMSK(PRESETN_UART_M0_PMU_HOLD) | + BIT_WITH_WMSK(RESETN_UART_M0_PMU_HOLD) | + BIT_WITH_WMSK(PRESETN_WDT_PMU_HOLD); + rstnhold_cofig1 = BIT_WITH_WMSK(PRESETN_RKPWM_PMU_HOLD) | + BIT_WITH_WMSK(PRESETN_PMUGRF_HOLD) | + BIT_WITH_WMSK(PRESETN_SGRF_HOLD) | + BIT_WITH_WMSK(PRESETN_GPIO0_HOLD) | + BIT_WITH_WMSK(PRESETN_GPIO1_HOLD) | + BIT_WITH_WMSK(PRESETN_CRU_PMU_HOLD) | + BIT_WITH_WMSK(PRESETN_PVTM_PMU_HOLD); + + mmio_write_32(PMUCRU_BASE + PMUCRU_RSTNHOLD_CON0, rstnhold_cofig0); + mmio_write_32(PMUCRU_BASE + PMUCRU_RSTNHOLD_CON1, rstnhold_cofig1); +} + +void restore_pmu_rsthold(void) +{ + mmio_write_32(PMUCRU_BASE + PMUCRU_RSTNHOLD_CON0, + slp_data.pmucru_rstnhold_con0 | REG_SOC_WMSK); + mmio_write_32(PMUCRU_BASE + PMUCRU_RSTNHOLD_CON1, + slp_data.pmucru_rstnhold_con1 | REG_SOC_WMSK); +} + /** * enable_dvfs_plls - To resume the specific PLLs * diff --git a/plat/rockchip/rk3399/drivers/soc/soc.h b/plat/rockchip/rk3399/drivers/soc/soc.h index c418337313..6100d95581 100644 --- a/plat/rockchip/rk3399/drivers/soc/soc.h +++ b/plat/rockchip/rk3399/drivers/soc/soc.h @@ -56,6 +56,43 @@ #define PMUCRU_GATE_CON(n) (0x100 + (n) * 4) #define CRU_GATE_CON(n) (0x300 + (n) * 4) +#define PMUCRU_RSTNHOLD_CON0 0x120 +enum { + PRESETN_NOC_PMU_HOLD = 1, + PRESETN_INTMEM_PMU_HOLD, + HRESETN_CM0S_PMU_HOLD, + HRESETN_CM0S_NOC_PMU_HOLD, + DRESETN_CM0S_PMU_HOLD, + POESETN_CM0S_PMU_HOLD, + PRESETN_SPI3_HOLD, + RESETN_SPI3_HOLD, + PRESETN_TIMER_PMU_0_1_HOLD, + RESETN_TIMER_PMU_0_HOLD, + RESETN_TIMER_PMU_1_HOLD, + PRESETN_UART_M0_PMU_HOLD, + RESETN_UART_M0_PMU_HOLD, + PRESETN_WDT_PMU_HOLD +}; + +#define PMUCRU_RSTNHOLD_CON1 0x124 +enum { + PRESETN_I2C0_HOLD, + PRESETN_I2C4_HOLD, + PRESETN_I2C8_HOLD, + PRESETN_MAILBOX_PMU_HOLD, + PRESETN_RKPWM_PMU_HOLD, + PRESETN_PMUGRF_HOLD, + PRESETN_SGRF_HOLD, + PRESETN_GPIO0_HOLD, + PRESETN_GPIO1_HOLD, + PRESETN_CRU_PMU_HOLD, + PRESETN_INTR_ARB_HOLD, + PRESETN_PVTM_PMU_HOLD, + RESETN_I2C0_HOLD, + RESETN_I2C4_HOLD, + RESETN_I2C8_HOLD +}; + enum plls_id { ALPLL_ID = 0, ABPLL_ID, @@ -97,6 +134,8 @@ struct deepsleep_data_s { 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]; + uint32_t pmucru_rstnhold_con0; + uint32_t pmucru_rstnhold_con1; }; /************************************************** @@ -256,5 +295,6 @@ void restore_abpll(void); void clk_gate_con_save(void); void clk_gate_con_disable(void); void clk_gate_con_restore(void); - +void set_pmu_rsthold(void); +void restore_pmu_rsthold(void); #endif /* __SOC_H__ */ From 4c3770d9cfc1b4710809c88afd87c10e27f30bd8 Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Fri, 26 May 2017 16:17:11 +0800 Subject: [PATCH 5/7] rockchip/rk3399: use slice1 to restore ddr slice1 ~ slice4 we do not have enough pmusram space now, so use slice1 to restore ddr slice1 ~ slice4, that's will save more pmusram space. Change-Id: Id54a7944f33d01a8f244cee6a8a0707bfe4d42da Signed-off-by: Lin Huang --- plat/rockchip/rk3399/drivers/dram/dram.h | 6 +++--- plat/rockchip/rk3399/drivers/dram/suspend.c | 7 +++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/plat/rockchip/rk3399/drivers/dram/dram.h b/plat/rockchip/rk3399/drivers/dram/dram.h index fede7eef83..0780fc3a26 100644 --- a/plat/rockchip/rk3399/drivers/dram/dram.h +++ b/plat/rockchip/rk3399/drivers/dram/dram.h @@ -25,10 +25,10 @@ struct rk3399_ddr_pctl_regs { struct rk3399_ddr_publ_regs { /* - * PHY registers from 0 to 511. - * Only registers 0-90 of each 128 register range are used. + * PHY registers from 0 to 90 for slice1. + * These are used to restore slice1-4 on resume. */ - uint32_t phy0[4][91]; + uint32_t phy0[91]; /* * PHY registers from 512 to 895. * Only registers 0-37 of each 128 register range are used. diff --git a/plat/rockchip/rk3399/drivers/dram/suspend.c b/plat/rockchip/rk3399/drivers/dram/suspend.c index 89f0cd3888..7d4abf0fab 100644 --- a/plat/rockchip/rk3399/drivers/dram/suspend.c +++ b/plat/rockchip/rk3399/drivers/dram/suspend.c @@ -531,7 +531,7 @@ static __pmusramfunc void pctl_cfg(uint32_t ch, for (i = 0; i < 4; i++) sram_regcpy(PHY_REG(ch, 128 * i), - (uintptr_t)&phy_regs->phy0[i][0], 91); + (uintptr_t)&phy_regs->phy0[0], 91); for (i = 0; i < 3; i++) sram_regcpy(PHY_REG(ch, 512 + 128 * i), @@ -698,9 +698,8 @@ void dmc_suspend(void) /* mask DENALI_PI_00_DATA.START, only copy here, will trigger later*/ params_pi[0] &= ~(0x1 << 0); - for (i = 0; i < 4; i++) - dram_regcpy((uintptr_t)&phy_regs->phy0[i][0], - PHY_REG(0, 128 * i), 91); + dram_regcpy((uintptr_t)&phy_regs->phy0[0], + PHY_REG(0, 0), 91); for (i = 0; i < 3; i++) dram_regcpy((uintptr_t)&phy_regs->phy512[i][0], From a7bb3388b1117da48eb0cc77c7512560be56221b Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Sat, 27 May 2017 17:47:01 +0800 Subject: [PATCH 6/7] rockchip/rk3399: do secure timer init in pmusram we will use timer in pmusarm, when logic power rail shutdown, the secure timer will gone, so need to initial it in pmusram. Change-Id: I472e7eec3fc197f56223e6fff9167556c1c5e3bc Signed-off-by: Lin Huang --- plat/rockchip/rk3399/drivers/dram/suspend.c | 2 ++ plat/rockchip/rk3399/drivers/secure/secure.c | 13 +++++++++++++ plat/rockchip/rk3399/drivers/secure/secure.h | 1 + 3 files changed, 16 insertions(+) diff --git a/plat/rockchip/rk3399/drivers/dram/suspend.c b/plat/rockchip/rk3399/drivers/dram/suspend.c index 7d4abf0fab..f66150ae89 100644 --- a/plat/rockchip/rk3399/drivers/dram/suspend.c +++ b/plat/rockchip/rk3399/drivers/dram/suspend.c @@ -726,6 +726,8 @@ __pmusramfunc void dmc_resume(void) uint32_t channel_mask = 0; uint32_t channel; + sram_secure_timer_init(); + /* * we switch ddr clock to abpll when suspend, * we set back to dpll here diff --git a/plat/rockchip/rk3399/drivers/secure/secure.c b/plat/rockchip/rk3399/drivers/secure/secure.c index 6b4f3b894a..589d833c8f 100644 --- a/plat/rockchip/rk3399/drivers/secure/secure.c +++ b/plat/rockchip/rk3399/drivers/secure/secure.c @@ -101,6 +101,19 @@ void secure_watchdog_enable(void) WMSK_BIT(PCLK_WDT_CM0_GATE_SHIFT)); } +__pmusramfunc void sram_secure_timer_init(void) +{ + mmio_write_32(STIMER1_CHN_BASE(5) + TIMER_END_COUNT0, 0xffffffff); + mmio_write_32(STIMER1_CHN_BASE(5) + TIMER_END_COUNT1, 0xffffffff); + + mmio_write_32(STIMER1_CHN_BASE(5) + TIMER_INIT_COUNT0, 0x0); + mmio_write_32(STIMER1_CHN_BASE(5) + TIMER_INIT_COUNT0, 0x0); + + /* auto reload & enable the timer */ + mmio_write_32(STIMER1_CHN_BASE(5) + TIMER_CONTROL_REG, + TIMER_EN | TIMER_FMODE); +} + void secure_timer_init(void) { mmio_write_32(STIMER1_CHN_BASE(5) + TIMER_END_COUNT0, 0xffffffff); diff --git a/plat/rockchip/rk3399/drivers/secure/secure.h b/plat/rockchip/rk3399/drivers/secure/secure.h index 7784ae7614..334805d0d1 100644 --- a/plat/rockchip/rk3399/drivers/secure/secure.h +++ b/plat/rockchip/rk3399/drivers/secure/secure.h @@ -100,5 +100,6 @@ void secure_watchdog_enable(void); void secure_timer_init(void); void secure_sgrf_init(void); void secure_sgrf_ddr_rgn_init(void); +__pmusramfunc void sram_secure_timer_init(void); #endif /* __PLAT_ROCKCHIP_RK3399_DRIVER_SECURE_H__ */ From dbc0f2dcc0cf4960e2a6064ddf50df9ce1513ec0 Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Wed, 14 Jun 2017 17:24:29 +0800 Subject: [PATCH 7/7] rockchip/rk3399: reinitilize secure sgrf when resume when shutdown logic power rail, the some sgrf register value will reset, so need to reinitilize secure. Change-Id: I8ad0570432e54441fe1c60dd2960a81fd58f7163 Signed-off-by: Lin Huang --- plat/rockchip/rk3399/drivers/pmu/pmu.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu.c b/plat/rockchip/rk3399/drivers/pmu/pmu.c index b1c373f7d5..c666c3c200 100644 --- a/plat/rockchip/rk3399/drivers/pmu/pmu.c +++ b/plat/rockchip/rk3399/drivers/pmu/pmu.c @@ -1413,6 +1413,8 @@ int rockchip_soc_sys_pwr_dm_resume(void) enable_dvfs_plls(); secure_watchdog_enable(); + secure_sgrf_init(); + secure_sgrf_ddr_rgn_init(); /* restore clk_ddrc_bpll_src_en gate */ mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(3),