xref: /rk3399_ARM-atf/plat/mediatek/common/lpm/mt_lp_rm.c (revision cd7890d79e9d508e82f3078f02e8277f8c8df181)
1*cd7890d7SBo-Chen Chen /*
2*cd7890d7SBo-Chen Chen  * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
3*cd7890d7SBo-Chen Chen  *
4*cd7890d7SBo-Chen Chen  * SPDX-License-Identifier: BSD-3-Clause
5*cd7890d7SBo-Chen Chen  */
6*cd7890d7SBo-Chen Chen 
7*cd7890d7SBo-Chen Chen #include <mt_lp_rm.h>
8*cd7890d7SBo-Chen Chen #include <stddef.h>
9*cd7890d7SBo-Chen Chen 
10*cd7890d7SBo-Chen Chen struct platform_mt_resource_manager {
11*cd7890d7SBo-Chen Chen 	unsigned int count;
12*cd7890d7SBo-Chen Chen 	struct mt_resource_manager *plat_rm;
13*cd7890d7SBo-Chen Chen };
14*cd7890d7SBo-Chen Chen 
15*cd7890d7SBo-Chen Chen static struct platform_mt_resource_manager plat_mt_rm;
16*cd7890d7SBo-Chen Chen 
17*cd7890d7SBo-Chen Chen int mt_lp_rm_register(struct mt_resource_manager *rm)
18*cd7890d7SBo-Chen Chen {
19*cd7890d7SBo-Chen Chen 	unsigned int i;
20*cd7890d7SBo-Chen Chen 	struct mt_resource_constraint *const *rc;
21*cd7890d7SBo-Chen Chen 
22*cd7890d7SBo-Chen Chen 	if ((rm == NULL) || (rm->consts == NULL) ||
23*cd7890d7SBo-Chen Chen 	    (plat_mt_rm.plat_rm != NULL)) {
24*cd7890d7SBo-Chen Chen 		return MT_RM_STATUS_BAD;
25*cd7890d7SBo-Chen Chen 	}
26*cd7890d7SBo-Chen Chen 
27*cd7890d7SBo-Chen Chen 	for (i = 0U, rc = rm->consts; *rc != NULL; i++, rc++) {
28*cd7890d7SBo-Chen Chen 		if ((*rc)->init != NULL) {
29*cd7890d7SBo-Chen Chen 			(*rc)->init();
30*cd7890d7SBo-Chen Chen 		}
31*cd7890d7SBo-Chen Chen 	}
32*cd7890d7SBo-Chen Chen 
33*cd7890d7SBo-Chen Chen 	plat_mt_rm.plat_rm = rm;
34*cd7890d7SBo-Chen Chen 	plat_mt_rm.count = i;
35*cd7890d7SBo-Chen Chen 
36*cd7890d7SBo-Chen Chen 	return MT_RM_STATUS_OK;
37*cd7890d7SBo-Chen Chen }
38*cd7890d7SBo-Chen Chen 
39*cd7890d7SBo-Chen Chen int mt_lp_rm_reset_constraint(int idx, unsigned int cpuid, int stateid)
40*cd7890d7SBo-Chen Chen {
41*cd7890d7SBo-Chen Chen 	struct mt_resource_constraint const *rc = NULL;
42*cd7890d7SBo-Chen Chen 
43*cd7890d7SBo-Chen Chen 	if ((plat_mt_rm.plat_rm == NULL) || (idx < 0) ||
44*cd7890d7SBo-Chen Chen 	    (idx >= plat_mt_rm.count)) {
45*cd7890d7SBo-Chen Chen 		return MT_RM_STATUS_BAD;
46*cd7890d7SBo-Chen Chen 	}
47*cd7890d7SBo-Chen Chen 
48*cd7890d7SBo-Chen Chen 	rc = plat_mt_rm.plat_rm->consts[idx];
49*cd7890d7SBo-Chen Chen 
50*cd7890d7SBo-Chen Chen 	if ((rc == NULL) || (rc->reset == NULL)) {
51*cd7890d7SBo-Chen Chen 		return MT_RM_STATUS_BAD;
52*cd7890d7SBo-Chen Chen 	}
53*cd7890d7SBo-Chen Chen 
54*cd7890d7SBo-Chen Chen 	return rc->reset(cpuid, stateid);
55*cd7890d7SBo-Chen Chen }
56*cd7890d7SBo-Chen Chen 
57*cd7890d7SBo-Chen Chen int mt_lp_rm_find_and_run_constraint(int idx, unsigned int cpuid,
58*cd7890d7SBo-Chen Chen 				     int stateid, void *priv)
59*cd7890d7SBo-Chen Chen {
60*cd7890d7SBo-Chen Chen 	int i, res = MT_RM_STATUS_BAD;
61*cd7890d7SBo-Chen Chen 	struct mt_resource_constraint *const *rc;
62*cd7890d7SBo-Chen Chen 	struct mt_resource_manager *rm = plat_mt_rm.plat_rm;
63*cd7890d7SBo-Chen Chen 
64*cd7890d7SBo-Chen Chen 	if ((rm == NULL) || (idx < 0) || (idx >= plat_mt_rm.count)) {
65*cd7890d7SBo-Chen Chen 		return res;
66*cd7890d7SBo-Chen Chen 	}
67*cd7890d7SBo-Chen Chen 
68*cd7890d7SBo-Chen Chen 	/* If subsys clk/mtcmos is on, add block-resource-off flag */
69*cd7890d7SBo-Chen Chen 	if (rm->update != NULL) {
70*cd7890d7SBo-Chen Chen 		res = rm->update(rm->consts, stateid, priv);
71*cd7890d7SBo-Chen Chen 		if (res != 0) {
72*cd7890d7SBo-Chen Chen 			return res;
73*cd7890d7SBo-Chen Chen 		}
74*cd7890d7SBo-Chen Chen 	}
75*cd7890d7SBo-Chen Chen 
76*cd7890d7SBo-Chen Chen 	for (i = idx, rc = (rm->consts + idx); *rc != NULL; i++, rc++) {
77*cd7890d7SBo-Chen Chen 		if (((*rc)->is_valid != NULL) &&
78*cd7890d7SBo-Chen Chen 		    ((*rc)->is_valid(cpuid, stateid))) {
79*cd7890d7SBo-Chen Chen 			if (((*rc)->run != NULL) &&
80*cd7890d7SBo-Chen Chen 			    ((*rc)->run(cpuid, stateid) == 0)) {
81*cd7890d7SBo-Chen Chen 				res = i;
82*cd7890d7SBo-Chen Chen 				break;
83*cd7890d7SBo-Chen Chen 			}
84*cd7890d7SBo-Chen Chen 		}
85*cd7890d7SBo-Chen Chen 	}
86*cd7890d7SBo-Chen Chen 
87*cd7890d7SBo-Chen Chen 	return res;
88*cd7890d7SBo-Chen Chen }
89*cd7890d7SBo-Chen Chen 
90*cd7890d7SBo-Chen Chen int mt_lp_rm_do_update(int stateid, int type, void const *p)
91*cd7890d7SBo-Chen Chen {
92*cd7890d7SBo-Chen Chen 	int res = MT_RM_STATUS_BAD;
93*cd7890d7SBo-Chen Chen 	struct mt_resource_constraint *const *rc;
94*cd7890d7SBo-Chen Chen 	struct mt_resource_manager *rm = plat_mt_rm.plat_rm;
95*cd7890d7SBo-Chen Chen 
96*cd7890d7SBo-Chen Chen 	if (rm == NULL) {
97*cd7890d7SBo-Chen Chen 		return res;
98*cd7890d7SBo-Chen Chen 	}
99*cd7890d7SBo-Chen Chen 
100*cd7890d7SBo-Chen Chen 	for (rc = rm->consts; *rc != NULL; rc++) {
101*cd7890d7SBo-Chen Chen 		if ((*rc)->update != NULL) {
102*cd7890d7SBo-Chen Chen 			res = (*rc)->update(stateid, type, p);
103*cd7890d7SBo-Chen Chen 			if (res != MT_RM_STATUS_OK) {
104*cd7890d7SBo-Chen Chen 				break;
105*cd7890d7SBo-Chen Chen 			}
106*cd7890d7SBo-Chen Chen 		}
107*cd7890d7SBo-Chen Chen 	}
108*cd7890d7SBo-Chen Chen 
109*cd7890d7SBo-Chen Chen 	return res;
110*cd7890d7SBo-Chen Chen }
111