xref: /arm-trusted-firmware/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_smp.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
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