blob: 9f079682291760ea9ac894ba4af4fcd577d13640 [file] [log] [blame]
developer7d46db62020-12-14 16:53:22 +08001/*
developer91bb08d2022-09-07 18:41:59 +08002 * Copyright (c) 2020-2023, MediaTek Inc. All rights reserved.
developer7d46db62020-12-14 16:53:22 +08003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
developer7d46db62020-12-14 16:53:22 +08007#include <stddef.h>
developer91bb08d2022-09-07 18:41:59 +08008#include <lpm/mt_lp_rm.h>
developer7d46db62020-12-14 16:53:22 +08009
10struct platform_mt_resource_manager {
11 unsigned int count;
12 struct mt_resource_manager *plat_rm;
13};
14
15static struct platform_mt_resource_manager plat_mt_rm;
16
17int 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
developerd0c3bab2023-01-06 19:57:15 +080039int mt_lp_rm_reset_constraint(unsigned int idx, unsigned int cpuid, int stateid)
developer7d46db62020-12-14 16:53:22 +080040{
41 struct mt_resource_constraint const *rc = NULL;
42
developerd0c3bab2023-01-06 19:57:15 +080043 if ((plat_mt_rm.plat_rm == NULL) || (idx >= plat_mt_rm.count)) {
developer7d46db62020-12-14 16:53:22 +080044 return MT_RM_STATUS_BAD;
45 }
46
47 rc = plat_mt_rm.plat_rm->consts[idx];
48
49 if ((rc == NULL) || (rc->reset == NULL)) {
50 return MT_RM_STATUS_BAD;
51 }
52
53 return rc->reset(cpuid, stateid);
54}
55
developer91bb08d2022-09-07 18:41:59 +080056int mt_lp_rm_get_status(unsigned int type, void *priv)
57{
58 int res = 0;
59 struct mt_resource_constraint *const *con;
60 struct mt_resource_manager *rm = plat_mt_rm.plat_rm;
61
62 if ((rm == NULL) || (type >= PLAT_RC_MAX)) {
63 return -1;
64 }
65
66 for (con = rm->consts; *con != NULL; con++) {
67 if ((*con)->get_status == NULL) {
68 continue;
69 }
70 res = (*con)->get_status(type, priv);
71 if (res == MT_RM_STATUS_STOP) {
72 break;
73 }
74 }
75
76 return res;
77}
78
developerd0c3bab2023-01-06 19:57:15 +080079int mt_lp_rm_do_constraint(unsigned int constraint_id, unsigned int cpuid, int stateid)
developer7d46db62020-12-14 16:53:22 +080080{
developerd0c3bab2023-01-06 19:57:15 +080081 int res = MT_RM_STATUS_BAD;
82 struct mt_resource_constraint const *rc;
83 struct mt_resource_manager *rm = plat_mt_rm.plat_rm;
84
85 if ((rm == NULL) || (constraint_id >= plat_mt_rm.count)) {
86 return res;
87 }
88
89 rc = rm->consts[constraint_id];
90 if ((rc != NULL) && (rc->run != NULL)) {
91 res = rc->run(cpuid, stateid);
92 }
93
94 return res;
95}
96
97int mt_lp_rm_find_constraint(unsigned int idx, unsigned int cpuid,
98 int stateid, void *priv)
99{
100 unsigned int i;
101 int res = MT_RM_STATUS_BAD;
developer7d46db62020-12-14 16:53:22 +0800102 struct mt_resource_constraint *const *rc;
103 struct mt_resource_manager *rm = plat_mt_rm.plat_rm;
104
developerd0c3bab2023-01-06 19:57:15 +0800105 if ((rm == NULL) || (idx >= plat_mt_rm.count)) {
developer7d46db62020-12-14 16:53:22 +0800106 return res;
107 }
108
109 /* If subsys clk/mtcmos is on, add block-resource-off flag */
110 if (rm->update != NULL) {
developerfbc1ea92023-01-06 15:50:33 +0800111 res = rm->update(rm->consts, plat_mt_rm.count, stateid, priv);
developer7d46db62020-12-14 16:53:22 +0800112 if (res != 0) {
developerd0c3bab2023-01-06 19:57:15 +0800113 return MT_RM_STATUS_BAD;
developer7d46db62020-12-14 16:53:22 +0800114 }
115 }
116
developerd0c3bab2023-01-06 19:57:15 +0800117 res = MT_RM_STATUS_BAD;
developer7d46db62020-12-14 16:53:22 +0800118 for (i = idx, rc = (rm->consts + idx); *rc != NULL; i++, rc++) {
119 if (((*rc)->is_valid != NULL) &&
120 ((*rc)->is_valid(cpuid, stateid))) {
developerd0c3bab2023-01-06 19:57:15 +0800121 res = i;
122 break;
developer7d46db62020-12-14 16:53:22 +0800123 }
124 }
125
126 return res;
127}
128
developerd0c3bab2023-01-06 19:57:15 +0800129int mt_lp_rm_find_and_run_constraint(unsigned int idx, unsigned int cpuid,
130 int stateid, void *priv)
131{
132 int res = MT_RM_STATUS_BAD;
133
134 res = mt_lp_rm_find_constraint(idx, cpuid, stateid, priv);
135 if (res != MT_RM_STATUS_BAD) {
136 mt_lp_rm_do_constraint(res, cpuid, stateid);
137 }
138
139 return res;
140}
141
developer7d46db62020-12-14 16:53:22 +0800142int mt_lp_rm_do_update(int stateid, int type, void const *p)
143{
144 int res = MT_RM_STATUS_BAD;
145 struct mt_resource_constraint *const *rc;
146 struct mt_resource_manager *rm = plat_mt_rm.plat_rm;
147
148 if (rm == NULL) {
149 return res;
150 }
151
152 for (rc = rm->consts; *rc != NULL; rc++) {
153 if ((*rc)->update != NULL) {
154 res = (*rc)->update(stateid, type, p);
155 if (res != MT_RM_STATUS_OK) {
156 break;
157 }
158 }
159 }
160
161 return res;
162}