xref: /rk3399_ARM-atf/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_smp.c (revision 3fb300a9648c4aafc13eb48d545d2d14908cbad3)
14fe7e6a8SEdward-JW Yang /*
24fe7e6a8SEdward-JW Yang  * Copyright (c) 2022, MediaTek Inc. All rights reserved.
34fe7e6a8SEdward-JW Yang  *
44fe7e6a8SEdward-JW Yang  * SPDX-License-Identifier: BSD-3-Clause
54fe7e6a8SEdward-JW Yang  */
64fe7e6a8SEdward-JW Yang 
74fe7e6a8SEdward-JW Yang #include <assert.h>
84fe7e6a8SEdward-JW Yang 
94fe7e6a8SEdward-JW Yang #include <arch_helpers.h>
104fe7e6a8SEdward-JW Yang #include <common/debug.h>
114fe7e6a8SEdward-JW Yang #include <drivers/delay_timer.h>
124fe7e6a8SEdward-JW Yang #include <plat/common/platform.h>
134fe7e6a8SEdward-JW Yang 
144fe7e6a8SEdward-JW Yang #include <lib/pm/mtk_pm.h>
154fe7e6a8SEdward-JW Yang #include <mcucfg.h>
164fe7e6a8SEdward-JW Yang #include "mt_cpu_pm.h"
174fe7e6a8SEdward-JW Yang #include "mt_smp.h"
184fe7e6a8SEdward-JW Yang 
is_core_power_status_on(unsigned int cpuid)194fe7e6a8SEdward-JW Yang static inline int is_core_power_status_on(unsigned int cpuid)
204fe7e6a8SEdward-JW Yang {
214fe7e6a8SEdward-JW Yang 	return !!(mmio_read_32(CPU_PWR_STATUS) & BIT(cpuid));
224fe7e6a8SEdward-JW Yang }
234fe7e6a8SEdward-JW Yang 
mt_smp_core_init_arch(unsigned int cluster,unsigned int cpu,int arm64,struct cpu_pwr_ctrl * pwr_ctrl)244fe7e6a8SEdward-JW Yang void mt_smp_core_init_arch(unsigned int cluster, unsigned int cpu, int arm64,
254fe7e6a8SEdward-JW Yang 			   struct cpu_pwr_ctrl *pwr_ctrl)
264fe7e6a8SEdward-JW Yang {
274fe7e6a8SEdward-JW Yang 	CPU_PM_ASSERT(cluster == 0);
284fe7e6a8SEdward-JW Yang 	CPU_PM_ASSERT(pwr_ctrl != NULL);
294fe7e6a8SEdward-JW Yang 
304fe7e6a8SEdward-JW Yang 	/* aa64naa32 in bits[16:23] */
314fe7e6a8SEdward-JW Yang 	if (arm64 != 0) {
324fe7e6a8SEdward-JW Yang 		mmio_setbits_32(pwr_ctrl->arch_addr, 1 << (16 + cpu));
334fe7e6a8SEdward-JW Yang 	} else {
344fe7e6a8SEdward-JW Yang 		mmio_clrbits_32(pwr_ctrl->arch_addr, 1 << (16 + cpu));
354fe7e6a8SEdward-JW Yang 	}
364fe7e6a8SEdward-JW Yang }
374fe7e6a8SEdward-JW Yang 
mt_smp_core_bootup_address_set(struct cpu_pwr_ctrl * pwr_ctrl,uintptr_t entry)384fe7e6a8SEdward-JW Yang void mt_smp_core_bootup_address_set(struct cpu_pwr_ctrl *pwr_ctrl, uintptr_t entry)
394fe7e6a8SEdward-JW Yang {
404fe7e6a8SEdward-JW Yang 	CPU_PM_ASSERT(pwr_ctrl != NULL);
414fe7e6a8SEdward-JW Yang 
424fe7e6a8SEdward-JW Yang 	/* Set bootup address */
434fe7e6a8SEdward-JW Yang 	mmio_write_32(pwr_ctrl->rvbaraddr_l, entry);
444fe7e6a8SEdward-JW Yang }
454fe7e6a8SEdward-JW Yang 
mt_smp_power_core_on(unsigned int cpu_id,struct cpu_pwr_ctrl * pwr_ctrl)464fe7e6a8SEdward-JW Yang int mt_smp_power_core_on(unsigned int cpu_id, struct cpu_pwr_ctrl *pwr_ctrl)
474fe7e6a8SEdward-JW Yang {
48*b8d63a7aSKai Liang 	uint32_t pwpr_reg;
494fe7e6a8SEdward-JW Yang 	unsigned int val = is_core_power_status_on(cpu_id);
504fe7e6a8SEdward-JW Yang 
514fe7e6a8SEdward-JW Yang 	CPU_PM_ASSERT(pwr_ctrl);
524fe7e6a8SEdward-JW Yang 
53*b8d63a7aSKai Liang #ifdef CPU_PM_SPM_CORE_POWERON
54*b8d63a7aSKai Liang 	pwpr_reg = pwr_ctrl->pwpr_intermediate;
55*b8d63a7aSKai Liang #else
56*b8d63a7aSKai Liang 	pwpr_reg = pwr_ctrl->pwpr;
57*b8d63a7aSKai Liang #endif
58*b8d63a7aSKai Liang 
59*b8d63a7aSKai Liang 	mmio_clrbits_32(pwpr_reg, RESETPWRON_CONFIG);
60*b8d63a7aSKai Liang 
614fe7e6a8SEdward-JW Yang 	if (val == 0) {
624fe7e6a8SEdward-JW Yang 		/*
634fe7e6a8SEdward-JW Yang 		 * Set to 0 after BIG VPROC bulk powered on (configure in MCUPM) and
644fe7e6a8SEdward-JW Yang 		 * before big core power-on sequence.
654fe7e6a8SEdward-JW Yang 		 */
664fe7e6a8SEdward-JW Yang 		if (cpu_id >= PLAT_CPU_PM_B_BUCK_ISO_ID) {
674fe7e6a8SEdward-JW Yang 			mmio_write_32(DREQ20_BIG_VPROC_ISO, 0);
684fe7e6a8SEdward-JW Yang 		}
694fe7e6a8SEdward-JW Yang 
70*b8d63a7aSKai Liang #ifdef CPU_PM_SPM_CORE_POWERON
71*b8d63a7aSKai Liang 		mmio_setbits_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG,
72*b8d63a7aSKai Liang 				SSPM_ALL_PWR_CTRL_EN);
73*b8d63a7aSKai Liang #endif
74*b8d63a7aSKai Liang 
754fe7e6a8SEdward-JW Yang 		mmio_setbits_32(pwr_ctrl->pwpr, PWR_RST_B);
764fe7e6a8SEdward-JW Yang 		dsbsy();
774fe7e6a8SEdward-JW Yang 
78*b8d63a7aSKai Liang 		/* Set mp0_spmc_pwr_on_cpuX = 1 */
79*b8d63a7aSKai Liang 		mmio_setbits_32(pwpr_reg, PWR_ON);
804fe7e6a8SEdward-JW Yang 
814fe7e6a8SEdward-JW Yang 		val = 0;
824fe7e6a8SEdward-JW Yang 		while (is_core_power_status_on(cpu_id) == 0) {
834fe7e6a8SEdward-JW Yang 			DO_SMP_CORE_ON_WAIT_TIMEOUT(val);
84*b8d63a7aSKai Liang 			mmio_clrbits_32(pwpr_reg, PWR_ON);
85*b8d63a7aSKai Liang 			mmio_setbits_32(pwpr_reg, PWR_ON);
864fe7e6a8SEdward-JW Yang 		}
874fe7e6a8SEdward-JW Yang 	} else {
884fe7e6a8SEdward-JW Yang 		INFO("[%s:%d] - core_%u haven been power on\n", __func__, __LINE__, cpu_id);
894fe7e6a8SEdward-JW Yang 	}
904fe7e6a8SEdward-JW Yang 
914fe7e6a8SEdward-JW Yang 	return MTK_CPUPM_E_OK;
924fe7e6a8SEdward-JW Yang }
934fe7e6a8SEdward-JW Yang 
mt_smp_power_core_off(struct cpu_pwr_ctrl * pwr_ctrl)944fe7e6a8SEdward-JW Yang int mt_smp_power_core_off(struct cpu_pwr_ctrl *pwr_ctrl)
954fe7e6a8SEdward-JW Yang {
96*b8d63a7aSKai Liang 	/* Set mp0_spmc_pwr_on_cpuX = 1 */
97*b8d63a7aSKai Liang #ifdef CPU_PM_SPM_CORE_POWERON
98*b8d63a7aSKai Liang 	mmio_clrbits_32(pwr_ctrl->pwpr_intermediate, PWR_ON);
99*b8d63a7aSKai Liang #else
1004fe7e6a8SEdward-JW Yang 	mmio_clrbits_32(pwr_ctrl->pwpr, PWR_ON);
101*b8d63a7aSKai Liang #endif
1024fe7e6a8SEdward-JW Yang 	return MTK_CPUPM_E_OK;
1034fe7e6a8SEdward-JW Yang }
1044fe7e6a8SEdward-JW Yang 
mt_smp_init(void)1054fe7e6a8SEdward-JW Yang void mt_smp_init(void)
1064fe7e6a8SEdward-JW Yang {
107*b8d63a7aSKai Liang 	/* INFO=SPMC_INIT: clear resetpwron of mcusys/cluster/core0 */
108*b8d63a7aSKai Liang #ifdef CPU_PM_SPM_CORE_POWERON
109*b8d63a7aSKai Liang 	mmio_write_32(SPM_POWERON_CONFIG_EN, PROJECT_CODE | BCLK_CG_EN);
110*b8d63a7aSKai Liang 	mmio_clrbits_32(SPM_VLP_MCUSYS_PWR_CON, RESETPWRON_CONFIG);
111*b8d63a7aSKai Liang 	mmio_clrbits_32(SPM_VLP_MP0_CPUTOP_PWR_CON, RESETPWRON_CONFIG);
112*b8d63a7aSKai Liang #else
1134fe7e6a8SEdward-JW Yang 	mmio_clrbits_32(SPM_MCUSYS_PWR_CON, RESETPWRON_CONFIG);
1144fe7e6a8SEdward-JW Yang 	mmio_clrbits_32(SPM_MP0_CPUTOP_PWR_CON, RESETPWRON_CONFIG);
115*b8d63a7aSKai Liang #endif
1164fe7e6a8SEdward-JW Yang }
117