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