summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/boardobj/boardobjgrpmask.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/boardobj/boardobjgrpmask.c')
-rw-r--r--drivers/gpu/nvgpu/boardobj/boardobjgrpmask.c366
1 files changed, 366 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/boardobj/boardobjgrpmask.c b/drivers/gpu/nvgpu/boardobj/boardobjgrpmask.c
new file mode 100644
index 00000000..93befc99
--- /dev/null
+++ b/drivers/gpu/nvgpu/boardobj/boardobjgrpmask.c
@@ -0,0 +1,366 @@
1/*
2 * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22#include "gk20a/gk20a.h"
23#include "boardobjgrp.h"
24#include "ctrl/ctrlboardobj.h"
25
26/*
27* Assures that unused bits (size .. (maskDataCount * 32 - 1)) are always zero.
28*/
29#define BOARDOBJGRPMASK_NORMALIZE(_pmask) \
30 ((_pmask)->data[(_pmask)->maskdatacount-1] &= (_pmask)->lastmaskfilter)
31
32u32 boardobjgrpmask_init(struct boardobjgrpmask *mask, u8 bitsize,
33 struct ctrl_boardobjgrp_mask *extmask)
34{
35 if (mask == NULL)
36 return -EINVAL;
37 if ((bitsize != CTRL_BOARDOBJGRP_E32_MAX_OBJECTS) &&
38 (bitsize != CTRL_BOARDOBJGRP_E255_MAX_OBJECTS))
39 return -EINVAL;
40
41 mask->bitcount = bitsize;
42 mask->maskdatacount = CTRL_BOARDOBJGRP_MASK_DATA_SIZE(bitsize);
43 mask->lastmaskfilter = bitsize %
44 CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_BIT_SIZE;
45
46 mask->lastmaskfilter = (mask->lastmaskfilter == 0) ?
47 0xFFFFFFFF : (u32)(BIT(mask->lastmaskfilter) - 1);
48
49 return (extmask == NULL) ?
50 boardobjgrpmask_clr(mask) :
51 boardobjgrpmask_import(mask, bitsize, extmask);
52}
53
54u32 boardobjgrpmask_import(struct boardobjgrpmask *mask, u8 bitsize,
55 struct ctrl_boardobjgrp_mask *extmask)
56{
57 u8 index;
58
59 if (mask == NULL)
60 return -EINVAL;
61 if (extmask == NULL)
62 return -EINVAL;
63 if (mask->bitcount != bitsize)
64 return -EINVAL;
65
66 for (index = 0; index < mask->maskdatacount; index++)
67 mask->data[index] = extmask->data[index];
68
69 BOARDOBJGRPMASK_NORMALIZE(mask);
70
71 return 0;
72}
73
74u32 boardobjgrpmask_export(struct boardobjgrpmask *mask, u8 bitsize,
75 struct ctrl_boardobjgrp_mask *extmask)
76{
77 u8 index;
78
79 if (mask == NULL)
80 return -EINVAL;
81 if (extmask == NULL)
82 return -EINVAL;
83 if (mask->bitcount != bitsize)
84 return -EINVAL;
85
86 for (index = 0; index < mask->maskdatacount; index++)
87 extmask->data[index] = mask->data[index];
88
89 return 0;
90}
91
92u32 boardobjgrpmask_clr(struct boardobjgrpmask *mask)
93{
94 u8 index;
95
96 if (mask == NULL)
97 return -EINVAL;
98 for (index = 0; index < mask->maskdatacount; index++)
99 mask->data[index] = 0;
100
101 return 0;
102}
103
104u32 boardobjgrpmask_set(struct boardobjgrpmask *mask)
105{
106 u8 index;
107
108 if (mask == NULL)
109 return -EINVAL;
110 for (index = 0; index < mask->maskdatacount; index++)
111 mask->data[index] = 0xFFFFFFFF;
112 BOARDOBJGRPMASK_NORMALIZE(mask);
113 return 0;
114}
115
116u32 boardobjgrpmask_inv(struct boardobjgrpmask *mask)
117{
118 u8 index;
119
120 if (mask == NULL)
121 return -EINVAL;
122 for (index = 0; index < mask->maskdatacount; index++)
123 mask->data[index] = ~mask->data[index];
124 BOARDOBJGRPMASK_NORMALIZE(mask);
125 return 0;
126}
127
128bool boardobjgrpmask_iszero(struct boardobjgrpmask *mask)
129{
130 u8 index;
131
132 if (mask == NULL)
133 return true;
134 for (index = 0; index < mask->maskdatacount; index++) {
135 if (mask->data[index] != 0)
136 return false;
137 }
138 return true;
139}
140
141u8 boardobjgrpmask_bitsetcount(struct boardobjgrpmask *mask)
142{
143 u8 index;
144 u8 result = 0;
145
146 if (mask == NULL)
147 return result;
148
149 for (index = 0; index < mask->maskdatacount; index++) {
150 u32 m = mask->data[index];
151
152 NUMSETBITS_32(m);
153 result += (u8)m;
154 }
155
156 return result;
157}
158
159u8 boardobjgrpmask_bitidxlowest(struct boardobjgrpmask *mask)
160{
161 u8 index;
162 u8 result = CTRL_BOARDOBJ_IDX_INVALID;
163
164 if (mask == NULL)
165 return result;
166
167 for (index = 0; index < mask->maskdatacount; index++) {
168 u32 m = mask->data[index];
169
170 if (m != 0) {
171 LOWESTBITIDX_32(m);
172 result = (u8)m + index *
173 CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_BIT_SIZE;
174 break;
175 }
176 }
177
178 return result;
179}
180
181u8 boardobjgrpmask_bitidxhighest(struct boardobjgrpmask *mask)
182{
183 u8 index;
184 u8 result = CTRL_BOARDOBJ_IDX_INVALID;
185
186 if (mask == NULL)
187 return result;
188
189 for (index = 0; index < mask->maskdatacount; index++) {
190 u32 m = mask->data[index];
191
192 if (m != 0) {
193 HIGHESTBITIDX_32(m);
194 result = (u8)m + index *
195 CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_BIT_SIZE;
196 break;
197 }
198 }
199
200 return result;
201}
202
203u32 boardobjgrpmask_bitclr(struct boardobjgrpmask *mask, u8 bitidx)
204{
205 u8 index;
206 u8 offset;
207
208 if (mask == NULL)
209 return -EINVAL;
210 if (bitidx >= mask->bitcount)
211 return -EINVAL;
212
213 index = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_INDEX(bitidx);
214 offset = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_OFFSET(bitidx);
215
216 mask->data[index] &= ~BIT(offset);
217
218 return 0;
219}
220
221u32 boardobjgrpmask_bitset(struct boardobjgrpmask *mask, u8 bitidx)
222{
223 u8 index;
224 u8 offset;
225
226 if (mask == NULL)
227 return -EINVAL;
228 if (bitidx >= mask->bitcount)
229 return -EINVAL;
230
231 index = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_INDEX(bitidx);
232 offset = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_OFFSET(bitidx);
233
234 mask->data[index] |= BIT(offset);
235
236 return 0;
237}
238
239u32 boardobjgrpmask_bitinv(struct boardobjgrpmask *mask, u8 bitidx)
240{
241 u8 index;
242 u8 offset;
243
244 if (mask == NULL)
245 return -EINVAL;
246 if (bitidx >= mask->bitcount)
247 return -EINVAL;
248
249 index = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_INDEX(bitidx);
250 offset = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_OFFSET(bitidx);
251
252 mask->data[index] ^= ~BIT(offset);
253
254 return 0;
255}
256
257bool boardobjgrpmask_bitget(struct boardobjgrpmask *mask, u8 bitidx)
258{
259 u8 index;
260 u8 offset;
261
262 if (mask == NULL)
263 return false;
264 if (bitidx >= mask->bitcount)
265 return false;
266
267 index = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_INDEX(bitidx);
268 offset = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_OFFSET(bitidx);
269
270 return (mask->data[index] & BIT(offset)) != 0;
271}
272
273u32 boardobjgrpmask_and(struct boardobjgrpmask *dst,
274 struct boardobjgrpmask *op1,
275 struct boardobjgrpmask *op2)
276{
277 u8 index;
278
279 if (!boardobjgrpmask_sizeeq(dst, op1))
280 return -EINVAL;
281 if (!boardobjgrpmask_sizeeq(dst, op2))
282 return -EINVAL;
283
284 for (index = 0; index < dst->maskdatacount; index++)
285 dst->data[index] = op1->data[index] & op2->data[index];
286
287 return 0;
288}
289
290u32 boardobjgrpmask_or(struct boardobjgrpmask *dst,
291 struct boardobjgrpmask *op1,
292 struct boardobjgrpmask *op2)
293{
294 u8 index;
295
296 if (!boardobjgrpmask_sizeeq(dst, op1))
297 return -EINVAL;
298 if (!boardobjgrpmask_sizeeq(dst, op2))
299 return -EINVAL;
300
301 for (index = 0; index < dst->maskdatacount; index++)
302 dst->data[index] = op1->data[index] | op2->data[index];
303
304 return 0;
305}
306
307u32 boardobjgrpmask_xor(struct boardobjgrpmask *dst,
308 struct boardobjgrpmask *op1,
309 struct boardobjgrpmask *op2)
310{
311 u8 index;
312
313 if (!boardobjgrpmask_sizeeq(dst, op1))
314 return -EINVAL;
315 if (!boardobjgrpmask_sizeeq(dst, op2))
316 return -EINVAL;
317
318 for (index = 0; index < dst->maskdatacount; index++)
319 dst->data[index] = op1->data[index] ^ op2->data[index];
320
321 return 0;
322}
323
324u32 boardobjgrpmask_copy(struct boardobjgrpmask *dst,
325 struct boardobjgrpmask *src)
326{
327 u8 index;
328
329 if (!boardobjgrpmask_sizeeq(dst, src))
330 return -EINVAL;
331
332 for (index = 0; index < dst->maskdatacount; index++)
333 dst->data[index] = src->data[index];
334
335 return 0;
336}
337
338bool boardobjgrpmask_sizeeq(struct boardobjgrpmask *op1,
339 struct boardobjgrpmask *op2)
340{
341 if (op1 == NULL)
342 return false;
343 if (op2 == NULL)
344 return false;
345
346 return op1->bitcount == op2->bitcount;
347}
348
349bool boardobjgrpmask_issubset(struct boardobjgrpmask *op1,
350 struct boardobjgrpmask *op2)
351{
352 u8 index;
353
354 if (!boardobjgrpmask_sizeeq(op2, op1))
355 return false;
356
357 for (index = 0; index < op1->maskdatacount; index++) {
358 u32 op_1 = op1->data[index];
359 u32 op_2 = op2->data[index];
360
361 if ((op_1 & op_2) != op_1)
362 return false;
363 }
364
365 return true;
366}