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