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