1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2022, MediaTek Inc. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <assert.h> 8*91f16700Schasinglulu 9*91f16700Schasinglulu #include <arch_helpers.h> 10*91f16700Schasinglulu #include <common/debug.h> 11*91f16700Schasinglulu #include <drivers/delay_timer.h> 12*91f16700Schasinglulu #include <plat/common/platform.h> 13*91f16700Schasinglulu 14*91f16700Schasinglulu #include <lib/pm/mtk_pm.h> 15*91f16700Schasinglulu #include <mcucfg.h> 16*91f16700Schasinglulu #include "mt_cpu_pm.h" 17*91f16700Schasinglulu #include "mt_smp.h" 18*91f16700Schasinglulu 19*91f16700Schasinglulu static inline int is_core_power_status_on(unsigned int cpuid) 20*91f16700Schasinglulu { 21*91f16700Schasinglulu return !!(mmio_read_32(CPU_PWR_STATUS) & BIT(cpuid)); 22*91f16700Schasinglulu } 23*91f16700Schasinglulu 24*91f16700Schasinglulu void mt_smp_core_init_arch(unsigned int cluster, unsigned int cpu, int arm64, 25*91f16700Schasinglulu struct cpu_pwr_ctrl *pwr_ctrl) 26*91f16700Schasinglulu { 27*91f16700Schasinglulu CPU_PM_ASSERT(cluster == 0); 28*91f16700Schasinglulu CPU_PM_ASSERT(pwr_ctrl != NULL); 29*91f16700Schasinglulu 30*91f16700Schasinglulu /* aa64naa32 in bits[16:23] */ 31*91f16700Schasinglulu if (arm64 != 0) { 32*91f16700Schasinglulu mmio_setbits_32(pwr_ctrl->arch_addr, 1 << (16 + cpu)); 33*91f16700Schasinglulu } else { 34*91f16700Schasinglulu mmio_clrbits_32(pwr_ctrl->arch_addr, 1 << (16 + cpu)); 35*91f16700Schasinglulu } 36*91f16700Schasinglulu } 37*91f16700Schasinglulu 38*91f16700Schasinglulu void mt_smp_core_bootup_address_set(struct cpu_pwr_ctrl *pwr_ctrl, uintptr_t entry) 39*91f16700Schasinglulu { 40*91f16700Schasinglulu CPU_PM_ASSERT(pwr_ctrl != NULL); 41*91f16700Schasinglulu 42*91f16700Schasinglulu /* Set bootup address */ 43*91f16700Schasinglulu mmio_write_32(pwr_ctrl->rvbaraddr_l, entry); 44*91f16700Schasinglulu } 45*91f16700Schasinglulu 46*91f16700Schasinglulu int mt_smp_power_core_on(unsigned int cpu_id, struct cpu_pwr_ctrl *pwr_ctrl) 47*91f16700Schasinglulu { 48*91f16700Schasinglulu unsigned int val = is_core_power_status_on(cpu_id); 49*91f16700Schasinglulu 50*91f16700Schasinglulu CPU_PM_ASSERT(pwr_ctrl); 51*91f16700Schasinglulu 52*91f16700Schasinglulu mmio_clrbits_32(pwr_ctrl->pwpr, RESETPWRON_CONFIG); 53*91f16700Schasinglulu if (val == 0) { 54*91f16700Schasinglulu /* 55*91f16700Schasinglulu * Set to 0 after BIG VPROC bulk powered on (configure in MCUPM) and 56*91f16700Schasinglulu * before big core power-on sequence. 57*91f16700Schasinglulu */ 58*91f16700Schasinglulu if (cpu_id >= PLAT_CPU_PM_B_BUCK_ISO_ID) { 59*91f16700Schasinglulu mmio_write_32(DREQ20_BIG_VPROC_ISO, 0); 60*91f16700Schasinglulu } 61*91f16700Schasinglulu 62*91f16700Schasinglulu mmio_setbits_32(pwr_ctrl->pwpr, PWR_RST_B); 63*91f16700Schasinglulu dsbsy(); 64*91f16700Schasinglulu 65*91f16700Schasinglulu /* set mp0_spmc_pwr_on_cpuX = 1 */ 66*91f16700Schasinglulu mmio_setbits_32(pwr_ctrl->pwpr, PWR_ON); 67*91f16700Schasinglulu 68*91f16700Schasinglulu val = 0; 69*91f16700Schasinglulu while (is_core_power_status_on(cpu_id) == 0) { 70*91f16700Schasinglulu DO_SMP_CORE_ON_WAIT_TIMEOUT(val); 71*91f16700Schasinglulu mmio_clrbits_32(pwr_ctrl->pwpr, PWR_ON); 72*91f16700Schasinglulu mmio_setbits_32(pwr_ctrl->pwpr, PWR_ON); 73*91f16700Schasinglulu } 74*91f16700Schasinglulu } else { 75*91f16700Schasinglulu INFO("[%s:%d] - core_%u haven been power on\n", __func__, __LINE__, cpu_id); 76*91f16700Schasinglulu } 77*91f16700Schasinglulu 78*91f16700Schasinglulu return MTK_CPUPM_E_OK; 79*91f16700Schasinglulu } 80*91f16700Schasinglulu 81*91f16700Schasinglulu int mt_smp_power_core_off(struct cpu_pwr_ctrl *pwr_ctrl) 82*91f16700Schasinglulu { 83*91f16700Schasinglulu /* set mp0_spmc_pwr_on_cpuX = 1 */ 84*91f16700Schasinglulu mmio_clrbits_32(pwr_ctrl->pwpr, PWR_ON); 85*91f16700Schasinglulu return MTK_CPUPM_E_OK; 86*91f16700Schasinglulu } 87*91f16700Schasinglulu 88*91f16700Schasinglulu void mt_smp_init(void) 89*91f16700Schasinglulu { 90*91f16700Schasinglulu /* clear RESETPWRON_CONFIG of mcusys/cluster/core0 */ 91*91f16700Schasinglulu mmio_clrbits_32(SPM_MCUSYS_PWR_CON, RESETPWRON_CONFIG); 92*91f16700Schasinglulu mmio_clrbits_32(SPM_MP0_CPUTOP_PWR_CON, RESETPWRON_CONFIG); 93*91f16700Schasinglulu } 94