diff options
author | davidcunado-arm <david.cunado@arm.com> | 2017-03-03 23:29:01 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-03-03 23:29:01 +0000 |
commit | 08ba8c6ea98bd3ad50ce89f584d68905d7de7561 (patch) | |
tree | a0263e68f9d5251166bdb45fc8eff30908fde22d /plat/rockchip/common | |
parent | 6feeb0814d3ae8892c3f5e197fe6b95d05e8ca84 (diff) | |
parent | ad2c05671da987bac7528177811d085bc958c630 (diff) |
Merge pull request #854 from rockchip-linux/pm_plat
rockchip: plat_pm.c: Change callbacks implement for our SOCs.
Diffstat (limited to 'plat/rockchip/common')
-rw-r--r-- | plat/rockchip/common/include/plat_private.h | 44 | ||||
-rw-r--r-- | plat/rockchip/common/plat_pm.c | 198 |
2 files changed, 160 insertions, 82 deletions
diff --git a/plat/rockchip/common/include/plat_private.h b/plat/rockchip/common/include/plat_private.h index 9638aae3..7aa0d85d 100644 --- a/plat/rockchip/common/include/plat_private.h +++ b/plat/rockchip/common/include/plat_private.h @@ -46,27 +46,6 @@ 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 __sram_incbin_start, __sram_incbin_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, @@ -121,7 +100,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); @@ -132,6 +110,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 e926345b..09c5397c 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; -} |