aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plat/rockchip/common/plat_pm.c13
-rw-r--r--plat/rockchip/rk3399/drivers/pmu/pmu.c83
-rw-r--r--plat/rockchip/rk3399/drivers/soc/soc.c16
-rw-r--r--plat/rockchip/rk3399/drivers/soc/soc.h12
4 files changed, 67 insertions, 57 deletions
diff --git a/plat/rockchip/common/plat_pm.c b/plat/rockchip/common/plat_pm.c
index d28100d9c..e926345be 100644
--- a/plat/rockchip/common/plat_pm.c
+++ b/plat/rockchip/common/plat_pm.c
@@ -317,18 +317,6 @@ static void __dead2 rockchip_system_poweroff(void)
rockchip_ops->system_off();
}
-static void
-__dead2 rockchip_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state)
-{
- if ((RK_CORE_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) &&
- (rockchip_ops)) {
- if (RK_SYSTEM_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE &&
- rockchip_ops->sys_pwr_down_wfi)
- rockchip_ops->sys_pwr_down_wfi(target_state);
- }
- psci_power_down_wfi();
-}
-
/*******************************************************************************
* Export the platform handlers via plat_rockchip_psci_pm_ops. The rockchip
* standard
@@ -341,7 +329,6 @@ const plat_psci_ops_t plat_rockchip_psci_pm_ops = {
.pwr_domain_suspend = rockchip_pwr_domain_suspend,
.pwr_domain_on_finish = rockchip_pwr_domain_on_finish,
.pwr_domain_suspend_finish = rockchip_pwr_domain_suspend_finish,
- .pwr_domain_pwr_down_wfi = rockchip_pwr_domain_pwr_down_wfi,
.system_reset = rockchip_system_reset,
.system_off = rockchip_system_poweroff,
.validate_power_state = rockchip_validate_power_state,
diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu.c b/plat/rockchip/rk3399/drivers/pmu/pmu.c
index 4ae766cea..8d3f482f4 100644
--- a/plat/rockchip/rk3399/drivers/pmu/pmu.c
+++ b/plat/rockchip/rk3399/drivers/pmu/pmu.c
@@ -48,6 +48,7 @@
#include <pwm.h>
#include <soc.h>
#include <bl31.h>
+#include <rk3399m0.h>
DEFINE_BAKERY_LOCK(rockchip_pd_lock);
@@ -840,8 +841,6 @@ static void sys_slp_config(void)
BIT(PMU_SCU_PD_EN) |
BIT(PMU_CCI_PD_EN) |
BIT(PMU_CLK_CORE_SRC_GATE_EN) |
- BIT(PMU_PERILP_PD_EN) |
- BIT(PMU_CLK_PERILP_SRC_GATE_EN) |
BIT(PMU_ALIVE_USE_LF) |
BIT(PMU_SREF0_ENTER_EN) |
BIT(PMU_SREF1_ENTER_EN) |
@@ -1058,6 +1057,38 @@ static void resume_gpio(void)
}
}
+static void m0_clock_init(void)
+{
+ /* enable clocks for M0 */
+ mmio_write_32(PMUCRU_BASE + PMUCRU_CLKGATE_CON2,
+ BITS_WITH_WMASK(0x0, 0x2f, 0));
+
+ /* switch the parent to xin24M and div == 1 */
+ mmio_write_32(PMUCRU_BASE + PMUCRU_CLKSEL_CON0,
+ BIT_WITH_WMSK(15) | BITS_WITH_WMASK(0x0, 0x1f, 8));
+
+ /* start M0 */
+ mmio_write_32(PMUCRU_BASE + PMUCRU_SOFTRST_CON0,
+ BITS_WITH_WMASK(0x0, 0x24, 0));
+
+ /* gating disable for M0 */
+ mmio_write_32(PMUCRU_BASE + PMUCRU_GATEDIS_CON0, BIT_WITH_WMSK(1));
+}
+
+static void m0_reset(void)
+{
+ /* stop M0 */
+ mmio_write_32(PMUCRU_BASE + PMUCRU_SOFTRST_CON0,
+ BITS_WITH_WMASK(0x24, 0x24, 0));
+
+ /* recover gating bit for M0 */
+ mmio_write_32(PMUCRU_BASE + PMUCRU_GATEDIS_CON0, WMSK_BIT(1));
+
+ /* disable clocks for M0 */
+ mmio_write_32(PMUCRU_BASE + PMUCRU_CLKGATE_CON2,
+ BITS_WITH_WMASK(0x2f, 0x2f, 0));
+}
+
static int sys_pwr_domain_suspend(void)
{
uint32_t wait_cnt = 0;
@@ -1071,12 +1102,12 @@ static int sys_pwr_domain_suspend(void)
BIT(PMU_CLR_CCIM0) |
BIT(PMU_CLR_CCIM1) |
BIT(PMU_CLR_CENTER) |
- BIT(PMU_CLR_PERILP) |
- BIT(PMU_CLR_PMU) |
- BIT(PMU_CLR_PERILPM0) |
BIT(PMU_CLR_GIC));
sys_slp_config();
+
+ m0_clock_init();
+
pmu_sgrf_rst_hld();
mmio_write_32(SGRF_BASE + SGRF_SOC_CON0_1(1),
@@ -1111,6 +1142,7 @@ static int sys_pwr_domain_suspend(void)
disable_dvfs_plls();
disable_pwms();
disable_nodvfs_plls();
+
suspend_apio();
suspend_gpio();
@@ -1186,12 +1218,12 @@ static int sys_pwr_domain_resume(void)
BIT(PMU_CLR_CCIM0) |
BIT(PMU_CLR_CCIM1) |
BIT(PMU_CLR_CENTER) |
- BIT(PMU_CLR_PERILP) |
- BIT(PMU_CLR_PMU) |
BIT(PMU_CLR_GIC));
plat_rockchip_gic_cpuif_enable();
+ m0_reset();
+
return 0;
}
@@ -1236,42 +1268,6 @@ void __dead2 soc_system_off(void)
while (1)
;
}
-static void __dead2 sys_pwr_down_wfi(const psci_power_state_t *target_state)
-{
- uint32_t wakeup_status;
-
- /*
- * Check wakeup status and abort suspend early if we see a wakeup
- * event.
- *
- * NOTE: technically I we're supposed to just execute a wfi here and
- * we'll either execute a normal suspend/resume or the wfi will be
- * treated as a no-op if a wake event was present and caused an abort
- * of the suspend/resume. For some reason that's not happening and if
- * we execute the wfi while a wake event is pending then the whole
- * system wedges.
- *
- * Until the above is solved this extra check prevents system wedges in
- * most cases but there is still a small race condition between checking
- * PMU_WAKEUP_STATUS and executing wfi. If a wake event happens in
- * there then we will die.
- */
- wakeup_status = mmio_read_32(PMU_BASE + PMU_WAKEUP_STATUS);
- if (wakeup_status) {
- WARN("early wake, will not enter power mode.\n");
-
- mmio_write_32(PMU_BASE + PMU_PWRMODE_CON, 0);
-
- disable_mmu_icache_el3();
- bl31_warm_entrypoint();
-
- while (1)
- ;
- } else {
- /* Enter WFI */
- psci_power_down_wfi();
- }
-}
static struct rockchip_pm_ops_cb pm_ops = {
.cores_pwr_dm_on = cores_pwr_domain_on,
@@ -1287,7 +1283,6 @@ static struct rockchip_pm_ops_cb pm_ops = {
.sys_pwr_dm_resume = sys_pwr_domain_resume,
.sys_gbl_soft_reset = soc_soft_reset,
.system_off = soc_system_off,
- .sys_pwr_down_wfi = sys_pwr_down_wfi,
};
void plat_rockchip_pmu_init(void)
diff --git a/plat/rockchip/rk3399/drivers/soc/soc.c b/plat/rockchip/rk3399/drivers/soc/soc.c
index 29bf6dda3..2dc70ec2e 100644
--- a/plat/rockchip/rk3399/drivers/soc/soc.c
+++ b/plat/rockchip/rk3399/drivers/soc/soc.c
@@ -35,6 +35,7 @@
#include <platform_def.h>
#include <plat_private.h>
#include <rk3399_def.h>
+#include <rk3399m0.h>
#include <soc.h>
/* Table of regions to map using the MMU. */
@@ -380,6 +381,20 @@ void __dead2 soc_global_soft_reset(void)
;
}
+static void soc_m0_init(void)
+{
+ /* secure config for pmu M0 */
+ mmio_write_32(SGRF_BASE + SGRF_PMU_CON(0), WMSK_BIT(7));
+
+ /* set the execute address for M0 */
+ mmio_write_32(SGRF_BASE + SGRF_PMU_CON(3),
+ BITS_WITH_WMASK((M0_BINCODE_BASE >> 12) & 0xffff,
+ 0xffff, 0));
+ mmio_write_32(SGRF_BASE + SGRF_PMU_CON(7),
+ BITS_WITH_WMASK((M0_BINCODE_BASE >> 28) & 0xf,
+ 0xf, 0));
+}
+
void plat_rockchip_soc_init(void)
{
secure_timer_init();
@@ -387,4 +402,5 @@ void plat_rockchip_soc_init(void)
sgrf_init();
soc_global_soft_reset_init();
plat_rockchip_gpio_init();
+ soc_m0_init();
}
diff --git a/plat/rockchip/rk3399/drivers/soc/soc.h b/plat/rockchip/rk3399/drivers/soc/soc.h
index 906452a38..da4cb54e7 100644
--- a/plat/rockchip/rk3399/drivers/soc/soc.h
+++ b/plat/rockchip/rk3399/drivers/soc/soc.h
@@ -293,6 +293,18 @@ struct deepsleep_data_s {
#define GRF_DDRC1_CON0 0xe388
#define GRF_DDRC1_CON1 0xe38c
+#define PMUCRU_CLKSEL_CON0 0x0080
+#define PMUCRU_CLKGATE_CON2 0x0108
+#define PMUCRU_SOFTRST_CON0 0x0110
+#define PMUCRU_GATEDIS_CON0 0x0130
+
+#define SGRF_SOC_CON6 0x0e018
+#define SGRF_PERILP_CON0 0x08100
+#define SGRF_PERILP_CON(n) (SGRF_PERILP_CON0 + (n) * 4)
+#define SGRF_PMU_CON0 0x0c100
+#define SGRF_PMU_CON(n) (SGRF_PMU_CON0 + (n) * 4)
+#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),