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