From f32ab4445a669cb44d51c97f388bb363ad22b824 Mon Sep 17 00:00:00 2001 From: "tony.xie" <tony.xie@rock-chips.com> Date: Wed, 1 Mar 2017 11:05:17 +0800 Subject: [PATCH] rockchip: plat_pm.c: Change callbacks implement for our SOCs. Remove struct rockchip_pm_ops_cb and instead of using weak functions implement; in this way we want the codes look clear and simple; Change-Id: Ib9e8a5e932fdfc2b3e6a1ec502c40dfe720ac400 Signed-off-by: tony.xie <tony.xie@rock-chips.com> --- plat/rockchip/common/include/plat_private.h | 44 ++--- plat/rockchip/common/plat_pm.c | 198 ++++++++++++++------ plat/rockchip/rk3399/drivers/pmu/pmu.c | 64 +++---- 3 files changed, 184 insertions(+), 122 deletions(-) diff --git a/plat/rockchip/common/include/plat_private.h b/plat/rockchip/common/include/plat_private.h index b2234a650..ce39d8fcc 100644 --- a/plat/rockchip/common/include/plat_private.h +++ b/plat/rockchip/common/include/plat_private.h @@ -45,27 +45,6 @@ extern uint32_t __bl31_sram_text_start, __bl31_sram_text_end; extern uint32_t __bl31_sram_data_start, __bl31_sram_data_end; -/****************************************************************************** - * For rockchip socs pm ops - ******************************************************************************/ -struct rockchip_pm_ops_cb { - int (*cores_pwr_dm_on)(unsigned long mpidr, uint64_t entrypoint); - int (*cores_pwr_dm_off)(void); - int (*cores_pwr_dm_on_finish)(void); - int (*cores_pwr_dm_suspend)(void); - int (*cores_pwr_dm_resume)(void); - /* hlvl is used for clusters or system level */ - int (*hlvl_pwr_dm_suspend)(uint32_t lvl, plat_local_state_t lvl_state); - int (*hlvl_pwr_dm_resume)(uint32_t lvl, plat_local_state_t lvl_state); - int (*hlvl_pwr_dm_off)(uint32_t lvl, plat_local_state_t lvl_state); - int (*hlvl_pwr_dm_on_finish)(uint32_t lvl, - plat_local_state_t lvl_state); - int (*sys_pwr_dm_suspend)(void); - int (*sys_pwr_dm_resume)(void); - void (*sys_gbl_soft_reset)(void) __dead2; - void (*system_off)(void) __dead2; - void (*sys_pwr_down_wfi)(const psci_power_state_t *state_info) __dead2; -}; /****************************************************************************** * The register have write-mask bits, it is mean, if you want to set the bits, @@ -120,7 +99,6 @@ void plat_rockchip_gic_pcpu_init(void); void plat_rockchip_pmusram_prepare(void); void plat_rockchip_pmu_init(void); void plat_rockchip_soc_init(void); -void plat_setup_rockchip_pm_ops(struct rockchip_pm_ops_cb *ops); uintptr_t plat_get_sec_entrypoint(void); void platform_cpu_warmboot(void); @@ -131,6 +109,28 @@ 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); +int rockchip_soc_cores_pwr_dm_on(unsigned long mpidr, uint64_t entrypoint); +int rockchip_soc_hlvl_pwr_dm_off(uint32_t lvl, + plat_local_state_t lvl_state); +int rockchip_soc_cores_pwr_dm_off(void); +int rockchip_soc_sys_pwr_dm_suspend(void); +int rockchip_soc_cores_pwr_dm_suspend(void); +int rockchip_soc_hlvl_pwr_dm_suspend(uint32_t lvl, + plat_local_state_t lvl_state); +int rockchip_soc_hlvl_pwr_dm_on_finish(uint32_t lvl, + plat_local_state_t lvl_state); +int rockchip_soc_cores_pwr_dm_on_finish(void); +int rockchip_soc_sys_pwr_dm_resume(void); + +int rockchip_soc_hlvl_pwr_dm_resume(uint32_t lvl, + plat_local_state_t lvl_state); +int rockchip_soc_cores_pwr_dm_resume(void); +void __dead2 rockchip_soc_soft_reset(void); +void __dead2 rockchip_soc_system_off(void); +void __dead2 rockchip_soc_cores_pd_pwr_dn_wfi( + const psci_power_state_t *target_state); +void __dead2 rockchip_soc_sys_pd_pwr_dn_wfi(void); + extern const unsigned char rockchip_power_domain_tree_desc[]; extern void *pmu_cpuson_entrypoint_start; diff --git a/plat/rockchip/common/plat_pm.c b/plat/rockchip/common/plat_pm.c index e926345be..09c5397cd 100644 --- a/plat/rockchip/common/plat_pm.c +++ b/plat/rockchip/common/plat_pm.c @@ -48,7 +48,103 @@ static uintptr_t rockchip_sec_entrypoint; -static struct rockchip_pm_ops_cb *rockchip_ops; +#pragma weak rockchip_soc_cores_pwr_dm_on +#pragma weak rockchip_soc_hlvl_pwr_dm_off +#pragma weak rockchip_soc_cores_pwr_dm_off +#pragma weak rockchip_soc_sys_pwr_dm_suspend +#pragma weak rockchip_soc_cores_pwr_dm_suspend +#pragma weak rockchip_soc_hlvl_pwr_dm_suspend +#pragma weak rockchip_soc_hlvl_pwr_dm_on_finish +#pragma weak rockchip_soc_cores_pwr_dm_on_finish +#pragma weak rockchip_soc_sys_pwr_dm_resume +#pragma weak rockchip_soc_hlvl_pwr_dm_resume +#pragma weak rockchip_soc_cores_pwr_dm_resume +#pragma weak rockchip_soc_soft_reset +#pragma weak rockchip_soc_system_off +#pragma weak rockchip_soc_sys_pd_pwr_dn_wfi +#pragma weak rockchip_soc_cores_pd_pwr_dn_wfi + +int rockchip_soc_cores_pwr_dm_on(unsigned long mpidr, uint64_t entrypoint) +{ + return PSCI_E_NOT_SUPPORTED; +} + +int rockchip_soc_hlvl_pwr_dm_off(uint32_t lvl, + plat_local_state_t lvl_state) +{ + return PSCI_E_NOT_SUPPORTED; +} + +int rockchip_soc_cores_pwr_dm_off(void) +{ + return PSCI_E_NOT_SUPPORTED; +} + +int rockchip_soc_sys_pwr_dm_suspend(void) +{ + return PSCI_E_NOT_SUPPORTED; +} + +int rockchip_soc_cores_pwr_dm_suspend(void) +{ + return PSCI_E_NOT_SUPPORTED; +} + +int rockchip_soc_hlvl_pwr_dm_suspend(uint32_t lvl, + plat_local_state_t lvl_state) +{ + return PSCI_E_NOT_SUPPORTED; +} + +int rockchip_soc_hlvl_pwr_dm_on_finish(uint32_t lvl, + plat_local_state_t lvl_state) +{ + return PSCI_E_NOT_SUPPORTED; +} + +int rockchip_soc_cores_pwr_dm_on_finish(void) +{ + return PSCI_E_NOT_SUPPORTED; +} + +int rockchip_soc_sys_pwr_dm_resume(void) +{ + return PSCI_E_NOT_SUPPORTED; +} + +int rockchip_soc_hlvl_pwr_dm_resume(uint32_t lvl, + plat_local_state_t lvl_state) +{ + return PSCI_E_NOT_SUPPORTED; +} + +int rockchip_soc_cores_pwr_dm_resume(void) +{ + return PSCI_E_NOT_SUPPORTED; +} + +void __dead2 rockchip_soc_soft_reset(void) +{ + while (1) + ; +} + +void __dead2 rockchip_soc_system_off(void) +{ + while (1) + ; +} + +void __dead2 rockchip_soc_cores_pd_pwr_dn_wfi( + const psci_power_state_t *target_state) +{ + psci_power_down_wfi(); +} + +void __dead2 rockchip_soc_sys_pd_pwr_dn_wfi(void) +{ + psci_power_down_wfi(); +} /******************************************************************************* * Rockchip standard platform handler called to check the validity of the power @@ -131,10 +227,7 @@ void rockchip_cpu_standby(plat_local_state_t cpu_state) ******************************************************************************/ int rockchip_pwr_domain_on(u_register_t mpidr) { - if (rockchip_ops && rockchip_ops->cores_pwr_dm_on) - rockchip_ops->cores_pwr_dm_on(mpidr, rockchip_sec_entrypoint); - - return PSCI_E_SUCCESS; + return rockchip_soc_cores_pwr_dm_on(mpidr, rockchip_sec_entrypoint); } /******************************************************************************* @@ -145,6 +238,7 @@ void rockchip_pwr_domain_off(const psci_power_state_t *target_state) { uint32_t lvl; plat_local_state_t lvl_state; + int ret; assert(RK_CORE_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE); @@ -153,17 +247,13 @@ void rockchip_pwr_domain_off(const psci_power_state_t *target_state) if (RK_CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) plat_cci_disable(); - if (!rockchip_ops || !rockchip_ops->cores_pwr_dm_off) - return; - - rockchip_ops->cores_pwr_dm_off(); - - if (!rockchip_ops->hlvl_pwr_dm_off) - return; + rockchip_soc_cores_pwr_dm_off(); for (lvl = MPIDR_AFFLVL1; lvl <= PLAT_MAX_PWR_LVL; lvl++) { lvl_state = target_state->pwr_domain_state[lvl]; - rockchip_ops->hlvl_pwr_dm_off(lvl, lvl_state); + ret = rockchip_soc_hlvl_pwr_dm_off(lvl, lvl_state); + if (ret == PSCI_E_NOT_SUPPORTED) + break; } } @@ -175,18 +265,15 @@ void rockchip_pwr_domain_suspend(const psci_power_state_t *target_state) { uint32_t lvl; plat_local_state_t lvl_state; + int ret; if (RK_CORE_PWR_STATE(target_state) != PLAT_MAX_OFF_STATE) return; - if (rockchip_ops) { - if (RK_SYSTEM_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE && - rockchip_ops->sys_pwr_dm_suspend) { - rockchip_ops->sys_pwr_dm_suspend(); - } else if (rockchip_ops->cores_pwr_dm_suspend) { - rockchip_ops->cores_pwr_dm_suspend(); - } - } + if (RK_SYSTEM_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) + rockchip_soc_sys_pwr_dm_suspend(); + else + rockchip_soc_cores_pwr_dm_suspend(); /* Prevent interrupts from spuriously waking up this cpu */ plat_rockchip_gic_cpuif_disable(); @@ -198,12 +285,11 @@ void rockchip_pwr_domain_suspend(const psci_power_state_t *target_state) if (RK_SYSTEM_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) return; - if (!rockchip_ops || !rockchip_ops->hlvl_pwr_dm_suspend) - return; - for (lvl = MPIDR_AFFLVL1; lvl <= PLAT_MAX_PWR_LVL; lvl++) { lvl_state = target_state->pwr_domain_state[lvl]; - rockchip_ops->hlvl_pwr_dm_suspend(lvl, lvl_state); + ret = rockchip_soc_hlvl_pwr_dm_suspend(lvl, lvl_state); + if (ret == PSCI_E_NOT_SUPPORTED) + break; } } @@ -216,22 +302,18 @@ void rockchip_pwr_domain_on_finish(const psci_power_state_t *target_state) { uint32_t lvl; plat_local_state_t lvl_state; + int ret; assert(RK_CORE_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE); - if (!rockchip_ops) - goto comm_finish; - - if (rockchip_ops->hlvl_pwr_dm_on_finish) { - for (lvl = MPIDR_AFFLVL1; lvl <= PLAT_MAX_PWR_LVL; lvl++) { - lvl_state = target_state->pwr_domain_state[lvl]; - rockchip_ops->hlvl_pwr_dm_on_finish(lvl, lvl_state); - } + for (lvl = MPIDR_AFFLVL1; lvl <= PLAT_MAX_PWR_LVL; lvl++) { + lvl_state = target_state->pwr_domain_state[lvl]; + ret = rockchip_soc_hlvl_pwr_dm_on_finish(lvl, lvl_state); + if (ret == PSCI_E_NOT_SUPPORTED) + break; } - if (rockchip_ops->cores_pwr_dm_on_finish) - rockchip_ops->cores_pwr_dm_on_finish(); -comm_finish: + rockchip_soc_cores_pwr_dm_on_finish(); /* Perform the common cluster specific operations */ if (RK_CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) { @@ -257,34 +339,30 @@ void rockchip_pwr_domain_suspend_finish(const psci_power_state_t *target_state) { uint32_t lvl; plat_local_state_t lvl_state; + int ret; /* Nothing to be done on waking up from retention from CPU level */ if (RK_CORE_PWR_STATE(target_state) != PLAT_MAX_OFF_STATE) return; - /* Perform system domain restore if woken up from system suspend */ - if (!rockchip_ops) - goto comm_finish; - if (RK_SYSTEM_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) { - if (rockchip_ops->sys_pwr_dm_resume) - rockchip_ops->sys_pwr_dm_resume(); + rockchip_soc_sys_pwr_dm_resume(); goto comm_finish; } - if (rockchip_ops->hlvl_pwr_dm_resume) { - for (lvl = MPIDR_AFFLVL1; lvl <= PLAT_MAX_PWR_LVL; lvl++) { - lvl_state = target_state->pwr_domain_state[lvl]; - rockchip_ops->hlvl_pwr_dm_resume(lvl, lvl_state); - } + for (lvl = MPIDR_AFFLVL1; lvl <= PLAT_MAX_PWR_LVL; lvl++) { + lvl_state = target_state->pwr_domain_state[lvl]; + ret = rockchip_soc_hlvl_pwr_dm_resume(lvl, lvl_state); + if (ret == PSCI_E_NOT_SUPPORTED) + break; } - if (rockchip_ops->cores_pwr_dm_resume) - rockchip_ops->cores_pwr_dm_resume(); + rockchip_soc_cores_pwr_dm_resume(); + /* * Program the gic per-cpu distributor or re-distributor interface. * For sys power domain operation, resuming of the gic needs to operate - * in rockchip_ops->sys_pwr_dm_resume, according to the sys power mode + * in rockchip_soc_sys_pwr_dm_resume(), according to the sys power mode * implements. */ plat_rockchip_gic_cpuif_enable(); @@ -302,9 +380,7 @@ comm_finish: ******************************************************************************/ static void __dead2 rockchip_system_reset(void) { - assert(rockchip_ops && rockchip_ops->sys_gbl_soft_reset); - - rockchip_ops->sys_gbl_soft_reset(); + rockchip_soc_soft_reset(); } /******************************************************************************* @@ -312,9 +388,16 @@ static void __dead2 rockchip_system_reset(void) ******************************************************************************/ static void __dead2 rockchip_system_poweroff(void) { - assert(rockchip_ops && rockchip_ops->system_off); + rockchip_soc_system_off(); +} - rockchip_ops->system_off(); +static void __dead2 rockchip_pd_pwr_down_wfi( + const psci_power_state_t *target_state) +{ + if (RK_SYSTEM_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) + rockchip_soc_sys_pd_pwr_dn_wfi(); + else + rockchip_soc_cores_pd_pwr_dn_wfi(target_state); } /******************************************************************************* @@ -348,8 +431,3 @@ uintptr_t plat_get_sec_entrypoint(void) assert(rockchip_sec_entrypoint); return rockchip_sec_entrypoint; } - -void plat_setup_rockchip_pm_ops(struct rockchip_pm_ops_cb *ops) -{ - rockchip_ops = ops; -} diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu.c b/plat/rockchip/rk3399/drivers/pmu/pmu.c index 05ca7fdd2..5bb29b3b7 100644 --- a/plat/rockchip/rk3399/drivers/pmu/pmu.c +++ b/plat/rockchip/rk3399/drivers/pmu/pmu.c @@ -623,7 +623,7 @@ static void nonboot_cpus_off(void) } } -static int cores_pwr_domain_on(unsigned long mpidr, uint64_t entrypoint) +int rockchip_soc_cores_pwr_dm_on(unsigned long mpidr, uint64_t entrypoint) { uint32_t cpu_id = plat_core_pos_by_mpidr(mpidr); @@ -635,19 +635,20 @@ static int cores_pwr_domain_on(unsigned long mpidr, uint64_t entrypoint) cpus_power_domain_on(cpu_id); - return 0; + return PSCI_E_SUCCESS; } -static int cores_pwr_domain_off(void) +int rockchip_soc_cores_pwr_dm_off(void) { uint32_t cpu_id = plat_my_core_pos(); cpus_power_domain_off(cpu_id, core_pwr_wfi); - return 0; + return PSCI_E_SUCCESS; } -static int hlvl_pwr_domain_off(uint32_t lvl, plat_local_state_t lvl_state) +int rockchip_soc_hlvl_pwr_dm_off(uint32_t lvl, + plat_local_state_t lvl_state) { switch (lvl) { case MPIDR_AFFLVL1: @@ -657,10 +658,10 @@ static int hlvl_pwr_domain_off(uint32_t lvl, plat_local_state_t lvl_state) break; } - return 0; + return PSCI_E_SUCCESS; } -static int cores_pwr_domain_suspend(void) +int rockchip_soc_cores_pwr_dm_suspend(void) { uint32_t cpu_id = plat_my_core_pos(); @@ -672,10 +673,10 @@ static int cores_pwr_domain_suspend(void) cpus_power_domain_off(cpu_id, core_pwr_wfi_int); - return 0; + return PSCI_E_SUCCESS; } -static int hlvl_pwr_domain_suspend(uint32_t lvl, plat_local_state_t lvl_state) +int rockchip_soc_hlvl_pwr_dm_suspend(uint32_t lvl, plat_local_state_t lvl_state) { switch (lvl) { case MPIDR_AFFLVL1: @@ -685,20 +686,20 @@ static int hlvl_pwr_domain_suspend(uint32_t lvl, plat_local_state_t lvl_state) break; } - return 0; + return PSCI_E_SUCCESS; } -static int cores_pwr_domain_on_finish(void) +int rockchip_soc_cores_pwr_dm_on_finish(void) { uint32_t cpu_id = plat_my_core_pos(); mmio_write_32(PMU_BASE + PMU_CORE_PM_CON(cpu_id), CORES_PM_DISABLE); - return 0; + return PSCI_E_SUCCESS; } -static int hlvl_pwr_domain_on_finish(uint32_t lvl, - plat_local_state_t lvl_state) +int rockchip_soc_hlvl_pwr_dm_on_finish(uint32_t lvl, + plat_local_state_t lvl_state) { switch (lvl) { case MPIDR_AFFLVL1: @@ -708,20 +709,20 @@ static int hlvl_pwr_domain_on_finish(uint32_t lvl, break; } - return 0; + return PSCI_E_SUCCESS; } -static int cores_pwr_domain_resume(void) +int rockchip_soc_cores_pwr_dm_resume(void) { uint32_t cpu_id = plat_my_core_pos(); /* Disable core_pm */ mmio_write_32(PMU_BASE + PMU_CORE_PM_CON(cpu_id), CORES_PM_DISABLE); - return 0; + return PSCI_E_SUCCESS; } -static int hlvl_pwr_domain_resume(uint32_t lvl, plat_local_state_t lvl_state) +int rockchip_soc_hlvl_pwr_dm_resume(uint32_t lvl, plat_local_state_t lvl_state) { switch (lvl) { case MPIDR_AFFLVL1: @@ -730,7 +731,7 @@ static int hlvl_pwr_domain_resume(uint32_t lvl, plat_local_state_t lvl_state) break; } - return 0; + return PSCI_E_SUCCESS; } /** @@ -1097,7 +1098,7 @@ static void m0_reset(void) BITS_WITH_WMASK(0x2f, 0x2f, 0)); } -static int sys_pwr_domain_suspend(void) +int rockchip_soc_sys_pwr_dm_suspend(void) { uint32_t wait_cnt = 0; uint32_t status = 0; @@ -1160,7 +1161,7 @@ static int sys_pwr_domain_suspend(void) return 0; } -static int sys_pwr_domain_resume(void) +int rockchip_soc_sys_pwr_dm_resume(void) { uint32_t wait_cnt = 0; uint32_t status = 0; @@ -1247,7 +1248,7 @@ static int sys_pwr_domain_resume(void) return 0; } -void __dead2 soc_soft_reset(void) +void __dead2 rockchip_soc_soft_reset(void) { struct gpio_info *rst_gpio; @@ -1264,7 +1265,7 @@ void __dead2 soc_soft_reset(void) ; } -void __dead2 soc_system_off(void) +void __dead2 rockchip_soc_system_off(void) { struct gpio_info *poweroff_gpio; @@ -1289,28 +1290,11 @@ void __dead2 soc_system_off(void) ; } -static struct rockchip_pm_ops_cb pm_ops = { - .cores_pwr_dm_on = cores_pwr_domain_on, - .cores_pwr_dm_off = cores_pwr_domain_off, - .cores_pwr_dm_on_finish = cores_pwr_domain_on_finish, - .cores_pwr_dm_suspend = cores_pwr_domain_suspend, - .cores_pwr_dm_resume = cores_pwr_domain_resume, - .hlvl_pwr_dm_suspend = hlvl_pwr_domain_suspend, - .hlvl_pwr_dm_resume = hlvl_pwr_domain_resume, - .hlvl_pwr_dm_off = hlvl_pwr_domain_off, - .hlvl_pwr_dm_on_finish = hlvl_pwr_domain_on_finish, - .sys_pwr_dm_suspend = sys_pwr_domain_suspend, - .sys_pwr_dm_resume = sys_pwr_domain_resume, - .sys_gbl_soft_reset = soc_soft_reset, - .system_off = soc_system_off, -}; - void plat_rockchip_pmu_init(void) { uint32_t cpu; rockchip_pd_lock_init(); - plat_setup_rockchip_pm_ops(&pm_ops); /* register requires 32bits mode, switch it to 32 bits */ cpu_warm_boot_addr = (uint64_t)platform_cpu_warmboot; -- GitLab