#include <rk3399_def.h>
#include <secure.h>
#include <soc.h>
+#include <string.h>
#include <pmu.h>
#include <pmu_com.h>
#include <pwm.h>
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.
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.
*
* 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));
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) |
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;
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();
suspend_apio();
suspend_gpio();
+ sram_save();
return 0;
}
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();
.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 = .;