1 /*
2 * Copyright (c) 2025, MediaTek Inc. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include <stdint.h>
8 #include <stdio.h>
9
10 #include <platform_def.h>
11
12 #include <lib/pm/mtk_pm.h>
13 #include <lpm_v2/mt_lp_rm.h>
14 #include <mt_cirq.h>
15 #include "mt_cpu_pm.h"
16 #include "mt_lp_irqremain.h"
17
18 static struct mt_irqremain remain_irqs;
19 static struct mt_irqremain *p_irqs;
20
mt_lp_irqremain_push(void)21 int mt_lp_irqremain_push(void)
22 {
23 if (remain_irqs.count >= MT_IRQ_REMAIN_MAX)
24 return -1;
25 remain_irqs.count += 1;
26 return 0;
27 }
28
mt_lp_irqremain_pop(void)29 int mt_lp_irqremain_pop(void)
30 {
31 if (remain_irqs.count == 0)
32 return -1;
33 remain_irqs.count -= 1;
34 return 0;
35 }
36
mt_lp_irqremain_set(unsigned int type,const struct mt_lp_irqinfo * info)37 int mt_lp_irqremain_set(unsigned int type,
38 const struct mt_lp_irqinfo *info)
39 {
40 unsigned int idx;
41
42 if (p_irqs || !info)
43 return -1;
44
45 idx = remain_irqs.count;
46 switch (type) {
47 case IRQS_REMAIN_IRQ:
48 remain_irqs.irqs[idx] = info->val;
49 break;
50 case IRQS_REMAIN_WAKEUP_CAT:
51 remain_irqs.wakeupsrc_cat[idx] = info->val;
52 break;
53 case IRQS_REMAIN_WAKEUP_SRC:
54 remain_irqs.wakeupsrc[idx] = info->val;
55 break;
56 }
57 return 0;
58 }
59
mt_lp_irqremain_get(unsigned int idx,unsigned int type,struct mt_lp_irqinfo * info)60 int mt_lp_irqremain_get(unsigned int idx, unsigned int type,
61 struct mt_lp_irqinfo *info)
62 {
63 if (!p_irqs || !info || (idx > remain_irqs.count))
64 return -1;
65
66 switch (type) {
67 case IRQS_REMAIN_IRQ:
68 info->val = remain_irqs.irqs[idx];
69 break;
70 case IRQS_REMAIN_WAKEUP_CAT:
71 info->val = remain_irqs.wakeupsrc_cat[idx];
72 break;
73 case IRQS_REMAIN_WAKEUP_SRC:
74 info->val = remain_irqs.wakeupsrc[idx];
75 break;
76 }
77 return 0;
78 }
79
mt_lp_irqremain_count(void)80 unsigned int mt_lp_irqremain_count(void)
81 {
82 return remain_irqs.count;
83 }
84
mt_lp_irqremain_submit(void)85 int mt_lp_irqremain_submit(void)
86 {
87 if (remain_irqs.count == 0)
88 return -1;
89 set_wakeup_sources(remain_irqs.irqs, remain_irqs.count);
90 mt_lp_rm_do_update(-1, PLAT_RC_UPDATE_REMAIN_IRQS, &remain_irqs);
91 p_irqs = &remain_irqs;
92 return 0;
93 }
94
mt_lp_irqremain_aquire(void)95 int mt_lp_irqremain_aquire(void)
96 {
97 if (!p_irqs)
98 return -1;
99
100 mt_cirq_sw_reset();
101 mt_cirq_clone_gic();
102 mt_cirq_enable();
103 return 0;
104 }
105
mt_lp_irqremain_release(void)106 int mt_lp_irqremain_release(void)
107 {
108 if (!p_irqs)
109 return -1;
110 mt_cirq_flush();
111 mt_cirq_disable();
112 return 0;
113 }
114
mt_lp_irqremain_init(void)115 void mt_lp_irqremain_init(void)
116 {
117 p_irqs = NULL;
118 }
119