diff options
author | Joshua Bakita <bakitajoshua@gmail.com> | 2023-06-28 18:24:25 -0400 |
---|---|---|
committer | Joshua Bakita <bakitajoshua@gmail.com> | 2023-06-28 18:24:25 -0400 |
commit | 01e6fac4d61fdd7fff5433942ec93fc2ea1e4df1 (patch) | |
tree | 4ef34501728a087be24f4ba0af90f91486bf780b /include/boardobj/boardobjgrp.c | |
parent | 306a03d18b305e4e573be3b2931978fa10679eb9 (diff) |
Include nvgpu headers
These are needed to build on NVIDIA's Jetson boards for the time
being. Only a couple structs are required, so it should be fairly
easy to remove this dependency at some point in the future.
Diffstat (limited to 'include/boardobj/boardobjgrp.c')
-rw-r--r-- | include/boardobj/boardobjgrp.c | 1046 |
1 files changed, 1046 insertions, 0 deletions
diff --git a/include/boardobj/boardobjgrp.c b/include/boardobj/boardobjgrp.c new file mode 100644 index 0000000..6832070 --- /dev/null +++ b/include/boardobj/boardobjgrp.c | |||
@@ -0,0 +1,1046 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016-2018, 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 | #include <nvgpu/gk20a.h> | ||
24 | |||
25 | #include "boardobjgrp.h" | ||
26 | #include "ctrl/ctrlboardobj.h" | ||
27 | #include "boardobj.h" | ||
28 | |||
29 | static boardobjgrp_objinsert boardobjgrp_objinsert_final; | ||
30 | static boardobjgrp_objgetbyidx boardobjgrp_objgetbyidx_final; | ||
31 | static boardobjgrp_objgetnext boardobjgrp_objgetnext_final; | ||
32 | static boardobjgrp_objremoveanddestroy boardobjgrp_objremoveanddestroy_final; | ||
33 | static boardobjgrp_pmudatainstget boardobjgrp_pmudatainstget_stub; | ||
34 | static boardobjgrp_pmustatusinstget boardobjgrp_pmustatusinstget_stub; | ||
35 | static int boardobjgrp_pmucmdsend(struct gk20a *g, | ||
36 | struct boardobjgrp *pboardobjgrp, | ||
37 | struct boardobjgrp_pmu_cmd *pcmd); | ||
38 | static int boardobjgrp_pmucmdsend_rpc(struct gk20a *g, | ||
39 | struct boardobjgrp *pboardobjgrp, | ||
40 | struct boardobjgrp_pmu_cmd *pcmd, | ||
41 | bool copy_out); | ||
42 | struct boardobjgrp_pmucmdhandler_params { | ||
43 | /* Pointer to the BOARDOBJGRP associated with this CMD */ | ||
44 | struct boardobjgrp *pboardobjgrp; | ||
45 | /* Pointer to structure representing this NV_PMU_BOARDOBJ_CMD_GRP */ | ||
46 | struct boardobjgrp_pmu_cmd *pcmd; | ||
47 | /* Boolean indicating whether the PMU successfully handled the CMD */ | ||
48 | u32 success; | ||
49 | }; | ||
50 | |||
51 | int boardobjgrp_construct_super(struct gk20a *g, | ||
52 | struct boardobjgrp *pboardobjgrp) | ||
53 | { | ||
54 | nvgpu_log_info(g, " "); | ||
55 | |||
56 | if (pboardobjgrp == NULL) { | ||
57 | return -EINVAL; | ||
58 | } | ||
59 | |||
60 | if (pboardobjgrp->ppobjects == NULL) { | ||
61 | return -EINVAL; | ||
62 | } | ||
63 | |||
64 | if (pboardobjgrp->mask == NULL) { | ||
65 | return -EINVAL; | ||
66 | } | ||
67 | |||
68 | pboardobjgrp->g = g; | ||
69 | pboardobjgrp->objmask = 0; | ||
70 | |||
71 | pboardobjgrp->classid = 0; | ||
72 | pboardobjgrp->pmu.unitid = BOARDOBJGRP_UNIT_ID_INVALID; | ||
73 | pboardobjgrp->pmu.classid = BOARDOBJGRP_GRP_CLASS_ID_INVALID; | ||
74 | pboardobjgrp->pmu.bset = false; | ||
75 | pboardobjgrp->pmu.rpc_func_id = BOARDOBJGRP_GRP_RPC_FUNC_ID_INVALID; | ||
76 | pboardobjgrp->pmu.set.id = BOARDOBJGRP_GRP_CMD_ID_INVALID; | ||
77 | pboardobjgrp->pmu.getstatus.id = BOARDOBJGRP_GRP_CMD_ID_INVALID; | ||
78 | |||
79 | /* Initialize basic interfaces */ | ||
80 | pboardobjgrp->destruct = boardobjgrp_destruct_super; | ||
81 | pboardobjgrp->objinsert = boardobjgrp_objinsert_final; | ||
82 | pboardobjgrp->objgetbyidx = boardobjgrp_objgetbyidx_final; | ||
83 | pboardobjgrp->objgetnext = boardobjgrp_objgetnext_final; | ||
84 | pboardobjgrp->objremoveanddestroy = | ||
85 | boardobjgrp_objremoveanddestroy_final; | ||
86 | |||
87 | pboardobjgrp->pmuinithandle = boardobjgrp_pmuinithandle_impl; | ||
88 | pboardobjgrp->pmuhdrdatainit = boardobjgrp_pmuhdrdatainit_super; | ||
89 | pboardobjgrp->pmudatainit = boardobjgrp_pmudatainit_super; | ||
90 | pboardobjgrp->pmuset = | ||
91 | g->ops.pmu_ver.boardobj.boardobjgrp_pmuset_impl; | ||
92 | pboardobjgrp->pmugetstatus = | ||
93 | g->ops.pmu_ver.boardobj.boardobjgrp_pmugetstatus_impl; | ||
94 | |||
95 | pboardobjgrp->pmudatainstget = boardobjgrp_pmudatainstget_stub; | ||
96 | pboardobjgrp->pmustatusinstget = boardobjgrp_pmustatusinstget_stub; | ||
97 | |||
98 | pboardobjgrp->objmaxidx = CTRL_BOARDOBJ_IDX_INVALID; | ||
99 | pboardobjgrp->bconstructed = true; | ||
100 | |||
101 | nvgpu_list_add(&pboardobjgrp->node, &g->boardobjgrp_head); | ||
102 | |||
103 | return 0; | ||
104 | } | ||
105 | |||
106 | int boardobjgrp_destruct_impl(struct boardobjgrp *pboardobjgrp) | ||
107 | { | ||
108 | struct gk20a *g = pboardobjgrp->g; | ||
109 | |||
110 | nvgpu_log_info(g, " "); | ||
111 | |||
112 | if (pboardobjgrp == NULL) { | ||
113 | return -EINVAL; | ||
114 | } | ||
115 | |||
116 | if (!pboardobjgrp->bconstructed) { | ||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | return pboardobjgrp->destruct(pboardobjgrp); | ||
121 | } | ||
122 | |||
123 | int boardobjgrp_destruct_super(struct boardobjgrp *pboardobjgrp) | ||
124 | { | ||
125 | struct boardobj *pboardobj; | ||
126 | struct gk20a *g = pboardobjgrp->g; | ||
127 | int status = 0; | ||
128 | int stat; | ||
129 | u8 index; | ||
130 | |||
131 | nvgpu_log_info(g, " "); | ||
132 | |||
133 | if (pboardobjgrp->mask == NULL) { | ||
134 | return -EINVAL; | ||
135 | } | ||
136 | if (pboardobjgrp->ppobjects == NULL) { | ||
137 | return -EINVAL; | ||
138 | } | ||
139 | |||
140 | BOARDOBJGRP_FOR_EACH(pboardobjgrp, struct boardobj*, pboardobj, index) { | ||
141 | stat = pboardobjgrp->objremoveanddestroy(pboardobjgrp, index); | ||
142 | if (status == 0) { | ||
143 | status = stat; | ||
144 | } | ||
145 | |||
146 | pboardobjgrp->ppobjects[index] = NULL; | ||
147 | pboardobjgrp->objmask &= ~BIT(index); | ||
148 | } | ||
149 | |||
150 | pboardobjgrp->objmask = 0; | ||
151 | |||
152 | if (pboardobjgrp->objmaxidx != CTRL_BOARDOBJ_IDX_INVALID) { | ||
153 | if (status == 0) { | ||
154 | status = -EINVAL; | ||
155 | } | ||
156 | |||
157 | WARN_ON(true); | ||
158 | } | ||
159 | |||
160 | /* Destroy the PMU CMD data */ | ||
161 | stat = boardobjgrp_pmucmd_destroy_impl(g, &pboardobjgrp->pmu.set); | ||
162 | if (status == 0) { | ||
163 | status = stat; | ||
164 | } | ||
165 | |||
166 | stat = boardobjgrp_pmucmd_destroy_impl(g, &pboardobjgrp->pmu.getstatus); | ||
167 | if (status == 0) { | ||
168 | status = stat; | ||
169 | } | ||
170 | |||
171 | nvgpu_list_del(&pboardobjgrp->node); | ||
172 | |||
173 | pboardobjgrp->bconstructed = false; | ||
174 | |||
175 | return status; | ||
176 | } | ||
177 | |||
178 | int boardobjgrp_pmucmd_construct_impl(struct gk20a *g, struct boardobjgrp | ||
179 | *pboardobjgrp, struct boardobjgrp_pmu_cmd *cmd, u8 id, u8 msgid, | ||
180 | u16 hdrsize, u16 entrysize, u16 fbsize, u32 ss_offset, u8 rpc_func_id) | ||
181 | { | ||
182 | nvgpu_log_info(g, " "); | ||
183 | |||
184 | /* Copy the parameters into the CMD*/ | ||
185 | cmd->id = id; | ||
186 | cmd->msgid = msgid; | ||
187 | cmd->hdrsize = (u8) hdrsize; | ||
188 | cmd->entrysize = (u8) entrysize; | ||
189 | cmd->fbsize = fbsize; | ||
190 | |||
191 | return 0; | ||
192 | } | ||
193 | |||
194 | int boardobjgrp_pmucmd_construct_impl_v1(struct gk20a *g, struct boardobjgrp | ||
195 | *pboardobjgrp, struct boardobjgrp_pmu_cmd *cmd, u8 id, u8 msgid, | ||
196 | u16 hdrsize, u16 entrysize, u16 fbsize, u32 ss_offset, u8 rpc_func_id) | ||
197 | { | ||
198 | nvgpu_log_fn(g, " "); | ||
199 | |||
200 | /* Copy the parameters into the CMD*/ | ||
201 | cmd->dmem_buffer_size = ((hdrsize > entrysize) ? hdrsize : entrysize); | ||
202 | cmd->super_surface_offset = ss_offset; | ||
203 | pboardobjgrp->pmu.rpc_func_id = rpc_func_id; | ||
204 | cmd->fbsize = fbsize; | ||
205 | |||
206 | nvgpu_log_fn(g, "DONE"); | ||
207 | return 0; | ||
208 | } | ||
209 | |||
210 | int boardobjgrp_pmucmd_destroy_impl(struct gk20a *g, | ||
211 | struct boardobjgrp_pmu_cmd *cmd) | ||
212 | { | ||
213 | struct nvgpu_mem *mem = &cmd->surf.sysmem_desc; | ||
214 | |||
215 | nvgpu_pmu_surface_free(g, mem); | ||
216 | return 0; | ||
217 | } | ||
218 | |||
219 | int is_boardobjgrp_pmucmd_id_valid_v0(struct gk20a *g, | ||
220 | struct boardobjgrp *pboardobjgrp, | ||
221 | struct boardobjgrp_pmu_cmd *pcmd) | ||
222 | { | ||
223 | int err = 0; | ||
224 | |||
225 | if (pcmd->id == BOARDOBJGRP_GRP_CMD_ID_INVALID) { | ||
226 | err = -EINVAL; | ||
227 | } | ||
228 | |||
229 | return err; | ||
230 | } | ||
231 | |||
232 | int is_boardobjgrp_pmucmd_id_valid_v1(struct gk20a *g, | ||
233 | struct boardobjgrp *pboardobjgrp, | ||
234 | struct boardobjgrp_pmu_cmd *cmd) | ||
235 | { | ||
236 | int err = 0; | ||
237 | |||
238 | if (pboardobjgrp->pmu.rpc_func_id == | ||
239 | BOARDOBJGRP_GRP_RPC_FUNC_ID_INVALID) { | ||
240 | err = -EINVAL; | ||
241 | } | ||
242 | |||
243 | return err; | ||
244 | } | ||
245 | |||
246 | int boardobjgrp_pmucmd_pmuinithandle_impl(struct gk20a *g, | ||
247 | struct boardobjgrp *pboardobjgrp, | ||
248 | struct boardobjgrp_pmu_cmd *pcmd) | ||
249 | { | ||
250 | int status = 0; | ||
251 | struct nvgpu_mem *sysmem_desc = &pcmd->surf.sysmem_desc; | ||
252 | |||
253 | nvgpu_log_info(g, " "); | ||
254 | |||
255 | if (g->ops.pmu_ver.boardobj.is_boardobjgrp_pmucmd_id_valid(g, | ||
256 | pboardobjgrp, pcmd)) { | ||
257 | goto boardobjgrp_pmucmd_pmuinithandle_exit; | ||
258 | } | ||
259 | |||
260 | if (!pcmd->fbsize) { | ||
261 | goto boardobjgrp_pmucmd_pmuinithandle_exit; | ||
262 | } | ||
263 | |||
264 | nvgpu_pmu_sysmem_surface_alloc(g, sysmem_desc, pcmd->fbsize); | ||
265 | /* we only have got sysmem later this will get copied to vidmem | ||
266 | surface*/ | ||
267 | pcmd->surf.vidmem_desc.size = 0; | ||
268 | |||
269 | pcmd->buf = (struct nv_pmu_boardobjgrp_super *)sysmem_desc->cpu_va; | ||
270 | |||
271 | boardobjgrp_pmucmd_pmuinithandle_exit: | ||
272 | return status; | ||
273 | } | ||
274 | |||
275 | int boardobjgrp_pmuinithandle_impl(struct gk20a *g, | ||
276 | struct boardobjgrp *pboardobjgrp) | ||
277 | { | ||
278 | int status = 0; | ||
279 | |||
280 | nvgpu_log_info(g, " "); | ||
281 | |||
282 | status = boardobjgrp_pmucmd_pmuinithandle_impl(g, pboardobjgrp, | ||
283 | &pboardobjgrp->pmu.set); | ||
284 | if (status) { | ||
285 | nvgpu_err(g, "failed to init pmu set cmd"); | ||
286 | goto boardobjgrp_pmuinithandle_exit; | ||
287 | } | ||
288 | |||
289 | status = boardobjgrp_pmucmd_pmuinithandle_impl(g, pboardobjgrp, | ||
290 | &pboardobjgrp->pmu.getstatus); | ||
291 | if (status) { | ||
292 | nvgpu_err(g, "failed to init get status command"); | ||
293 | goto boardobjgrp_pmuinithandle_exit; | ||
294 | } | ||
295 | |||
296 | /* If the GRP_SET CMD has not been allocated, nothing left to do. */ | ||
297 | if ((g->ops.pmu_ver.boardobj.is_boardobjgrp_pmucmd_id_valid(g, | ||
298 | pboardobjgrp, &pboardobjgrp->pmu.set))|| | ||
299 | (BOARDOBJGRP_IS_EMPTY(pboardobjgrp))) { | ||
300 | goto boardobjgrp_pmuinithandle_exit; | ||
301 | } | ||
302 | |||
303 | /* Send the BOARDOBJGRP to the pmu via RM_PMU_BOARDOBJ_CMD_GRP. */ | ||
304 | status = pboardobjgrp->pmuset(g, pboardobjgrp); | ||
305 | if (status) { | ||
306 | nvgpu_err(g, "failed to send boardobg grp to PMU"); | ||
307 | } | ||
308 | |||
309 | boardobjgrp_pmuinithandle_exit: | ||
310 | return status; | ||
311 | } | ||
312 | |||
313 | |||
314 | int boardobjgrp_pmuhdrdatainit_super(struct gk20a *g, struct boardobjgrp | ||
315 | *pboardobjgrp, struct nv_pmu_boardobjgrp_super *pboardobjgrppmu, | ||
316 | struct boardobjgrpmask *mask) | ||
317 | { | ||
318 | nvgpu_log_info(g, " "); | ||
319 | |||
320 | if (pboardobjgrp == NULL) { | ||
321 | return -EINVAL; | ||
322 | } | ||
323 | if (pboardobjgrppmu == NULL) { | ||
324 | return -EINVAL; | ||
325 | } | ||
326 | pboardobjgrppmu->type = pboardobjgrp->type; | ||
327 | pboardobjgrppmu->class_id = pboardobjgrp->classid; | ||
328 | pboardobjgrppmu->obj_slots = BOARDOBJGRP_PMU_SLOTS_GET(pboardobjgrp); | ||
329 | pboardobjgrppmu->flags = 0; | ||
330 | |||
331 | nvgpu_log_info(g, " Done"); | ||
332 | return 0; | ||
333 | } | ||
334 | |||
335 | static int boardobjgrp_pmudatainstget_stub(struct gk20a *g, | ||
336 | struct nv_pmu_boardobjgrp *boardobjgrppmu, | ||
337 | struct nv_pmu_boardobj **ppboardobjpmudata, u8 idx) | ||
338 | { | ||
339 | nvgpu_log_info(g, " "); | ||
340 | return -EINVAL; | ||
341 | } | ||
342 | |||
343 | |||
344 | static int boardobjgrp_pmustatusinstget_stub(struct gk20a *g, | ||
345 | void *pboardobjgrppmu, | ||
346 | struct nv_pmu_boardobj_query **ppBoardobjpmustatus, u8 idx) | ||
347 | { | ||
348 | nvgpu_log_info(g, " "); | ||
349 | return -EINVAL; | ||
350 | } | ||
351 | |||
352 | int boardobjgrp_pmudatainit_legacy(struct gk20a *g, | ||
353 | struct boardobjgrp *pboardobjgrp, | ||
354 | struct nv_pmu_boardobjgrp_super *pboardobjgrppmu) | ||
355 | { | ||
356 | int status = 0; | ||
357 | struct boardobj *pboardobj = NULL; | ||
358 | struct nv_pmu_boardobj *ppmudata = NULL; | ||
359 | u8 index; | ||
360 | |||
361 | nvgpu_log_info(g, " "); | ||
362 | |||
363 | if (pboardobjgrp == NULL) { | ||
364 | return -EINVAL; | ||
365 | } | ||
366 | if (pboardobjgrppmu == NULL) { | ||
367 | return -EINVAL; | ||
368 | } | ||
369 | |||
370 | boardobjgrpe32hdrset((struct nv_pmu_boardobjgrp *)pboardobjgrppmu, | ||
371 | pboardobjgrp->objmask); | ||
372 | |||
373 | BOARDOBJGRP_FOR_EACH_INDEX_IN_MASK(32, index, pboardobjgrp->objmask) { | ||
374 | /* Obtain pointer to the current instance of the Object from the Group */ | ||
375 | pboardobj = pboardobjgrp->objgetbyidx(pboardobjgrp, index); | ||
376 | if (NULL == pboardobj) { | ||
377 | nvgpu_err(g, "could not get object instance"); | ||
378 | status = -EINVAL; | ||
379 | goto boardobjgrppmudatainit_legacy_done; | ||
380 | } | ||
381 | |||
382 | status = pboardobjgrp->pmudatainstget(g, | ||
383 | (struct nv_pmu_boardobjgrp *)pboardobjgrppmu, | ||
384 | &ppmudata, index); | ||
385 | if (status) { | ||
386 | nvgpu_err(g, "could not get object instance"); | ||
387 | goto boardobjgrppmudatainit_legacy_done; | ||
388 | } | ||
389 | |||
390 | /* Initialize the PMU Data */ | ||
391 | status = pboardobj->pmudatainit(g, pboardobj, ppmudata); | ||
392 | if (status) { | ||
393 | nvgpu_err(g, | ||
394 | "could not parse pmu for device %d", index); | ||
395 | goto boardobjgrppmudatainit_legacy_done; | ||
396 | } | ||
397 | } | ||
398 | BOARDOBJGRP_FOR_EACH_INDEX_IN_MASK_END | ||
399 | |||
400 | boardobjgrppmudatainit_legacy_done: | ||
401 | nvgpu_log_info(g, " Done"); | ||
402 | return status; | ||
403 | } | ||
404 | |||
405 | int boardobjgrp_pmudatainit_super(struct gk20a *g, struct boardobjgrp | ||
406 | *pboardobjgrp, struct nv_pmu_boardobjgrp_super *pboardobjgrppmu) | ||
407 | { | ||
408 | int status = 0; | ||
409 | struct boardobj *pboardobj = NULL; | ||
410 | struct nv_pmu_boardobj *ppmudata = NULL; | ||
411 | u8 index; | ||
412 | |||
413 | nvgpu_log_info(g, " "); | ||
414 | |||
415 | if (pboardobjgrp == NULL) { | ||
416 | return -EINVAL; | ||
417 | } | ||
418 | if (pboardobjgrppmu == NULL) { | ||
419 | return -EINVAL; | ||
420 | } | ||
421 | |||
422 | /* Initialize the PMU HDR data.*/ | ||
423 | status = pboardobjgrp->pmuhdrdatainit(g, pboardobjgrp, pboardobjgrppmu, | ||
424 | pboardobjgrp->mask); | ||
425 | if (status) { | ||
426 | nvgpu_err(g, "unable to init boardobjgrp pmuhdr data"); | ||
427 | goto boardobjgrppmudatainit_super_done; | ||
428 | } | ||
429 | |||
430 | BOARDOBJGRP_FOR_EACH(pboardobjgrp, struct boardobj*, pboardobj, index) { | ||
431 | status = pboardobjgrp->pmudatainstget(g, | ||
432 | (struct nv_pmu_boardobjgrp *)pboardobjgrppmu, | ||
433 | &ppmudata, index); | ||
434 | if (status) { | ||
435 | nvgpu_err(g, "could not get object instance"); | ||
436 | goto boardobjgrppmudatainit_super_done; | ||
437 | } | ||
438 | |||
439 | /* Initialize the PMU Data and send to PMU */ | ||
440 | status = pboardobj->pmudatainit(g, pboardobj, ppmudata); | ||
441 | if (status) { | ||
442 | nvgpu_err(g, | ||
443 | "could not parse pmu for device %d", index); | ||
444 | goto boardobjgrppmudatainit_super_done; | ||
445 | } | ||
446 | } | ||
447 | |||
448 | boardobjgrppmudatainit_super_done: | ||
449 | nvgpu_log_info(g, " Done"); | ||
450 | return status; | ||
451 | } | ||
452 | |||
453 | static int check_boardobjgrp_param(struct gk20a *g, | ||
454 | struct boardobjgrp *pboardobjgrp) | ||
455 | { | ||
456 | if (pboardobjgrp == NULL) { | ||
457 | return -EINVAL; | ||
458 | } | ||
459 | |||
460 | if (!pboardobjgrp->bconstructed) { | ||
461 | return -EINVAL; | ||
462 | } | ||
463 | |||
464 | if (pboardobjgrp->pmu.unitid == BOARDOBJGRP_UNIT_ID_INVALID) { | ||
465 | return -EINVAL; | ||
466 | } | ||
467 | |||
468 | if (pboardobjgrp->pmu.classid == BOARDOBJGRP_GRP_CLASS_ID_INVALID) { | ||
469 | return -EINVAL; | ||
470 | } | ||
471 | |||
472 | /* If no objects in the group, return early */ | ||
473 | if (BOARDOBJGRP_IS_EMPTY(pboardobjgrp)) { | ||
474 | return -EINVAL; | ||
475 | } | ||
476 | |||
477 | return 0; | ||
478 | } | ||
479 | |||
480 | int boardobjgrp_pmuset_impl(struct gk20a *g, struct boardobjgrp *pboardobjgrp) | ||
481 | { | ||
482 | int status = 0; | ||
483 | struct boardobjgrp_pmu_cmd *pcmd = | ||
484 | (struct boardobjgrp_pmu_cmd *)(&pboardobjgrp->pmu.set); | ||
485 | |||
486 | nvgpu_log_info(g, " "); | ||
487 | |||
488 | if (check_boardobjgrp_param(g, pboardobjgrp)) { | ||
489 | return -EINVAL; | ||
490 | } | ||
491 | |||
492 | if (pboardobjgrp->pmu.set.id == BOARDOBJGRP_GRP_CMD_ID_INVALID) { | ||
493 | return -EINVAL; | ||
494 | } | ||
495 | |||
496 | if ((pcmd->hdrsize == 0) || | ||
497 | (pcmd->entrysize == 0) || | ||
498 | (pcmd->buf == NULL)) { | ||
499 | return -EINVAL; | ||
500 | } | ||
501 | |||
502 | /* Initialize PMU buffer with BOARDOBJGRP data. */ | ||
503 | memset(pcmd->buf, 0x0, pcmd->fbsize); | ||
504 | status = pboardobjgrp->pmudatainit(g, pboardobjgrp, | ||
505 | pcmd->buf); | ||
506 | if (status) { | ||
507 | nvgpu_err(g, "could not parse pmu data"); | ||
508 | goto boardobjgrp_pmuset_exit; | ||
509 | } | ||
510 | |||
511 | /* | ||
512 | * Reset the boolean that indicates set status for most recent | ||
513 | * instance of BOARDOBJGRP. | ||
514 | */ | ||
515 | pboardobjgrp->pmu.bset = false; | ||
516 | |||
517 | /* | ||
518 | * alloc mem in vidmem & copy constructed pmu boardobjgrp data from | ||
519 | * sysmem to vidmem | ||
520 | */ | ||
521 | if (pcmd->surf.vidmem_desc.size == 0) { | ||
522 | nvgpu_pmu_vidmem_surface_alloc(g, &pcmd->surf.vidmem_desc, | ||
523 | pcmd->fbsize); | ||
524 | } | ||
525 | nvgpu_mem_wr_n(g, &pcmd->surf.vidmem_desc, 0, pcmd->buf, pcmd->fbsize); | ||
526 | |||
527 | /* Send the SET PMU CMD to the PMU */ | ||
528 | status = boardobjgrp_pmucmdsend(g, pboardobjgrp, | ||
529 | pcmd); | ||
530 | if (status) { | ||
531 | nvgpu_err(g, "could not send SET CMD to PMU"); | ||
532 | goto boardobjgrp_pmuset_exit; | ||
533 | } | ||
534 | |||
535 | pboardobjgrp->pmu.bset = true; | ||
536 | |||
537 | boardobjgrp_pmuset_exit: | ||
538 | return status; | ||
539 | } | ||
540 | |||
541 | int boardobjgrp_pmuset_impl_v1(struct gk20a *g, | ||
542 | struct boardobjgrp *pboardobjgrp) | ||
543 | { | ||
544 | struct nvgpu_pmu *pmu = &g->pmu; | ||
545 | int status = 0; | ||
546 | struct boardobjgrp_pmu_cmd *pcmd = | ||
547 | (struct boardobjgrp_pmu_cmd *)(&pboardobjgrp->pmu.set); | ||
548 | |||
549 | nvgpu_log_info(g, " "); | ||
550 | |||
551 | if (check_boardobjgrp_param(g, pboardobjgrp)) { | ||
552 | return -EINVAL; | ||
553 | } | ||
554 | |||
555 | if ((pcmd->buf == NULL) && | ||
556 | (pboardobjgrp->pmu.rpc_func_id == | ||
557 | BOARDOBJGRP_GRP_RPC_FUNC_ID_INVALID)) { | ||
558 | return -EINVAL; | ||
559 | } | ||
560 | |||
561 | /* Initialize PMU buffer with BOARDOBJGRP data. */ | ||
562 | memset(pcmd->buf, 0x0, pcmd->fbsize); | ||
563 | status = pboardobjgrp->pmudatainit(g, pboardobjgrp, | ||
564 | pcmd->buf); | ||
565 | if (status) { | ||
566 | nvgpu_err(g, "could not parse pmu data"); | ||
567 | goto boardobjgrp_pmuset_exit; | ||
568 | } | ||
569 | |||
570 | /* | ||
571 | * Reset the boolean that indicates set status | ||
572 | * for most recent instance of BOARDOBJGRP. | ||
573 | */ | ||
574 | pboardobjgrp->pmu.bset = false; | ||
575 | |||
576 | /* | ||
577 | * copy constructed pmu boardobjgrp data from | ||
578 | * sysmem to pmu super surface present in FB | ||
579 | */ | ||
580 | nvgpu_mem_wr_n(g, &pmu->super_surface_buf, | ||
581 | pcmd->super_surface_offset, pcmd->buf, | ||
582 | pcmd->fbsize); | ||
583 | |||
584 | /* Send the SET PMU CMD to the PMU using RPC*/ | ||
585 | status = boardobjgrp_pmucmdsend_rpc(g, pboardobjgrp, | ||
586 | pcmd, false); | ||
587 | if (status) { | ||
588 | nvgpu_err(g, "could not send SET CMD to PMU"); | ||
589 | goto boardobjgrp_pmuset_exit; | ||
590 | } | ||
591 | |||
592 | pboardobjgrp->pmu.bset = true; | ||
593 | |||
594 | boardobjgrp_pmuset_exit: | ||
595 | return status; | ||
596 | } | ||
597 | |||
598 | int | ||
599 | boardobjgrp_pmugetstatus_impl(struct gk20a *g, struct boardobjgrp *pboardobjgrp, | ||
600 | struct boardobjgrpmask *mask) | ||
601 | { | ||
602 | int status = 0; | ||
603 | struct boardobjgrp_pmu_cmd *pcmd = | ||
604 | (struct boardobjgrp_pmu_cmd *)(&pboardobjgrp->pmu.getstatus); | ||
605 | struct boardobjgrp_pmu_cmd *pset = | ||
606 | (struct boardobjgrp_pmu_cmd *)(&pboardobjgrp->pmu.set); | ||
607 | |||
608 | nvgpu_log_info(g, " "); | ||
609 | |||
610 | if (check_boardobjgrp_param(g, pboardobjgrp)) { | ||
611 | return -EINVAL; | ||
612 | } | ||
613 | |||
614 | if (pset->id == BOARDOBJGRP_GRP_CMD_ID_INVALID) { | ||
615 | return -EINVAL; | ||
616 | } | ||
617 | |||
618 | if ((pcmd->hdrsize == 0) || | ||
619 | (pcmd->entrysize == 0) || | ||
620 | (pcmd->buf == NULL)) { | ||
621 | return -EINVAL; | ||
622 | } | ||
623 | |||
624 | /* | ||
625 | * Can only GET_STATUS if the BOARDOBJGRP has been previously SET to the | ||
626 | * PMU | ||
627 | */ | ||
628 | if (!pboardobjgrp->pmu.bset) { | ||
629 | return -EINVAL; | ||
630 | } | ||
631 | |||
632 | /* | ||
633 | * alloc mem in vidmem & copy constructed pmu boardobjgrp data from | ||
634 | * sysmem to vidmem | ||
635 | */ | ||
636 | if (pcmd->surf.vidmem_desc.size == 0) { | ||
637 | nvgpu_pmu_vidmem_surface_alloc(g, &pcmd->surf.vidmem_desc, | ||
638 | pcmd->fbsize); | ||
639 | } | ||
640 | |||
641 | /* | ||
642 | * Initialize PMU buffer with the mask of BOARDOBJGRPs for which to | ||
643 | * retrieve status | ||
644 | */ | ||
645 | |||
646 | memset(pcmd->buf, 0x0, pcmd->fbsize); | ||
647 | status = pboardobjgrp->pmuhdrdatainit(g, pboardobjgrp, | ||
648 | pcmd->buf, mask); | ||
649 | if (status) { | ||
650 | nvgpu_err(g, "could not init PMU HDR data"); | ||
651 | goto boardobjgrp_pmugetstatus_exit; | ||
652 | } | ||
653 | |||
654 | nvgpu_mem_wr_n(g, &pcmd->surf.vidmem_desc, 0, pset->buf, pset->hdrsize); | ||
655 | /* Send the GET_STATUS PMU CMD to the PMU */ | ||
656 | status = boardobjgrp_pmucmdsend(g, pboardobjgrp, | ||
657 | &pboardobjgrp->pmu.getstatus); | ||
658 | if (status) { | ||
659 | nvgpu_err(g, "could not send GET_STATUS cmd to PMU"); | ||
660 | goto boardobjgrp_pmugetstatus_exit; | ||
661 | } | ||
662 | |||
663 | /*copy the data back to sysmem buffer that belongs to command*/ | ||
664 | nvgpu_mem_rd_n(g, &pcmd->surf.vidmem_desc, 0, pcmd->buf, pcmd->fbsize); | ||
665 | |||
666 | boardobjgrp_pmugetstatus_exit: | ||
667 | return status; | ||
668 | } | ||
669 | |||
670 | int | ||
671 | boardobjgrp_pmugetstatus_impl_v1(struct gk20a *g, struct boardobjgrp *pboardobjgrp, | ||
672 | struct boardobjgrpmask *mask) | ||
673 | { | ||
674 | struct nvgpu_pmu *pmu = &g->pmu; | ||
675 | int status = 0; | ||
676 | struct boardobjgrp_pmu_cmd *pcmd = | ||
677 | (struct boardobjgrp_pmu_cmd *)(&pboardobjgrp->pmu.getstatus); | ||
678 | |||
679 | nvgpu_log_info(g, " "); | ||
680 | |||
681 | if (check_boardobjgrp_param(g, pboardobjgrp)) { | ||
682 | return -EINVAL; | ||
683 | } | ||
684 | |||
685 | if ((pcmd->buf == NULL) && | ||
686 | (pboardobjgrp->pmu.rpc_func_id == | ||
687 | BOARDOBJGRP_GRP_RPC_FUNC_ID_INVALID)) { | ||
688 | return -EINVAL; | ||
689 | } | ||
690 | |||
691 | /* | ||
692 | * Can only GET_STATUS if the BOARDOBJGRP has been | ||
693 | * previously SET to the PMU | ||
694 | */ | ||
695 | if (!pboardobjgrp->pmu.bset) { | ||
696 | return -EINVAL; | ||
697 | } | ||
698 | |||
699 | /* | ||
700 | * Initialize PMU buffer with the mask of | ||
701 | * BOARDOBJGRPs for which to retrieve status | ||
702 | */ | ||
703 | memset(pcmd->buf, 0x0, pcmd->fbsize); | ||
704 | status = pboardobjgrp->pmuhdrdatainit(g, pboardobjgrp, | ||
705 | pcmd->buf, mask); | ||
706 | if (status) { | ||
707 | nvgpu_err(g, "could not init PMU HDR data"); | ||
708 | goto boardobjgrp_pmugetstatus_exit; | ||
709 | } | ||
710 | |||
711 | /* | ||
712 | * copy constructed pmu boardobjgrp data from | ||
713 | * sysmem to pmu super surface present in FB | ||
714 | */ | ||
715 | nvgpu_mem_wr_n(g, &pmu->super_surface_buf, pcmd->super_surface_offset, | ||
716 | pcmd->buf, pcmd->fbsize); | ||
717 | /* Send the GET_STATUS PMU CMD to the PMU */ | ||
718 | status = boardobjgrp_pmucmdsend_rpc(g, pboardobjgrp, | ||
719 | pcmd, true); | ||
720 | if (status) { | ||
721 | nvgpu_err(g, "could not send GET_STATUS cmd to PMU"); | ||
722 | goto boardobjgrp_pmugetstatus_exit; | ||
723 | } | ||
724 | |||
725 | /*copy the data back to sysmem buffer that belongs to command*/ | ||
726 | nvgpu_mem_rd_n(g, &pmu->super_surface_buf,pcmd->super_surface_offset, | ||
727 | pcmd->buf, pcmd->fbsize); | ||
728 | |||
729 | boardobjgrp_pmugetstatus_exit: | ||
730 | return status; | ||
731 | } | ||
732 | |||
733 | static int | ||
734 | boardobjgrp_objinsert_final(struct boardobjgrp *pboardobjgrp, | ||
735 | struct boardobj *pboardobj, u8 index) | ||
736 | { | ||
737 | struct gk20a *g = pboardobjgrp->g; | ||
738 | |||
739 | nvgpu_log_info(g, " "); | ||
740 | |||
741 | if (pboardobjgrp == NULL) { | ||
742 | return -EINVAL; | ||
743 | } | ||
744 | |||
745 | if (pboardobj == NULL) { | ||
746 | return -EINVAL; | ||
747 | } | ||
748 | |||
749 | if (index > pboardobjgrp->objslots) { | ||
750 | return -EINVAL; | ||
751 | } | ||
752 | |||
753 | if (pboardobjgrp->ppobjects[index] != NULL) { | ||
754 | return -EINVAL; | ||
755 | } | ||
756 | |||
757 | /* | ||
758 | * Check that this BOARDOBJ has not already been added to a | ||
759 | * BOARDOBJGRP | ||
760 | */ | ||
761 | if (pboardobj->idx != CTRL_BOARDOBJ_IDX_INVALID) { | ||
762 | return -EINVAL; | ||
763 | } | ||
764 | |||
765 | pboardobjgrp->ppobjects[index] = pboardobj; | ||
766 | pboardobjgrp->objmaxidx = (u8)(BOARDOBJGRP_IS_EMPTY(pboardobjgrp) ? | ||
767 | index : max(pboardobjgrp->objmaxidx, index)); | ||
768 | pboardobj->idx = index; | ||
769 | |||
770 | pboardobjgrp->objmask |= BIT(index); | ||
771 | |||
772 | nvgpu_log_info(g, " Done"); | ||
773 | |||
774 | return boardobjgrpmask_bitset(pboardobjgrp->mask, index); | ||
775 | } | ||
776 | |||
777 | static struct boardobj *boardobjgrp_objgetbyidx_final( | ||
778 | struct boardobjgrp *pboardobjgrp, u8 index) | ||
779 | { | ||
780 | if (!boardobjgrp_idxisvalid(pboardobjgrp, index)) { | ||
781 | return NULL; | ||
782 | } | ||
783 | return pboardobjgrp->ppobjects[index]; | ||
784 | } | ||
785 | |||
786 | static struct boardobj *boardobjgrp_objgetnext_final( | ||
787 | struct boardobjgrp *pboardobjgrp, u8 *currentindex, | ||
788 | struct boardobjgrpmask *mask) | ||
789 | { | ||
790 | struct boardobj *pboardobjnext = NULL; | ||
791 | u8 objmaxidx; | ||
792 | u8 index; | ||
793 | |||
794 | if (currentindex == NULL) { | ||
795 | return NULL; | ||
796 | } | ||
797 | |||
798 | if (pboardobjgrp == NULL) { | ||
799 | return NULL; | ||
800 | } | ||
801 | |||
802 | /* Search from next element unless first object was requested */ | ||
803 | index = (*currentindex != CTRL_BOARDOBJ_IDX_INVALID) ? | ||
804 | (*currentindex + 1) : 0; | ||
805 | |||
806 | /* For the cases below in which we have to return NULL */ | ||
807 | *currentindex = CTRL_BOARDOBJ_IDX_INVALID; | ||
808 | |||
809 | |||
810 | /* Validate provided mask */ | ||
811 | if (mask != NULL) { | ||
812 | if (!(boardobjgrpmask_sizeeq(pboardobjgrp->mask, mask))) { | ||
813 | return NULL; | ||
814 | } | ||
815 | } | ||
816 | |||
817 | objmaxidx = pboardobjgrp->objmaxidx; | ||
818 | |||
819 | if (objmaxidx != CTRL_BOARDOBJ_IDX_INVALID) { | ||
820 | for (; index <= objmaxidx; index++) { | ||
821 | pboardobjnext = pboardobjgrp->ppobjects[index]; | ||
822 | if (pboardobjnext != NULL) { | ||
823 | /* Filter results using client provided mask.*/ | ||
824 | if (mask != NULL) { | ||
825 | if (!boardobjgrpmask_bitget(mask, | ||
826 | index)) { | ||
827 | pboardobjnext = NULL; | ||
828 | continue; | ||
829 | } | ||
830 | } | ||
831 | *currentindex = index; | ||
832 | break; | ||
833 | } | ||
834 | } | ||
835 | } | ||
836 | |||
837 | return pboardobjnext; | ||
838 | } | ||
839 | |||
840 | static int boardobjgrp_objremoveanddestroy_final( | ||
841 | struct boardobjgrp *pboardobjgrp, | ||
842 | u8 index) | ||
843 | { | ||
844 | int status = 0; | ||
845 | int stat; | ||
846 | struct gk20a *g = pboardobjgrp->g; | ||
847 | |||
848 | nvgpu_log_info(g, " "); | ||
849 | |||
850 | if (!boardobjgrp_idxisvalid(pboardobjgrp, index)) { | ||
851 | return -EINVAL; | ||
852 | } | ||
853 | |||
854 | if (pboardobjgrp->objmaxidx == CTRL_BOARDOBJ_IDX_INVALID) { | ||
855 | return -EINVAL; | ||
856 | } | ||
857 | |||
858 | status = pboardobjgrp->ppobjects[index]->destruct( | ||
859 | pboardobjgrp->ppobjects[index]); | ||
860 | |||
861 | pboardobjgrp->ppobjects[index] = NULL; | ||
862 | |||
863 | pboardobjgrp->objmask &= ~BIT(index); | ||
864 | |||
865 | stat = boardobjgrpmask_bitclr(pboardobjgrp->mask, index); | ||
866 | if (stat) { | ||
867 | if (status == 0) { | ||
868 | status = stat; | ||
869 | } | ||
870 | } | ||
871 | |||
872 | /* objmaxidx requires update only if that very object was removed */ | ||
873 | if (pboardobjgrp->objmaxidx == index) { | ||
874 | pboardobjgrp->objmaxidx = | ||
875 | boardobjgrpmask_bitidxhighest(pboardobjgrp->mask); | ||
876 | } | ||
877 | |||
878 | return status; | ||
879 | } | ||
880 | |||
881 | void boardobjgrpe32hdrset(struct nv_pmu_boardobjgrp *hdr, u32 objmask) | ||
882 | { | ||
883 | u32 slots = objmask; | ||
884 | |||
885 | HIGHESTBITIDX_32(slots); | ||
886 | slots++; | ||
887 | |||
888 | hdr->super.type = CTRL_BOARDOBJGRP_TYPE_E32; | ||
889 | hdr->super.class_id = 0; | ||
890 | hdr->super.obj_slots = (u8)slots; | ||
891 | hdr->obj_mask = objmask; | ||
892 | } | ||
893 | |||
894 | static void boardobjgrp_pmucmdhandler(struct gk20a *g, struct pmu_msg *msg, | ||
895 | void *param, u32 handle, u32 status) | ||
896 | { | ||
897 | struct nv_pmu_boardobj_msg_grp *pgrpmsg; | ||
898 | struct boardobjgrp_pmucmdhandler_params *phandlerparams = | ||
899 | (struct boardobjgrp_pmucmdhandler_params *)param; | ||
900 | struct boardobjgrp *pboardobjgrp = phandlerparams->pboardobjgrp; | ||
901 | struct boardobjgrp_pmu_cmd *pgrpcmd = phandlerparams->pcmd; | ||
902 | |||
903 | nvgpu_log_info(g, " "); | ||
904 | |||
905 | pgrpmsg = &msg->msg.boardobj.grp; | ||
906 | |||
907 | if (pgrpmsg->class_id != pboardobjgrp->pmu.classid) { | ||
908 | nvgpu_err(g, | ||
909 | "Unrecognized GRP type: unit %x class id=0x%02x cmd id %x", | ||
910 | msg->hdr.unit_id, pboardobjgrp->pmu.classid, | ||
911 | pgrpcmd->id); | ||
912 | return; | ||
913 | } | ||
914 | |||
915 | if (msg->msg.boardobj.msg_type != pgrpcmd->msgid) { | ||
916 | nvgpu_err(g, | ||
917 | "unsupported msg for unit %x class %x cmd id %x msg %x", | ||
918 | msg->hdr.unit_id, pboardobjgrp->pmu.classid, | ||
919 | pgrpcmd->id, msg->msg.boardobj.msg_type); | ||
920 | return; | ||
921 | } | ||
922 | |||
923 | if (msg->msg.boardobj.grp_set.flcn_status != 0) { | ||
924 | nvgpu_err(g, | ||
925 | "cmd abort for unit %x class %x cmd id %x status %x", | ||
926 | msg->hdr.unit_id, pboardobjgrp->pmu.classid, | ||
927 | pgrpcmd->id, | ||
928 | msg->msg.boardobj.grp_set.flcn_status); | ||
929 | return; | ||
930 | } | ||
931 | |||
932 | phandlerparams->success = pgrpmsg->b_success ? 1 : 0; | ||
933 | |||
934 | if (!pgrpmsg->b_success) { | ||
935 | nvgpu_err(g, | ||
936 | "failed GRPCMD: msgtype=0x%x, classid=0x%x, cmd id %x", | ||
937 | pgrpmsg->msg_type, pgrpmsg->class_id, | ||
938 | pgrpcmd->id); | ||
939 | return; | ||
940 | } | ||
941 | } | ||
942 | |||
943 | static int boardobjgrp_pmucmdsend(struct gk20a *g, | ||
944 | struct boardobjgrp *pboardobjgrp, | ||
945 | struct boardobjgrp_pmu_cmd *pcmd) | ||
946 | { | ||
947 | struct boardobjgrp_pmucmdhandler_params handlerparams; | ||
948 | struct pmu_payload payload; | ||
949 | struct nv_pmu_boardobj_cmd_grp *pgrpcmd; | ||
950 | struct pmu_cmd cmd; | ||
951 | u32 seqdesc; | ||
952 | int status = 0; | ||
953 | |||
954 | nvgpu_log_info(g, " "); | ||
955 | |||
956 | memset(&payload, 0, sizeof(payload)); | ||
957 | memset(&handlerparams, 0, sizeof(handlerparams)); | ||
958 | memset(&cmd, 0, sizeof(struct pmu_cmd)); | ||
959 | cmd.hdr.unit_id = pboardobjgrp->pmu.unitid; | ||
960 | cmd.hdr.size = sizeof(struct nv_pmu_boardobj_cmd_grp) + | ||
961 | sizeof(struct pmu_hdr); | ||
962 | |||
963 | pgrpcmd = &cmd.cmd.boardobj.grp; | ||
964 | pgrpcmd->cmd_type = pcmd->id; | ||
965 | pgrpcmd->class_id = pboardobjgrp->pmu.classid; | ||
966 | pgrpcmd->grp.hdr_size = pcmd->hdrsize; | ||
967 | pgrpcmd->grp.entry_size = pcmd->entrysize; | ||
968 | |||
969 | /* | ||
970 | * copy vidmem information to boardobj_cmd_grp | ||
971 | */ | ||
972 | nvgpu_pmu_surface_describe(g, &pcmd->surf.vidmem_desc, | ||
973 | &pgrpcmd->grp.fb); | ||
974 | |||
975 | /* | ||
976 | * PMU reads command from sysmem so assigned | ||
977 | * "payload.in.buf = pcmd->buf" | ||
978 | * but PMU access pmu boardobjgrp data from vidmem copied above | ||
979 | */ | ||
980 | payload.in.buf = pcmd->buf; | ||
981 | payload.in.size = max(pcmd->hdrsize, pcmd->entrysize); | ||
982 | payload.in.fb_size = PMU_CMD_SUBMIT_PAYLOAD_PARAMS_FB_SIZE_UNUSED; | ||
983 | payload.in.offset = offsetof(struct nv_pmu_boardobj_cmd_grp, grp); | ||
984 | |||
985 | /* Setup the handler params to communicate back results.*/ | ||
986 | handlerparams.pboardobjgrp = pboardobjgrp; | ||
987 | handlerparams.pcmd = pcmd; | ||
988 | handlerparams.success = 0; | ||
989 | |||
990 | status = nvgpu_pmu_cmd_post(g, &cmd, NULL, &payload, | ||
991 | PMU_COMMAND_QUEUE_LPQ, | ||
992 | boardobjgrp_pmucmdhandler, | ||
993 | (void *)&handlerparams, | ||
994 | &seqdesc, ~0); | ||
995 | if (status) { | ||
996 | nvgpu_err(g, | ||
997 | "unable to post boardobj grp cmd for unit %x cmd id %x", | ||
998 | cmd.hdr.unit_id, pcmd->id); | ||
999 | goto boardobjgrp_pmucmdsend_exit; | ||
1000 | } | ||
1001 | pmu_wait_message_cond(&g->pmu, | ||
1002 | gk20a_get_gr_idle_timeout(g), | ||
1003 | &handlerparams.success, 1); | ||
1004 | if (handlerparams.success == 0) { | ||
1005 | nvgpu_err(g, "could not process cmd"); | ||
1006 | status = -ETIMEDOUT; | ||
1007 | goto boardobjgrp_pmucmdsend_exit; | ||
1008 | } | ||
1009 | |||
1010 | boardobjgrp_pmucmdsend_exit: | ||
1011 | return status; | ||
1012 | } | ||
1013 | |||
1014 | static int boardobjgrp_pmucmdsend_rpc(struct gk20a *g, | ||
1015 | struct boardobjgrp *pboardobjgrp, | ||
1016 | struct boardobjgrp_pmu_cmd *pcmd, | ||
1017 | bool copy_out) | ||
1018 | { | ||
1019 | struct nvgpu_pmu *pmu = &g->pmu; | ||
1020 | struct nv_pmu_rpc_struct_board_obj_grp_cmd rpc; | ||
1021 | int status = 0; | ||
1022 | |||
1023 | nvgpu_log_fn(g, " "); | ||
1024 | |||
1025 | memset(&rpc, 0, sizeof(struct nv_pmu_rpc_struct_board_obj_grp_cmd)); | ||
1026 | |||
1027 | rpc.class_id = pboardobjgrp->pmu.classid; | ||
1028 | rpc.command_id = copy_out ? | ||
1029 | NV_PMU_BOARDOBJGRP_CMD_GET_STATUS : | ||
1030 | NV_PMU_BOARDOBJGRP_CMD_SET; | ||
1031 | |||
1032 | rpc.hdr.unit_id = pboardobjgrp->pmu.unitid; | ||
1033 | rpc.hdr.function = pboardobjgrp->pmu.rpc_func_id; | ||
1034 | rpc.hdr.flags = 0x0; | ||
1035 | |||
1036 | status = nvgpu_pmu_rpc_execute(pmu, &(rpc.hdr), | ||
1037 | (sizeof(rpc) - sizeof(rpc.scratch)), | ||
1038 | pcmd->dmem_buffer_size, | ||
1039 | NULL, NULL, copy_out); | ||
1040 | |||
1041 | if (status) { | ||
1042 | nvgpu_err(g, "Failed to execute RPC, status=0x%x", status); | ||
1043 | } | ||
1044 | |||
1045 | return status; | ||
1046 | } | ||