xref: /rk3399_ARM-atf/plat/mediatek/drivers/cpu_pm/cpcv5_4/mt_smp.c (revision 06f3c7058c42a9f1a9f7df75ea2de71a000855e8)
1 /*
2  * Copyright (c) 2025, 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_ppu.h"
18 #include "mt_smp.h"
19 
20 #define is_core_power_status_on(_pwr_ctrl)\
21 	(!!((mmio_read_32(_pwr_ctrl->pwr.ppu_pwsr)) & (PPU_PWSR_STATE_ON)))
22 
23 #ifndef CPU_PM_CORE_ARCH64_ONLY
24 void mt_smp_core_init_arch(int cluster,
25 			   int cpu,
26 			   int arm64,
27 			   struct cpu_pwr_ctrl *pwr_ctrl)
28 {
29 	CPU_PM_ASSERT(cluster == 0);
30 	CPU_PM_ASSERT(pwr_ctrl);
31 
32 	/* aa64naa32 in bits[16:23] */
33 	if (arm64)
34 		mmio_setbits_32(pwr_ctrl->arch_addr,
35 				BIT(AA64NAA32_FLAG_START_BIT + cpu));
36 	else
37 		mmio_clrbits_32(pwr_ctrl->arch_addr,
38 				BIT(AA64NAA32_FLAG_START_BIT + cpu));
39 }
40 #endif /* CPU_PM_CORE_ARCH64_ONLY */
41 
42 void mt_smp_core_bootup_address_set(int cluster,
43 				    int cpu,
44 				    struct cpu_pwr_ctrl *pwr_ctrl,
45 				    uintptr_t entry)
46 {
47 	CPU_PM_ASSERT(pwr_ctrl);
48 
49 	/* Set bootup address */
50 	mmio_write_32(pwr_ctrl->rvbaraddr_l, entry);
51 	mmio_write_32(pwr_ctrl->rvbaraddr_h, 0);
52 }
53 
54 int mt_smp_power_core_on(unsigned int cpu_id, struct cpu_pwr_ctrl *pwr_ctrl)
55 {
56 	unsigned int val = 0;
57 
58 	CPU_PM_ASSERT(pwr_ctrl);
59 
60 	mt_smp_ppu_pwr_set(&pwr_ctrl->pwr, PPU_PWPR_DYNAMIC_MODE, PPU_PWPR_OFF);
61 	val = is_core_power_status_on(pwr_ctrl);
62 	if (!val) {
63 		mmio_clrbits_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG,
64 				GIC_WAKEUP_IGNORE(cpu_id));
65 		mmio_setbits_32(SPM_EXT_INT_WAKEUP_REQ_SET, BIT(cpu_id));
66 
67 		mmio_clrbits_32(SPMC_CONTROL_CONFIG,
68 				SPMC_CPU_RESET_PWRON_CONFIG << (cpu_id));
69 		dsbsy();
70 		isb();
71 
72 		while (!is_core_power_status_on(pwr_ctrl))
73 			DO_SMP_CORE_ON_WAIT_TIMEOUT(cpu_id, val);
74 		mmio_setbits_32(SPM_EXT_INT_WAKEUP_REQ_CLR, BIT(cpu_id));
75 	} else {
76 		mmio_clrbits_32(SPMC_CONTROL_CONFIG,
77 				SPMC_CPU_RESET_PWRON_CONFIG << (cpu_id));
78 		INFO("[%s:%d] - core_%u have been power on\n",
79 		     __func__, __LINE__, cpu_id);
80 	}
81 
82 	return MTK_CPUPM_E_OK;
83 }
84 
85 int mt_smp_power_core_off(unsigned int cpu_id, struct cpu_pwr_ctrl *pwr_ctrl)
86 {
87 	mmio_setbits_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG,
88 			GIC_WAKEUP_IGNORE(cpu_id));
89 	return MTK_CPUPM_E_OK;
90 }
91 
92 void mt_smp_init(void)
93 {
94 	mmio_write_32(SPM_POWERON_CONFIG_EN, PROJECT_CODE | BCLK_CG_EN);
95 
96 	/* INFO=SPMC_INIT: clear resetpwron of mcusys/cluster/core0 */
97 	mmio_clrbits_32(SPMC_CONTROL_CONFIG, SPMC_MCUSYS_RESET_PWRON_CONFIG);
98 	mmio_clrbits_32(SPMC_CONTROL_CONFIG, SPMC_CPUTOP_RESET_PWRON_CONFIG);
99 
100 	/* Switch DSU ISO/CKDIS control from PCSM to PPU */
101 	mmio_setbits_32(CPC_FCM_SPMC_SW_CFG2,
102 			(CPUSYS_PPU_CLK_EN_CTRL | CPUSYS_PPU_ISO_CTRL));
103 
104 #ifdef SPM_CPU_BUCK_ISO_CON
105 	/* Make sure that buck iso have been released before power on */
106 	mmio_write_32(SPM_CPU_BUCK_ISO_CON, SPM_CPU_BUCK_ISO_DEFAUT);
107 #endif /* SPM_CPU_BUCK_ISO_CON */
108 }
109