rockchip/rk3399: enable PMU_PERILP_PD_EN bit when suspend
authorLin Huang <hl@rock-chips.com>
Tue, 16 May 2017 08:40:46 +0000 (16:40 +0800)
committerCaesar Wang <wxt@rock-chips.com>
Thu, 8 Jun 2017 01:59:53 +0000 (09:59 +0800)
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 <hl@rock-chips.com>
Signed-off-by: Derek Basehore <dbasehore@chromium.org>
Signed-off-by: Caesar Wang <wxt@rock-chips.com>
plat/rockchip/common/include/plat_private.h
plat/rockchip/common/pmusram/pmu_sram_cpus_on.S
plat/rockchip/rk3368/drivers/pmu/pmu.c
plat/rockchip/rk3399/drivers/pmu/pmu.c
plat/rockchip/rk3399/include/plat.ld.S
plat/rockchip/rk3399/include/shared/addressmap_shared.h

index f0aee08777e7f607941a7178227aced1e502d522..b9540f23e6b0499cdb22489ffa865ad4640ea038 100644 (file)
@@ -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;
 
 
 /******************************************************************************
index 64261ac00b216cddc6afc1147ea1d657dd0aa1e1..06dfea95b2c999e503789c3a4356f6c9def532e9 100644 (file)
@@ -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
index ad0b5ffe6fd2a00c87712f91ad9d029ccf6ec386..1767967f34178188d480bfb8cb4db05f81f2e0d2 100644 (file)
@@ -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;
index cf1ea48d5c64ee76b66997f614cb32bb232e9f5f..f6c47f433a6873a166dfeba30a6a4310b6a232a9 100644 (file)
@@ -21,6 +21,7 @@
 #include <rk3399_def.h>
 #include <secure.h>
 #include <soc.h>
+#include <string.h>
 #include <pmu.h>
 #include <pmu_com.h>
 #include <pwm.h>
@@ -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();
index 86ca0494b7c069bcfb29f35923c736c94809c87c..c42d9a9aa36411e9fbdb00aa59ecac47940ea256 100644 (file)
@@ -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 = .;
index d72633e5d6c822803e69e3009d47848f85f663ce..fe23e56909d362a741f68b3659f1c0c8b95a112a 100644 (file)
@@ -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,