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> 1782c00c2fSJames Liao #include <mtspmc.h> 1882c00c2fSJames Liao #include <plat/common/platform.h> 1982c00c2fSJames Liao #include <plat_mtk_lpm.h> 200f408247SNina Wu #include <plat_params.h> 2182c00c2fSJames Liao #include <plat_pm.h> 22*26f3dbe2SHsin-Hsiung Wang #include <pmic.h> 23f85f37d4SNina Wu 2482c00c2fSJames Liao /* 2582c00c2fSJames Liao * Cluster state request: 2682c00c2fSJames Liao * [0] : The CPU requires cluster power down 2782c00c2fSJames Liao * [1] : The CPU requires cluster power on 2882c00c2fSJames Liao */ 2982c00c2fSJames Liao #define coordinate_cluster(onoff) write_clusterpwrdn_el1(onoff) 3082c00c2fSJames Liao #define coordinate_cluster_pwron() coordinate_cluster(1) 3182c00c2fSJames Liao #define coordinate_cluster_pwroff() coordinate_cluster(0) 3282c00c2fSJames Liao 3382c00c2fSJames Liao /* platform secure entry point */ 3482c00c2fSJames Liao static uintptr_t secure_entrypoint; 3582c00c2fSJames Liao /* per-CPU power state */ 3682c00c2fSJames Liao static unsigned int plat_power_state[PLATFORM_CORE_COUNT]; 3782c00c2fSJames Liao 3882c00c2fSJames Liao /* platform CPU power domain - ops */ 3982c00c2fSJames Liao static const struct mt_lpm_tz *plat_mt_pm; 4082c00c2fSJames Liao 4182c00c2fSJames Liao #define plat_mt_pm_invoke(_name, _cpu, _state) ({ \ 4282c00c2fSJames Liao int ret = -1; \ 4382c00c2fSJames Liao if (plat_mt_pm != NULL && plat_mt_pm->_name != NULL) { \ 4482c00c2fSJames Liao ret = plat_mt_pm->_name(_cpu, _state); \ 4582c00c2fSJames Liao } \ 4682c00c2fSJames Liao ret; }) 4782c00c2fSJames Liao 4882c00c2fSJames Liao #define plat_mt_pm_invoke_no_check(_name, _cpu, _state) ({ \ 4982c00c2fSJames Liao if (plat_mt_pm != NULL && plat_mt_pm->_name != NULL) { \ 5082c00c2fSJames Liao (void) plat_mt_pm->_name(_cpu, _state); \ 5182c00c2fSJames Liao } \ 5282c00c2fSJames Liao }) 5382c00c2fSJames Liao 5482c00c2fSJames Liao /* 5582c00c2fSJames Liao * Common MTK_platform operations to power on/off a 5682c00c2fSJames Liao * CPU in response to a CPU_ON, CPU_OFF or CPU_SUSPEND request. 5782c00c2fSJames Liao */ 5882c00c2fSJames Liao 5982c00c2fSJames Liao static void plat_cpu_pwrdwn_common(unsigned int cpu, 6082c00c2fSJames Liao const psci_power_state_t *state, unsigned int req_pstate) 6182c00c2fSJames Liao { 6282c00c2fSJames Liao assert(cpu == plat_my_core_pos()); 6382c00c2fSJames Liao 6482c00c2fSJames Liao plat_mt_pm_invoke_no_check(pwr_cpu_dwn, cpu, state); 6582c00c2fSJames Liao 6682c00c2fSJames Liao if ((psci_get_pstate_pwrlvl(req_pstate) >= MTK_AFFLVL_CLUSTER) || 6782c00c2fSJames Liao (req_pstate == 0U)) { /* hotplug off */ 6882c00c2fSJames Liao coordinate_cluster_pwroff(); 6982c00c2fSJames Liao } 7082c00c2fSJames Liao 7182c00c2fSJames Liao /* Prevent interrupts from spuriously waking up this CPU */ 7282c00c2fSJames Liao mt_gic_rdistif_save(); 7382c00c2fSJames Liao gicv3_cpuif_disable(cpu); 7482c00c2fSJames Liao gicv3_rdistif_off(cpu); 7582c00c2fSJames Liao } 7682c00c2fSJames Liao 7782c00c2fSJames Liao static void plat_cpu_pwron_common(unsigned int cpu, 7882c00c2fSJames Liao const psci_power_state_t *state, unsigned int req_pstate) 7982c00c2fSJames Liao { 8082c00c2fSJames Liao assert(cpu == plat_my_core_pos()); 8182c00c2fSJames Liao 8282c00c2fSJames Liao plat_mt_pm_invoke_no_check(pwr_cpu_on, cpu, state); 8382c00c2fSJames Liao 8482c00c2fSJames Liao coordinate_cluster_pwron(); 8582c00c2fSJames Liao 8682c00c2fSJames Liao /* Enable the GIC CPU interface */ 8782c00c2fSJames Liao gicv3_rdistif_on(cpu); 8882c00c2fSJames Liao gicv3_cpuif_enable(cpu); 8982c00c2fSJames Liao mt_gic_rdistif_init(); 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 { 9882c00c2fSJames Liao mt_gic_rdistif_restore(); 9982c00c2fSJames Liao } 10082c00c2fSJames Liao } 10182c00c2fSJames Liao 10282c00c2fSJames Liao /* 10382c00c2fSJames Liao * Common MTK_platform operations to power on/off a 10482c00c2fSJames Liao * cluster in response to a CPU_ON, CPU_OFF or CPU_SUSPEND request. 10582c00c2fSJames Liao */ 10682c00c2fSJames Liao 10782c00c2fSJames Liao static void plat_cluster_pwrdwn_common(unsigned int cpu, 10882c00c2fSJames Liao const psci_power_state_t *state, unsigned int req_pstate) 10982c00c2fSJames Liao { 11082c00c2fSJames Liao assert(cpu == plat_my_core_pos()); 11182c00c2fSJames Liao 11282c00c2fSJames Liao if (plat_mt_pm_invoke(pwr_cluster_dwn, cpu, state) != 0) { 11382c00c2fSJames Liao coordinate_cluster_pwron(); 11482c00c2fSJames Liao 11582c00c2fSJames Liao /* TODO: return on fail. 11682c00c2fSJames Liao * Add a 'return' here before adding any code following 11782c00c2fSJames Liao * the if-block. 11882c00c2fSJames Liao */ 11982c00c2fSJames Liao } 12082c00c2fSJames Liao } 12182c00c2fSJames Liao 12282c00c2fSJames Liao static void plat_cluster_pwron_common(unsigned int cpu, 12382c00c2fSJames Liao const psci_power_state_t *state, unsigned int req_pstate) 12482c00c2fSJames Liao { 12582c00c2fSJames Liao assert(cpu == plat_my_core_pos()); 12682c00c2fSJames Liao 12782c00c2fSJames Liao if (plat_mt_pm_invoke(pwr_cluster_on, cpu, state) != 0) { 12882c00c2fSJames Liao /* TODO: return on fail. 12982c00c2fSJames Liao * Add a 'return' here before adding any code following 13082c00c2fSJames Liao * the if-block. 13182c00c2fSJames Liao */ 13282c00c2fSJames Liao } 13382c00c2fSJames Liao } 13482c00c2fSJames Liao 13582c00c2fSJames Liao /* 13682c00c2fSJames Liao * Common MTK_platform operations to power on/off a 13782c00c2fSJames Liao * mcusys in response to a CPU_ON, CPU_OFF or CPU_SUSPEND request. 13882c00c2fSJames Liao */ 13982c00c2fSJames Liao 14082c00c2fSJames Liao static void plat_mcusys_pwrdwn_common(unsigned int cpu, 14182c00c2fSJames Liao const psci_power_state_t *state, unsigned int req_pstate) 14282c00c2fSJames Liao { 14382c00c2fSJames Liao assert(cpu == plat_my_core_pos()); 14482c00c2fSJames Liao 14582c00c2fSJames Liao if (plat_mt_pm_invoke(pwr_mcusys_dwn, cpu, state) != 0) { 14682c00c2fSJames Liao return; /* return on fail */ 14782c00c2fSJames Liao } 14882c00c2fSJames Liao 14982c00c2fSJames Liao mt_gic_distif_save(); 15082c00c2fSJames Liao gic_sgi_save_all(); 15182c00c2fSJames Liao } 15282c00c2fSJames Liao 15382c00c2fSJames Liao static void plat_mcusys_pwron_common(unsigned int cpu, 15482c00c2fSJames Liao const psci_power_state_t *state, unsigned int req_pstate) 15582c00c2fSJames Liao { 15682c00c2fSJames Liao assert(cpu == plat_my_core_pos()); 15782c00c2fSJames Liao 15882c00c2fSJames Liao if (plat_mt_pm_invoke(pwr_mcusys_on, cpu, state) != 0) { 15982c00c2fSJames Liao return; /* return on fail */ 16082c00c2fSJames Liao } 16182c00c2fSJames Liao 16282c00c2fSJames Liao mt_gic_init(); 16382c00c2fSJames Liao mt_gic_distif_restore(); 16482c00c2fSJames Liao gic_sgi_restore_all(); 16582c00c2fSJames Liao 16682c00c2fSJames Liao plat_mt_pm_invoke_no_check(pwr_mcusys_on_finished, cpu, state); 16782c00c2fSJames Liao } 16882c00c2fSJames Liao 16982c00c2fSJames Liao /* 17082c00c2fSJames Liao * plat_psci_ops implementation 17182c00c2fSJames Liao */ 17282c00c2fSJames Liao 17382c00c2fSJames Liao static void plat_cpu_standby(plat_local_state_t cpu_state) 17482c00c2fSJames Liao { 17582c00c2fSJames Liao uint64_t scr; 17682c00c2fSJames Liao 17782c00c2fSJames Liao scr = read_scr_el3(); 17882c00c2fSJames Liao write_scr_el3(scr | SCR_IRQ_BIT | SCR_FIQ_BIT); 17982c00c2fSJames Liao 18082c00c2fSJames Liao isb(); 18182c00c2fSJames Liao dsb(); 18282c00c2fSJames Liao wfi(); 18382c00c2fSJames Liao 18482c00c2fSJames Liao write_scr_el3(scr); 18582c00c2fSJames Liao } 18682c00c2fSJames Liao 18782c00c2fSJames Liao static int plat_power_domain_on(u_register_t mpidr) 18882c00c2fSJames Liao { 18982c00c2fSJames Liao unsigned int cpu = (unsigned int)plat_core_pos_by_mpidr(mpidr); 19082c00c2fSJames Liao unsigned int cluster = 0U; 19182c00c2fSJames Liao 19282c00c2fSJames Liao if (cpu >= PLATFORM_CORE_COUNT) { 19382c00c2fSJames Liao return PSCI_E_INVALID_PARAMS; 19482c00c2fSJames Liao } 19582c00c2fSJames Liao 19682c00c2fSJames Liao if (!spm_get_cluster_powerstate(cluster)) { 19782c00c2fSJames Liao spm_poweron_cluster(cluster); 19882c00c2fSJames Liao } 19982c00c2fSJames Liao 20082c00c2fSJames Liao /* init CPU reset arch as AARCH64 */ 20182c00c2fSJames Liao mcucfg_init_archstate(cluster, cpu, true); 20282c00c2fSJames Liao mcucfg_set_bootaddr(cluster, cpu, secure_entrypoint); 20382c00c2fSJames Liao spm_poweron_cpu(cluster, cpu); 20482c00c2fSJames Liao 20582c00c2fSJames Liao return PSCI_E_SUCCESS; 20682c00c2fSJames Liao } 20782c00c2fSJames Liao 20882c00c2fSJames Liao static void plat_power_domain_on_finish(const psci_power_state_t *state) 20982c00c2fSJames Liao { 21082c00c2fSJames Liao unsigned long mpidr = read_mpidr_el1(); 21182c00c2fSJames Liao unsigned int cpu = (unsigned int)plat_core_pos_by_mpidr(mpidr); 21282c00c2fSJames Liao 21382c00c2fSJames Liao assert(cpu < PLATFORM_CORE_COUNT); 21482c00c2fSJames Liao 21582c00c2fSJames Liao /* Allow IRQs to wakeup this core in IDLE flow */ 21682c00c2fSJames Liao mcucfg_enable_gic_wakeup(0U, cpu); 21782c00c2fSJames Liao 21882c00c2fSJames Liao if (IS_CLUSTER_OFF_STATE(state)) { 21982c00c2fSJames Liao plat_cluster_pwron_common(cpu, state, 0U); 22082c00c2fSJames Liao } 22182c00c2fSJames Liao 22282c00c2fSJames Liao plat_cpu_pwron_common(cpu, state, 0U); 22382c00c2fSJames Liao } 22482c00c2fSJames Liao 22582c00c2fSJames Liao static void plat_power_domain_off(const psci_power_state_t *state) 22682c00c2fSJames Liao { 22782c00c2fSJames Liao unsigned long mpidr = read_mpidr_el1(); 22882c00c2fSJames Liao unsigned int cpu = (unsigned int)plat_core_pos_by_mpidr(mpidr); 22982c00c2fSJames Liao 23082c00c2fSJames Liao assert(cpu < PLATFORM_CORE_COUNT); 23182c00c2fSJames Liao 23282c00c2fSJames Liao plat_cpu_pwrdwn_common(cpu, state, 0U); 23382c00c2fSJames Liao spm_poweroff_cpu(0U, cpu); 23482c00c2fSJames Liao 23582c00c2fSJames Liao /* prevent unintended IRQs from waking up the hot-unplugged core */ 23682c00c2fSJames Liao mcucfg_disable_gic_wakeup(0U, cpu); 23782c00c2fSJames Liao 23882c00c2fSJames Liao if (IS_CLUSTER_OFF_STATE(state)) { 23982c00c2fSJames Liao plat_cluster_pwrdwn_common(cpu, state, 0U); 24082c00c2fSJames Liao } 24182c00c2fSJames Liao } 24282c00c2fSJames Liao 24382c00c2fSJames Liao static void plat_power_domain_suspend(const psci_power_state_t *state) 24482c00c2fSJames Liao { 24582c00c2fSJames Liao unsigned int cpu = plat_my_core_pos(); 24682c00c2fSJames Liao 24782c00c2fSJames Liao assert(cpu < PLATFORM_CORE_COUNT); 24882c00c2fSJames Liao 24982c00c2fSJames Liao plat_mt_pm_invoke_no_check(pwr_prompt, cpu, state); 25082c00c2fSJames Liao 25182c00c2fSJames Liao /* Perform the common CPU specific operations */ 25282c00c2fSJames Liao plat_cpu_pwrdwn_common(cpu, state, plat_power_state[cpu]); 25382c00c2fSJames Liao 25482c00c2fSJames Liao if (IS_CLUSTER_OFF_STATE(state)) { 25582c00c2fSJames Liao /* Perform the common cluster specific operations */ 25682c00c2fSJames Liao plat_cluster_pwrdwn_common(cpu, state, plat_power_state[cpu]); 25782c00c2fSJames Liao } 25882c00c2fSJames Liao 25982c00c2fSJames Liao if (IS_MCUSYS_OFF_STATE(state)) { 26082c00c2fSJames Liao /* Perform the common mcusys specific operations */ 26182c00c2fSJames Liao plat_mcusys_pwrdwn_common(cpu, state, plat_power_state[cpu]); 26282c00c2fSJames Liao } 26382c00c2fSJames Liao } 26482c00c2fSJames Liao 26582c00c2fSJames Liao static void plat_power_domain_suspend_finish(const psci_power_state_t *state) 26682c00c2fSJames Liao { 26782c00c2fSJames Liao unsigned int cpu = plat_my_core_pos(); 26882c00c2fSJames Liao 26982c00c2fSJames Liao assert(cpu < PLATFORM_CORE_COUNT); 27082c00c2fSJames Liao 27182c00c2fSJames Liao if (IS_MCUSYS_OFF_STATE(state)) { 27282c00c2fSJames Liao /* Perform the common mcusys specific operations */ 27382c00c2fSJames Liao plat_mcusys_pwron_common(cpu, state, plat_power_state[cpu]); 27482c00c2fSJames Liao } 27582c00c2fSJames Liao 27682c00c2fSJames Liao if (IS_CLUSTER_OFF_STATE(state)) { 27782c00c2fSJames Liao /* Perform the common cluster specific operations */ 27882c00c2fSJames Liao plat_cluster_pwron_common(cpu, state, plat_power_state[cpu]); 27982c00c2fSJames Liao } 28082c00c2fSJames Liao 28182c00c2fSJames Liao /* Perform the common CPU specific operations */ 28282c00c2fSJames Liao plat_cpu_pwron_common(cpu, state, plat_power_state[cpu]); 28382c00c2fSJames Liao 28482c00c2fSJames Liao plat_mt_pm_invoke_no_check(pwr_reflect, cpu, state); 28582c00c2fSJames Liao } 28682c00c2fSJames Liao 28782c00c2fSJames Liao static int plat_validate_power_state(unsigned int power_state, 28882c00c2fSJames Liao psci_power_state_t *req_state) 28982c00c2fSJames Liao { 29082c00c2fSJames Liao unsigned int pstate = psci_get_pstate_type(power_state); 29182c00c2fSJames Liao unsigned int aff_lvl = psci_get_pstate_pwrlvl(power_state); 29282c00c2fSJames Liao unsigned int cpu = plat_my_core_pos(); 29382c00c2fSJames Liao 29482c00c2fSJames Liao if (aff_lvl > PLAT_MAX_PWR_LVL) { 29582c00c2fSJames Liao return PSCI_E_INVALID_PARAMS; 29682c00c2fSJames Liao } 29782c00c2fSJames Liao 29882c00c2fSJames Liao if (pstate == PSTATE_TYPE_STANDBY) { 29982c00c2fSJames Liao req_state->pwr_domain_state[0] = PLAT_MAX_RET_STATE; 30082c00c2fSJames Liao } else { 30182c00c2fSJames Liao unsigned int i; 30282c00c2fSJames Liao unsigned int pstate_id = psci_get_pstate_id(power_state); 30382c00c2fSJames Liao plat_local_state_t s = MTK_LOCAL_STATE_OFF; 30482c00c2fSJames Liao 30582c00c2fSJames Liao /* Use pstate_id to be power domain state */ 30682c00c2fSJames Liao if (pstate_id > s) { 30782c00c2fSJames Liao s = (plat_local_state_t)pstate_id; 30882c00c2fSJames Liao } 30982c00c2fSJames Liao 31082c00c2fSJames Liao for (i = 0U; i <= aff_lvl; i++) { 31182c00c2fSJames Liao req_state->pwr_domain_state[i] = s; 31282c00c2fSJames Liao } 31382c00c2fSJames Liao } 31482c00c2fSJames Liao 31582c00c2fSJames Liao plat_power_state[cpu] = power_state; 31682c00c2fSJames Liao return PSCI_E_SUCCESS; 31782c00c2fSJames Liao } 31882c00c2fSJames Liao 31982c00c2fSJames Liao static void plat_get_sys_suspend_power_state(psci_power_state_t *req_state) 32082c00c2fSJames Liao { 32182c00c2fSJames Liao unsigned int lv; 32282c00c2fSJames Liao unsigned int cpu = plat_my_core_pos(); 32382c00c2fSJames Liao 32482c00c2fSJames Liao for (lv = PSCI_CPU_PWR_LVL; lv <= PLAT_MAX_PWR_LVL; lv++) { 32582c00c2fSJames Liao req_state->pwr_domain_state[lv] = PLAT_MAX_OFF_STATE; 32682c00c2fSJames Liao } 32782c00c2fSJames Liao 32882c00c2fSJames Liao plat_power_state[cpu] = 32982c00c2fSJames Liao psci_make_powerstate( 33082c00c2fSJames Liao MT_PLAT_PWR_STATE_SYSTEM_SUSPEND, 33182c00c2fSJames Liao PSTATE_TYPE_POWERDOWN, PLAT_MAX_PWR_LVL); 33282c00c2fSJames Liao 33382c00c2fSJames Liao flush_dcache_range((uintptr_t) 33482c00c2fSJames Liao &plat_power_state[cpu], 33582c00c2fSJames Liao sizeof(plat_power_state[cpu])); 33682c00c2fSJames Liao } 33782c00c2fSJames Liao 338*26f3dbe2SHsin-Hsiung Wang static void __dead2 plat_mtk_system_off(void) 339*26f3dbe2SHsin-Hsiung Wang { 340*26f3dbe2SHsin-Hsiung Wang INFO("MTK System Off\n"); 341*26f3dbe2SHsin-Hsiung Wang 342*26f3dbe2SHsin-Hsiung Wang pmic_power_off(); 343*26f3dbe2SHsin-Hsiung Wang 344*26f3dbe2SHsin-Hsiung Wang wfi(); 345*26f3dbe2SHsin-Hsiung Wang ERROR("MTK System Off: operation not handled.\n"); 346*26f3dbe2SHsin-Hsiung Wang panic(); 347*26f3dbe2SHsin-Hsiung Wang } 348*26f3dbe2SHsin-Hsiung Wang 3490f408247SNina Wu static void __dead2 plat_mtk_system_reset(void) 3500f408247SNina Wu { 3510f408247SNina Wu struct bl_aux_gpio_info *gpio_reset = plat_get_mtk_gpio_reset(); 3520f408247SNina Wu 3530f408247SNina Wu INFO("MTK System Reset\n"); 3540f408247SNina Wu 3550f408247SNina Wu gpio_set_value(gpio_reset->index, gpio_reset->polarity); 3560f408247SNina Wu 3570f408247SNina Wu wfi(); 3580f408247SNina Wu ERROR("MTK System Reset: operation not handled.\n"); 3590f408247SNina Wu panic(); 3600f408247SNina Wu } 361f85f37d4SNina Wu 36282c00c2fSJames Liao static const plat_psci_ops_t plat_psci_ops = { 3630f408247SNina Wu .system_reset = plat_mtk_system_reset, 36482c00c2fSJames Liao .cpu_standby = plat_cpu_standby, 36582c00c2fSJames Liao .pwr_domain_on = plat_power_domain_on, 36682c00c2fSJames Liao .pwr_domain_on_finish = plat_power_domain_on_finish, 36782c00c2fSJames Liao .pwr_domain_off = plat_power_domain_off, 36882c00c2fSJames Liao .pwr_domain_suspend = plat_power_domain_suspend, 36982c00c2fSJames Liao .pwr_domain_suspend_finish = plat_power_domain_suspend_finish, 370*26f3dbe2SHsin-Hsiung Wang .system_off = plat_mtk_system_off, 37182c00c2fSJames Liao .validate_power_state = plat_validate_power_state, 37282c00c2fSJames Liao .get_sys_suspend_power_state = plat_get_sys_suspend_power_state 373f85f37d4SNina Wu }; 374f85f37d4SNina Wu 375f85f37d4SNina Wu int plat_setup_psci_ops(uintptr_t sec_entrypoint, 376f85f37d4SNina Wu const plat_psci_ops_t **psci_ops) 377f85f37d4SNina Wu { 37882c00c2fSJames Liao *psci_ops = &plat_psci_ops; 37982c00c2fSJames Liao secure_entrypoint = sec_entrypoint; 38082c00c2fSJames Liao 38182c00c2fSJames Liao /* 38282c00c2fSJames Liao * init the warm reset config for boot CPU 38382c00c2fSJames Liao * reset arch as AARCH64 38482c00c2fSJames Liao * reset addr as function bl31_warm_entrypoint() 38582c00c2fSJames Liao */ 38682c00c2fSJames Liao mcucfg_init_archstate(0U, 0U, true); 38782c00c2fSJames Liao mcucfg_set_bootaddr(0U, 0U, secure_entrypoint); 38882c00c2fSJames Liao 38982c00c2fSJames Liao spmc_init(); 39082c00c2fSJames Liao plat_mt_pm = mt_plat_cpu_pm_init(); 391f85f37d4SNina Wu 392f85f37d4SNina Wu return 0; 393f85f37d4SNina Wu } 394