xref: /rk3399_ARM-atf/plat/mediatek/common/lpm_v2/mt_lp_rm.c (revision e7be9243d071b37d13d826824ec4bb8c8b39caa2)
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 
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 
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 
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 
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 
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 
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 
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 
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