summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/boardobj
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/boardobj')
-rw-r--r--drivers/gpu/nvgpu/boardobj/boardobj.c94
-rw-r--r--drivers/gpu/nvgpu/boardobj/boardobj.h102
-rw-r--r--drivers/gpu/nvgpu/boardobj/boardobjgrp.c787
-rw-r--r--drivers/gpu/nvgpu/boardobj/boardobjgrp.h416
-rw-r--r--drivers/gpu/nvgpu/boardobj/boardobjgrp_e255.c86
-rw-r--r--drivers/gpu/nvgpu/boardobj/boardobjgrp_e255.h50
-rw-r--r--drivers/gpu/nvgpu/boardobj/boardobjgrp_e32.c85
-rw-r--r--drivers/gpu/nvgpu/boardobj/boardobjgrp_e32.h65
-rw-r--r--drivers/gpu/nvgpu/boardobj/boardobjgrpmask.c366
-rw-r--r--drivers/gpu/nvgpu/boardobj/boardobjgrpmask.h119
10 files changed, 2170 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/boardobj/boardobj.c b/drivers/gpu/nvgpu/boardobj/boardobj.c
new file mode 100644
index 00000000..f9be6981
--- /dev/null
+++ b/drivers/gpu/nvgpu/boardobj/boardobj.c
@@ -0,0 +1,94 @@
1/*
2 * Copyright (c) 2016-2017, 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
23#include <nvgpu/kmem.h>
24
25#include "gk20a/gk20a.h"
26#include "boardobj.h"
27#include "ctrl/ctrlboardobj.h"
28
29u32 boardobj_construct_super(struct gk20a *g, struct boardobj **ppboardobj,
30 u16 size, void *args)
31{
32 struct boardobj *pboardobj = NULL;
33 struct boardobj *devtmp = (struct boardobj *)args;
34
35 gk20a_dbg_info(" ");
36
37 if (devtmp == NULL)
38 return -EINVAL;
39
40 if (*ppboardobj == NULL) {
41 *ppboardobj = nvgpu_kzalloc(g, size);
42 if (*ppboardobj == NULL)
43 return -ENOMEM;
44 (*ppboardobj)->allocated = true;
45 }
46
47 pboardobj = *ppboardobj;
48 pboardobj->g = g;
49 pboardobj->type = devtmp->type;
50 pboardobj->idx = CTRL_BOARDOBJ_IDX_INVALID;
51 pboardobj->type_mask = BIT(pboardobj->type) | devtmp->type_mask;
52
53 pboardobj->implements = boardobj_implements_super;
54 pboardobj->destruct = boardobj_destruct_super;
55 pboardobj->pmudatainit = boardobj_pmudatainit_super;
56
57 nvgpu_list_add(&pboardobj->node, &g->boardobj_head);
58
59 return 0;
60}
61
62u32 boardobj_destruct_super(struct boardobj *pboardobj)
63{
64 gk20a_dbg_info("");
65 if (pboardobj == NULL)
66 return -EINVAL;
67
68 nvgpu_list_del(&pboardobj->node);
69 if (pboardobj->allocated)
70 nvgpu_kfree(pboardobj->g, pboardobj);
71
72 return 0;
73}
74
75bool boardobj_implements_super(struct gk20a *g, struct boardobj *pboardobj,
76 u8 type)
77{
78 gk20a_dbg_info("");
79
80 return (0 != (pboardobj->type_mask & BIT(type)));
81}
82
83u32 boardobj_pmudatainit_super(struct gk20a *g, struct boardobj *pboardobj,
84 struct nv_pmu_boardobj *pmudata)
85{
86 gk20a_dbg_info("");
87 if (pboardobj == NULL)
88 return -EINVAL;
89 if (pmudata == NULL)
90 return -EINVAL;
91 pmudata->type = pboardobj->type;
92 gk20a_dbg_info(" Done");
93 return 0;
94}
diff --git a/drivers/gpu/nvgpu/boardobj/boardobj.h b/drivers/gpu/nvgpu/boardobj/boardobj.h
new file mode 100644
index 00000000..a433fda8
--- /dev/null
+++ b/drivers/gpu/nvgpu/boardobj/boardobj.h
@@ -0,0 +1,102 @@
1/*
2* Copyright (c) 2016-2017, 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
23#ifndef _BOARDOBJ_H_
24#define _BOARDOBJ_H_
25
26#include <nvgpu/pmuif/nvgpu_gpmu_cmdif.h>
27
28#include "ctrl/ctrlboardobj.h"
29
30struct boardobj;
31
32/*
33* check whether the specified BOARDOBJ object implements the queried
34* type/class enumeration.
35*/
36typedef bool boardobj_implements(struct gk20a *g, struct boardobj *pboardobj,
37 u8 type);
38
39/*
40* Fills out the appropriate the nv_pmu_xxxx_device_desc_<xyz> driver->PMU
41* description structure, describing this BOARDOBJ board device to the PMU.
42*
43*/
44typedef u32 boardobj_pmudatainit(struct gk20a *g, struct boardobj *pboardobj,
45 struct nv_pmu_boardobj *pmudata);
46
47/*
48* Constructor for the base Board Object. Called by each device-specific
49* implementation of the BOARDOBJ interface to initialize the board object.
50*/
51typedef u32 boardobj_construct(struct gk20a *g, struct boardobj **pboardobj,
52 u16 size, void *args);
53
54/*
55* Destructor for the base board object. Called by each device-Specific
56* implementation of the BOARDOBJ interface to destroy the board object.
57* This has to be explicitly set by each device that extends from the
58* board object.
59*/
60typedef u32 boardobj_destruct(struct boardobj *pboardobj);
61
62/*
63* Base Class for all physical or logical device on the PCB.
64* Contains fields common to all devices on the board. Specific types of
65* devices may extend this object adding any details specific to that
66* device or device-type.
67*/
68
69struct boardobj {
70 struct gk20a *g;
71
72 u8 type; /*type of the device*/
73 u8 idx; /*index of boardobj within in its group*/
74 /* true if allocated in constructor. destructor should free */
75 u8 allocated;
76 u32 type_mask; /*mask of types this boardobjimplements*/
77 boardobj_implements *implements;
78 boardobj_destruct *destruct;
79 /*
80 * Access interface apis which will be overridden by the devices
81 * that inherit from BOARDOBJ
82 */
83 boardobj_pmudatainit *pmudatainit;
84 struct nvgpu_list_node node;
85};
86
87boardobj_construct boardobj_construct_super;
88boardobj_destruct boardobj_destruct_super;
89boardobj_implements boardobj_implements_super;
90boardobj_pmudatainit boardobj_pmudatainit_super;
91
92#define BOARDOBJ_GET_TYPE(pobj) (((struct boardobj *)(pobj))->type)
93#define BOARDOBJ_GET_IDX(pobj) (((struct boardobj *)(pobj))->idx)
94
95static inline struct boardobj *
96boardobj_from_node(struct nvgpu_list_node *node)
97{
98 return (struct boardobj *)
99 ((uintptr_t)node - offsetof(struct boardobj, node));
100};
101
102#endif
diff --git a/drivers/gpu/nvgpu/boardobj/boardobjgrp.c b/drivers/gpu/nvgpu/boardobj/boardobjgrp.c
new file mode 100644
index 00000000..caed11e9
--- /dev/null
+++ b/drivers/gpu/nvgpu/boardobj/boardobjgrp.c
@@ -0,0 +1,787 @@
1/*
2* Copyright (c) 2016-2017, 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 <nvgpu/bug.h>
23
24#include "gk20a/gk20a.h"
25#include "boardobjgrp.h"
26#include "ctrl/ctrlboardobj.h"
27#include "boardobj.h"
28
29static boardobjgrp_objinsert boardobjgrp_objinsert_final;
30static boardobjgrp_objgetbyidx boardobjgrp_objgetbyidx_final;
31static boardobjgrp_objgetnext boardobjgrp_objgetnext_final;
32static boardobjgrp_objremoveanddestroy boardobjgrp_objremoveanddestroy_final;
33static boardobjgrp_pmudatainstget boardobjgrp_pmudatainstget_stub;
34static boardobjgrp_pmustatusinstget boardobjgrp_pmustatusinstget_stub;
35static u32 boardobjgrp_pmucmdsend(struct gk20a *g,
36 struct boardobjgrp *pboardobjgrp,
37 struct boardobjgrp_pmu_cmd *pcmd);
38struct boardobjgrp_pmucmdhandler_params {
39 /* Pointer to the BOARDOBJGRP associated with this CMD */
40 struct boardobjgrp *pboardobjgrp;
41 /* Pointer to structure representing this NV_PMU_BOARDOBJ_CMD_GRP */
42 struct boardobjgrp_pmu_cmd *pcmd;
43 /* Boolean indicating whether the PMU successfully handled the CMD */
44 u32 success;
45};
46
47u32 boardobjgrp_construct_super(struct gk20a *g, struct boardobjgrp *pboardobjgrp)
48{
49 gk20a_dbg_info("");
50
51 if (pboardobjgrp == NULL)
52 return -EINVAL;
53
54 if (pboardobjgrp->ppobjects == NULL)
55 return -EINVAL;
56
57 if (pboardobjgrp->mask == NULL)
58 return -EINVAL;
59
60 pboardobjgrp->g = g;
61 pboardobjgrp->objmask = 0;
62
63 pboardobjgrp->classid = 0;
64 pboardobjgrp->pmu.unitid = BOARDOBJGRP_UNIT_ID_INVALID;
65 pboardobjgrp->pmu.classid = BOARDOBJGRP_GRP_CLASS_ID_INVALID;
66 pboardobjgrp->pmu.set.id = BOARDOBJGRP_GRP_CMD_ID_INVALID;
67 pboardobjgrp->pmu.getstatus.id = BOARDOBJGRP_GRP_CMD_ID_INVALID;
68
69 /* Initialize basic interfaces */
70 pboardobjgrp->destruct = boardobjgrp_destruct_super;
71 pboardobjgrp->objinsert = boardobjgrp_objinsert_final;
72 pboardobjgrp->objgetbyidx = boardobjgrp_objgetbyidx_final;
73 pboardobjgrp->objgetnext = boardobjgrp_objgetnext_final;
74 pboardobjgrp->objremoveanddestroy =
75 boardobjgrp_objremoveanddestroy_final;
76
77 pboardobjgrp->pmuinithandle = boardobjgrp_pmuinithandle_impl;
78 pboardobjgrp->pmuhdrdatainit = boardobjgrp_pmuhdrdatainit_super;
79 pboardobjgrp->pmudatainit = boardobjgrp_pmudatainit_super;
80 pboardobjgrp->pmuset = boardobjgrp_pmuset_impl;
81 pboardobjgrp->pmugetstatus = boardobjgrp_pmugetstatus_impl;
82
83 pboardobjgrp->pmudatainstget = boardobjgrp_pmudatainstget_stub;
84 pboardobjgrp->pmustatusinstget = boardobjgrp_pmustatusinstget_stub;
85
86 pboardobjgrp->objmaxidx = CTRL_BOARDOBJ_IDX_INVALID;
87 pboardobjgrp->bconstructed = true;
88
89 nvgpu_list_add(&pboardobjgrp->node, &g->boardobjgrp_head);
90
91 return 0;
92}
93
94u32 boardobjgrp_destruct_impl(struct boardobjgrp *pboardobjgrp)
95{
96 gk20a_dbg_info("");
97
98 if (pboardobjgrp == NULL)
99 return -EINVAL;
100
101 if (!pboardobjgrp->bconstructed)
102 return 0;
103
104 return pboardobjgrp->destruct(pboardobjgrp);
105}
106
107u32 boardobjgrp_destruct_super(struct boardobjgrp *pboardobjgrp)
108{
109 struct boardobj *pboardobj;
110 struct gk20a *g = pboardobjgrp->g;
111 u32 status = 0;
112 u32 stat;
113 u8 index;
114
115 gk20a_dbg_info("");
116
117 if (pboardobjgrp->mask == NULL)
118 return -EINVAL;
119 if (pboardobjgrp->ppobjects == NULL)
120 return -EINVAL;
121
122 BOARDOBJGRP_FOR_EACH(pboardobjgrp, struct boardobj*, pboardobj, index) {
123 stat = pboardobjgrp->objremoveanddestroy(pboardobjgrp, index);
124 if (status == 0)
125 status = stat;
126
127 pboardobjgrp->ppobjects[index] = NULL;
128 pboardobjgrp->objmask &= ~BIT(index);
129 }
130
131 pboardobjgrp->objmask = 0;
132
133 if (pboardobjgrp->objmaxidx != CTRL_BOARDOBJ_IDX_INVALID) {
134 if (status == 0)
135 status = -EINVAL;
136
137 WARN_ON(true);
138 }
139
140 /* Destroy the PMU CMD data */
141 stat = boardobjgrp_pmucmd_destroy_impl(g, &pboardobjgrp->pmu.set);
142 if (status == 0)
143 status = stat;
144
145 stat = boardobjgrp_pmucmd_destroy_impl(g, &pboardobjgrp->pmu.getstatus);
146 if (status == 0)
147 status = stat;
148
149 nvgpu_list_del(&pboardobjgrp->node);
150
151 pboardobjgrp->bconstructed = false;
152
153 return status;
154}
155
156u32 boardobjgrp_pmucmd_construct_impl(struct gk20a *g, struct boardobjgrp
157 *pboardobjgrp, struct boardobjgrp_pmu_cmd *cmd, u8 id, u8 msgid,
158 u8 hdrsize, u8 entrysize, u16 fbsize)
159{
160 gk20a_dbg_info("");
161
162 /* Copy the parameters into the CMD*/
163 cmd->id = id;
164 cmd->msgid = msgid;
165 cmd->hdrsize = hdrsize;
166 cmd->entrysize = entrysize;
167 cmd->fbsize = fbsize;
168
169 return 0;
170}
171
172u32 boardobjgrp_pmucmd_destroy_impl(struct gk20a *g,
173 struct boardobjgrp_pmu_cmd *cmd)
174{
175 struct nvgpu_mem *mem = &cmd->surf.sysmem_desc;
176
177 nvgpu_pmu_surface_free(g, mem);
178 return 0;
179}
180
181u32 boardobjgrp_pmucmd_pmuinithandle_impl(struct gk20a *g,
182 struct boardobjgrp *pboardobjgrp,
183 struct boardobjgrp_pmu_cmd *pcmd)
184{
185 u32 status = 0;
186 struct nvgpu_mem *sysmem_desc = &pcmd->surf.sysmem_desc;
187
188 gk20a_dbg_info("");
189
190 if (pcmd->id == BOARDOBJGRP_GRP_CMD_ID_INVALID)
191 goto boardobjgrp_pmucmd_pmuinithandle_exit;
192
193 nvgpu_pmu_sysmem_surface_alloc(g, sysmem_desc, pcmd->fbsize);
194 /* we only have got sysmem later this will get copied to vidmem
195 surface*/
196 pcmd->surf.vidmem_desc.size = 0;
197
198 pcmd->buf = (struct nv_pmu_boardobjgrp_super *)sysmem_desc->cpu_va;
199
200boardobjgrp_pmucmd_pmuinithandle_exit:
201 return status;
202}
203
204u32 boardobjgrp_pmuinithandle_impl(struct gk20a *g,
205 struct boardobjgrp *pboardobjgrp)
206{
207 u32 status = 0;
208
209 gk20a_dbg_info("");
210
211 status = boardobjgrp_pmucmd_pmuinithandle_impl(g, pboardobjgrp,
212 &pboardobjgrp->pmu.set);
213 if (status) {
214 nvgpu_err(g, "failed to init pmu set cmd");
215 goto boardobjgrp_pmuinithandle_exit;
216 }
217
218 status = boardobjgrp_pmucmd_pmuinithandle_impl(g, pboardobjgrp,
219 &pboardobjgrp->pmu.getstatus);
220 if (status) {
221 nvgpu_err(g, "failed to init get status command");
222 goto boardobjgrp_pmuinithandle_exit;
223 }
224
225 /* If the GRP_SET CMD has not been allocated, nothing left to do. */
226 if (((pboardobjgrp->pmu.set.id) == BOARDOBJGRP_GRP_CMD_ID_INVALID) ||
227 (BOARDOBJGRP_IS_EMPTY(pboardobjgrp)))
228 goto boardobjgrp_pmuinithandle_exit;
229
230 /* Send the BOARDOBJGRP to the pmu via RM_PMU_BOARDOBJ_CMD_GRP. */
231 status = pboardobjgrp->pmuset(g, pboardobjgrp);
232 if (status)
233 nvgpu_err(g, "failed to send boardobg grp to PMU");
234
235boardobjgrp_pmuinithandle_exit:
236 return status;
237}
238
239
240u32 boardobjgrp_pmuhdrdatainit_super(struct gk20a *g, struct boardobjgrp
241 *pboardobjgrp, struct nv_pmu_boardobjgrp_super *pboardobjgrppmu,
242 struct boardobjgrpmask *mask)
243{
244 gk20a_dbg_info("");
245
246 if (pboardobjgrp == NULL)
247 return -EINVAL;
248 if (pboardobjgrppmu == NULL)
249 return -EINVAL;
250 pboardobjgrppmu->type = pboardobjgrp->type;
251 pboardobjgrppmu->class_id = pboardobjgrp->classid;
252 pboardobjgrppmu->obj_slots = BOARDOBJGRP_PMU_SLOTS_GET(pboardobjgrp);
253
254 gk20a_dbg_info(" Done");
255 return 0;
256}
257
258static u32 boardobjgrp_pmudatainstget_stub(struct gk20a *g,
259 struct nv_pmu_boardobjgrp *boardobjgrppmu,
260 struct nv_pmu_boardobj **ppboardobjpmudata, u8 idx)
261{
262 gk20a_dbg_info("");
263 return -EINVAL;
264}
265
266
267static u32 boardobjgrp_pmustatusinstget_stub(struct gk20a *g,
268 void *pboardobjgrppmu,
269 struct nv_pmu_boardobj_query **ppBoardobjpmustatus, u8 idx)
270{
271 gk20a_dbg_info("");
272 return -EINVAL;
273}
274
275u32 boardobjgrp_pmudatainit_legacy(struct gk20a *g,
276 struct boardobjgrp *pboardobjgrp,
277 struct nv_pmu_boardobjgrp_super *pboardobjgrppmu)
278{
279 u32 status = 0;
280 struct boardobj *pboardobj = NULL;
281 struct nv_pmu_boardobj *ppmudata = NULL;
282 u8 index;
283
284 gk20a_dbg_info("");
285
286 if (pboardobjgrp == NULL)
287 return -EINVAL;
288 if (pboardobjgrppmu == NULL)
289 return -EINVAL;
290
291 boardobjgrpe32hdrset((struct nv_pmu_boardobjgrp *)pboardobjgrppmu,
292 pboardobjgrp->objmask);
293
294 BOARDOBJGRP_FOR_EACH_INDEX_IN_MASK(32, index, pboardobjgrp->objmask) {
295 /* Obtain pointer to the current instance of the Object from the Group */
296 pboardobj = pboardobjgrp->objgetbyidx(pboardobjgrp, index);
297 if (NULL == pboardobj) {
298 nvgpu_err(g, "could not get object instance");
299 status = -EINVAL;
300 goto boardobjgrppmudatainit_legacy_done;
301 }
302
303 status = pboardobjgrp->pmudatainstget(g,
304 (struct nv_pmu_boardobjgrp *)pboardobjgrppmu,
305 &ppmudata, index);
306 if (status) {
307 nvgpu_err(g, "could not get object instance");
308 goto boardobjgrppmudatainit_legacy_done;
309 }
310
311 /* Initialize the PMU Data */
312 status = pboardobj->pmudatainit(g, pboardobj, ppmudata);
313 if (status) {
314 nvgpu_err(g,
315 "could not parse pmu for device %d", index);
316 goto boardobjgrppmudatainit_legacy_done;
317 }
318 }
319 BOARDOBJGRP_FOR_EACH_INDEX_IN_MASK_END
320
321boardobjgrppmudatainit_legacy_done:
322 gk20a_dbg_info(" Done");
323 return status;
324}
325
326u32 boardobjgrp_pmudatainit_super(struct gk20a *g, struct boardobjgrp
327 *pboardobjgrp, struct nv_pmu_boardobjgrp_super *pboardobjgrppmu)
328{
329 u32 status = 0;
330 struct boardobj *pboardobj = NULL;
331 struct nv_pmu_boardobj *ppmudata = NULL;
332 u8 index;
333
334 gk20a_dbg_info("");
335
336 if (pboardobjgrp == NULL)
337 return -EINVAL;
338 if (pboardobjgrppmu == NULL)
339 return -EINVAL;
340
341 /* Initialize the PMU HDR data.*/
342 status = pboardobjgrp->pmuhdrdatainit(g, pboardobjgrp, pboardobjgrppmu,
343 pboardobjgrp->mask);
344 if (status) {
345 nvgpu_err(g, "unable to init boardobjgrp pmuhdr data");
346 goto boardobjgrppmudatainit_super_done;
347 }
348
349 BOARDOBJGRP_FOR_EACH(pboardobjgrp, struct boardobj*, pboardobj, index) {
350 status = pboardobjgrp->pmudatainstget(g,
351 (struct nv_pmu_boardobjgrp *)pboardobjgrppmu,
352 &ppmudata, index);
353 if (status) {
354 nvgpu_err(g, "could not get object instance");
355 goto boardobjgrppmudatainit_super_done;
356 }
357
358 /* Initialize the PMU Data and send to PMU */
359 status = pboardobj->pmudatainit(g, pboardobj, ppmudata);
360 if (status) {
361 nvgpu_err(g,
362 "could not parse pmu for device %d", index);
363 goto boardobjgrppmudatainit_super_done;
364 }
365 }
366
367boardobjgrppmudatainit_super_done:
368 gk20a_dbg_info(" Done");
369 return status;
370}
371
372u32 boardobjgrp_pmuset_impl(struct gk20a *g, struct boardobjgrp *pboardobjgrp)
373{
374 u32 status = 0;
375 struct boardobjgrp_pmu_cmd *pcmd = &pboardobjgrp->pmu.set;
376 gk20a_dbg_info("");
377
378 if (pboardobjgrp == NULL)
379 return -EINVAL;
380
381 if (!pboardobjgrp->bconstructed)
382 return -EINVAL;
383
384 if (pboardobjgrp->pmu.unitid == BOARDOBJGRP_UNIT_ID_INVALID)
385 return -EINVAL;
386
387 if (pboardobjgrp->pmu.classid == BOARDOBJGRP_GRP_CLASS_ID_INVALID)
388 return -EINVAL;
389
390 if (pboardobjgrp->pmu.set.id == BOARDOBJGRP_GRP_CMD_ID_INVALID)
391 return -EINVAL;
392
393 if ((pcmd->hdrsize == 0) ||
394 (pcmd->entrysize == 0) ||
395 (pcmd->buf == NULL))
396 return -EINVAL;
397
398 /* If no objects in the group, return early */
399 if (BOARDOBJGRP_IS_EMPTY(pboardobjgrp))
400 return -EINVAL;
401
402 /* Initialize PMU buffer with BOARDOBJGRP data. */
403 memset(pcmd->buf, 0x0, pcmd->fbsize);
404 status = pboardobjgrp->pmudatainit(g, pboardobjgrp,
405 pcmd->buf);
406 if (status) {
407 nvgpu_err(g, "could not parse pmu data");
408 goto boardobjgrp_pmuset_exit;
409 }
410
411 /*
412 * Reset the boolean that indicates set status for most recent
413 * instance of BOARDOBJGRP.
414 */
415 pboardobjgrp->pmu.bset = false;
416
417 /*
418 * alloc mem in vidmem & copy constructed pmu boardobjgrp data from
419 * sysmem to vidmem
420 */
421 if (pcmd->surf.vidmem_desc.size == 0) {
422 nvgpu_pmu_vidmem_surface_alloc(g, &pcmd->surf.vidmem_desc,
423 pcmd->fbsize);
424 }
425 nvgpu_mem_wr_n(g, &pcmd->surf.vidmem_desc, 0, pcmd->buf, pcmd->fbsize);
426
427 /* Send the SET PMU CMD to the PMU */
428 status = boardobjgrp_pmucmdsend(g, pboardobjgrp,
429 pcmd);
430 if (status) {
431 nvgpu_err(g, "could not send SET CMD to PMU");
432 goto boardobjgrp_pmuset_exit;
433 }
434
435 pboardobjgrp->pmu.bset = true;
436
437boardobjgrp_pmuset_exit:
438 return status;
439}
440
441u32
442boardobjgrp_pmugetstatus_impl(struct gk20a *g, struct boardobjgrp *pboardobjgrp,
443 struct boardobjgrpmask *mask)
444{
445 u32 status = 0;
446 struct boardobjgrp_pmu_cmd *pcmd = &pboardobjgrp->pmu.getstatus;
447 struct boardobjgrp_pmu_cmd *pset = &pboardobjgrp->pmu.set;
448
449 gk20a_dbg_info("");
450
451 if (pboardobjgrp == NULL)
452 return -EINVAL;
453
454 if (!pboardobjgrp->bconstructed)
455 return -EINVAL;
456
457 if (pboardobjgrp->pmu.unitid == BOARDOBJGRP_UNIT_ID_INVALID)
458 return -EINVAL;
459
460 if (pboardobjgrp->pmu.classid == BOARDOBJGRP_GRP_CLASS_ID_INVALID)
461 return -EINVAL;
462
463 if (pboardobjgrp->pmu.set.id == BOARDOBJGRP_GRP_CMD_ID_INVALID)
464 return -EINVAL;
465
466 if ((pcmd->hdrsize == 0) ||
467 (pcmd->entrysize == 0) ||
468 (pcmd->buf == NULL))
469 return -EINVAL;
470
471 /* If no objects in the group, return early */
472 if (BOARDOBJGRP_IS_EMPTY(pboardobjgrp))
473 return -EINVAL;
474
475 /*
476 * Can only GET_STATUS if the BOARDOBJGRP has been previously SET to the
477 * PMU
478 */
479 if (!pboardobjgrp->pmu.bset)
480 return -EINVAL;
481
482 /*
483 * alloc mem in vidmem & copy constructed pmu boardobjgrp data from
484 * sysmem to vidmem
485 */
486 if (pcmd->surf.vidmem_desc.size == 0) {
487 nvgpu_pmu_vidmem_surface_alloc(g, &pcmd->surf.vidmem_desc,
488 pcmd->fbsize);
489 }
490
491 /*
492 * Initialize PMU buffer with the mask of BOARDOBJGRPs for which to
493 * retrieve status
494 */
495
496 memset(pcmd->buf, 0x0, pcmd->fbsize);
497 status = pboardobjgrp->pmuhdrdatainit(g, pboardobjgrp,
498 pcmd->buf, mask);
499 if (status) {
500 nvgpu_err(g, "could not init PMU HDR data");
501 goto boardobjgrp_pmugetstatus_exit;
502 }
503
504 nvgpu_mem_wr_n(g, &pcmd->surf.vidmem_desc, 0, pset->buf, pset->hdrsize);
505 /* Send the GET_STATUS PMU CMD to the PMU */
506 status = boardobjgrp_pmucmdsend(g, pboardobjgrp,
507 &pboardobjgrp->pmu.getstatus);
508 if (status) {
509 nvgpu_err(g, "could not send GET_STATUS cmd to PMU");
510 goto boardobjgrp_pmugetstatus_exit;
511 }
512
513 /*copy the data back to sysmem buffer that belongs to command*/
514 nvgpu_mem_rd_n(g, &pcmd->surf.vidmem_desc, 0, pcmd->buf, pcmd->fbsize);
515
516boardobjgrp_pmugetstatus_exit:
517 return status;
518}
519
520static u32
521boardobjgrp_objinsert_final(struct boardobjgrp *pboardobjgrp,
522 struct boardobj *pboardobj, u8 index)
523{
524
525 gk20a_dbg_info("");
526
527 if (pboardobjgrp == NULL)
528 return -EINVAL;
529
530 if (pboardobj == NULL)
531 return -EINVAL;
532
533 if (index > pboardobjgrp->objslots)
534 return -EINVAL;
535
536 if (pboardobjgrp->ppobjects[index] != NULL)
537 return -EINVAL;
538
539 /*
540 * Check that this BOARDOBJ has not already been added to a
541 * BOARDOBJGRP
542 */
543 if (pboardobj->idx != CTRL_BOARDOBJ_IDX_INVALID)
544 return -EINVAL;
545
546 pboardobjgrp->ppobjects[index] = pboardobj;
547 pboardobjgrp->objmaxidx = BOARDOBJGRP_IS_EMPTY(pboardobjgrp) ?
548 index : max(pboardobjgrp->objmaxidx, index);
549 pboardobj->idx = index;
550
551 pboardobjgrp->objmask |= BIT(index);
552
553 gk20a_dbg_info(" Done");
554
555 return boardobjgrpmask_bitset(pboardobjgrp->mask, index);
556}
557
558static struct boardobj *boardobjgrp_objgetbyidx_final(
559 struct boardobjgrp *pboardobjgrp, u8 index)
560{
561 if (!boardobjgrp_idxisvalid(pboardobjgrp, index))
562 return NULL;
563 return pboardobjgrp->ppobjects[index];
564}
565
566static struct boardobj *boardobjgrp_objgetnext_final(
567 struct boardobjgrp *pboardobjgrp, u8 *currentindex,
568 struct boardobjgrpmask *mask)
569{
570 struct boardobj *pboardobjnext = NULL;
571 u8 objmaxidx;
572 u8 index;
573
574 if (currentindex == NULL)
575 return NULL;
576
577 if (pboardobjgrp == NULL)
578 return NULL;
579
580 /* Search from next element unless first object was requested */
581 index = (*currentindex != CTRL_BOARDOBJ_IDX_INVALID) ?
582 (*currentindex + 1) : 0;
583
584 /* For the cases below in which we have to return NULL */
585 *currentindex = CTRL_BOARDOBJ_IDX_INVALID;
586
587
588 /* Validate provided mask */
589 if (mask != NULL) {
590 if (!(boardobjgrpmask_sizeeq(pboardobjgrp->mask, mask)))
591 return NULL;
592 }
593
594 objmaxidx = pboardobjgrp->objmaxidx;
595
596 if (objmaxidx != CTRL_BOARDOBJ_IDX_INVALID) {
597 for (; index <= objmaxidx; index++) {
598 pboardobjnext = pboardobjgrp->ppobjects[index];
599 if (pboardobjnext != NULL) {
600 /* Filter results using client provided mask.*/
601 if (mask != NULL) {
602 if (!boardobjgrpmask_bitget(mask,
603 index)) {
604 pboardobjnext = NULL;
605 continue;
606 }
607 }
608 *currentindex = index;
609 break;
610 }
611 }
612 }
613
614 return pboardobjnext;
615}
616
617static u32 boardobjgrp_objremoveanddestroy_final(
618 struct boardobjgrp *pboardobjgrp,
619 u8 index)
620{
621 u32 status = 0;
622 u32 stat;
623
624 gk20a_dbg_info("");
625
626 if (!boardobjgrp_idxisvalid(pboardobjgrp, index))
627 return -EINVAL;
628
629 if (pboardobjgrp->objmaxidx == CTRL_BOARDOBJ_IDX_INVALID)
630 return -EINVAL;
631
632 status = pboardobjgrp->ppobjects[index]->destruct(
633 pboardobjgrp->ppobjects[index]);
634
635 pboardobjgrp->ppobjects[index] = NULL;
636
637 pboardobjgrp->objmask &= ~BIT(index);
638
639 stat = boardobjgrpmask_bitclr(pboardobjgrp->mask, index);
640 if (stat) {
641 if (status == 0)
642 status = stat;
643 }
644
645 /* objmaxidx requires update only if that very object was removed */
646 if (pboardobjgrp->objmaxidx == index) {
647 pboardobjgrp->objmaxidx =
648 boardobjgrpmask_bitidxhighest(pboardobjgrp->mask);
649 }
650
651 return status;
652}
653
654void boardobjgrpe32hdrset(struct nv_pmu_boardobjgrp *hdr, u32 objmask)
655{
656 u32 slots = objmask;
657
658 gk20a_dbg_info("");
659
660 HIGHESTBITIDX_32(slots);
661 slots++;
662
663 hdr->super.type = CTRL_BOARDOBJGRP_TYPE_E32;
664 hdr->super.class_id = 0;
665 hdr->super.obj_slots = (u8)slots;
666 hdr->obj_mask = objmask;
667}
668
669static void boardobjgrp_pmucmdhandler(struct gk20a *g, struct pmu_msg *msg,
670 void *param, u32 handle, u32 status)
671{
672 struct nv_pmu_boardobj_msg_grp *pgrpmsg;
673 struct boardobjgrp_pmucmdhandler_params *phandlerparams =
674 (struct boardobjgrp_pmucmdhandler_params *)param;
675 struct boardobjgrp *pboardobjgrp = phandlerparams->pboardobjgrp;
676 struct boardobjgrp_pmu_cmd *pgrpcmd = phandlerparams->pcmd;
677
678 gk20a_dbg_info("");
679
680 pgrpmsg = &msg->msg.boardobj.grp;
681
682 if (pgrpmsg->class_id != pboardobjgrp->pmu.classid) {
683 nvgpu_err(g,
684 "Unrecognized GRP type: unit %x class id=0x%02x cmd id %x",
685 msg->hdr.unit_id, pboardobjgrp->pmu.classid,
686 pgrpcmd->id);
687 return;
688 }
689
690 if (msg->msg.boardobj.msg_type != pgrpcmd->msgid) {
691 nvgpu_err(g,
692 "unsupported msg for unit %x class %x cmd id %x msg %x",
693 msg->hdr.unit_id, pboardobjgrp->pmu.classid,
694 pgrpcmd->id, msg->msg.boardobj.msg_type);
695 return;
696 }
697
698 if (msg->msg.boardobj.grp_set.flcn_status != 0) {
699 nvgpu_err(g,
700 "cmd abort for unit %x class %x cmd id %x status %x",
701 msg->hdr.unit_id, pboardobjgrp->pmu.classid,
702 pgrpcmd->id,
703 msg->msg.boardobj.grp_set.flcn_status);
704 return;
705 }
706
707 phandlerparams->success = pgrpmsg->b_success ? 1 : 0;
708
709 if (!pgrpmsg->b_success) {
710 nvgpu_err(g,
711 "failed GRPCMD: msgtype=0x%x, classid=0x%x, cmd id %x",
712 pgrpmsg->msg_type, pgrpmsg->class_id,
713 pgrpcmd->id);
714 return;
715 }
716}
717
718static u32 boardobjgrp_pmucmdsend(struct gk20a *g,
719 struct boardobjgrp *pboardobjgrp,
720 struct boardobjgrp_pmu_cmd *pcmd)
721{
722 struct boardobjgrp_pmucmdhandler_params handlerparams;
723 struct pmu_payload payload;
724 struct nv_pmu_boardobj_cmd_grp *pgrpcmd;
725 struct pmu_cmd cmd;
726 u32 seqdesc;
727 u32 status = 0;
728
729 gk20a_dbg_info("");
730
731 memset(&payload, 0, sizeof(payload));
732 memset(&handlerparams, 0, sizeof(handlerparams));
733 memset(&cmd, 0, sizeof(struct pmu_cmd));
734 cmd.hdr.unit_id = pboardobjgrp->pmu.unitid;
735 cmd.hdr.size = sizeof(struct nv_pmu_boardobj_cmd_grp) +
736 sizeof(struct pmu_hdr);
737
738 pgrpcmd = &cmd.cmd.boardobj.grp;
739 pgrpcmd->cmd_type = pcmd->id;
740 pgrpcmd->class_id = pboardobjgrp->pmu.classid;
741 pgrpcmd->grp.hdr_size = pcmd->hdrsize;
742 pgrpcmd->grp.entry_size = pcmd->entrysize;
743
744 /*
745 * copy vidmem information to boardobj_cmd_grp
746 */
747 nvgpu_pmu_surface_describe(g, &pcmd->surf.vidmem_desc,
748 &pgrpcmd->grp.fb);
749
750 /*
751 * PMU reads command from sysmem so assigned
752 * "payload.in.buf = pcmd->buf"
753 * but PMU access pmu boardobjgrp data from vidmem copied above
754 */
755 payload.in.buf = pcmd->buf;
756 payload.in.size = max(pcmd->hdrsize, pcmd->entrysize);
757 payload.in.fb_size = PMU_CMD_SUBMIT_PAYLOAD_PARAMS_FB_SIZE_UNUSED;
758 payload.in.offset = offsetof(struct nv_pmu_boardobj_cmd_grp, grp);
759
760 /* Setup the handler params to communicate back results.*/
761 handlerparams.pboardobjgrp = pboardobjgrp;
762 handlerparams.pcmd = pcmd;
763 handlerparams.success = 0;
764
765 status = nvgpu_pmu_cmd_post(g, &cmd, NULL, &payload,
766 PMU_COMMAND_QUEUE_LPQ,
767 boardobjgrp_pmucmdhandler,
768 (void *)&handlerparams,
769 &seqdesc, ~0);
770 if (status) {
771 nvgpu_err(g,
772 "unable to post boardobj grp cmd for unit %x cmd id %x",
773 cmd.hdr.unit_id, pcmd->id);
774 goto boardobjgrp_pmucmdsend_exit;
775 }
776 pmu_wait_message_cond(&g->pmu,
777 gk20a_get_gr_idle_timeout(g),
778 &handlerparams.success, 1);
779 if (handlerparams.success == 0) {
780 nvgpu_err(g, "could not process cmd");
781 status = -ETIMEDOUT;
782 goto boardobjgrp_pmucmdsend_exit;
783 }
784
785boardobjgrp_pmucmdsend_exit:
786 return status;
787}
diff --git a/drivers/gpu/nvgpu/boardobj/boardobjgrp.h b/drivers/gpu/nvgpu/boardobj/boardobjgrp.h
new file mode 100644
index 00000000..32e92ae0
--- /dev/null
+++ b/drivers/gpu/nvgpu/boardobj/boardobjgrp.h
@@ -0,0 +1,416 @@
1/*
2* Copyright (c) 2016-2017, 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
23#ifndef _BOARDOBJGRP_H_
24#define _BOARDOBJGRP_H_
25
26struct boardobjgrp;
27struct gk20a;
28
29/* ------------------------ Includes ----------------------------------------*/
30#include "ctrl/ctrlboardobj.h"
31#include "boardobj.h"
32#include "boardobjgrpmask.h"
33
34/*
35* Board Object Group destructor.
36*
37*/
38typedef u32 boardobjgrp_destruct(struct boardobjgrp *pboardobjgrp);
39
40/*
41* Inserts a previously constructed Board Object into a Board Object Group for
42* tracking. Objects are inserted in the array based on the given index.
43*/
44typedef u32 boardobjgrp_objinsert(struct boardobjgrp *pboardobjgrp,
45 struct boardobj *pboardobj, u8 index);
46
47/*
48* Retrieves a Board Object from a Board Object Group using the group's index.
49*
50*/
51typedef struct boardobj *boardobjgrp_objgetbyidx(
52 struct boardobjgrp *pBobrdobjgrp, u8 index);
53
54/*
55* Retrieve Board Object immediately following one pointed by @ref pcurrentindex
56* filtered out by the provided mask. If (pMask == NULL) => no filtering.
57*/
58typedef struct boardobj *boardobjgrp_objgetnext(
59 struct boardobjgrp *pboardobjgrp,
60 u8 *currentindex, struct boardobjgrpmask *mask);
61
62/*
63* Board Object Group Remover and destructor. This is used to remove and
64* destruct specific entry from the Board Object Group.
65*/
66typedef u32 boardobjgrp_objremoveanddestroy(struct boardobjgrp *pboardobjgrp,
67 u8 index);
68
69/*
70* BOARDOBJGRP handler for PMU_UNIT_INIT. Calls the PMU_UNIT_INIT handlers
71* for the constructed PMU CMDs, and then sets the object via the
72* PMU_BOARDOBJ_CMD_GRP interface (if constructed).
73*/
74typedef u32 boardobjgrp_pmuinithandle(struct gk20a *g,
75 struct boardobjgrp *pboardobjGrp);
76
77/*
78* Fills out the appropriate the PMU_BOARDOBJGRP_<xyz> driver<->PMU description
79* header structure, more specifically a mask of BOARDOBJs.
80*/
81typedef u32 boardobjgrp_pmuhdrdatainit(struct gk20a *g,
82 struct boardobjgrp *pboardobjgrp,
83 struct nv_pmu_boardobjgrp_super *pboardobjgrppmu,
84 struct boardobjgrpmask *mask);
85
86/*
87* Fills out the appropriate the PMU_BOARDOBJGRP_<xyz> driver->PMU description
88* structure, describing the BOARDOBJGRP and all of its BOARDOBJs to the PMU.
89*/
90typedef u32 boardobjgrp_pmudatainit(struct gk20a *g,
91 struct boardobjgrp *pboardobjgrp,
92 struct nv_pmu_boardobjgrp_super *pboardobjgrppmu);
93
94/*
95* Sends a BOARDOBJGRP to the PMU via the PMU_BOARDOBJ_CMD_GRP interface.
96* This interface leverages @ref boardobjgrp_pmudatainit to populate the
97* structure.
98*/
99typedef u32 boardobjgrp_pmuset(struct gk20a *g,
100 struct boardobjgrp *pboardobjgrp);
101
102/*
103* Gets the dynamic status of the PMU BOARDOBJGRP via the
104* PMU_BOARDOBJ_CMD_GRP GET_STATUS interface.
105*/
106typedef u32 boardobjgrp_pmugetstatus(struct gk20a *g,
107 struct boardobjgrp *pboardobjgrp,
108 struct boardobjgrpmask *mask);
109
110typedef u32 boardobjgrp_pmudatainstget(struct gk20a *g,
111 struct nv_pmu_boardobjgrp *boardobjgrppmu,
112 struct nv_pmu_boardobj **ppboardobjpmudata, u8 idx);
113
114typedef u32 boardobjgrp_pmustatusinstget(struct gk20a *g, void *pboardobjgrppmu,
115 struct nv_pmu_boardobj_query **ppBoardobjpmustatus, u8 idx);
116
117/*
118* Structure describing an PMU CMD for interacting with the representaition
119* of this BOARDOBJGRP within the PMU.
120*/
121struct boardobjgrp_pmu_cmd {
122 u8 id;
123 u8 msgid;
124 u8 hdrsize;
125 u8 entrysize;
126 u16 fbsize;
127 struct nv_pmu_boardobjgrp_super *buf;
128 struct pmu_surface surf;
129};
130
131/*
132* Structure of state describing how to communicate with representation of this
133* BOARDOBJGRP in the PMU.
134*/
135struct boardobjgrp_pmu {
136 u8 unitid;
137 u8 classid;
138 bool bset;
139 struct boardobjgrp_pmu_cmd set;
140 struct boardobjgrp_pmu_cmd getstatus;
141};
142
143/*
144* Function by which a class which implements BOARDOBJGRP can construct a PMU
145* CMD. This provides the various information describing the PMU CMD including
146* the CMD and MSG ID and the size of the various sturctures in the payload.
147*/
148typedef u32 boardobjgrp_pmucmd_construct(struct gk20a *g,
149 struct boardobjgrp *pboardobjgrp,
150 struct boardobjgrp_pmu_cmd *cmd, u8 id, u8 msgid,
151 u8 hdrsize, u8 entrysize, u16 fbsize);
152
153/*
154* Destroys BOARDOBJGRP PMU SW state. CMD.
155*/
156typedef u32 boardobjgrp_pmucmd_destroy(struct gk20a *g,
157 struct boardobjgrp_pmu_cmd *cmd);
158
159/*
160* init handler for the BOARDOBJGRP PMU CMD. Allocates and maps the
161* PMU CMD payload within both the PMU and driver so that it can be referenced
162* at run-time.
163*/
164typedef u32 boardobjgrp_pmucmd_pmuinithandle(struct gk20a *g,
165 struct boardobjgrp *pboardobjgrp,
166 struct boardobjgrp_pmu_cmd *cmd);
167
168/*
169* Base Class Group for all physical or logical device on the PCB.
170* Contains fields common to all devices on the board. Specific types of
171* devices groups may extend this object adding any details specific to that
172* device group or device-type.
173*/
174struct boardobjgrp {
175 struct gk20a *g;
176 u32 objmask;
177 bool bconstructed;
178 u8 type;
179 u8 classid;
180 struct boardobj **ppobjects;
181 struct boardobjgrpmask *mask;
182 u8 objslots;
183 u8 objmaxidx;
184 struct boardobjgrp_pmu pmu;
185
186 /* Basic interfaces */
187 boardobjgrp_destruct *destruct;
188 boardobjgrp_objinsert *objinsert;
189 boardobjgrp_objgetbyidx *objgetbyidx;
190 boardobjgrp_objgetnext *objgetnext;
191 boardobjgrp_objremoveanddestroy *objremoveanddestroy;
192
193 /* PMU interfaces */
194 boardobjgrp_pmuinithandle *pmuinithandle;
195 boardobjgrp_pmuhdrdatainit *pmuhdrdatainit;
196 boardobjgrp_pmudatainit *pmudatainit;
197 boardobjgrp_pmuset *pmuset;
198 boardobjgrp_pmugetstatus *pmugetstatus;
199
200 boardobjgrp_pmudatainstget *pmudatainstget;
201 boardobjgrp_pmustatusinstget *pmustatusinstget;
202 struct nvgpu_list_node node;
203};
204
205/*
206* Macro test whether a specified index into the BOARDOBJGRP is valid.
207*
208*/
209#define boardobjgrp_idxisvalid(_pboardobjgrp, _idx) \
210 (((_idx) < (_pboardobjgrp)->objslots) && \
211 ((_pboardobjgrp)->ppobjects[(_idx)] != NULL))
212
213/*
214* Macro test whether a specified BOARDOBJGRP is empty.
215*/
216#define BOARDOBJGRP_IS_EMPTY(_pboardobjgrp) \
217 ((!((_pboardobjgrp)->bconstructed)) || \
218 ((_pboardobjgrp)->objmaxidx == CTRL_BOARDOBJ_IDX_INVALID))
219
220#define boardobjgrp_objinsert(_pboardobjgrp, _pboardobj, _idx) \
221 ((_pboardobjgrp)->objinsert((_pboardobjgrp), (_pboardobj), (_idx)))
222
223/*
224* Helper macro to determine the "next" open/empty index after all allocated
225* objects. This is intended to be used to find the index at which objects can
226* be inserted contiguously (i.e. w/o fear of colliding with existing objects).
227*/
228#define BOARDOBJGRP_NEXT_EMPTY_IDX(_pboardobjgrp) \
229 ((CTRL_BOARDOBJ_IDX_INVALID == (_pboardobjgrp)->objmaxidx) ? 0 : \
230 ((((_pboardobjgrp)->objmaxidx + 1) >= (_pboardobjgrp)->objslots) ? \
231 (u8)CTRL_BOARDOBJ_IDX_INVALID : (u8)((_pboardobjgrp)->objmaxidx + 1)))
232
233/*
234* Helper macro to determine the number of @ref BOARDOBJ pointers
235* that are required to be allocated in PMU @ref ppObjects.
236*/
237#define BOARDOBJGRP_PMU_SLOTS_GET(_pboardobjgrp) \
238 ((CTRL_BOARDOBJ_IDX_INVALID == (_pboardobjgrp)->objmaxidx) ? 0 : \
239 (u8)((_pboardobjgrp)->objmaxidx + 1))
240
241#define BOARDOBJGRP_OBJ_GET_BY_IDX(_pboardobjgrp, _idx) \
242 ((_pboardobjgrp)->objgetbyidx((_pboardobjgrp), (_idx)))
243
244/*
245* macro to look-up next object while tolerating error if
246* Board Object Group is not constructed.
247*/
248
249#define boardobjgrpobjgetnextsafe(_pgrp, _pindex, _pmask) \
250 ((_pgrp)->bconstructed ? \
251 (_pgrp)->objgetnext((_pgrp), (_pindex), (_pmask)) : NULL)
252
253/*
254* Used to traverse all Board Objects stored within @ref _pgrp in the increasing
255* index order.
256* If @ref _pmask is provided only objects specified by the mask are traversed.
257*/
258#define BOARDOBJGRP_ITERATOR(_pgrp, _ptype, _pobj, _index, _pmask) \
259 for (_index = CTRL_BOARDOBJ_IDX_INVALID, \
260 _pobj = (_ptype)boardobjgrpobjgetnextsafe((_pgrp), &_index, (_pmask));\
261 _pobj != NULL; \
262 _pobj = (_ptype)boardobjgrpobjgetnextsafe((_pgrp), &_index, (_pmask)))
263#define BOARDOBJGRP_FOR_EACH(_pgrp, _ptype, _pobj, _index) \
264 BOARDOBJGRP_ITERATOR(_pgrp, _ptype, _pobj, _index, NULL)
265
266#define BOARDOBJGRP_FOR_EACH_INDEX_IN_MASK(mask_width, index, mask) \
267{ \
268 u##mask_width lcl_msk = (u##mask_width)(mask); \
269 for (index = 0; lcl_msk != 0; index++, lcl_msk >>= 1) { \
270 if (((u##mask_width)((u64)1) & lcl_msk) == 0) { \
271 continue; \
272 }
273
274#define BOARDOBJGRP_FOR_EACH_INDEX_IN_MASK_END \
275 } \
276}
277
278
279/*!
280* Invalid UNIT_ID. Used to indicate that the implementing class has not set
281* @ref BOARDOBJGRP::unitId and, thus, certain BOARDOBJGRP PMU interfaces are
282* not supported.
283*/
284#define BOARDOBJGRP_UNIT_ID_INVALID 255
285
286/*!
287* Invalid UNIT_ID. Used to indicate that the implementing class has not set
288* @ref BOARDOBJGRP::grpType and, thus, certain BOARDOBJGRP PMU interfaces are
289* not supported.
290*/
291#define BOARDOBJGRP_GRP_CLASS_ID_INVALID 255
292
293/*!
294* Invalid UNIT_ID. Used to indicate that the implementing class has not set
295* @ref BOARDOBJGRP::grpSetCmdId and, thus, certain BOARDOBJGRP PMU interfaces
296* are not supported.
297*/
298#define BOARDOBJGRP_GRP_CMD_ID_INVALID 255
299
300/*!
301* Helper macro to construct a BOARDOBJGRP's PMU SW state.
302*
303* @param[out] pboardobjgrp BOARDOBJGRP pointer
304* @param[in] _eng
305* Implementing engine/unit which manages the BOARDOBJGRP.
306* @param[in] _class
307* Class ID of BOARDOBJGRP.
308*/
309#define BOARDOBJGRP_PMU_CONSTRUCT(pboardobjgrp, _ENG, _CLASS) \
310do { \
311 (pboardobjgrp)->pmu.unitid = PMU_UNIT_##_ENG; \
312 (pboardobjgrp)->pmu.classid = \
313 NV_PMU_##_ENG##_BOARDOBJGRP_CLASS_ID_##_CLASS; \
314} while (0)
315
316#define BOARDOBJGRP_PMU_CMD_GRP_SET_CONSTRUCT(pgpu, pboardobjgrp, eng, ENG, \
317 class, CLASS) \
318 boardobjgrp_pmucmd_construct_impl( \
319 pgpu, /* pgpu */ \
320 pboardobjgrp, /* pboardobjgrp */ \
321 &((pboardobjgrp)->pmu.set), /* pcmd */ \
322 NV_PMU_##ENG##_CMD_ID_BOARDOBJ_GRP_SET, /* id */ \
323 NV_PMU_##ENG##_MSG_ID_BOARDOBJ_GRP_SET, /* msgid */ \
324 (u32)sizeof(union nv_pmu_##eng##_##class##_boardobjgrp_set_header_aligned), \
325 (u32)sizeof(union nv_pmu_##eng##_##class##_boardobj_set_union_aligned), \
326 (u32)sizeof(struct nv_pmu_##eng##_##class##_boardobj_grp_set))
327
328#define BOARDOBJGRP_PMU_CMD_GRP_GET_STATUS_CONSTRUCT(pgpu, pboardobjgrp, \
329 eng, ENG, class, CLASS) \
330 boardobjgrp_pmucmd_construct_impl( \
331 pgpu, /* pGpu */ \
332 pboardobjgrp, /* pBoardObjGrp */ \
333 &((pboardobjgrp)->pmu.getstatus), /* pCmd */ \
334 NV_PMU_##ENG##_CMD_ID_BOARDOBJ_GRP_GET_STATUS, /* id */ \
335 NV_PMU_##ENG##_MSG_ID_BOARDOBJ_GRP_GET_STATUS, /* msgid */ \
336 (u32)sizeof(union nv_pmu_##eng##_##class##_boardobjgrp_get_status_header_aligned), \
337 (u32)sizeof(union nv_pmu_##eng##_##class##_boardobj_get_status_union_aligned), \
338 (u32)sizeof(struct nv_pmu_##eng##_##class##_boardobj_grp_get_status))
339
340/* ------------------------ Function Prototypes ----------------------------- */
341/* Constructor and destructor */
342u32 boardobjgrp_construct_super(struct gk20a *g, struct boardobjgrp *pboardobjgrp);
343boardobjgrp_destruct boardobjgrp_destruct_impl;
344boardobjgrp_destruct boardobjgrp_destruct_super;
345
346/* PMU_CMD interfaces */
347boardobjgrp_pmucmd_construct boardobjgrp_pmucmd_construct_impl;
348boardobjgrp_pmucmd_destroy boardobjgrp_pmucmd_destroy_impl;
349boardobjgrp_pmucmd_pmuinithandle boardobjgrp_pmucmd_pmuinithandle_impl;
350
351/* BOARDOBJGRP interfaces */
352boardobjgrp_pmuinithandle boardobjgrp_pmuinithandle_impl;
353boardobjgrp_pmuhdrdatainit boardobjgrp_pmuhdrdatainit_super;
354boardobjgrp_pmudatainit boardobjgrp_pmudatainit_super;
355
356boardobjgrp_pmudatainit boardobjgrp_pmudatainit_legacy;
357boardobjgrp_pmuset boardobjgrp_pmuset_impl;
358boardobjgrp_pmugetstatus boardobjgrp_pmugetstatus_impl;
359
360void boardobjgrpe32hdrset(struct nv_pmu_boardobjgrp *hdr, u32 objmask);
361
362#define HIGHESTBITIDX_32(n32) \
363{ \
364 u32 count = 0; \
365 while (n32 >>= 1) \
366 count++; \
367 n32 = count; \
368}
369
370#define LOWESTBIT(x) ((x) & (((x)-1) ^ (x)))
371
372#define HIGHESTBIT(n32) \
373{ \
374 HIGHESTBITIDX_32(n32); \
375 n32 = NVBIT(n32); \
376}
377
378#define ONEBITSET(x) ((x) && (((x) & ((x)-1)) == 0))
379
380#define LOWESTBITIDX_32(n32) \
381{ \
382 n32 = LOWESTBIT(n32); \
383 IDX_32(n32); \
384}
385
386#define NUMSETBITS_32(n32) \
387{ \
388 n32 = n32 - ((n32 >> 1) & 0x55555555); \
389 n32 = (n32 & 0x33333333) + ((n32 >> 2) & 0x33333333); \
390 n32 = (((n32 + (n32 >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24; \
391}
392
393#define IDX_32(n32) \
394{ \
395 u32 idx = 0; \
396 if ((n32) & 0xFFFF0000) \
397 idx += 16; \
398 if ((n32) & 0xFF00FF00) \
399 idx += 8; \
400 if ((n32) & 0xF0F0F0F0) \
401 idx += 4; \
402 if ((n32) & 0xCCCCCCCC) \
403 idx += 2; \
404 if ((n32) & 0xAAAAAAAA) \
405 idx += 1; \
406 (n32) = idx; \
407}
408
409static inline struct boardobjgrp *
410boardobjgrp_from_node(struct nvgpu_list_node *node)
411{
412 return (struct boardobjgrp *)
413 ((uintptr_t)node - offsetof(struct boardobjgrp, node));
414};
415
416#endif
diff --git a/drivers/gpu/nvgpu/boardobj/boardobjgrp_e255.c b/drivers/gpu/nvgpu/boardobj/boardobjgrp_e255.c
new file mode 100644
index 00000000..7aabb89e
--- /dev/null
+++ b/drivers/gpu/nvgpu/boardobj/boardobjgrp_e255.c
@@ -0,0 +1,86 @@
1/*
2* Copyright (c) 2016-2017, 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
23#include "gk20a/gk20a.h"
24#include "boardobj.h"
25#include "boardobjgrp_e255.h"
26#include "ctrl/ctrlboardobj.h"
27#include "boardobjgrp.h"
28#include "boardobjgrpmask.h"
29
30u32 boardobjgrpconstruct_e255(struct gk20a *g,
31 struct boardobjgrp_e255 *pboardobjgrp_e255)
32{
33 u32 status = 0;
34 u8 objslots;
35
36 gk20a_dbg_info("");
37
38 objslots = 255;
39 status = boardobjgrpmask_e255_init(&pboardobjgrp_e255->mask, NULL);
40 if (status)
41 goto boardobjgrpconstruct_e255_exit;
42
43 pboardobjgrp_e255->super.type = CTRL_BOARDOBJGRP_TYPE_E255;
44 pboardobjgrp_e255->super.ppobjects = pboardobjgrp_e255->objects;
45 pboardobjgrp_e255->super.objslots = objslots;
46 pboardobjgrp_e255->super.mask = &(pboardobjgrp_e255->mask.super);
47
48 status = boardobjgrp_construct_super(g, &pboardobjgrp_e255->super);
49 if (status)
50 goto boardobjgrpconstruct_e255_exit;
51
52 pboardobjgrp_e255->super.pmuhdrdatainit =
53 boardobjgrp_pmuhdrdatainit_e255;
54
55boardobjgrpconstruct_e255_exit:
56 return status;
57}
58
59u32 boardobjgrp_pmuhdrdatainit_e255(struct gk20a *g,
60 struct boardobjgrp *pboardobjgrp,
61 struct nv_pmu_boardobjgrp_super *pboardobjgrppmu,
62 struct boardobjgrpmask *mask)
63{
64 struct nv_pmu_boardobjgrp_e255 *pgrpe255 =
65 (struct nv_pmu_boardobjgrp_e255 *)pboardobjgrppmu;
66 u32 status;
67
68 gk20a_dbg_info("");
69
70 if (pboardobjgrp == NULL)
71 return -EINVAL;
72
73 if (pboardobjgrppmu == NULL)
74 return -EINVAL;
75
76 status = boardobjgrpmask_export(mask,
77 mask->bitcount,
78 &pgrpe255->obj_mask.super);
79 if (status) {
80 nvgpu_err(g, "e255 init:failed export grpmask");
81 return status;
82 }
83
84 return boardobjgrp_pmuhdrdatainit_super(g,
85 pboardobjgrp, pboardobjgrppmu, mask);
86}
diff --git a/drivers/gpu/nvgpu/boardobj/boardobjgrp_e255.h b/drivers/gpu/nvgpu/boardobj/boardobjgrp_e255.h
new file mode 100644
index 00000000..76aa902a
--- /dev/null
+++ b/drivers/gpu/nvgpu/boardobj/boardobjgrp_e255.h
@@ -0,0 +1,50 @@
1/*
2 * Copyright (c) 2016-2017, 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
23#ifndef _BOARDOBJGRP_E255_H_
24#define _BOARDOBJGRP_E255_H_
25
26#include "ctrl/ctrlboardobj.h"
27#include "boardobj.h"
28#include "boardobjgrpmask.h"
29#include "boardobj/boardobjgrp.h"
30
31/*
32 * boardobjgrp_e255 is @ref BOARDOBJGRP child class allowing storage of up
33 * to 255 @ref BOARDOBJ object pointers with single static 255-bit mask denoting
34 * valid object pointers.
35 */
36struct boardobjgrp_e255 {
37 struct boardobjgrp super;
38 struct boardobj *objects[CTRL_BOARDOBJGRP_E255_MAX_OBJECTS];
39 struct boardobjgrpmask_e255 mask;
40};
41
42#define boardobjgrp_pmudatainit_e255(g, pboardpbjgrp, pboardobjgrppmu) \
43 boardobjgrp_pmudatainit_super(g, pboardpbjgrp, pboardobjgrppmu)
44
45/* Constructor and destructor */
46u32 boardobjgrpconstruct_e255(struct gk20a *g, struct boardobjgrp_e255 *pboardobjgrp);
47boardobjgrp_destruct boardobjgrpdestruct_e255;
48boardobjgrp_pmuhdrdatainit boardobjgrp_pmuhdrdatainit_e255;
49
50#endif
diff --git a/drivers/gpu/nvgpu/boardobj/boardobjgrp_e32.c b/drivers/gpu/nvgpu/boardobj/boardobjgrp_e32.c
new file mode 100644
index 00000000..e793e34c
--- /dev/null
+++ b/drivers/gpu/nvgpu/boardobj/boardobjgrp_e32.c
@@ -0,0 +1,85 @@
1/*
2* Copyright (c) 2016-2017, 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
23#include "gk20a/gk20a.h"
24#include "boardobj.h"
25#include "boardobjgrp.h"
26#include "boardobjgrp_e32.h"
27#include "ctrl/ctrlboardobj.h"
28#include "boardobjgrpmask.h"
29
30
31u32 boardobjgrpconstruct_e32(struct gk20a *g,
32 struct boardobjgrp_e32 *pboardobjgrp_e32)
33{
34 u32 status;
35 u8 objslots;
36
37 gk20a_dbg_info("");
38 objslots = 32;
39
40 status = boardobjgrpmask_e32_init(&pboardobjgrp_e32->mask, NULL);
41 if (status)
42 goto boardobjgrpconstruct_e32_exit;
43
44 pboardobjgrp_e32->super.type = CTRL_BOARDOBJGRP_TYPE_E32;
45 pboardobjgrp_e32->super.ppobjects = pboardobjgrp_e32->objects;
46 pboardobjgrp_e32->super.objslots = objslots;
47 pboardobjgrp_e32->super.mask = &(pboardobjgrp_e32->mask.super);
48
49 status = boardobjgrp_construct_super(g, &pboardobjgrp_e32->super);
50 if (status)
51 goto boardobjgrpconstruct_e32_exit;
52
53 pboardobjgrp_e32->super.pmuhdrdatainit = boardobjgrp_pmuhdrdatainit_e32;
54
55boardobjgrpconstruct_e32_exit:
56 return status;
57}
58
59u32 boardobjgrp_pmuhdrdatainit_e32(struct gk20a *g,
60 struct boardobjgrp *pboardobjgrp,
61 struct nv_pmu_boardobjgrp_super *pboardobjgrppmu,
62 struct boardobjgrpmask *mask)
63{
64 struct nv_pmu_boardobjgrp_e32 *pgrpe32 =
65 (struct nv_pmu_boardobjgrp_e32 *)pboardobjgrppmu;
66 u32 status;
67
68 gk20a_dbg_info("");
69
70 if (pboardobjgrp == NULL)
71 return -EINVAL;
72
73 if (pboardobjgrppmu == NULL)
74 return -EINVAL;
75 status = boardobjgrpmask_export(mask,
76 mask->bitcount,
77 &pgrpe32->obj_mask.super);
78 if (status) {
79 nvgpu_err(g, "e32 init:failed export grpmask");
80 return status;
81 }
82
83 return boardobjgrp_pmuhdrdatainit_super(g,
84 pboardobjgrp, pboardobjgrppmu, mask);
85}
diff --git a/drivers/gpu/nvgpu/boardobj/boardobjgrp_e32.h b/drivers/gpu/nvgpu/boardobj/boardobjgrp_e32.h
new file mode 100644
index 00000000..97c737a5
--- /dev/null
+++ b/drivers/gpu/nvgpu/boardobj/boardobjgrp_e32.h
@@ -0,0 +1,65 @@
1/*
2 * Copyright (c) 2016-2017, 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
23#ifndef _BOARDOBJGRP_E32_H_
24#define _BOARDOBJGRP_E32_H_
25
26#include "ctrl/ctrlboardobj.h"
27#include "boardobj.h"
28#include "boardobjgrp.h"
29#include "boardobjgrpmask.h"
30#include "boardobj/boardobjgrp.h"
31
32/*
33 * boardobjgrp_e32 is @ref BOARDOBJGRP child class allowing storage of up to 32
34 * @ref BOARDOBJ object pointers with single static 32-bit mask denoting valid
35 * object pointers.
36 */
37struct boardobjgrp_e32 {
38 /*
39 * BOARDOBJGRP super-class. Must be first element of the structure.
40 */
41 struct boardobjgrp super;
42 /*
43 * Statically allocated array of PBOARDOBJ-s
44 */
45 struct boardobj *objects[CTRL_BOARDOBJGRP_E32_MAX_OBJECTS];
46
47 /*
48 * Statically allocated mask strcuture referenced by super::pMask.
49 */
50 struct boardobjgrpmask_e32 mask;
51};
52
53/*
54 * Wrapper to the _SUPER implementation. Provided for the child classes which
55 * implement this interface.
56 */
57#define boardobjgrp_pmudatainit_e32(g, pboardpbjgrp, pboardobjgrppmu) \
58 boardobjgrp_pmudatainit_super(g, pboardpbjgrp, pboardobjgrppmu)
59
60/* Constructor and destructor */
61u32 boardobjgrpconstruct_e32(struct gk20a *g, struct boardobjgrp_e32 *pboardobjgrp);
62boardobjgrp_destruct boardobjgrpdestruct_e32;
63boardobjgrp_pmuhdrdatainit boardobjgrp_pmuhdrdatainit_e32;
64
65#endif
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}
diff --git a/drivers/gpu/nvgpu/boardobj/boardobjgrpmask.h b/drivers/gpu/nvgpu/boardobj/boardobjgrpmask.h
new file mode 100644
index 00000000..aacabfe9
--- /dev/null
+++ b/drivers/gpu/nvgpu/boardobj/boardobjgrpmask.h
@@ -0,0 +1,119 @@
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
23#ifndef _BOARDOBJGRPMASK_H_
24#define _BOARDOBJGRPMASK_H_
25
26#include "ctrl/ctrlboardobj.h"
27
28
29/*
30* Board Object Group Mask super-structure.
31* Used to unify access to all BOARDOBJGRPMASK_E** child classes
32*/
33struct boardobjgrpmask {
34 /* Number of bits supported by the mask */
35 u8 bitcount;
36 /* Number of 32-bit words required to store all @ref bitCount bits */
37 u8 maskdatacount;
38 /*
39 * Bit-mask of used-bits within last 32-bit word. Used to
40 * normalize data
41 */
42 u32 lastmaskfilter;
43 /*
44 * Start of the array of 32-bit words representing the bit-mask
45 * Must be the last element of the structure.
46 */
47 u32 data[CTRL_BOARDOBJGRP_MASK_ARRAY_START_SIZE];
48};
49
50struct boardobjgrpmask_e32 {
51 /*
52 * BOARDOBJGRPMASK super-class. Must be the first element of the
53 * structure.
54 */
55 struct boardobjgrpmask super;
56 /*u32 data_e32[1]; */
57};
58
59struct boardobjgrpmask_e255 {
60 /*
61 * BOARDOBJGRPMASK super-class. Must be the first element of the
62 * structure.
63 */
64 struct boardobjgrpmask super;
65 u32 data_e255[254];
66};
67
68/* Init and I/O operations.*/
69u32 boardobjgrpmask_init(struct boardobjgrpmask *mask, u8 bitsize,
70 struct ctrl_boardobjgrp_mask *extmask);
71u32 boardobjgrpmask_import(struct boardobjgrpmask *mask, u8 bitsize,
72 struct ctrl_boardobjgrp_mask *extmask);
73u32 boardobjgrpmask_export(struct boardobjgrpmask *mask, u8 bitsize,
74 struct ctrl_boardobjgrp_mask *extmask);
75
76/* Operations on all bits of a single mask.*/
77u32 boardobjgrpmask_clr(struct boardobjgrpmask *mask);
78u32 boardobjgrpmask_set(struct boardobjgrpmask *mask);
79u32 boardobjgrpmask_inv(struct boardobjgrpmask *mask);
80bool boardobjgrpmask_iszero(struct boardobjgrpmask *mask);
81u8 boardobjgrpmask_bitsetcount(struct boardobjgrpmask *mask);
82u8 boardobjgrpmask_bitidxlowest(struct boardobjgrpmask *mask);
83u8 boardobjgrpmask_bitidxhighest(struct boardobjgrpmask *mask);
84
85/* Operations on a single bit of a single mask */
86u32 boardobjgrpmask_bitclr(struct boardobjgrpmask *mask, u8 bitidx);
87u32 boardobjgrpmask_bitset(struct boardobjgrpmask *mask, u8 bitidx);
88u32 boardobjgrpmask_bitinv(struct boardobjgrpmask *mask, u8 bitidx);
89bool boardobjgrpmask_bitget(struct boardobjgrpmask *mask, u8 bitidx);
90
91/* Operations on a multiple masks */
92u32 boardobjgrpmask_and(struct boardobjgrpmask *dst,
93 struct boardobjgrpmask *op1,
94 struct boardobjgrpmask *op2);
95u32 boardobjgrpmask_or(struct boardobjgrpmask *dst, struct boardobjgrpmask *op1,
96 struct boardobjgrpmask *op2);
97u32 boardobjgrpmask_xor(struct boardobjgrpmask *dst,
98 struct boardobjgrpmask *op1,
99 struct boardobjgrpmask *op2);
100
101/* Special interfaces */
102u32 boardobjgrpmask_copy(struct boardobjgrpmask *dst,
103 struct boardobjgrpmask *src);
104bool boardobjgrpmask_sizeeq(struct boardobjgrpmask *op1,
105 struct boardobjgrpmask *op2);
106bool boardobjgrpmask_issubset(struct boardobjgrpmask *op1,
107 struct boardobjgrpmask *op2);
108
109/* init boardobjgrpmask_e32 structure */
110#define boardobjgrpmask_e32_init(pmaske32, pextmask) \
111 boardobjgrpmask_init(&(pmaske32)->super, \
112 CTRL_BOARDOBJGRP_E32_MAX_OBJECTS, (pextmask))
113
114/* init boardobjgrpmask_e255 structure */
115#define boardobjgrpmask_e255_init(pmaske255, pextmask) \
116 boardobjgrpmask_init(&(pmaske255)->super, \
117 CTRL_BOARDOBJGRP_E255_MAX_OBJECTS, (pextmask))
118
119#endif