xref: /arm-trusted-firmware/plat/mediatek/lib/pm/mtk_pm.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 #include <plat/common/platform.h>
9*91f16700Schasinglulu #include <lib/pm/mtk_pm.h>
10*91f16700Schasinglulu 
11*91f16700Schasinglulu #define MTK_PM_ST_SMP_READY	BIT(0)
12*91f16700Schasinglulu #define MTK_PM_ST_PWR_READY	BIT(1)
13*91f16700Schasinglulu #define MTK_PM_ST_RESET_READY	BIT(2)
14*91f16700Schasinglulu 
15*91f16700Schasinglulu static uintptr_t mtk_secure_entrypoint;
16*91f16700Schasinglulu static plat_init_func mtk_plat_smp_init;
17*91f16700Schasinglulu static plat_psci_ops_t mtk_pm_ops;
18*91f16700Schasinglulu static unsigned int mtk_pm_status;
19*91f16700Schasinglulu 
20*91f16700Schasinglulu uintptr_t plat_pm_get_warm_entry(void)
21*91f16700Schasinglulu {
22*91f16700Schasinglulu 	return mtk_secure_entrypoint;
23*91f16700Schasinglulu }
24*91f16700Schasinglulu 
25*91f16700Schasinglulu int plat_pm_ops_setup_pwr(struct plat_pm_pwr_ctrl *ops)
26*91f16700Schasinglulu {
27*91f16700Schasinglulu 	if (!ops) {
28*91f16700Schasinglulu 		return MTK_CPUPM_E_FAIL;
29*91f16700Schasinglulu 	}
30*91f16700Schasinglulu 
31*91f16700Schasinglulu #if CONFIG_MTK_CPU_SUSPEND_EN
32*91f16700Schasinglulu 	if (!mtk_pm_ops.pwr_domain_suspend) {
33*91f16700Schasinglulu 		mtk_pm_ops.pwr_domain_suspend = ops->pwr_domain_suspend;
34*91f16700Schasinglulu 	}
35*91f16700Schasinglulu 
36*91f16700Schasinglulu 	if (!mtk_pm_ops.pwr_domain_suspend_finish) {
37*91f16700Schasinglulu 		mtk_pm_ops.pwr_domain_suspend_finish = ops->pwr_domain_suspend_finish;
38*91f16700Schasinglulu 	}
39*91f16700Schasinglulu 
40*91f16700Schasinglulu 	if (!mtk_pm_ops.validate_power_state) {
41*91f16700Schasinglulu 		mtk_pm_ops.validate_power_state = ops->validate_power_state;
42*91f16700Schasinglulu 	}
43*91f16700Schasinglulu 
44*91f16700Schasinglulu 	if (!mtk_pm_ops.get_sys_suspend_power_state) {
45*91f16700Schasinglulu 		mtk_pm_ops.get_sys_suspend_power_state = ops->get_sys_suspend_power_state;
46*91f16700Schasinglulu 	}
47*91f16700Schasinglulu 
48*91f16700Schasinglulu 	mtk_pm_status |= MTK_PM_ST_PWR_READY;
49*91f16700Schasinglulu #endif
50*91f16700Schasinglulu 	return MTK_CPUPM_E_OK;
51*91f16700Schasinglulu }
52*91f16700Schasinglulu 
53*91f16700Schasinglulu int plat_pm_ops_setup_smp(struct plat_pm_smp_ctrl *ops)
54*91f16700Schasinglulu {
55*91f16700Schasinglulu 	if (!ops) {
56*91f16700Schasinglulu 		return MTK_CPUPM_E_FAIL;
57*91f16700Schasinglulu 	}
58*91f16700Schasinglulu 
59*91f16700Schasinglulu #if CONFIG_MTK_SMP_EN
60*91f16700Schasinglulu 	if (!mtk_pm_ops.pwr_domain_on) {
61*91f16700Schasinglulu 		mtk_pm_ops.pwr_domain_on = ops->pwr_domain_on;
62*91f16700Schasinglulu 	}
63*91f16700Schasinglulu 
64*91f16700Schasinglulu 	if (!mtk_pm_ops.pwr_domain_on_finish) {
65*91f16700Schasinglulu 		mtk_pm_ops.pwr_domain_on_finish = ops->pwr_domain_on_finish;
66*91f16700Schasinglulu 	}
67*91f16700Schasinglulu 
68*91f16700Schasinglulu 	if (!mtk_pm_ops.pwr_domain_off) {
69*91f16700Schasinglulu 		mtk_pm_ops.pwr_domain_off = ops->pwr_domain_off;
70*91f16700Schasinglulu 	}
71*91f16700Schasinglulu 
72*91f16700Schasinglulu 	if (!mtk_plat_smp_init) {
73*91f16700Schasinglulu 		mtk_plat_smp_init = ops->init;
74*91f16700Schasinglulu 	}
75*91f16700Schasinglulu 
76*91f16700Schasinglulu 	mtk_pm_status |= MTK_PM_ST_SMP_READY;
77*91f16700Schasinglulu #endif
78*91f16700Schasinglulu 	return MTK_CPUPM_E_OK;
79*91f16700Schasinglulu }
80*91f16700Schasinglulu 
81*91f16700Schasinglulu int plat_pm_ops_setup_reset(struct plat_pm_reset_ctrl *ops)
82*91f16700Schasinglulu {
83*91f16700Schasinglulu 	if (!ops) {
84*91f16700Schasinglulu 		return MTK_CPUPM_E_FAIL;
85*91f16700Schasinglulu 	}
86*91f16700Schasinglulu 
87*91f16700Schasinglulu 	if (!mtk_pm_ops.system_off) {
88*91f16700Schasinglulu 		mtk_pm_ops.system_off = ops->system_off;
89*91f16700Schasinglulu 	}
90*91f16700Schasinglulu 
91*91f16700Schasinglulu 	if (!mtk_pm_ops.system_reset) {
92*91f16700Schasinglulu 		mtk_pm_ops.system_reset = ops->system_reset;
93*91f16700Schasinglulu 	}
94*91f16700Schasinglulu 
95*91f16700Schasinglulu 	if (!mtk_pm_ops.system_reset2) {
96*91f16700Schasinglulu 		mtk_pm_ops.system_reset2 = ops->system_reset2;
97*91f16700Schasinglulu 	}
98*91f16700Schasinglulu 
99*91f16700Schasinglulu 	mtk_pm_status |= MTK_PM_ST_RESET_READY;
100*91f16700Schasinglulu 
101*91f16700Schasinglulu 	return MTK_CPUPM_E_OK;
102*91f16700Schasinglulu }
103*91f16700Schasinglulu 
104*91f16700Schasinglulu int plat_setup_psci_ops(uintptr_t sec_entrypoint,
105*91f16700Schasinglulu 			const plat_psci_ops_t **psci_ops)
106*91f16700Schasinglulu {
107*91f16700Schasinglulu 	*psci_ops = &mtk_pm_ops;
108*91f16700Schasinglulu 	mtk_secure_entrypoint = sec_entrypoint;
109*91f16700Schasinglulu 
110*91f16700Schasinglulu 	if (mtk_plat_smp_init) {
111*91f16700Schasinglulu 		unsigned int cpu_id = plat_my_core_pos();
112*91f16700Schasinglulu 
113*91f16700Schasinglulu 		mtk_plat_smp_init(cpu_id, mtk_secure_entrypoint);
114*91f16700Schasinglulu 	}
115*91f16700Schasinglulu 	INFO("%s, smp:(%d), pwr_ctrl:(%d), system_reset:(%d)\n", __func__,
116*91f16700Schasinglulu 	     !!(mtk_pm_status & MTK_PM_ST_SMP_READY),
117*91f16700Schasinglulu 	     !!(mtk_pm_status & MTK_PM_ST_PWR_READY),
118*91f16700Schasinglulu 	     !!(mtk_pm_status & MTK_PM_ST_RESET_READY));
119*91f16700Schasinglulu 	return 0;
120*91f16700Schasinglulu }
121