blob: 0ee15e968940367d044ac76ba188cd47bf12c402 [file] [log] [blame]
developera4938652022-09-05 16:36:31 +08001/*
developer90e10802024-12-28 21:25:21 +08002 * Copyright (c) 2025, Mediatek Inc. All rights reserved.
developera4938652022-09-05 16:36:31 +08003 *
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
developer3378af82022-10-14 16:19:25 +080012#include <vendor_pubsub_events.h>
developera4938652022-09-05 16:36:31 +080013#endif
14
Edward-JW Yang80ac32f2022-09-15 21:09:10 +080015#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)
developera4938652022-09-05 16:36:31 +080020
developera4938652022-09-05 16:36:31 +080021#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
36enum 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
47enum 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
55struct 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
62typedef void (*plat_init_func)(unsigned int, uintptr_t);
63
64struct 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
71struct 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
79struct 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
85struct mtk_cpu_pm_info {
86 unsigned int cpuid;
87 unsigned int mode;
88};
89
90struct mtk_cpu_pm_state {
91 unsigned int afflv;
92 unsigned int state_id;
93 const psci_power_state_t *raw;
94};
95
96struct mtk_cpupm_pwrstate {
97 struct mtk_cpu_pm_info info;
98 struct mtk_cpu_pm_state pwr;
99};
100
101struct 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
116enum mt_cpupm_pwr_domain {
117 CPUPM_PWR_ON,
118 CPUPM_PWR_OFF,
119};
120
121typedef unsigned int mtk_pstate_type;
122
123struct 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
138int register_cpu_pm_ops(unsigned int fn_flags, struct mtk_cpu_pm_ops *ops);
139int register_cpu_smp_ops(unsigned int fn_flags, struct mtk_cpu_smp_ops *ops);
140
141struct 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
developer90e10802024-12-28 21:25:21 +0800172/* [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
developera4938652022-09-05 16:36:31 +0800176#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)
developer90e10802024-12-28 21:25:21 +0800183#define MT_CPUPM_SUBCRIBE_EL3_UPTIME_SYNC_WITH_KERNEL(_fn)
developera4938652022-09-05 16:36:31 +0800184#endif
185
Edward-JW Yang80ac32f2022-09-15 21:09:10 +0800186/*
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)
developera4938652022-09-05 16:36:31 +0800207
developer90e10802024-12-28 21:25:21 +0800208#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)
developera4938652022-09-05 16:36:31 +0800212
213#define PLAT_MT_SYSTEM_SUSPEND PLAT_MAX_OFF_STATE
214#define PLAT_MT_CPU_SUSPEND_CLUSTER PLAT_MAX_RET_STATE
Edward-JW Yang80ac32f2022-09-15 21:09:10 +0800215#define PLAT_MT_CPU_SUSPEND_MCUSYS PLAT_MAX_RET_STATE
developera4938652022-09-05 16:36:31 +0800216
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
Edward-JW Yang80ac32f2022-09-15 21:09:10 +0800220#define IS_PLAT_SUSPEND_ID(stateid) (stateid == MT_PLAT_PWR_STATE_SUSPEND)
developera4938652022-09-05 16:36:31 +0800221
Edward-JW Yang80ac32f2022-09-15 21:09:10 +0800222#define IS_PLAT_MCUSYSOFF_AFFLV(afflv) (afflv >= PLAT_MT_CPU_SUSPEND_MCUSYS)
developera4938652022-09-05 16:36:31 +0800223
224int plat_pm_ops_setup_pwr(struct plat_pm_pwr_ctrl *ops);
225int plat_pm_ops_setup_reset(struct plat_pm_reset_ctrl *ops);
226int plat_pm_ops_setup_smp(struct plat_pm_smp_ctrl *ops);
227uintptr_t plat_pm_get_warm_entry(void);
228
229#endif