xref: /rk3399_ARM-atf/plat/mediatek/lib/pm/mtk_pm.h (revision 10ecd58093a34e95e2dfad65b1180610f29397cc)
1 /*
2  * Copyright (c) 2025, Mediatek Inc. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef MTK_PM_H
8 #define MTK_PM_H
9 #include <lib/psci/psci.h>
10 
11 #if MTK_PUBEVENT_ENABLE
12 #include <vendor_pubsub_events.h>
13 #endif
14 
15 #define MTK_CPUPM_E_OK			(0)
16 #define MTK_CPUPM_E_UNKNOWN		(-1)
17 #define MTK_CPUPM_E_ERR			(-2)
18 #define MTK_CPUPM_E_FAIL		(-3)
19 #define MTK_CPUPM_E_NOT_SUPPORT		(-4)
20 
21 #define MTK_CPUPM_FN_PWR_LOCK_AQUIRE		BIT(0)
22 #define MTK_CPUPM_FN_INIT			BIT(1)
23 #define MTK_CPUPM_FN_PWR_STATE_VALID		BIT(2)
24 #define MTK_CPUPM_FN_PWR_ON_CORE_PREPARE	BIT(3)
25 #define MTK_CPUPM_FN_SUSPEND_CORE		BIT(4)
26 #define MTK_CPUPM_FN_RESUME_CORE		BIT(5)
27 #define MTK_CPUPM_FN_SUSPEND_CLUSTER		BIT(6)
28 #define MTK_CPUPM_FN_RESUME_CLUSTER		BIT(7)
29 #define MTK_CPUPM_FN_SUSPEND_MCUSYS		BIT(8)
30 #define MTK_CPUPM_FN_RESUME_MCUSYS		BIT(9)
31 #define MTK_CPUPM_FN_CPUPM_GET_PWR_STATE	BIT(10)
32 #define MTK_CPUPM_FN_SMP_INIT			BIT(11)
33 #define MTK_CPUPM_FN_SMP_CORE_ON		BIT(12)
34 #define MTK_CPUPM_FN_SMP_CORE_OFF		BIT(13)
35 
36 enum mtk_cpupm_pstate {
37 	MTK_CPUPM_CORE_ON,
38 	MTK_CPUPM_CORE_OFF,
39 	MTK_CPUPM_CORE_SUSPEND,
40 	MTK_CPUPM_CORE_RESUME,
41 	MTK_CPUPM_CLUSTER_SUSPEND,
42 	MTK_CPUPM_CLUSTER_RESUME,
43 	MTK_CPUPM_MCUSYS_SUSPEND,
44 	MTK_CPUPM_MCUSYS_RESUME,
45 };
46 
47 enum mtk_cpu_pm_mode {
48 	MTK_CPU_PM_CPUIDLE,
49 	MTK_CPU_PM_SMP,
50 };
51 
52 #define MT_IRQ_REMAIN_MAX	(32)
53 #define MT_IRQ_REMAIN_CAT_LOG	BIT(31)
54 
55 struct mt_irqremain {
56 	unsigned int count;
57 	unsigned int irqs[MT_IRQ_REMAIN_MAX];
58 	unsigned int wakeupsrc_cat[MT_IRQ_REMAIN_MAX];
59 	unsigned int wakeupsrc[MT_IRQ_REMAIN_MAX];
60 };
61 
62 typedef void (*plat_init_func)(unsigned int, uintptr_t);
63 
64 struct plat_pm_smp_ctrl {
65 	plat_init_func init;
66 	int (*pwr_domain_on)(u_register_t mpidr);
67 	void (*pwr_domain_off)(const psci_power_state_t *target_state);
68 	void (*pwr_domain_on_finish)(const psci_power_state_t *target_state);
69 };
70 
71 struct plat_pm_pwr_ctrl {
72 	void (*pwr_domain_suspend)(const psci_power_state_t *target_state);
73 	void (*pwr_domain_on_finish_late)(const psci_power_state_t *target_state);
74 	void (*pwr_domain_suspend_finish)(const psci_power_state_t *target_state);
75 	int (*validate_power_state)(unsigned int power_state, psci_power_state_t *req_state);
76 	void (*get_sys_suspend_power_state)(psci_power_state_t *req_state);
77 };
78 
79 struct plat_pm_reset_ctrl {
80 	__dead2 void (*system_off)();
81 	__dead2 void (*system_reset)();
82 	int (*system_reset2)(int is_vendor, int reset_type, u_register_t cookie);
83 };
84 
85 struct mtk_cpu_pm_info {
86 	unsigned int cpuid;
87 	unsigned int mode;
88 };
89 
90 struct mtk_cpu_pm_state {
91 	unsigned int afflv;
92 	unsigned int state_id;
93 	const psci_power_state_t *raw;
94 };
95 
96 struct mtk_cpupm_pwrstate {
97 	struct mtk_cpu_pm_info info;
98 	struct mtk_cpu_pm_state pwr;
99 };
100 
101 struct mtk_cpu_smp_ops {
102 	void (*init)(unsigned int cpu, uintptr_t sec_entrypoint);
103 	int (*cpu_pwr_on_prepare)(unsigned int cpu, uintptr_t entry);
104 	void (*cpu_on)(const struct mtk_cpupm_pwrstate *state);
105 	void (*cpu_off)(const struct mtk_cpupm_pwrstate *state);
106 	int (*invoke)(unsigned int funcID, void *priv);
107 };
108 
109 #define MT_CPUPM_PWR_DOMAIN_CORE		BIT(0)
110 #define MT_CPUPM_PWR_DOMAIN_PERCORE_DSU		BIT(1)
111 #define MT_CPUPM_PWR_DOMAIN_PERCORE_DSU_MEM	BIT(2)
112 #define MT_CPUPM_PWR_DOMAIN_CLUSTER		BIT(3)
113 #define MT_CPUPM_PWR_DOMAIN_MCUSYS		BIT(4)
114 #define MT_CPUPM_PWR_DOMAIN_SUSPEND		BIT(5)
115 
116 enum mt_cpupm_pwr_domain {
117 	CPUPM_PWR_ON,
118 	CPUPM_PWR_OFF,
119 };
120 
121 typedef	unsigned int mtk_pstate_type;
122 
123 struct mtk_cpu_pm_ops {
124 	void (*init)(unsigned int cpu, uintptr_t sec_entrypoint);
125 	unsigned int (*get_pstate)(enum mt_cpupm_pwr_domain domain,
126 				   const mtk_pstate_type psci_state,
127 				   const struct mtk_cpupm_pwrstate *state);
128 	int (*pwr_state_valid)(unsigned int afflv, unsigned int state);
129 	void (*cpu_suspend)(const struct mtk_cpupm_pwrstate *state);
130 	void (*cpu_resume)(const struct mtk_cpupm_pwrstate *state);
131 	void (*cluster_suspend)(const struct mtk_cpupm_pwrstate *state);
132 	void (*cluster_resume)(const struct mtk_cpupm_pwrstate *state);
133 	void (*mcusys_suspend)(const struct mtk_cpupm_pwrstate *state);
134 	void (*mcusys_resume)(const struct mtk_cpupm_pwrstate *state);
135 	int (*invoke)(unsigned int funcID, void *priv);
136 };
137 
138 int register_cpu_pm_ops(unsigned int fn_flags, struct mtk_cpu_pm_ops *ops);
139 int register_cpu_smp_ops(unsigned int fn_flags, struct mtk_cpu_smp_ops *ops);
140 
141 struct mt_cpupm_event_data {
142 	unsigned int cpuid;
143 	unsigned int pwr_domain;
144 };
145 
146 /* Extension event for platform driver */
147 #if MTK_PUBEVENT_ENABLE
148 /* [PUB_EVENT] Core power on */
149 #define MT_CPUPM_SUBCRIBE_EVENT_PWR_ON(_fn) \
150 	SUBSCRIBE_TO_EVENT(mt_cpupm_publish_pwr_on, _fn)
151 
152 /* [PUB_EVENT] Core power off */
153 #define MT_CPUPM_SUBCRIBE_EVENT_PWR_OFF(_fn) \
154 	SUBSCRIBE_TO_EVENT(mt_cpupm_publish_pwr_off, _fn)
155 
156 /* [PUB_EVENT] Cluster power on */
157 #define MT_CPUPM_SUBCRIBE_CLUSTER_PWR_ON(_fn) \
158 	SUBSCRIBE_TO_EVENT(mt_cpupm_publish_afflv_pwr_on, _fn)
159 
160 /* [PUB_EVENT] Cluster power off */
161 #define MT_CPUPM_SUBCRIBE_CLUSTER_PWR_OFF(_fn) \
162 	SUBSCRIBE_TO_EVENT(mt_cpupm_publish_afflv_pwr_off, _fn)
163 
164 /* [PUB_EVENT] Mcusys power on */
165 #define MT_CPUPM_SUBCRIBE_MCUSYS_PWR_ON(_fn) \
166 	SUBSCRIBE_TO_EVENT(mt_cpupm_publish_afflv_pwr_on, _fn)
167 
168 /* [PUB_EVENT] Mcusys power off */
169 #define MT_CPUPM_SUBCRIBE_MCUSYS_PWR_OFF(_fn) \
170 	SUBSCRIBE_TO_EVENT(mt_cpupm_publish_afflv_pwr_off, _fn)
171 
172 /* [PUB_EVENT] el3 time sync */
173 #define MT_CPUPM_SUBCRIBE_EL3_UPTIME_SYNC_WITH_KERNEL(_fn) \
174 	SUBSCRIBE_TO_EVENT(el3_uptime_sync_with_kernel, _fn)
175 
176 #else
177 #define MT_CPUPM_SUBCRIBE_EVENT_PWR_ON(_fn)
178 #define MT_CPUPM_SUBCRIBE_EVENT_PWR_OFF(_fn)
179 #define MT_CPUPM_SUBCRIBE_CLUSTER_PWR_ON(_fn)
180 #define MT_CPUPM_SUBCRIBE_CLUSTER_PWR_OFF(_fn)
181 #define MT_CPUPM_SUBCRIBE_MCUSYS_PWR_ON(_fn)
182 #define MT_CPUPM_SUBCRIBE_MCUSYS_PWR_OFF(_fn)
183 #define MT_CPUPM_SUBCRIBE_EL3_UPTIME_SYNC_WITH_KERNEL(_fn)
184 #endif
185 
186 /*
187  * Definition c-state power domain.
188  * bit[7:4] (main state id):
189  *  - 1: Cluster.
190  *  - 2: Mcusys.
191  *  - 3: Memory.
192  *  - 4: System pll.
193  *  - 5: System bus.
194  *  - 6: SoC 26m/DCXO.
195  *  - 7: Vcore buck.
196  *  - 15: Suspend.
197  * bit[3:0] (reserved for state_id extension):
198  *  - 4: CPU buck.
199  */
200 #define MT_PLAT_PWR_STATE_CLUSTER	(0x0010)
201 #define MT_PLAT_PWR_STATE_MCUSYS	(0x0020)
202 #define MT_PLAT_PWR_STATE_MCUSYS_BUCK	(0x0024)
203 #define MT_PLAT_PWR_STATE_SYSTEM_MEM	(0x0030)
204 #define MT_PLAT_PWR_STATE_SYSTEM_PLL	(0x0040)
205 #define MT_PLAT_PWR_STATE_SYSTEM_BUS	(0x0050)
206 #define MT_PLAT_PWR_STATE_SUSPEND	(0x00f0)
207 
208 #define IS_MT_PLAT_PWR_STATE(state, target_state) \
209 	((state & target_state) == target_state)
210 #define IS_MT_PLAT_PWR_STATE_MCUSYS(state) \
211 	IS_MT_PLAT_PWR_STATE(state, MT_PLAT_PWR_STATE_MCUSYS)
212 
213 #define PLAT_MT_SYSTEM_SUSPEND		PLAT_MAX_OFF_STATE
214 #define PLAT_MT_CPU_SUSPEND_CLUSTER	PLAT_MAX_RET_STATE
215 #define PLAT_MT_CPU_SUSPEND_MCUSYS	PLAT_MAX_RET_STATE
216 
217 #define IS_PLAT_SYSTEM_SUSPEND(aff)	(aff == PLAT_MT_SYSTEM_SUSPEND)
218 #define IS_PLAT_SYSTEM_RETENTION(aff)	(aff >= PLAT_MAX_RET_STATE)
219 
220 #define IS_PLAT_SUSPEND_ID(stateid)	(stateid == MT_PLAT_PWR_STATE_SUSPEND)
221 
222 #define IS_PLAT_MCUSYSOFF_AFFLV(afflv)	(afflv >= PLAT_MT_CPU_SUSPEND_MCUSYS)
223 
224 int plat_pm_ops_setup_pwr(struct plat_pm_pwr_ctrl *ops);
225 int plat_pm_ops_setup_reset(struct plat_pm_reset_ctrl *ops);
226 int plat_pm_ops_setup_smp(struct plat_pm_smp_ctrl *ops);
227 uintptr_t plat_pm_get_warm_entry(void);
228 
229 #endif
230