1f85f37d4SNina Wu /* 2f85f37d4SNina Wu * Copyright (c) 2020, MediaTek Inc. All rights reserved. 3f85f37d4SNina Wu * 4f85f37d4SNina Wu * SPDX-License-Identifier: BSD-3-Clause 5f85f37d4SNina Wu */ 6f85f37d4SNina Wu 7f85f37d4SNina Wu /* common headers */ 882c00c2fSJames Liao #include <assert.h> 982c00c2fSJames Liao 100f408247SNina Wu #include <arch_helpers.h> 110f408247SNina Wu #include <common/debug.h> 120f408247SNina Wu #include <drivers/gpio.h> 13f85f37d4SNina Wu #include <lib/psci/psci.h> 14f85f37d4SNina Wu 1582c00c2fSJames Liao /* platform specific headers */ 1682c00c2fSJames Liao #include <mt_gic_v3.h> 178709c939Selly.chiang #include <mtk_ptp3_common.h> 1882c00c2fSJames Liao #include <mtspmc.h> 1982c00c2fSJames Liao #include <plat/common/platform.h> 20*5183e637SRex-BC Chen #include <plat_dfd.h> 2182c00c2fSJames Liao #include <plat_mtk_lpm.h> 220f408247SNina Wu #include <plat_params.h> 2382c00c2fSJames Liao #include <plat_pm.h> 2426f3dbe2SHsin-Hsiung Wang #include <pmic.h> 25b686d330SYuchen Huang #include <rtc.h> 26f85f37d4SNina Wu 2782c00c2fSJames Liao /* 2882c00c2fSJames Liao * Cluster state request: 2982c00c2fSJames Liao * [0] : The CPU requires cluster power down 3082c00c2fSJames Liao * [1] : The CPU requires cluster power on 3182c00c2fSJames Liao */ 3282c00c2fSJames Liao #define coordinate_cluster(onoff) write_clusterpwrdn_el1(onoff) 3382c00c2fSJames Liao #define coordinate_cluster_pwron() coordinate_cluster(1) 3482c00c2fSJames Liao #define coordinate_cluster_pwroff() coordinate_cluster(0) 3582c00c2fSJames Liao 3682c00c2fSJames Liao /* platform secure entry point */ 3782c00c2fSJames Liao static uintptr_t secure_entrypoint; 3882c00c2fSJames Liao /* per-CPU power state */ 3982c00c2fSJames Liao static unsigned int plat_power_state[PLATFORM_CORE_COUNT]; 4082c00c2fSJames Liao 4182c00c2fSJames Liao /* platform CPU power domain - ops */ 4282c00c2fSJames Liao static const struct mt_lpm_tz *plat_mt_pm; 4382c00c2fSJames Liao 4482c00c2fSJames Liao #define plat_mt_pm_invoke(_name, _cpu, _state) ({ \ 4582c00c2fSJames Liao int ret = -1; \ 4682c00c2fSJames Liao if (plat_mt_pm != NULL && plat_mt_pm->_name != NULL) { \ 4782c00c2fSJames Liao ret = plat_mt_pm->_name(_cpu, _state); \ 4882c00c2fSJames Liao } \ 4982c00c2fSJames Liao ret; }) 5082c00c2fSJames Liao 5182c00c2fSJames Liao #define plat_mt_pm_invoke_no_check(_name, _cpu, _state) ({ \ 5282c00c2fSJames Liao if (plat_mt_pm != NULL && plat_mt_pm->_name != NULL) { \ 5382c00c2fSJames Liao (void) plat_mt_pm->_name(_cpu, _state); \ 5482c00c2fSJames Liao } \ 5582c00c2fSJames Liao }) 5682c00c2fSJames Liao 5782c00c2fSJames Liao /* 5882c00c2fSJames Liao * Common MTK_platform operations to power on/off a 5982c00c2fSJames Liao * CPU in response to a CPU_ON, CPU_OFF or CPU_SUSPEND request. 6082c00c2fSJames Liao */ 6182c00c2fSJames Liao 6282c00c2fSJames Liao static void plat_cpu_pwrdwn_common(unsigned int cpu, 6382c00c2fSJames Liao const psci_power_state_t *state, unsigned int req_pstate) 6482c00c2fSJames Liao { 6582c00c2fSJames Liao assert(cpu == plat_my_core_pos()); 6682c00c2fSJames Liao 6782c00c2fSJames Liao plat_mt_pm_invoke_no_check(pwr_cpu_dwn, cpu, state); 6882c00c2fSJames Liao 6982c00c2fSJames Liao if ((psci_get_pstate_pwrlvl(req_pstate) >= MTK_AFFLVL_CLUSTER) || 7082c00c2fSJames Liao (req_pstate == 0U)) { /* hotplug off */ 7182c00c2fSJames Liao coordinate_cluster_pwroff(); 7282c00c2fSJames Liao } 7382c00c2fSJames Liao 7482c00c2fSJames Liao /* Prevent interrupts from spuriously waking up this CPU */ 7582c00c2fSJames Liao mt_gic_rdistif_save(); 7682c00c2fSJames Liao gicv3_cpuif_disable(cpu); 7782c00c2fSJames Liao gicv3_rdistif_off(cpu); 788709c939Selly.chiang /* PTP3 config */ 798709c939Selly.chiang ptp3_deinit(cpu); 8082c00c2fSJames Liao } 8182c00c2fSJames Liao 8282c00c2fSJames Liao static void plat_cpu_pwron_common(unsigned int cpu, 8382c00c2fSJames Liao const psci_power_state_t *state, unsigned int req_pstate) 8482c00c2fSJames Liao { 8582c00c2fSJames Liao assert(cpu == plat_my_core_pos()); 8682c00c2fSJames Liao 8782c00c2fSJames Liao plat_mt_pm_invoke_no_check(pwr_cpu_on, cpu, state); 8882c00c2fSJames Liao 8982c00c2fSJames Liao coordinate_cluster_pwron(); 9082c00c2fSJames Liao 9182c00c2fSJames Liao /* 9282c00c2fSJames Liao * If mcusys does power down before then restore 9382c00c2fSJames Liao * all CPUs' GIC Redistributors 9482c00c2fSJames Liao */ 9582c00c2fSJames Liao if (IS_MCUSYS_OFF_STATE(state)) { 9682c00c2fSJames Liao mt_gic_rdistif_restore_all(); 9782c00c2fSJames Liao } else { 98df60025fSRoger Lu gicv3_rdistif_on(cpu); 99df60025fSRoger Lu gicv3_cpuif_enable(cpu); 100df60025fSRoger Lu mt_gic_rdistif_init(); 10182c00c2fSJames Liao mt_gic_rdistif_restore(); 10282c00c2fSJames Liao } 1038709c939Selly.chiang 1048709c939Selly.chiang /* PTP3 config */ 1058709c939Selly.chiang ptp3_init(cpu); 10682c00c2fSJames Liao } 10782c00c2fSJames Liao 10882c00c2fSJames Liao /* 10982c00c2fSJames Liao * Common MTK_platform operations to power on/off a 11082c00c2fSJames Liao * cluster in response to a CPU_ON, CPU_OFF or CPU_SUSPEND request. 11182c00c2fSJames Liao */ 11282c00c2fSJames Liao 11382c00c2fSJames Liao static void plat_cluster_pwrdwn_common(unsigned int cpu, 11482c00c2fSJames Liao const psci_power_state_t *state, unsigned int req_pstate) 11582c00c2fSJames Liao { 11682c00c2fSJames Liao assert(cpu == plat_my_core_pos()); 11782c00c2fSJames Liao 11882c00c2fSJames Liao if (plat_mt_pm_invoke(pwr_cluster_dwn, cpu, state) != 0) { 11982c00c2fSJames Liao coordinate_cluster_pwron(); 12082c00c2fSJames Liao 12182c00c2fSJames Liao /* TODO: return on fail. 12282c00c2fSJames Liao * Add a 'return' here before adding any code following 12382c00c2fSJames Liao * the if-block. 12482c00c2fSJames Liao */ 12582c00c2fSJames Liao } 12682c00c2fSJames Liao } 12782c00c2fSJames Liao 12882c00c2fSJames Liao static void plat_cluster_pwron_common(unsigned int cpu, 12982c00c2fSJames Liao const psci_power_state_t *state, unsigned int req_pstate) 13082c00c2fSJames Liao { 13182c00c2fSJames Liao assert(cpu == plat_my_core_pos()); 13282c00c2fSJames Liao 13382c00c2fSJames Liao if (plat_mt_pm_invoke(pwr_cluster_on, cpu, state) != 0) { 13482c00c2fSJames Liao /* TODO: return on fail. 13582c00c2fSJames Liao * Add a 'return' here before adding any code following 13682c00c2fSJames Liao * the if-block. 13782c00c2fSJames Liao */ 13882c00c2fSJames Liao } 13982c00c2fSJames Liao } 14082c00c2fSJames Liao 14182c00c2fSJames Liao /* 14282c00c2fSJames Liao * Common MTK_platform operations to power on/off a 14382c00c2fSJames Liao * mcusys in response to a CPU_ON, CPU_OFF or CPU_SUSPEND request. 14482c00c2fSJames Liao */ 14582c00c2fSJames Liao 14682c00c2fSJames Liao static void plat_mcusys_pwrdwn_common(unsigned int cpu, 14782c00c2fSJames Liao const psci_power_state_t *state, unsigned int req_pstate) 14882c00c2fSJames Liao { 14982c00c2fSJames Liao assert(cpu == plat_my_core_pos()); 15082c00c2fSJames Liao 15182c00c2fSJames Liao if (plat_mt_pm_invoke(pwr_mcusys_dwn, cpu, state) != 0) { 15282c00c2fSJames Liao return; /* return on fail */ 15382c00c2fSJames Liao } 15482c00c2fSJames Liao 15582c00c2fSJames Liao mt_gic_distif_save(); 15682c00c2fSJames Liao gic_sgi_save_all(); 15782c00c2fSJames Liao } 15882c00c2fSJames Liao 15982c00c2fSJames Liao static void plat_mcusys_pwron_common(unsigned int cpu, 16082c00c2fSJames Liao const psci_power_state_t *state, unsigned int req_pstate) 16182c00c2fSJames Liao { 16282c00c2fSJames Liao assert(cpu == plat_my_core_pos()); 16382c00c2fSJames Liao 16482c00c2fSJames Liao if (plat_mt_pm_invoke(pwr_mcusys_on, cpu, state) != 0) { 16582c00c2fSJames Liao return; /* return on fail */ 16682c00c2fSJames Liao } 16782c00c2fSJames Liao 16882c00c2fSJames Liao mt_gic_init(); 16982c00c2fSJames Liao mt_gic_distif_restore(); 17082c00c2fSJames Liao gic_sgi_restore_all(); 17182c00c2fSJames Liao 172*5183e637SRex-BC Chen dfd_resume(); 173*5183e637SRex-BC Chen 17482c00c2fSJames Liao plat_mt_pm_invoke_no_check(pwr_mcusys_on_finished, cpu, state); 17582c00c2fSJames Liao } 17682c00c2fSJames Liao 17782c00c2fSJames Liao /* 17882c00c2fSJames Liao * plat_psci_ops implementation 17982c00c2fSJames Liao */ 18082c00c2fSJames Liao 18182c00c2fSJames Liao static void plat_cpu_standby(plat_local_state_t cpu_state) 18282c00c2fSJames Liao { 18382c00c2fSJames Liao uint64_t scr; 18482c00c2fSJames Liao 18582c00c2fSJames Liao scr = read_scr_el3(); 18682c00c2fSJames Liao write_scr_el3(scr | SCR_IRQ_BIT | SCR_FIQ_BIT); 18782c00c2fSJames Liao 18882c00c2fSJames Liao isb(); 18982c00c2fSJames Liao dsb(); 19082c00c2fSJames Liao wfi(); 19182c00c2fSJames Liao 19282c00c2fSJames Liao write_scr_el3(scr); 19382c00c2fSJames Liao } 19482c00c2fSJames Liao 19582c00c2fSJames Liao static int plat_power_domain_on(u_register_t mpidr) 19682c00c2fSJames Liao { 19782c00c2fSJames Liao unsigned int cpu = (unsigned int)plat_core_pos_by_mpidr(mpidr); 19882c00c2fSJames Liao unsigned int cluster = 0U; 19982c00c2fSJames Liao 20082c00c2fSJames Liao if (cpu >= PLATFORM_CORE_COUNT) { 20182c00c2fSJames Liao return PSCI_E_INVALID_PARAMS; 20282c00c2fSJames Liao } 20382c00c2fSJames Liao 20482c00c2fSJames Liao if (!spm_get_cluster_powerstate(cluster)) { 20582c00c2fSJames Liao spm_poweron_cluster(cluster); 20682c00c2fSJames Liao } 20782c00c2fSJames Liao 20882c00c2fSJames Liao /* init CPU reset arch as AARCH64 */ 20982c00c2fSJames Liao mcucfg_init_archstate(cluster, cpu, true); 21082c00c2fSJames Liao mcucfg_set_bootaddr(cluster, cpu, secure_entrypoint); 21182c00c2fSJames Liao spm_poweron_cpu(cluster, cpu); 21282c00c2fSJames Liao 21382c00c2fSJames Liao return PSCI_E_SUCCESS; 21482c00c2fSJames Liao } 21582c00c2fSJames Liao 21682c00c2fSJames Liao static void plat_power_domain_on_finish(const psci_power_state_t *state) 21782c00c2fSJames Liao { 21882c00c2fSJames Liao unsigned long mpidr = read_mpidr_el1(); 21982c00c2fSJames Liao unsigned int cpu = (unsigned int)plat_core_pos_by_mpidr(mpidr); 22082c00c2fSJames Liao 22182c00c2fSJames Liao assert(cpu < PLATFORM_CORE_COUNT); 22282c00c2fSJames Liao 22382c00c2fSJames Liao /* Allow IRQs to wakeup this core in IDLE flow */ 22482c00c2fSJames Liao mcucfg_enable_gic_wakeup(0U, cpu); 22582c00c2fSJames Liao 22682c00c2fSJames Liao if (IS_CLUSTER_OFF_STATE(state)) { 22782c00c2fSJames Liao plat_cluster_pwron_common(cpu, state, 0U); 22882c00c2fSJames Liao } 22982c00c2fSJames Liao 23082c00c2fSJames Liao plat_cpu_pwron_common(cpu, state, 0U); 23182c00c2fSJames Liao } 23282c00c2fSJames Liao 23382c00c2fSJames Liao static void plat_power_domain_off(const psci_power_state_t *state) 23482c00c2fSJames Liao { 23582c00c2fSJames Liao unsigned long mpidr = read_mpidr_el1(); 23682c00c2fSJames Liao unsigned int cpu = (unsigned int)plat_core_pos_by_mpidr(mpidr); 23782c00c2fSJames Liao 23882c00c2fSJames Liao assert(cpu < PLATFORM_CORE_COUNT); 23982c00c2fSJames Liao 24082c00c2fSJames Liao plat_cpu_pwrdwn_common(cpu, state, 0U); 24182c00c2fSJames Liao spm_poweroff_cpu(0U, cpu); 24282c00c2fSJames Liao 24382c00c2fSJames Liao /* prevent unintended IRQs from waking up the hot-unplugged core */ 24482c00c2fSJames Liao mcucfg_disable_gic_wakeup(0U, cpu); 24582c00c2fSJames Liao 24682c00c2fSJames Liao if (IS_CLUSTER_OFF_STATE(state)) { 24782c00c2fSJames Liao plat_cluster_pwrdwn_common(cpu, state, 0U); 24882c00c2fSJames Liao } 24982c00c2fSJames Liao } 25082c00c2fSJames Liao 25182c00c2fSJames Liao static void plat_power_domain_suspend(const psci_power_state_t *state) 25282c00c2fSJames Liao { 25382c00c2fSJames Liao unsigned int cpu = plat_my_core_pos(); 25482c00c2fSJames Liao 25582c00c2fSJames Liao assert(cpu < PLATFORM_CORE_COUNT); 25682c00c2fSJames Liao 25782c00c2fSJames Liao plat_mt_pm_invoke_no_check(pwr_prompt, cpu, state); 25882c00c2fSJames Liao 25982c00c2fSJames Liao /* Perform the common CPU specific operations */ 26082c00c2fSJames Liao plat_cpu_pwrdwn_common(cpu, state, plat_power_state[cpu]); 26182c00c2fSJames Liao 26282c00c2fSJames Liao if (IS_CLUSTER_OFF_STATE(state)) { 26382c00c2fSJames Liao /* Perform the common cluster specific operations */ 26482c00c2fSJames Liao plat_cluster_pwrdwn_common(cpu, state, plat_power_state[cpu]); 26582c00c2fSJames Liao } 26682c00c2fSJames Liao 26782c00c2fSJames Liao if (IS_MCUSYS_OFF_STATE(state)) { 26882c00c2fSJames Liao /* Perform the common mcusys specific operations */ 26982c00c2fSJames Liao plat_mcusys_pwrdwn_common(cpu, state, plat_power_state[cpu]); 27082c00c2fSJames Liao } 27182c00c2fSJames Liao } 27282c00c2fSJames Liao 27382c00c2fSJames Liao static void plat_power_domain_suspend_finish(const psci_power_state_t *state) 27482c00c2fSJames Liao { 27582c00c2fSJames Liao unsigned int cpu = plat_my_core_pos(); 27682c00c2fSJames Liao 27782c00c2fSJames Liao assert(cpu < PLATFORM_CORE_COUNT); 27882c00c2fSJames Liao 27982c00c2fSJames Liao if (IS_MCUSYS_OFF_STATE(state)) { 28082c00c2fSJames Liao /* Perform the common mcusys specific operations */ 28182c00c2fSJames Liao plat_mcusys_pwron_common(cpu, state, plat_power_state[cpu]); 28282c00c2fSJames Liao } 28382c00c2fSJames Liao 28482c00c2fSJames Liao if (IS_CLUSTER_OFF_STATE(state)) { 28582c00c2fSJames Liao /* Perform the common cluster specific operations */ 28682c00c2fSJames Liao plat_cluster_pwron_common(cpu, state, plat_power_state[cpu]); 28782c00c2fSJames Liao } 28882c00c2fSJames Liao 28982c00c2fSJames Liao /* Perform the common CPU specific operations */ 29082c00c2fSJames Liao plat_cpu_pwron_common(cpu, state, plat_power_state[cpu]); 29182c00c2fSJames Liao 29282c00c2fSJames Liao plat_mt_pm_invoke_no_check(pwr_reflect, cpu, state); 29382c00c2fSJames Liao } 29482c00c2fSJames Liao 29582c00c2fSJames Liao static int plat_validate_power_state(unsigned int power_state, 29682c00c2fSJames Liao psci_power_state_t *req_state) 29782c00c2fSJames Liao { 29882c00c2fSJames Liao unsigned int pstate = psci_get_pstate_type(power_state); 29982c00c2fSJames Liao unsigned int aff_lvl = psci_get_pstate_pwrlvl(power_state); 30082c00c2fSJames Liao unsigned int cpu = plat_my_core_pos(); 30182c00c2fSJames Liao 30282c00c2fSJames Liao if (pstate == PSTATE_TYPE_STANDBY) { 30382c00c2fSJames Liao req_state->pwr_domain_state[0] = PLAT_MAX_RET_STATE; 30482c00c2fSJames Liao } else { 30582c00c2fSJames Liao unsigned int i; 30682c00c2fSJames Liao unsigned int pstate_id = psci_get_pstate_id(power_state); 30782c00c2fSJames Liao plat_local_state_t s = MTK_LOCAL_STATE_OFF; 30882c00c2fSJames Liao 30982c00c2fSJames Liao /* Use pstate_id to be power domain state */ 31082c00c2fSJames Liao if (pstate_id > s) { 31182c00c2fSJames Liao s = (plat_local_state_t)pstate_id; 31282c00c2fSJames Liao } 31382c00c2fSJames Liao 31482c00c2fSJames Liao for (i = 0U; i <= aff_lvl; i++) { 31582c00c2fSJames Liao req_state->pwr_domain_state[i] = s; 31682c00c2fSJames Liao } 31782c00c2fSJames Liao } 31882c00c2fSJames Liao 31982c00c2fSJames Liao plat_power_state[cpu] = power_state; 32082c00c2fSJames Liao return PSCI_E_SUCCESS; 32182c00c2fSJames Liao } 32282c00c2fSJames Liao 32382c00c2fSJames Liao static void plat_get_sys_suspend_power_state(psci_power_state_t *req_state) 32482c00c2fSJames Liao { 32582c00c2fSJames Liao unsigned int lv; 32682c00c2fSJames Liao unsigned int cpu = plat_my_core_pos(); 32782c00c2fSJames Liao 32882c00c2fSJames Liao for (lv = PSCI_CPU_PWR_LVL; lv <= PLAT_MAX_PWR_LVL; lv++) { 32982c00c2fSJames Liao req_state->pwr_domain_state[lv] = PLAT_MAX_OFF_STATE; 33082c00c2fSJames Liao } 33182c00c2fSJames Liao 33282c00c2fSJames Liao plat_power_state[cpu] = 33382c00c2fSJames Liao psci_make_powerstate( 33482c00c2fSJames Liao MT_PLAT_PWR_STATE_SYSTEM_SUSPEND, 33582c00c2fSJames Liao PSTATE_TYPE_POWERDOWN, PLAT_MAX_PWR_LVL); 33682c00c2fSJames Liao 33782c00c2fSJames Liao flush_dcache_range((uintptr_t) 33882c00c2fSJames Liao &plat_power_state[cpu], 33982c00c2fSJames Liao sizeof(plat_power_state[cpu])); 34082c00c2fSJames Liao } 34182c00c2fSJames Liao 34226f3dbe2SHsin-Hsiung Wang static void __dead2 plat_mtk_system_off(void) 34326f3dbe2SHsin-Hsiung Wang { 34426f3dbe2SHsin-Hsiung Wang INFO("MTK System Off\n"); 34526f3dbe2SHsin-Hsiung Wang 346b686d330SYuchen Huang rtc_power_off_sequence(); 34726f3dbe2SHsin-Hsiung Wang pmic_power_off(); 34826f3dbe2SHsin-Hsiung Wang 34926f3dbe2SHsin-Hsiung Wang wfi(); 35026f3dbe2SHsin-Hsiung Wang ERROR("MTK System Off: operation not handled.\n"); 35126f3dbe2SHsin-Hsiung Wang panic(); 35226f3dbe2SHsin-Hsiung Wang } 35326f3dbe2SHsin-Hsiung Wang 3540f408247SNina Wu static void __dead2 plat_mtk_system_reset(void) 3550f408247SNina Wu { 3560f408247SNina Wu struct bl_aux_gpio_info *gpio_reset = plat_get_mtk_gpio_reset(); 3570f408247SNina Wu 3580f408247SNina Wu INFO("MTK System Reset\n"); 3590f408247SNina Wu 3600f408247SNina Wu gpio_set_value(gpio_reset->index, gpio_reset->polarity); 3610f408247SNina Wu 3620f408247SNina Wu wfi(); 3630f408247SNina Wu ERROR("MTK System Reset: operation not handled.\n"); 3640f408247SNina Wu panic(); 3650f408247SNina Wu } 366f85f37d4SNina Wu 36782c00c2fSJames Liao static const plat_psci_ops_t plat_psci_ops = { 3680f408247SNina Wu .system_reset = plat_mtk_system_reset, 36982c00c2fSJames Liao .cpu_standby = plat_cpu_standby, 37082c00c2fSJames Liao .pwr_domain_on = plat_power_domain_on, 37182c00c2fSJames Liao .pwr_domain_on_finish = plat_power_domain_on_finish, 37282c00c2fSJames Liao .pwr_domain_off = plat_power_domain_off, 37382c00c2fSJames Liao .pwr_domain_suspend = plat_power_domain_suspend, 37482c00c2fSJames Liao .pwr_domain_suspend_finish = plat_power_domain_suspend_finish, 37526f3dbe2SHsin-Hsiung Wang .system_off = plat_mtk_system_off, 37682c00c2fSJames Liao .validate_power_state = plat_validate_power_state, 37782c00c2fSJames Liao .get_sys_suspend_power_state = plat_get_sys_suspend_power_state 378f85f37d4SNina Wu }; 379f85f37d4SNina Wu 380f85f37d4SNina Wu int plat_setup_psci_ops(uintptr_t sec_entrypoint, 381f85f37d4SNina Wu const plat_psci_ops_t **psci_ops) 382f85f37d4SNina Wu { 38382c00c2fSJames Liao *psci_ops = &plat_psci_ops; 38482c00c2fSJames Liao secure_entrypoint = sec_entrypoint; 38582c00c2fSJames Liao 38682c00c2fSJames Liao /* 38782c00c2fSJames Liao * init the warm reset config for boot CPU 38882c00c2fSJames Liao * reset arch as AARCH64 38982c00c2fSJames Liao * reset addr as function bl31_warm_entrypoint() 39082c00c2fSJames Liao */ 39182c00c2fSJames Liao mcucfg_init_archstate(0U, 0U, true); 39282c00c2fSJames Liao mcucfg_set_bootaddr(0U, 0U, secure_entrypoint); 39382c00c2fSJames Liao 39482c00c2fSJames Liao spmc_init(); 39582c00c2fSJames Liao plat_mt_pm = mt_plat_cpu_pm_init(); 396f85f37d4SNina Wu 397f85f37d4SNina Wu return 0; 398f85f37d4SNina Wu } 399