xref: /rk3399_ARM-atf/plat/mediatek/lib/pm/mtk_pm.h (revision cf2df874cd09305ac7282fadb0fef6be597dfffb)
16ca2046eSEdward-JW Yang /*
2*4ba679daSKai Liang  * Copyright (c) 2025, Mediatek Inc. All rights reserved.
36ca2046eSEdward-JW Yang  *
46ca2046eSEdward-JW Yang  * SPDX-License-Identifier: BSD-3-Clause
56ca2046eSEdward-JW Yang  */
66ca2046eSEdward-JW Yang 
76ca2046eSEdward-JW Yang #ifndef MTK_PM_H
86ca2046eSEdward-JW Yang #define MTK_PM_H
96ca2046eSEdward-JW Yang #include <lib/psci/psci.h>
106ca2046eSEdward-JW Yang 
116ca2046eSEdward-JW Yang #if MTK_PUBEVENT_ENABLE
120b1186a3SRex-BC Chen #include <vendor_pubsub_events.h>
136ca2046eSEdward-JW Yang #endif
146ca2046eSEdward-JW Yang 
156ca2046eSEdward-JW Yang #define MTK_CPUPM_E_OK			(0)
166ca2046eSEdward-JW Yang #define MTK_CPUPM_E_UNKNOWN		(-1)
176ca2046eSEdward-JW Yang #define MTK_CPUPM_E_ERR			(-2)
186ca2046eSEdward-JW Yang #define MTK_CPUPM_E_FAIL		(-3)
196ca2046eSEdward-JW Yang #define MTK_CPUPM_E_NOT_SUPPORT		(-4)
206ca2046eSEdward-JW Yang 
216ca2046eSEdward-JW Yang #define MTK_CPUPM_FN_PWR_LOCK_AQUIRE		BIT(0)
226ca2046eSEdward-JW Yang #define MTK_CPUPM_FN_INIT			BIT(1)
236ca2046eSEdward-JW Yang #define MTK_CPUPM_FN_PWR_STATE_VALID		BIT(2)
246ca2046eSEdward-JW Yang #define MTK_CPUPM_FN_PWR_ON_CORE_PREPARE	BIT(3)
256ca2046eSEdward-JW Yang #define MTK_CPUPM_FN_SUSPEND_CORE		BIT(4)
266ca2046eSEdward-JW Yang #define MTK_CPUPM_FN_RESUME_CORE		BIT(5)
276ca2046eSEdward-JW Yang #define MTK_CPUPM_FN_SUSPEND_CLUSTER		BIT(6)
286ca2046eSEdward-JW Yang #define MTK_CPUPM_FN_RESUME_CLUSTER		BIT(7)
296ca2046eSEdward-JW Yang #define MTK_CPUPM_FN_SUSPEND_MCUSYS		BIT(8)
306ca2046eSEdward-JW Yang #define MTK_CPUPM_FN_RESUME_MCUSYS		BIT(9)
316ca2046eSEdward-JW Yang #define MTK_CPUPM_FN_CPUPM_GET_PWR_STATE	BIT(10)
326ca2046eSEdward-JW Yang #define MTK_CPUPM_FN_SMP_INIT			BIT(11)
336ca2046eSEdward-JW Yang #define MTK_CPUPM_FN_SMP_CORE_ON		BIT(12)
346ca2046eSEdward-JW Yang #define MTK_CPUPM_FN_SMP_CORE_OFF		BIT(13)
356ca2046eSEdward-JW Yang 
366ca2046eSEdward-JW Yang enum mtk_cpupm_pstate {
376ca2046eSEdward-JW Yang 	MTK_CPUPM_CORE_ON,
386ca2046eSEdward-JW Yang 	MTK_CPUPM_CORE_OFF,
396ca2046eSEdward-JW Yang 	MTK_CPUPM_CORE_SUSPEND,
406ca2046eSEdward-JW Yang 	MTK_CPUPM_CORE_RESUME,
416ca2046eSEdward-JW Yang 	MTK_CPUPM_CLUSTER_SUSPEND,
426ca2046eSEdward-JW Yang 	MTK_CPUPM_CLUSTER_RESUME,
436ca2046eSEdward-JW Yang 	MTK_CPUPM_MCUSYS_SUSPEND,
446ca2046eSEdward-JW Yang 	MTK_CPUPM_MCUSYS_RESUME,
456ca2046eSEdward-JW Yang };
466ca2046eSEdward-JW Yang 
476ca2046eSEdward-JW Yang enum mtk_cpu_pm_mode {
486ca2046eSEdward-JW Yang 	MTK_CPU_PM_CPUIDLE,
496ca2046eSEdward-JW Yang 	MTK_CPU_PM_SMP,
506ca2046eSEdward-JW Yang };
516ca2046eSEdward-JW Yang 
526ca2046eSEdward-JW Yang #define MT_IRQ_REMAIN_MAX	(32)
536ca2046eSEdward-JW Yang #define MT_IRQ_REMAIN_CAT_LOG	BIT(31)
546ca2046eSEdward-JW Yang 
556ca2046eSEdward-JW Yang struct mt_irqremain {
566ca2046eSEdward-JW Yang 	unsigned int count;
576ca2046eSEdward-JW Yang 	unsigned int irqs[MT_IRQ_REMAIN_MAX];
586ca2046eSEdward-JW Yang 	unsigned int wakeupsrc_cat[MT_IRQ_REMAIN_MAX];
596ca2046eSEdward-JW Yang 	unsigned int wakeupsrc[MT_IRQ_REMAIN_MAX];
606ca2046eSEdward-JW Yang };
616ca2046eSEdward-JW Yang 
626ca2046eSEdward-JW Yang typedef void (*plat_init_func)(unsigned int, uintptr_t);
636ca2046eSEdward-JW Yang 
646ca2046eSEdward-JW Yang struct plat_pm_smp_ctrl {
656ca2046eSEdward-JW Yang 	plat_init_func init;
666ca2046eSEdward-JW Yang 	int (*pwr_domain_on)(u_register_t mpidr);
676ca2046eSEdward-JW Yang 	void (*pwr_domain_off)(const psci_power_state_t *target_state);
686ca2046eSEdward-JW Yang 	void (*pwr_domain_on_finish)(const psci_power_state_t *target_state);
696ca2046eSEdward-JW Yang };
706ca2046eSEdward-JW Yang 
716ca2046eSEdward-JW Yang struct plat_pm_pwr_ctrl {
726ca2046eSEdward-JW Yang 	void (*pwr_domain_suspend)(const psci_power_state_t *target_state);
736ca2046eSEdward-JW Yang 	void (*pwr_domain_on_finish_late)(const psci_power_state_t *target_state);
746ca2046eSEdward-JW Yang 	void (*pwr_domain_suspend_finish)(const psci_power_state_t *target_state);
756ca2046eSEdward-JW Yang 	int (*validate_power_state)(unsigned int power_state, psci_power_state_t *req_state);
766ca2046eSEdward-JW Yang 	void (*get_sys_suspend_power_state)(psci_power_state_t *req_state);
776ca2046eSEdward-JW Yang };
786ca2046eSEdward-JW Yang 
796ca2046eSEdward-JW Yang struct plat_pm_reset_ctrl {
806ca2046eSEdward-JW Yang 	__dead2 void (*system_off)();
816ca2046eSEdward-JW Yang 	__dead2 void (*system_reset)();
826ca2046eSEdward-JW Yang 	int (*system_reset2)(int is_vendor, int reset_type, u_register_t cookie);
836ca2046eSEdward-JW Yang };
846ca2046eSEdward-JW Yang 
856ca2046eSEdward-JW Yang struct mtk_cpu_pm_info {
866ca2046eSEdward-JW Yang 	unsigned int cpuid;
876ca2046eSEdward-JW Yang 	unsigned int mode;
886ca2046eSEdward-JW Yang };
896ca2046eSEdward-JW Yang 
906ca2046eSEdward-JW Yang struct mtk_cpu_pm_state {
916ca2046eSEdward-JW Yang 	unsigned int afflv;
926ca2046eSEdward-JW Yang 	unsigned int state_id;
936ca2046eSEdward-JW Yang 	const psci_power_state_t *raw;
946ca2046eSEdward-JW Yang };
956ca2046eSEdward-JW Yang 
966ca2046eSEdward-JW Yang struct mtk_cpupm_pwrstate {
976ca2046eSEdward-JW Yang 	struct mtk_cpu_pm_info info;
986ca2046eSEdward-JW Yang 	struct mtk_cpu_pm_state pwr;
996ca2046eSEdward-JW Yang };
1006ca2046eSEdward-JW Yang 
1016ca2046eSEdward-JW Yang struct mtk_cpu_smp_ops {
1026ca2046eSEdward-JW Yang 	void (*init)(unsigned int cpu, uintptr_t sec_entrypoint);
1036ca2046eSEdward-JW Yang 	int (*cpu_pwr_on_prepare)(unsigned int cpu, uintptr_t entry);
1046ca2046eSEdward-JW Yang 	void (*cpu_on)(const struct mtk_cpupm_pwrstate *state);
1056ca2046eSEdward-JW Yang 	void (*cpu_off)(const struct mtk_cpupm_pwrstate *state);
1066ca2046eSEdward-JW Yang 	int (*invoke)(unsigned int funcID, void *priv);
1076ca2046eSEdward-JW Yang };
1086ca2046eSEdward-JW Yang 
1096ca2046eSEdward-JW Yang #define MT_CPUPM_PWR_DOMAIN_CORE		BIT(0)
1106ca2046eSEdward-JW Yang #define MT_CPUPM_PWR_DOMAIN_PERCORE_DSU		BIT(1)
1116ca2046eSEdward-JW Yang #define MT_CPUPM_PWR_DOMAIN_PERCORE_DSU_MEM	BIT(2)
1126ca2046eSEdward-JW Yang #define MT_CPUPM_PWR_DOMAIN_CLUSTER		BIT(3)
1136ca2046eSEdward-JW Yang #define MT_CPUPM_PWR_DOMAIN_MCUSYS		BIT(4)
1146ca2046eSEdward-JW Yang #define MT_CPUPM_PWR_DOMAIN_SUSPEND		BIT(5)
1156ca2046eSEdward-JW Yang 
1166ca2046eSEdward-JW Yang enum mt_cpupm_pwr_domain {
1176ca2046eSEdward-JW Yang 	CPUPM_PWR_ON,
1186ca2046eSEdward-JW Yang 	CPUPM_PWR_OFF,
1196ca2046eSEdward-JW Yang };
1206ca2046eSEdward-JW Yang 
1216ca2046eSEdward-JW Yang typedef	unsigned int mtk_pstate_type;
1226ca2046eSEdward-JW Yang 
1236ca2046eSEdward-JW Yang struct mtk_cpu_pm_ops {
1246ca2046eSEdward-JW Yang 	void (*init)(unsigned int cpu, uintptr_t sec_entrypoint);
1256ca2046eSEdward-JW Yang 	unsigned int (*get_pstate)(enum mt_cpupm_pwr_domain domain,
1266ca2046eSEdward-JW Yang 				   const mtk_pstate_type psci_state,
1276ca2046eSEdward-JW Yang 				   const struct mtk_cpupm_pwrstate *state);
1286ca2046eSEdward-JW Yang 	int (*pwr_state_valid)(unsigned int afflv, unsigned int state);
1296ca2046eSEdward-JW Yang 	void (*cpu_suspend)(const struct mtk_cpupm_pwrstate *state);
1306ca2046eSEdward-JW Yang 	void (*cpu_resume)(const struct mtk_cpupm_pwrstate *state);
1316ca2046eSEdward-JW Yang 	void (*cluster_suspend)(const struct mtk_cpupm_pwrstate *state);
1326ca2046eSEdward-JW Yang 	void (*cluster_resume)(const struct mtk_cpupm_pwrstate *state);
1336ca2046eSEdward-JW Yang 	void (*mcusys_suspend)(const struct mtk_cpupm_pwrstate *state);
1346ca2046eSEdward-JW Yang 	void (*mcusys_resume)(const struct mtk_cpupm_pwrstate *state);
1356ca2046eSEdward-JW Yang 	int (*invoke)(unsigned int funcID, void *priv);
1366ca2046eSEdward-JW Yang };
1376ca2046eSEdward-JW Yang 
1386ca2046eSEdward-JW Yang int register_cpu_pm_ops(unsigned int fn_flags, struct mtk_cpu_pm_ops *ops);
1396ca2046eSEdward-JW Yang int register_cpu_smp_ops(unsigned int fn_flags, struct mtk_cpu_smp_ops *ops);
1406ca2046eSEdward-JW Yang 
1416ca2046eSEdward-JW Yang struct mt_cpupm_event_data {
1426ca2046eSEdward-JW Yang 	unsigned int cpuid;
1436ca2046eSEdward-JW Yang 	unsigned int pwr_domain;
1446ca2046eSEdward-JW Yang };
1456ca2046eSEdward-JW Yang 
1466ca2046eSEdward-JW Yang /* Extension event for platform driver */
1476ca2046eSEdward-JW Yang #if MTK_PUBEVENT_ENABLE
1486ca2046eSEdward-JW Yang /* [PUB_EVENT] Core power on */
1496ca2046eSEdward-JW Yang #define MT_CPUPM_SUBCRIBE_EVENT_PWR_ON(_fn) \
1506ca2046eSEdward-JW Yang 	SUBSCRIBE_TO_EVENT(mt_cpupm_publish_pwr_on, _fn)
1516ca2046eSEdward-JW Yang 
1526ca2046eSEdward-JW Yang /* [PUB_EVENT] Core power off */
1536ca2046eSEdward-JW Yang #define MT_CPUPM_SUBCRIBE_EVENT_PWR_OFF(_fn) \
1546ca2046eSEdward-JW Yang 	SUBSCRIBE_TO_EVENT(mt_cpupm_publish_pwr_off, _fn)
1556ca2046eSEdward-JW Yang 
1566ca2046eSEdward-JW Yang /* [PUB_EVENT] Cluster power on */
1576ca2046eSEdward-JW Yang #define MT_CPUPM_SUBCRIBE_CLUSTER_PWR_ON(_fn) \
1586ca2046eSEdward-JW Yang 	SUBSCRIBE_TO_EVENT(mt_cpupm_publish_afflv_pwr_on, _fn)
1596ca2046eSEdward-JW Yang 
1606ca2046eSEdward-JW Yang /* [PUB_EVENT] Cluster power off */
1616ca2046eSEdward-JW Yang #define MT_CPUPM_SUBCRIBE_CLUSTER_PWR_OFF(_fn) \
1626ca2046eSEdward-JW Yang 	SUBSCRIBE_TO_EVENT(mt_cpupm_publish_afflv_pwr_off, _fn)
1636ca2046eSEdward-JW Yang 
1646ca2046eSEdward-JW Yang /* [PUB_EVENT] Mcusys power on */
1656ca2046eSEdward-JW Yang #define MT_CPUPM_SUBCRIBE_MCUSYS_PWR_ON(_fn) \
1666ca2046eSEdward-JW Yang 	SUBSCRIBE_TO_EVENT(mt_cpupm_publish_afflv_pwr_on, _fn)
1676ca2046eSEdward-JW Yang 
1686ca2046eSEdward-JW Yang /* [PUB_EVENT] Mcusys power off */
1696ca2046eSEdward-JW Yang #define MT_CPUPM_SUBCRIBE_MCUSYS_PWR_OFF(_fn) \
1706ca2046eSEdward-JW Yang 	SUBSCRIBE_TO_EVENT(mt_cpupm_publish_afflv_pwr_off, _fn)
1716ca2046eSEdward-JW Yang 
172*4ba679daSKai Liang /* [PUB_EVENT] el3 time sync */
173*4ba679daSKai Liang #define MT_CPUPM_SUBCRIBE_EL3_UPTIME_SYNC_WITH_KERNEL(_fn) \
174*4ba679daSKai Liang 	SUBSCRIBE_TO_EVENT(el3_uptime_sync_with_kernel, _fn)
175*4ba679daSKai Liang 
1766ca2046eSEdward-JW Yang #else
1776ca2046eSEdward-JW Yang #define MT_CPUPM_SUBCRIBE_EVENT_PWR_ON(_fn)
1786ca2046eSEdward-JW Yang #define MT_CPUPM_SUBCRIBE_EVENT_PWR_OFF(_fn)
1796ca2046eSEdward-JW Yang #define MT_CPUPM_SUBCRIBE_CLUSTER_PWR_ON(_fn)
1806ca2046eSEdward-JW Yang #define MT_CPUPM_SUBCRIBE_CLUSTER_PWR_OFF(_fn)
1816ca2046eSEdward-JW Yang #define MT_CPUPM_SUBCRIBE_MCUSYS_PWR_ON(_fn)
1826ca2046eSEdward-JW Yang #define MT_CPUPM_SUBCRIBE_MCUSYS_PWR_OFF(_fn)
183*4ba679daSKai Liang #define MT_CPUPM_SUBCRIBE_EL3_UPTIME_SYNC_WITH_KERNEL(_fn)
1846ca2046eSEdward-JW Yang #endif
1856ca2046eSEdward-JW Yang 
186e35f4cbfSEdward-JW Yang /*
187e35f4cbfSEdward-JW Yang  * Definition c-state power domain.
188e35f4cbfSEdward-JW Yang  * bit[7:4] (main state id):
189e35f4cbfSEdward-JW Yang  *  - 1: Cluster.
190e35f4cbfSEdward-JW Yang  *  - 2: Mcusys.
191e35f4cbfSEdward-JW Yang  *  - 3: Memory.
192e35f4cbfSEdward-JW Yang  *  - 4: System pll.
193e35f4cbfSEdward-JW Yang  *  - 5: System bus.
194e35f4cbfSEdward-JW Yang  *  - 6: SoC 26m/DCXO.
195e35f4cbfSEdward-JW Yang  *  - 7: Vcore buck.
196e35f4cbfSEdward-JW Yang  *  - 15: Suspend.
197e35f4cbfSEdward-JW Yang  * bit[3:0] (reserved for state_id extension):
198e35f4cbfSEdward-JW Yang  *  - 4: CPU buck.
199e35f4cbfSEdward-JW Yang  */
200e35f4cbfSEdward-JW Yang #define MT_PLAT_PWR_STATE_CLUSTER	(0x0010)
201e35f4cbfSEdward-JW Yang #define MT_PLAT_PWR_STATE_MCUSYS	(0x0020)
202e35f4cbfSEdward-JW Yang #define MT_PLAT_PWR_STATE_MCUSYS_BUCK	(0x0024)
203e35f4cbfSEdward-JW Yang #define MT_PLAT_PWR_STATE_SYSTEM_MEM	(0x0030)
204e35f4cbfSEdward-JW Yang #define MT_PLAT_PWR_STATE_SYSTEM_PLL	(0x0040)
205e35f4cbfSEdward-JW Yang #define MT_PLAT_PWR_STATE_SYSTEM_BUS	(0x0050)
206e35f4cbfSEdward-JW Yang #define MT_PLAT_PWR_STATE_SUSPEND	(0x00f0)
2076ca2046eSEdward-JW Yang 
208*4ba679daSKai Liang #define IS_MT_PLAT_PWR_STATE(state, target_state) \
209*4ba679daSKai Liang 	((state & target_state) == target_state)
210*4ba679daSKai Liang #define IS_MT_PLAT_PWR_STATE_MCUSYS(state) \
211*4ba679daSKai Liang 	IS_MT_PLAT_PWR_STATE(state, MT_PLAT_PWR_STATE_MCUSYS)
2126ca2046eSEdward-JW Yang 
2136ca2046eSEdward-JW Yang #define PLAT_MT_SYSTEM_SUSPEND		PLAT_MAX_OFF_STATE
2146ca2046eSEdward-JW Yang #define PLAT_MT_CPU_SUSPEND_CLUSTER	PLAT_MAX_RET_STATE
215e35f4cbfSEdward-JW Yang #define PLAT_MT_CPU_SUSPEND_MCUSYS	PLAT_MAX_RET_STATE
2166ca2046eSEdward-JW Yang 
2176ca2046eSEdward-JW Yang #define IS_PLAT_SYSTEM_SUSPEND(aff)	(aff == PLAT_MT_SYSTEM_SUSPEND)
2186ca2046eSEdward-JW Yang #define IS_PLAT_SYSTEM_RETENTION(aff)	(aff >= PLAT_MAX_RET_STATE)
2196ca2046eSEdward-JW Yang 
220e35f4cbfSEdward-JW Yang #define IS_PLAT_SUSPEND_ID(stateid)	(stateid == MT_PLAT_PWR_STATE_SUSPEND)
2216ca2046eSEdward-JW Yang 
222e35f4cbfSEdward-JW Yang #define IS_PLAT_MCUSYSOFF_AFFLV(afflv)	(afflv >= PLAT_MT_CPU_SUSPEND_MCUSYS)
2236ca2046eSEdward-JW Yang 
2246ca2046eSEdward-JW Yang int plat_pm_ops_setup_pwr(struct plat_pm_pwr_ctrl *ops);
2256ca2046eSEdward-JW Yang int plat_pm_ops_setup_reset(struct plat_pm_reset_ctrl *ops);
2266ca2046eSEdward-JW Yang int plat_pm_ops_setup_smp(struct plat_pm_smp_ctrl *ops);
2276ca2046eSEdward-JW Yang uintptr_t plat_pm_get_warm_entry(void);
2286ca2046eSEdward-JW Yang 
2296ca2046eSEdward-JW Yang #endif
230