blob: 257caa3d5ea0e7d70f72b6400c168daccc17954c [file] [log] [blame]
developer451d49d2022-11-16 21:52:21 +08001/*
2 * Copyright (c) 2023, MediaTek Inc. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <lpm/mt_lpm_smc.h>
8#include <mt_spm.h>
9#include "mt_spm_rc_api.h"
10#include "mt_spm_rc_internal.h"
11
12int spm_rc_condition_modifier(unsigned int id, unsigned int act,
13 const void *val,
14 enum mt_spm_rm_rc_type dest_rc_id,
15 struct mt_spm_cond_tables * const tlb)
16{
17 unsigned int rc_id, cond_id, cond;
18 int res = 0;
19
20 spin_lock(&spm_lock);
21 rc_id = SPM_RC_UPDATE_COND_RC_ID_GET(id);
22 cond_id = SPM_RC_UPDATE_COND_ID_GET(id);
23
24 do {
25 if ((dest_rc_id != rc_id) || (val == NULL) || (tlb == NULL)) {
26 res = -1;
27 break;
28 }
29
30 cond = *((unsigned int *)val);
31
32 if (cond_id < PLAT_SPM_COND_MAX) {
33 if ((act & MT_LPM_SMC_ACT_SET) > 0U) {
34 SPM_RC_BITS_SET(tlb->table_cg[cond_id], cond);
35 } else if ((act & MT_LPM_SMC_ACT_CLR) > 0U) {
36 SPM_RC_BITS_CLR(tlb->table_cg[cond_id], cond);
37 } else {
38 res = -1;
39 }
40 } else if ((cond_id - PLAT_SPM_COND_MAX) < PLAT_SPM_COND_PLL_MAX) {
41 unsigned int pll_idx = cond_id - PLAT_SPM_COND_MAX;
42
43 cond = !!cond;
44 if ((act & MT_LPM_SMC_ACT_SET) > 0U) {
45 SPM_RC_BITS_SET(tlb->table_pll, (cond << pll_idx));
46 } else if ((act & MT_LPM_SMC_ACT_CLR) > 0U) {
47 SPM_RC_BITS_CLR(tlb->table_pll, (cond << pll_idx));
48 } else {
49 res = -1;
50 }
51 } else {
52 res = -1;
53 }
54 } while (0);
55
56 spin_unlock(&spm_lock);
57
58 return res;
59}
60
61int spm_rc_constraint_status_get(unsigned int id, unsigned int type,
62 unsigned int act,
63 enum mt_spm_rm_rc_type dest_rc_id,
64 struct constraint_status * const src,
65 struct constraint_status * const dest)
66{
67 if (((id != MT_RM_CONSTRAINT_ID_ALL) && (id != dest_rc_id)) || (dest == NULL) ||
68 (src == NULL)) {
69 return -1;
70 }
71 spin_lock(&spm_lock);
72
73 switch (type) {
74 case CONSTRAINT_GET_ENTER_CNT:
75 if (id == MT_RM_CONSTRAINT_ID_ALL) {
76 dest->enter_cnt += src->enter_cnt;
77 } else {
78 dest->enter_cnt = src->enter_cnt;
79 }
80 break;
81 case CONSTRAINT_GET_VALID:
82 dest->is_valid = src->is_valid;
83 break;
84 case CONSTRAINT_COND_BLOCK:
85 dest->is_cond_block = src->is_cond_block;
86 dest->all_pll_dump = src->all_pll_dump;
87 break;
88 case CONSTRAINT_GET_COND_BLOCK_DETAIL:
89 dest->cond_res = src->cond_res;
90 break;
91 case CONSTRAINT_GET_RESIDNECY:
92 dest->residency = src->residency;
93 if (act & MT_LPM_SMC_ACT_CLR) {
94 src->residency = 0;
95 }
96 break;
97 default:
98 break;
99 }
100
101 spin_unlock(&spm_lock);
102 return 0;
103}
104
105int spm_rc_constraint_status_set(unsigned int id, unsigned int type,
106 unsigned int act,
107 enum mt_spm_rm_rc_type dest_rc_id,
108 struct constraint_status * const src,
109 struct constraint_status * const dest)
110{
111 if (((id != MT_RM_CONSTRAINT_ID_ALL) && (id != dest_rc_id)) || (dest == NULL)) {
112 return -1;
113 }
114
115 spin_lock(&spm_lock);
116
117 switch (type) {
118 case CONSTRAINT_UPDATE_VALID:
119 if (src != NULL) {
120 if ((act & MT_LPM_SMC_ACT_SET) > 0U) {
121 SPM_RC_BITS_SET(dest->is_valid, src->is_valid);
122 } else if ((act & MT_LPM_SMC_ACT_CLR) > 0U) {
123 SPM_RC_BITS_CLR(dest->is_valid, src->is_valid);
124 }
125 }
126 break;
127 case CONSTRAINT_RESIDNECY:
128 if (act & MT_LPM_SMC_ACT_CLR) {
129 dest->residency = 0;
130 }
131 break;
132 default:
133 break;
134 }
135
136 spin_unlock(&spm_lock);
137
138 return 0;
139}
140
141int spm_rc_constraint_valid_set(enum mt_spm_rm_rc_type id,
142 enum mt_spm_rm_rc_type dest_rc_id,
143 unsigned int valid,
144 struct constraint_status * const dest)
145{
146 if (((id != MT_RM_CONSTRAINT_ID_ALL) && (id != dest_rc_id)) || (dest == NULL)) {
147 return -1;
148 }
149
150 spin_lock(&spm_lock);
151 SPM_RC_BITS_SET(dest->is_valid, valid);
152 spin_unlock(&spm_lock);
153
154 return 0;
155}
156
157int spm_rc_constraint_valid_clr(enum mt_spm_rm_rc_type id,
158 enum mt_spm_rm_rc_type dest_rc_id,
159 unsigned int valid,
160 struct constraint_status * const dest)
161{
162 if (((id != MT_RM_CONSTRAINT_ID_ALL) && (id != dest_rc_id)) || (dest == NULL)) {
163 return -1;
164 }
165
166 spin_lock(&spm_lock);
167 SPM_RC_BITS_CLR(dest->is_valid, valid);
168 spin_unlock(&spm_lock);
169
170 return 0;
171}