xref: /rk3399_ARM-atf/plat/mediatek/common/lpm/mt_lp_rm.c (revision 1c5fc9a25417cbfb08c8aa12a2e398e202fda3d7)
1 /*
2  * Copyright (c) 2020-2023, MediaTek Inc. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <stddef.h>
8 #include <lpm/mt_lp_rm.h>
9 
10 struct platform_mt_resource_manager {
11 	unsigned int count;
12 	struct mt_resource_manager *plat_rm;
13 };
14 
15 static struct platform_mt_resource_manager plat_mt_rm;
16 
17 int mt_lp_rm_register(struct mt_resource_manager *rm)
18 {
19 	unsigned int i;
20 	struct mt_resource_constraint *const *rc;
21 
22 	if ((rm == NULL) || (rm->consts == NULL) ||
23 	    (plat_mt_rm.plat_rm != NULL)) {
24 		return MT_RM_STATUS_BAD;
25 	}
26 
27 	for (i = 0U, rc = rm->consts; *rc != NULL; i++, rc++) {
28 		if ((*rc)->init != NULL) {
29 			(*rc)->init();
30 		}
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(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 < 0) ||
44 	    (idx >= plat_mt_rm.count)) {
45 		return MT_RM_STATUS_BAD;
46 	}
47 
48 	rc = plat_mt_rm.plat_rm->consts[idx];
49 
50 	if ((rc == NULL) || (rc->reset == NULL)) {
51 		return MT_RM_STATUS_BAD;
52 	}
53 
54 	return rc->reset(cpuid, stateid);
55 }
56 
57 int mt_lp_rm_get_status(unsigned int type, void *priv)
58 {
59 	int res = 0;
60 	struct mt_resource_constraint *const *con;
61 	struct mt_resource_manager *rm = plat_mt_rm.plat_rm;
62 
63 	if ((rm == NULL) || (type >= PLAT_RC_MAX)) {
64 		return -1;
65 	}
66 
67 	for (con = rm->consts; *con != NULL; con++) {
68 		if ((*con)->get_status == NULL) {
69 			continue;
70 		}
71 		res = (*con)->get_status(type, priv);
72 		if (res == MT_RM_STATUS_STOP) {
73 			break;
74 		}
75 	}
76 
77 	return res;
78 }
79 
80 int mt_lp_rm_find_and_run_constraint(int idx, unsigned int cpuid,
81 				     int stateid, void *priv)
82 {
83 	int i, res = MT_RM_STATUS_BAD;
84 	struct mt_resource_constraint *const *rc;
85 	struct mt_resource_manager *rm = plat_mt_rm.plat_rm;
86 
87 	if ((rm == NULL) || (idx < 0) || (idx >= plat_mt_rm.count)) {
88 		return res;
89 	}
90 
91 	/* If subsys clk/mtcmos is on, add block-resource-off flag */
92 	if (rm->update != NULL) {
93 		res = rm->update(rm->consts, stateid, priv);
94 		if (res != 0) {
95 			return res;
96 		}
97 	}
98 
99 	for (i = idx, rc = (rm->consts + idx); *rc != NULL; i++, rc++) {
100 		if (((*rc)->is_valid != NULL) &&
101 		    ((*rc)->is_valid(cpuid, stateid))) {
102 			if (((*rc)->run != NULL) &&
103 			    ((*rc)->run(cpuid, stateid) == 0)) {
104 				res = i;
105 				break;
106 			}
107 		}
108 	}
109 
110 	return res;
111 }
112 
113 int mt_lp_rm_do_update(int stateid, int type, void const *p)
114 {
115 	int res = MT_RM_STATUS_BAD;
116 	struct mt_resource_constraint *const *rc;
117 	struct mt_resource_manager *rm = plat_mt_rm.plat_rm;
118 
119 	if (rm == NULL) {
120 		return res;
121 	}
122 
123 	for (rc = rm->consts; *rc != NULL; rc++) {
124 		if ((*rc)->update != NULL) {
125 			res = (*rc)->update(stateid, type, p);
126 			if (res != MT_RM_STATUS_OK) {
127 				break;
128 			}
129 		}
130 	}
131 
132 	return res;
133 }
134