From 4e836d3578a6817756a320022f0595ec2ee50f3f Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Tue, 16 May 2017 16:40:46 +0800 Subject: [PATCH] rockchip/rk3399: enable PMU_PERILP_PD_EN bit when suspend with PMU_PERILP_PD_EN bit enable, the soc will shutdown cm0, crypto, dcf, imem(normal SRAM), dmac, bootrom, efuse_con, spi, i2c, uart, saradc, tsadc when suspend, we have M0 code need to run when suspend in normal SRAM, so we need to take care of that. Change-Id: I8c066637e5b81d4b1d53197450b9d592cbe00793 Signed-off-by: Lin Huang Signed-off-by: Derek Basehore Signed-off-by: Caesar Wang --- plat/rockchip/common/include/plat_private.h | 2 + .../common/pmusram/pmu_sram_cpus_on.S | 2 +- plat/rockchip/rk3368/drivers/pmu/pmu.c | 10 ++++ plat/rockchip/rk3399/drivers/pmu/pmu.c | 53 ++++++++++++++++++- plat/rockchip/rk3399/include/plat.ld.S | 9 ++++ .../rk3399/include/shared/addressmap_shared.h | 3 ++ 6 files changed, 76 insertions(+), 3 deletions(-) diff --git a/plat/rockchip/common/include/plat_private.h b/plat/rockchip/common/include/plat_private.h index f0aee087..b9540f23 100644 --- a/plat/rockchip/common/include/plat_private.h +++ b/plat/rockchip/common/include/plat_private.h @@ -24,7 +24,9 @@ extern uint32_t __bl31_sram_text_start, __bl31_sram_text_end; extern uint32_t __bl31_sram_data_start, __bl31_sram_data_end; extern uint32_t __bl31_sram_stack_start, __bl31_sram_stack_end; +extern uint32_t __bl31_sram_text_real_end, __bl31_sram_data_real_end; extern uint32_t __sram_incbin_start, __sram_incbin_end; +extern uint32_t __sram_incbin_real_end; /****************************************************************************** diff --git a/plat/rockchip/common/pmusram/pmu_sram_cpus_on.S b/plat/rockchip/common/pmusram/pmu_sram_cpus_on.S index 64261ac0..06dfea95 100644 --- a/plat/rockchip/common/pmusram/pmu_sram_cpus_on.S +++ b/plat/rockchip/common/pmusram/pmu_sram_cpus_on.S @@ -25,7 +25,7 @@ ddr_resume: mov sp, x2 bl dmc_restore #endif - + bl sram_restore sys_resume: bl psci_entrypoint endfunc pmu_cpuson_entrypoint diff --git a/plat/rockchip/rk3368/drivers/pmu/pmu.c b/plat/rockchip/rk3368/drivers/pmu/pmu.c index ad0b5ffe..1767967f 100644 --- a/plat/rockchip/rk3368/drivers/pmu/pmu.c +++ b/plat/rockchip/rk3368/drivers/pmu/pmu.c @@ -280,6 +280,16 @@ static void nonboot_cpus_off(void) } } +void sram_save(void) +{ + /* TODO: support the sdram save for rk3368 SoCs*/ +} + +void sram_restore(void) +{ + /* TODO: support the sdram restore for rk3368 SoCs */ +} + int rockchip_soc_cores_pwr_dm_on(unsigned long mpidr, uint64_t entrypoint) { uint32_t cpu, cluster; diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu.c b/plat/rockchip/rk3399/drivers/pmu/pmu.c index cf1ea48d..f6c47f43 100644 --- a/plat/rockchip/rk3399/drivers/pmu/pmu.c +++ b/plat/rockchip/rk3399/drivers/pmu/pmu.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -30,6 +31,7 @@ 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]; /* * There are two ways to powering on or off on core. @@ -759,6 +761,18 @@ static void init_pmu_counts(void) mmio_write_32(PMU_BASE + PMU_CENTER_PWRDN_CNT, CYCL_24M_CNT_MS(1)); mmio_write_32(PMU_BASE + PMU_CENTER_PWRUP_CNT, CYCL_24M_CNT_MS(1)); + /* + * when we enable PMU_CLR_PERILP, it will shut down the SRAM, but + * M0 code run in SRAM, and we need it to check whether cpu enter + * FSM status, so we must wait M0 finish their code and enter WFI, + * then we can shutdown SRAM, according FSM order: + * ST_NORMAL->..->ST_SCU_L_PWRDN->..->ST_CENTER_PWRDN->ST_PERILP_PWRDN + * we can add delay when shutdown ST_SCU_L_PWRDN to guarantee M0 get + * the FSM status and enter WFI, then enable PMU_CLR_PERILP. + */ + mmio_write_32(PMU_BASE + PMU_SCU_L_PWRDN_CNT, CYCL_24M_CNT_MS(5)); + mmio_write_32(PMU_BASE + PMU_SCU_L_PWRUP_CNT, CYCL_24M_CNT_US(1)); + /* * Set CPU/GPU to 1 us. * @@ -766,8 +780,6 @@ static void init_pmu_counts(void) * counts here. After all ATF controls all these other bits and also * chooses which clock these counters use. */ - mmio_write_32(PMU_BASE + PMU_SCU_L_PWRDN_CNT, CYCL_24M_CNT_US(1)); - mmio_write_32(PMU_BASE + PMU_SCU_L_PWRUP_CNT, CYCL_24M_CNT_US(1)); mmio_write_32(PMU_BASE + PMU_SCU_B_PWRDN_CNT, CYCL_24M_CNT_US(1)); mmio_write_32(PMU_BASE + PMU_SCU_B_PWRUP_CNT, CYCL_24M_CNT_US(1)); mmio_write_32(PMU_BASE + PMU_GPU_PWRDN_CNT, CYCL_24M_CNT_US(1)); @@ -815,6 +827,8 @@ static void sys_slp_config(void) BIT(PMU_DDRIO1_RET_EN) | BIT(PMU_DDRIO_RET_HW_DE_REQ) | BIT(PMU_CENTER_PD_EN) | + BIT(PMU_PERILP_PD_EN) | + BIT(PMU_CLK_PERILP_SRC_GATE_EN) | BIT(PMU_PLL_PD_EN) | BIT(PMU_CLK_CENTER_SRC_GATE_EN) | BIT(PMU_OSC_DIS) | @@ -1028,6 +1042,36 @@ static void m0_configure_suspend(void) mmio_write_32(M0_PARAM_ADDR + PARAM_M0_FUNC, M0_FUNC_SUSPEND); } +void sram_save(void) +{ + size_t text_size = (char *)&__bl31_sram_text_real_end - + (char *)&__bl31_sram_text_start; + size_t data_size = (char *)&__bl31_sram_data_real_end - + (char *)&__bl31_sram_data_start; + size_t incbin_size = (char *)&__sram_incbin_real_end - + (char *)&__sram_incbin_start; + + memcpy(&store_sram[0], &__bl31_sram_text_start, text_size); + memcpy(&store_sram[text_size], &__bl31_sram_data_start, data_size); + memcpy(&store_sram[text_size + data_size], &__sram_incbin_start, + incbin_size); +} + +void sram_restore(void) +{ + size_t text_size = (char *)&__bl31_sram_text_real_end - + (char *)&__bl31_sram_text_start; + size_t data_size = (char *)&__bl31_sram_data_real_end - + (char *)&__bl31_sram_data_start; + size_t incbin_size = (char *)&__sram_incbin_real_end - + (char *)&__sram_incbin_start; + + memcpy(&__bl31_sram_text_start, &store_sram[0], text_size); + memcpy(&__bl31_sram_data_start, &store_sram[text_size], data_size); + memcpy(&__sram_incbin_start, &store_sram[text_size + data_size], + incbin_size); +} + int rockchip_soc_sys_pwr_dm_suspend(void) { uint32_t wait_cnt = 0; @@ -1045,6 +1089,8 @@ int rockchip_soc_sys_pwr_dm_suspend(void) BIT(PMU_CLR_CCIM0) | BIT(PMU_CLR_CCIM1) | BIT(PMU_CLR_CENTER) | + BIT(PMU_CLR_PERILP) | + BIT(PMU_CLR_PERILPM0) | BIT(PMU_CLR_GIC)); sys_slp_config(); @@ -1090,6 +1136,7 @@ int rockchip_soc_sys_pwr_dm_suspend(void) suspend_apio(); suspend_gpio(); + sram_save(); return 0; } @@ -1171,6 +1218,8 @@ int rockchip_soc_sys_pwr_dm_resume(void) BIT(PMU_CLR_CCIM0) | BIT(PMU_CLR_CCIM1) | BIT(PMU_CLR_CENTER) | + BIT(PMU_CLR_PERILP) | + BIT(PMU_CLR_PERILPM0) | BIT(PMU_CLR_GIC)); plat_rockchip_gic_cpuif_enable(); diff --git a/plat/rockchip/rk3399/include/plat.ld.S b/plat/rockchip/rk3399/include/plat.ld.S index 86ca0494..c42d9a9a 100644 --- a/plat/rockchip/rk3399/include/plat.ld.S +++ b/plat/rockchip/rk3399/include/plat.ld.S @@ -30,24 +30,33 @@ SECTIONS .incbin_sram : ALIGN(4096) { __sram_incbin_start = .; *(.sram.incbin) + __sram_incbin_real_end = .; . = ALIGN(4096); __sram_incbin_end = .; } >SRAM + ASSERT((__sram_incbin_real_end - __sram_incbin_start) <= + SRAM_BIN_LIMIT, ".incbin_sram has exceeded its limit") .text_sram : ALIGN(4096) { __bl31_sram_text_start = .; *(.sram.text) *(.sram.rodata) + __bl31_sram_text_real_end = .; . = ALIGN(4096); __bl31_sram_text_end = .; } >SRAM + ASSERT((__bl31_sram_text_real_end - __bl31_sram_text_start) <= + SRAM_TEXT_LIMIT, ".text_sram has exceeded its limit") .data_sram : ALIGN(4096) { __bl31_sram_data_start = .; *(.sram.data) + __bl31_sram_data_real_end = .; . = ALIGN(4096); __bl31_sram_data_end = .; } >SRAM + ASSERT((__bl31_sram_data_real_end - __bl31_sram_data_start) <= + SRAM_DATA_LIMIT, ".data_sram has exceeded its limit") .stack_sram : ALIGN(4096) { __bl31_sram_stack_start = .; diff --git a/plat/rockchip/rk3399/include/shared/addressmap_shared.h b/plat/rockchip/rk3399/include/shared/addressmap_shared.h index d72633e5..fe23e569 100644 --- a/plat/rockchip/rk3399/include/shared/addressmap_shared.h +++ b/plat/rockchip/rk3399/include/shared/addressmap_shared.h @@ -9,6 +9,9 @@ #define SIZE_K(n) ((n) * 1024) #define SIZE_M(n) ((n) * 1024 * 1024) +#define SRAM_TEXT_LIMIT (4 * 1024) +#define SRAM_DATA_LIMIT (4 * 1024) +#define SRAM_BIN_LIMIT (4 * 1024) /* * The parts of the shared defined registers address with AP and M0, -- 2.30.2