diff options
Diffstat (limited to 'plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm.c')
-rw-r--r-- | plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm.c | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm.c b/plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm.c index d6d4af742..b483c367d 100644 --- a/plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm.c +++ b/plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm.c @@ -12,6 +12,8 @@ #include <lib/spinlock.h> #include <mt_cpu_pm_cpc.h> +#include <mt_lp_irqremain.h> +#include <mt_lp_rm.h> #include <mt_mcdi.h> #include <plat_mtk_lpm.h> #include <plat_pm.h> @@ -73,27 +75,49 @@ static int pwr_mcusys_pwron(unsigned int cpu, const psci_power_state_t *state) static int pwr_mcusys_pwron_finished(unsigned int cpu, const psci_power_state_t *state) { + int state_id = state->pwr_domain_state[MTK_AFFLVL_MCUSYS]; + if (!IS_MCUSYS_OFF_STATE(state) || (plat_mt_lp_cpu_rc < 0)) { return -1; } + mt_lp_rm_reset_constraint(plat_mt_lp_cpu_rc, cpu, state_id); + mt_lp_irqremain_release(); + return 0; } static int pwr_mcusys_pwrdwn(unsigned int cpu, const psci_power_state_t *state) { + int state_id = state->pwr_domain_state[MTK_AFFLVL_MCUSYS]; + if (!IS_MCUSYS_OFF_STATE(state)) { goto mt_pwr_mcusysoff_break; } - if (mcdi_try_init() != 0) { /* not ready to process mcusys-off */ + if (mcdi_try_init() != 0) { goto mt_pwr_mcusysoff_break; } + if (mtk_cpc_mcusys_off_prepare() != CPC_SUCCESS) { + goto mt_pwr_mcusysoff_break; + } + + plat_mt_lp_cpu_rc = + mt_lp_rm_find_and_run_constraint(0, cpu, state_id, NULL); + + if (plat_mt_lp_cpu_rc < 0) { + goto mt_pwr_mcusysoff_reflect; + } + + mt_lp_irqremain_aquire(); + return 0; -mt_pwr_mcusysoff_break: +mt_pwr_mcusysoff_reflect: + mtk_cpc_mcusys_off_reflect(); +mt_pwr_mcusysoff_break: plat_mt_lp_cpu_rc = -1; return -1; @@ -119,5 +143,7 @@ const struct mt_lpm_tz *mt_plat_cpu_pm_init(void) INFO("MCDI init done.\n"); } + mt_lp_irqremain_init(); + return &plat_pm; } |