1 /*
2 * Copyright (c) 2025, MediaTek Inc. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include <stddef.h>
8
9 #include <lpm_v2/mt_lp_rm.h>
10
11 struct platform_mt_resource_manager {
12 unsigned int count;
13 struct mt_resource_manager *plat_rm;
14 };
15
16 static struct platform_mt_resource_manager plat_mt_rm;
17
mt_lp_rm_register(struct mt_resource_manager * rm)18 int mt_lp_rm_register(struct mt_resource_manager *rm)
19 {
20 unsigned int i;
21 struct mt_resource_constraint *const *rc;
22
23 if ((rm == NULL) || (rm->consts == NULL) ||
24 (plat_mt_rm.plat_rm != NULL)) {
25 return MT_RM_STATUS_BAD;
26 }
27
28 for (i = 0U, rc = rm->consts; *rc != NULL; i++, rc++) {
29 if ((*rc)->init != NULL)
30 (*rc)->init();
31 }
32
33 plat_mt_rm.plat_rm = rm;
34 plat_mt_rm.count = i;
35
36 return MT_RM_STATUS_OK;
37 }
38
mt_lp_rm_reset_constraint(unsigned int idx,unsigned int cpuid,int stateid)39 int mt_lp_rm_reset_constraint(unsigned int idx, unsigned int cpuid, int stateid)
40 {
41 struct mt_resource_constraint const *rc = NULL;
42
43 if ((plat_mt_rm.plat_rm == NULL) || (idx >= plat_mt_rm.count))
44 return MT_RM_STATUS_BAD;
45
46 rc = plat_mt_rm.plat_rm->consts[idx];
47
48 if ((rc == NULL) || (rc->reset == NULL))
49 return MT_RM_STATUS_BAD;
50
51 return rc->reset(cpuid, stateid);
52 }
53
mt_lp_rm_get_status(unsigned int type,void * priv)54 int mt_lp_rm_get_status(unsigned int type, void *priv)
55 {
56 int res = 0;
57 struct mt_resource_constraint *const *con;
58 struct mt_resource_manager *rm = plat_mt_rm.plat_rm;
59
60 if ((rm == NULL) || (type >= PLAT_RC_MAX))
61 return -1;
62
63 for (con = rm->consts; *con != NULL; con++) {
64 if ((*con)->get_status == NULL)
65 continue;
66
67 res = (*con)->get_status(type, priv);
68 if (res == MT_RM_STATUS_STOP)
69 break;
70 }
71
72 return res;
73 }
74
mt_lp_rm_do_constraint(unsigned int constraint_id,unsigned int cpuid,int stateid)75 int mt_lp_rm_do_constraint(unsigned int constraint_id, unsigned int cpuid, int stateid)
76 {
77 int res = MT_RM_STATUS_BAD;
78 struct mt_resource_constraint const *rc;
79 struct mt_resource_manager *rm = plat_mt_rm.plat_rm;
80
81 if ((rm == NULL) || (constraint_id >= plat_mt_rm.count))
82 return res;
83
84 rc = rm->consts[constraint_id];
85 if ((rc != NULL) && (rc->run != NULL))
86 res = rc->run(cpuid, stateid);
87
88 return res;
89 }
90
mt_lp_rm_find_constraint(unsigned int idx,unsigned int cpuid,int stateid,void * priv)91 int mt_lp_rm_find_constraint(unsigned int idx, unsigned int cpuid,
92 int stateid, void *priv)
93 {
94 unsigned int i;
95 int res = MT_RM_STATUS_BAD;
96 struct mt_resource_constraint *const *rc;
97 struct mt_resource_manager *rm = plat_mt_rm.plat_rm;
98
99 if ((rm == NULL) || (idx >= plat_mt_rm.count))
100 return res;
101
102 /* If subsys clk/mtcmos is on, add block-resource-off flag */
103 if (rm->update != NULL) {
104 res = rm->update(rm->consts, plat_mt_rm.count, stateid, priv);
105 if (res != 0)
106 return MT_RM_STATUS_BAD;
107 }
108
109 res = MT_RM_STATUS_BAD;
110 for (i = idx, rc = (rm->consts + idx); *rc != NULL; i++, rc++) {
111 if (((*rc)->is_valid != NULL) &&
112 ((*rc)->is_valid(cpuid, stateid))) {
113 res = i;
114 break;
115 }
116 }
117
118 return res;
119 }
120
mt_lp_rm_find_and_run_constraint(unsigned int idx,unsigned int cpuid,int stateid,void * priv)121 int mt_lp_rm_find_and_run_constraint(unsigned int idx, unsigned int cpuid,
122 int stateid, void *priv)
123 {
124 int res = MT_RM_STATUS_BAD;
125
126 res = mt_lp_rm_find_constraint(idx, cpuid, stateid, priv);
127 if (res != MT_RM_STATUS_BAD)
128 mt_lp_rm_do_constraint(res, cpuid, stateid);
129
130 return res;
131 }
132
mt_lp_rm_do_update(int stateid,int type,void const * p)133 int mt_lp_rm_do_update(int stateid, int type, void const *p)
134 {
135 int res = MT_RM_STATUS_BAD;
136 struct mt_resource_constraint *const *rc;
137 struct mt_resource_manager *rm = plat_mt_rm.plat_rm;
138
139 if (rm == NULL)
140 return res;
141
142 for (rc = rm->consts; *rc != NULL; rc++) {
143 if ((*rc)->update != NULL) {
144 res = (*rc)->update(stateid, type, p);
145 if (res != MT_RM_STATUS_OK)
146 break;
147 }
148 }
149
150 return res;
151 }
152
mt_lp_rm_do_hwctrl(unsigned int type,int set,void * priv)153 int mt_lp_rm_do_hwctrl(unsigned int type, int set, void *priv)
154 {
155 struct mt_resource_manager *rm = plat_mt_rm.plat_rm;
156 int res = 0;
157
158 if (!rm || !rm->hwctrl || (type >= PLAT_AP_HW_CTRL_MAX))
159 return -1;
160
161 res = rm->hwctrl(type, set, priv);
162
163 return res;
164 }
165