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 */ 8*82c00c2fSJames Liao #include <assert.h> 9*82c00c2fSJames 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 15*82c00c2fSJames Liao /* platform specific headers */ 16*82c00c2fSJames Liao #include <mt_gic_v3.h> 17*82c00c2fSJames Liao #include <mtspmc.h> 18*82c00c2fSJames Liao #include <plat/common/platform.h> 19*82c00c2fSJames Liao #include <plat_mtk_lpm.h> 200f408247SNina Wu #include <plat_params.h> 21*82c00c2fSJames Liao #include <plat_pm.h> 22f85f37d4SNina Wu 23*82c00c2fSJames Liao /* 24*82c00c2fSJames Liao * Cluster state request: 25*82c00c2fSJames Liao * [0] : The CPU requires cluster power down 26*82c00c2fSJames Liao * [1] : The CPU requires cluster power on 27*82c00c2fSJames Liao */ 28*82c00c2fSJames Liao #define coordinate_cluster(onoff) write_clusterpwrdn_el1(onoff) 29*82c00c2fSJames Liao #define coordinate_cluster_pwron() coordinate_cluster(1) 30*82c00c2fSJames Liao #define coordinate_cluster_pwroff() coordinate_cluster(0) 31*82c00c2fSJames Liao 32*82c00c2fSJames Liao /* platform secure entry point */ 33*82c00c2fSJames Liao static uintptr_t secure_entrypoint; 34*82c00c2fSJames Liao /* per-CPU power state */ 35*82c00c2fSJames Liao static unsigned int plat_power_state[PLATFORM_CORE_COUNT]; 36*82c00c2fSJames Liao 37*82c00c2fSJames Liao /* platform CPU power domain - ops */ 38*82c00c2fSJames Liao static const struct mt_lpm_tz *plat_mt_pm; 39*82c00c2fSJames Liao 40*82c00c2fSJames Liao #define plat_mt_pm_invoke(_name, _cpu, _state) ({ \ 41*82c00c2fSJames Liao int ret = -1; \ 42*82c00c2fSJames Liao if (plat_mt_pm != NULL && plat_mt_pm->_name != NULL) { \ 43*82c00c2fSJames Liao ret = plat_mt_pm->_name(_cpu, _state); \ 44*82c00c2fSJames Liao } \ 45*82c00c2fSJames Liao ret; }) 46*82c00c2fSJames Liao 47*82c00c2fSJames Liao #define plat_mt_pm_invoke_no_check(_name, _cpu, _state) ({ \ 48*82c00c2fSJames Liao if (plat_mt_pm != NULL && plat_mt_pm->_name != NULL) { \ 49*82c00c2fSJames Liao (void) plat_mt_pm->_name(_cpu, _state); \ 50*82c00c2fSJames Liao } \ 51*82c00c2fSJames Liao }) 52*82c00c2fSJames Liao 53*82c00c2fSJames Liao /* 54*82c00c2fSJames Liao * Common MTK_platform operations to power on/off a 55*82c00c2fSJames Liao * CPU in response to a CPU_ON, CPU_OFF or CPU_SUSPEND request. 56*82c00c2fSJames Liao */ 57*82c00c2fSJames Liao 58*82c00c2fSJames Liao static void plat_cpu_pwrdwn_common(unsigned int cpu, 59*82c00c2fSJames Liao const psci_power_state_t *state, unsigned int req_pstate) 60*82c00c2fSJames Liao { 61*82c00c2fSJames Liao assert(cpu == plat_my_core_pos()); 62*82c00c2fSJames Liao 63*82c00c2fSJames Liao plat_mt_pm_invoke_no_check(pwr_cpu_dwn, cpu, state); 64*82c00c2fSJames Liao 65*82c00c2fSJames Liao if ((psci_get_pstate_pwrlvl(req_pstate) >= MTK_AFFLVL_CLUSTER) || 66*82c00c2fSJames Liao (req_pstate == 0U)) { /* hotplug off */ 67*82c00c2fSJames Liao coordinate_cluster_pwroff(); 68*82c00c2fSJames Liao } 69*82c00c2fSJames Liao 70*82c00c2fSJames Liao /* Prevent interrupts from spuriously waking up this CPU */ 71*82c00c2fSJames Liao mt_gic_rdistif_save(); 72*82c00c2fSJames Liao gicv3_cpuif_disable(cpu); 73*82c00c2fSJames Liao gicv3_rdistif_off(cpu); 74*82c00c2fSJames Liao } 75*82c00c2fSJames Liao 76*82c00c2fSJames Liao static void plat_cpu_pwron_common(unsigned int cpu, 77*82c00c2fSJames Liao const psci_power_state_t *state, unsigned int req_pstate) 78*82c00c2fSJames Liao { 79*82c00c2fSJames Liao assert(cpu == plat_my_core_pos()); 80*82c00c2fSJames Liao 81*82c00c2fSJames Liao plat_mt_pm_invoke_no_check(pwr_cpu_on, cpu, state); 82*82c00c2fSJames Liao 83*82c00c2fSJames Liao coordinate_cluster_pwron(); 84*82c00c2fSJames Liao 85*82c00c2fSJames Liao /* Enable the GIC CPU interface */ 86*82c00c2fSJames Liao gicv3_rdistif_on(cpu); 87*82c00c2fSJames Liao gicv3_cpuif_enable(cpu); 88*82c00c2fSJames Liao mt_gic_rdistif_init(); 89*82c00c2fSJames Liao 90*82c00c2fSJames Liao /* 91*82c00c2fSJames Liao * If mcusys does power down before then restore 92*82c00c2fSJames Liao * all CPUs' GIC Redistributors 93*82c00c2fSJames Liao */ 94*82c00c2fSJames Liao if (IS_MCUSYS_OFF_STATE(state)) { 95*82c00c2fSJames Liao mt_gic_rdistif_restore_all(); 96*82c00c2fSJames Liao } else { 97*82c00c2fSJames Liao mt_gic_rdistif_restore(); 98*82c00c2fSJames Liao } 99*82c00c2fSJames Liao } 100*82c00c2fSJames Liao 101*82c00c2fSJames Liao /* 102*82c00c2fSJames Liao * Common MTK_platform operations to power on/off a 103*82c00c2fSJames Liao * cluster in response to a CPU_ON, CPU_OFF or CPU_SUSPEND request. 104*82c00c2fSJames Liao */ 105*82c00c2fSJames Liao 106*82c00c2fSJames Liao static void plat_cluster_pwrdwn_common(unsigned int cpu, 107*82c00c2fSJames Liao const psci_power_state_t *state, unsigned int req_pstate) 108*82c00c2fSJames Liao { 109*82c00c2fSJames Liao assert(cpu == plat_my_core_pos()); 110*82c00c2fSJames Liao 111*82c00c2fSJames Liao if (plat_mt_pm_invoke(pwr_cluster_dwn, cpu, state) != 0) { 112*82c00c2fSJames Liao coordinate_cluster_pwron(); 113*82c00c2fSJames Liao 114*82c00c2fSJames Liao /* TODO: return on fail. 115*82c00c2fSJames Liao * Add a 'return' here before adding any code following 116*82c00c2fSJames Liao * the if-block. 117*82c00c2fSJames Liao */ 118*82c00c2fSJames Liao } 119*82c00c2fSJames Liao } 120*82c00c2fSJames Liao 121*82c00c2fSJames Liao static void plat_cluster_pwron_common(unsigned int cpu, 122*82c00c2fSJames Liao const psci_power_state_t *state, unsigned int req_pstate) 123*82c00c2fSJames Liao { 124*82c00c2fSJames Liao assert(cpu == plat_my_core_pos()); 125*82c00c2fSJames Liao 126*82c00c2fSJames Liao if (plat_mt_pm_invoke(pwr_cluster_on, cpu, state) != 0) { 127*82c00c2fSJames Liao /* TODO: return on fail. 128*82c00c2fSJames Liao * Add a 'return' here before adding any code following 129*82c00c2fSJames Liao * the if-block. 130*82c00c2fSJames Liao */ 131*82c00c2fSJames Liao } 132*82c00c2fSJames Liao } 133*82c00c2fSJames Liao 134*82c00c2fSJames Liao /* 135*82c00c2fSJames Liao * Common MTK_platform operations to power on/off a 136*82c00c2fSJames Liao * mcusys in response to a CPU_ON, CPU_OFF or CPU_SUSPEND request. 137*82c00c2fSJames Liao */ 138*82c00c2fSJames Liao 139*82c00c2fSJames Liao static void plat_mcusys_pwrdwn_common(unsigned int cpu, 140*82c00c2fSJames Liao const psci_power_state_t *state, unsigned int req_pstate) 141*82c00c2fSJames Liao { 142*82c00c2fSJames Liao assert(cpu == plat_my_core_pos()); 143*82c00c2fSJames Liao 144*82c00c2fSJames Liao if (plat_mt_pm_invoke(pwr_mcusys_dwn, cpu, state) != 0) { 145*82c00c2fSJames Liao return; /* return on fail */ 146*82c00c2fSJames Liao } 147*82c00c2fSJames Liao 148*82c00c2fSJames Liao mt_gic_distif_save(); 149*82c00c2fSJames Liao gic_sgi_save_all(); 150*82c00c2fSJames Liao } 151*82c00c2fSJames Liao 152*82c00c2fSJames Liao static void plat_mcusys_pwron_common(unsigned int cpu, 153*82c00c2fSJames Liao const psci_power_state_t *state, unsigned int req_pstate) 154*82c00c2fSJames Liao { 155*82c00c2fSJames Liao assert(cpu == plat_my_core_pos()); 156*82c00c2fSJames Liao 157*82c00c2fSJames Liao if (plat_mt_pm_invoke(pwr_mcusys_on, cpu, state) != 0) { 158*82c00c2fSJames Liao return; /* return on fail */ 159*82c00c2fSJames Liao } 160*82c00c2fSJames Liao 161*82c00c2fSJames Liao mt_gic_init(); 162*82c00c2fSJames Liao mt_gic_distif_restore(); 163*82c00c2fSJames Liao gic_sgi_restore_all(); 164*82c00c2fSJames Liao 165*82c00c2fSJames Liao plat_mt_pm_invoke_no_check(pwr_mcusys_on_finished, cpu, state); 166*82c00c2fSJames Liao } 167*82c00c2fSJames Liao 168*82c00c2fSJames Liao /* 169*82c00c2fSJames Liao * plat_psci_ops implementation 170*82c00c2fSJames Liao */ 171*82c00c2fSJames Liao 172*82c00c2fSJames Liao static void plat_cpu_standby(plat_local_state_t cpu_state) 173*82c00c2fSJames Liao { 174*82c00c2fSJames Liao uint64_t scr; 175*82c00c2fSJames Liao 176*82c00c2fSJames Liao scr = read_scr_el3(); 177*82c00c2fSJames Liao write_scr_el3(scr | SCR_IRQ_BIT | SCR_FIQ_BIT); 178*82c00c2fSJames Liao 179*82c00c2fSJames Liao isb(); 180*82c00c2fSJames Liao dsb(); 181*82c00c2fSJames Liao wfi(); 182*82c00c2fSJames Liao 183*82c00c2fSJames Liao write_scr_el3(scr); 184*82c00c2fSJames Liao } 185*82c00c2fSJames Liao 186*82c00c2fSJames Liao static int plat_power_domain_on(u_register_t mpidr) 187*82c00c2fSJames Liao { 188*82c00c2fSJames Liao unsigned int cpu = (unsigned int)plat_core_pos_by_mpidr(mpidr); 189*82c00c2fSJames Liao unsigned int cluster = 0U; 190*82c00c2fSJames Liao 191*82c00c2fSJames Liao if (cpu >= PLATFORM_CORE_COUNT) { 192*82c00c2fSJames Liao return PSCI_E_INVALID_PARAMS; 193*82c00c2fSJames Liao } 194*82c00c2fSJames Liao 195*82c00c2fSJames Liao if (!spm_get_cluster_powerstate(cluster)) { 196*82c00c2fSJames Liao spm_poweron_cluster(cluster); 197*82c00c2fSJames Liao } 198*82c00c2fSJames Liao 199*82c00c2fSJames Liao /* init CPU reset arch as AARCH64 */ 200*82c00c2fSJames Liao mcucfg_init_archstate(cluster, cpu, true); 201*82c00c2fSJames Liao mcucfg_set_bootaddr(cluster, cpu, secure_entrypoint); 202*82c00c2fSJames Liao spm_poweron_cpu(cluster, cpu); 203*82c00c2fSJames Liao 204*82c00c2fSJames Liao return PSCI_E_SUCCESS; 205*82c00c2fSJames Liao } 206*82c00c2fSJames Liao 207*82c00c2fSJames Liao static void plat_power_domain_on_finish(const psci_power_state_t *state) 208*82c00c2fSJames Liao { 209*82c00c2fSJames Liao unsigned long mpidr = read_mpidr_el1(); 210*82c00c2fSJames Liao unsigned int cpu = (unsigned int)plat_core_pos_by_mpidr(mpidr); 211*82c00c2fSJames Liao 212*82c00c2fSJames Liao assert(cpu < PLATFORM_CORE_COUNT); 213*82c00c2fSJames Liao 214*82c00c2fSJames Liao /* Allow IRQs to wakeup this core in IDLE flow */ 215*82c00c2fSJames Liao mcucfg_enable_gic_wakeup(0U, cpu); 216*82c00c2fSJames Liao 217*82c00c2fSJames Liao if (IS_CLUSTER_OFF_STATE(state)) { 218*82c00c2fSJames Liao plat_cluster_pwron_common(cpu, state, 0U); 219*82c00c2fSJames Liao } 220*82c00c2fSJames Liao 221*82c00c2fSJames Liao plat_cpu_pwron_common(cpu, state, 0U); 222*82c00c2fSJames Liao } 223*82c00c2fSJames Liao 224*82c00c2fSJames Liao static void plat_power_domain_off(const psci_power_state_t *state) 225*82c00c2fSJames Liao { 226*82c00c2fSJames Liao unsigned long mpidr = read_mpidr_el1(); 227*82c00c2fSJames Liao unsigned int cpu = (unsigned int)plat_core_pos_by_mpidr(mpidr); 228*82c00c2fSJames Liao 229*82c00c2fSJames Liao assert(cpu < PLATFORM_CORE_COUNT); 230*82c00c2fSJames Liao 231*82c00c2fSJames Liao plat_cpu_pwrdwn_common(cpu, state, 0U); 232*82c00c2fSJames Liao spm_poweroff_cpu(0U, cpu); 233*82c00c2fSJames Liao 234*82c00c2fSJames Liao /* prevent unintended IRQs from waking up the hot-unplugged core */ 235*82c00c2fSJames Liao mcucfg_disable_gic_wakeup(0U, cpu); 236*82c00c2fSJames Liao 237*82c00c2fSJames Liao if (IS_CLUSTER_OFF_STATE(state)) { 238*82c00c2fSJames Liao plat_cluster_pwrdwn_common(cpu, state, 0U); 239*82c00c2fSJames Liao } 240*82c00c2fSJames Liao } 241*82c00c2fSJames Liao 242*82c00c2fSJames Liao static void plat_power_domain_suspend(const psci_power_state_t *state) 243*82c00c2fSJames Liao { 244*82c00c2fSJames Liao unsigned int cpu = plat_my_core_pos(); 245*82c00c2fSJames Liao 246*82c00c2fSJames Liao assert(cpu < PLATFORM_CORE_COUNT); 247*82c00c2fSJames Liao 248*82c00c2fSJames Liao plat_mt_pm_invoke_no_check(pwr_prompt, cpu, state); 249*82c00c2fSJames Liao 250*82c00c2fSJames Liao /* Perform the common CPU specific operations */ 251*82c00c2fSJames Liao plat_cpu_pwrdwn_common(cpu, state, plat_power_state[cpu]); 252*82c00c2fSJames Liao 253*82c00c2fSJames Liao if (IS_CLUSTER_OFF_STATE(state)) { 254*82c00c2fSJames Liao /* Perform the common cluster specific operations */ 255*82c00c2fSJames Liao plat_cluster_pwrdwn_common(cpu, state, plat_power_state[cpu]); 256*82c00c2fSJames Liao } 257*82c00c2fSJames Liao 258*82c00c2fSJames Liao if (IS_MCUSYS_OFF_STATE(state)) { 259*82c00c2fSJames Liao /* Perform the common mcusys specific operations */ 260*82c00c2fSJames Liao plat_mcusys_pwrdwn_common(cpu, state, plat_power_state[cpu]); 261*82c00c2fSJames Liao } 262*82c00c2fSJames Liao } 263*82c00c2fSJames Liao 264*82c00c2fSJames Liao static void plat_power_domain_suspend_finish(const psci_power_state_t *state) 265*82c00c2fSJames Liao { 266*82c00c2fSJames Liao unsigned int cpu = plat_my_core_pos(); 267*82c00c2fSJames Liao 268*82c00c2fSJames Liao assert(cpu < PLATFORM_CORE_COUNT); 269*82c00c2fSJames Liao 270*82c00c2fSJames Liao if (IS_MCUSYS_OFF_STATE(state)) { 271*82c00c2fSJames Liao /* Perform the common mcusys specific operations */ 272*82c00c2fSJames Liao plat_mcusys_pwron_common(cpu, state, plat_power_state[cpu]); 273*82c00c2fSJames Liao } 274*82c00c2fSJames Liao 275*82c00c2fSJames Liao if (IS_CLUSTER_OFF_STATE(state)) { 276*82c00c2fSJames Liao /* Perform the common cluster specific operations */ 277*82c00c2fSJames Liao plat_cluster_pwron_common(cpu, state, plat_power_state[cpu]); 278*82c00c2fSJames Liao } 279*82c00c2fSJames Liao 280*82c00c2fSJames Liao /* Perform the common CPU specific operations */ 281*82c00c2fSJames Liao plat_cpu_pwron_common(cpu, state, plat_power_state[cpu]); 282*82c00c2fSJames Liao 283*82c00c2fSJames Liao plat_mt_pm_invoke_no_check(pwr_reflect, cpu, state); 284*82c00c2fSJames Liao } 285*82c00c2fSJames Liao 286*82c00c2fSJames Liao static int plat_validate_power_state(unsigned int power_state, 287*82c00c2fSJames Liao psci_power_state_t *req_state) 288*82c00c2fSJames Liao { 289*82c00c2fSJames Liao unsigned int pstate = psci_get_pstate_type(power_state); 290*82c00c2fSJames Liao unsigned int aff_lvl = psci_get_pstate_pwrlvl(power_state); 291*82c00c2fSJames Liao unsigned int cpu = plat_my_core_pos(); 292*82c00c2fSJames Liao 293*82c00c2fSJames Liao if (aff_lvl > PLAT_MAX_PWR_LVL) { 294*82c00c2fSJames Liao return PSCI_E_INVALID_PARAMS; 295*82c00c2fSJames Liao } 296*82c00c2fSJames Liao 297*82c00c2fSJames Liao if (pstate == PSTATE_TYPE_STANDBY) { 298*82c00c2fSJames Liao req_state->pwr_domain_state[0] = PLAT_MAX_RET_STATE; 299*82c00c2fSJames Liao } else { 300*82c00c2fSJames Liao unsigned int i; 301*82c00c2fSJames Liao unsigned int pstate_id = psci_get_pstate_id(power_state); 302*82c00c2fSJames Liao plat_local_state_t s = MTK_LOCAL_STATE_OFF; 303*82c00c2fSJames Liao 304*82c00c2fSJames Liao /* Use pstate_id to be power domain state */ 305*82c00c2fSJames Liao if (pstate_id > s) { 306*82c00c2fSJames Liao s = (plat_local_state_t)pstate_id; 307*82c00c2fSJames Liao } 308*82c00c2fSJames Liao 309*82c00c2fSJames Liao for (i = 0U; i <= aff_lvl; i++) { 310*82c00c2fSJames Liao req_state->pwr_domain_state[i] = s; 311*82c00c2fSJames Liao } 312*82c00c2fSJames Liao } 313*82c00c2fSJames Liao 314*82c00c2fSJames Liao plat_power_state[cpu] = power_state; 315*82c00c2fSJames Liao return PSCI_E_SUCCESS; 316*82c00c2fSJames Liao } 317*82c00c2fSJames Liao 318*82c00c2fSJames Liao static void plat_get_sys_suspend_power_state(psci_power_state_t *req_state) 319*82c00c2fSJames Liao { 320*82c00c2fSJames Liao unsigned int lv; 321*82c00c2fSJames Liao unsigned int cpu = plat_my_core_pos(); 322*82c00c2fSJames Liao 323*82c00c2fSJames Liao for (lv = PSCI_CPU_PWR_LVL; lv <= PLAT_MAX_PWR_LVL; lv++) { 324*82c00c2fSJames Liao req_state->pwr_domain_state[lv] = PLAT_MAX_OFF_STATE; 325*82c00c2fSJames Liao } 326*82c00c2fSJames Liao 327*82c00c2fSJames Liao plat_power_state[cpu] = 328*82c00c2fSJames Liao psci_make_powerstate( 329*82c00c2fSJames Liao MT_PLAT_PWR_STATE_SYSTEM_SUSPEND, 330*82c00c2fSJames Liao PSTATE_TYPE_POWERDOWN, PLAT_MAX_PWR_LVL); 331*82c00c2fSJames Liao 332*82c00c2fSJames Liao flush_dcache_range((uintptr_t) 333*82c00c2fSJames Liao &plat_power_state[cpu], 334*82c00c2fSJames Liao sizeof(plat_power_state[cpu])); 335*82c00c2fSJames Liao } 336*82c00c2fSJames Liao 3370f408247SNina Wu static void __dead2 plat_mtk_system_reset(void) 3380f408247SNina Wu { 3390f408247SNina Wu struct bl_aux_gpio_info *gpio_reset = plat_get_mtk_gpio_reset(); 3400f408247SNina Wu 3410f408247SNina Wu INFO("MTK System Reset\n"); 3420f408247SNina Wu 3430f408247SNina Wu gpio_set_value(gpio_reset->index, gpio_reset->polarity); 3440f408247SNina Wu 3450f408247SNina Wu wfi(); 3460f408247SNina Wu ERROR("MTK System Reset: operation not handled.\n"); 3470f408247SNina Wu panic(); 3480f408247SNina Wu } 349f85f37d4SNina Wu 350*82c00c2fSJames Liao static const plat_psci_ops_t plat_psci_ops = { 3510f408247SNina Wu .system_reset = plat_mtk_system_reset, 352*82c00c2fSJames Liao .cpu_standby = plat_cpu_standby, 353*82c00c2fSJames Liao .pwr_domain_on = plat_power_domain_on, 354*82c00c2fSJames Liao .pwr_domain_on_finish = plat_power_domain_on_finish, 355*82c00c2fSJames Liao .pwr_domain_off = plat_power_domain_off, 356*82c00c2fSJames Liao .pwr_domain_suspend = plat_power_domain_suspend, 357*82c00c2fSJames Liao .pwr_domain_suspend_finish = plat_power_domain_suspend_finish, 358*82c00c2fSJames Liao .validate_power_state = plat_validate_power_state, 359*82c00c2fSJames Liao .get_sys_suspend_power_state = plat_get_sys_suspend_power_state 360f85f37d4SNina Wu }; 361f85f37d4SNina Wu 362f85f37d4SNina Wu int plat_setup_psci_ops(uintptr_t sec_entrypoint, 363f85f37d4SNina Wu const plat_psci_ops_t **psci_ops) 364f85f37d4SNina Wu { 365*82c00c2fSJames Liao *psci_ops = &plat_psci_ops; 366*82c00c2fSJames Liao secure_entrypoint = sec_entrypoint; 367*82c00c2fSJames Liao 368*82c00c2fSJames Liao /* 369*82c00c2fSJames Liao * init the warm reset config for boot CPU 370*82c00c2fSJames Liao * reset arch as AARCH64 371*82c00c2fSJames Liao * reset addr as function bl31_warm_entrypoint() 372*82c00c2fSJames Liao */ 373*82c00c2fSJames Liao mcucfg_init_archstate(0U, 0U, true); 374*82c00c2fSJames Liao mcucfg_set_bootaddr(0U, 0U, secure_entrypoint); 375*82c00c2fSJames Liao 376*82c00c2fSJames Liao spmc_init(); 377*82c00c2fSJames Liao plat_mt_pm = mt_plat_cpu_pm_init(); 378f85f37d4SNina Wu 379f85f37d4SNina Wu return 0; 380f85f37d4SNina Wu } 381