aboutsummaryrefslogtreecommitdiffstats
path: root/include/pmu_perf/vfe_var.c
diff options
context:
space:
mode:
authorJoshua Bakita <bakitajoshua@gmail.com>2024-09-25 16:09:09 -0400
committerJoshua Bakita <bakitajoshua@gmail.com>2024-09-25 16:09:09 -0400
commitf347fde22f1297e4f022600d201780d5ead78114 (patch)
tree76be305d6187003a1e0486ff6e91efb1062ae118 /include/pmu_perf/vfe_var.c
parent8340d234d78a7d0f46c11a584de538148b78b7cb (diff)
Delete no-longer-needed nvgpu headersHEADmasterjbakita-wip
The dependency on these was removed in commit 8340d234.
Diffstat (limited to 'include/pmu_perf/vfe_var.c')
-rw-r--r--include/pmu_perf/vfe_var.c1091
1 files changed, 0 insertions, 1091 deletions
diff --git a/include/pmu_perf/vfe_var.c b/include/pmu_perf/vfe_var.c
deleted file mode 100644
index a94c2d9..0000000
--- a/include/pmu_perf/vfe_var.c
+++ /dev/null
@@ -1,1091 +0,0 @@
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
23#include <nvgpu/bios.h>
24#include <nvgpu/gk20a.h>
25
26#include "pmu_perf.h"
27#include "vfe_var.h"
28#include "boardobj/boardobjgrp.h"
29#include "boardobj/boardobjgrp_e32.h"
30#include "ctrl/ctrlclk.h"
31#include "ctrl/ctrlvolt.h"
32#include "ctrl/ctrlperf.h"
33
34static int devinit_get_vfe_var_table(struct gk20a *g,
35 struct vfe_vars *pvarobjs);
36static int vfe_var_construct_single(struct gk20a *g,
37 struct boardobj **ppboardobj,
38 u16 size, void *pargs);
39
40static int _vfe_vars_pmudatainit(struct gk20a *g,
41 struct boardobjgrp *pboardobjgrp,
42 struct nv_pmu_boardobjgrp_super *pboardobjgrppmu)
43{
44 struct nv_pmu_perf_vfe_var_boardobjgrp_set_header *pset =
45 (struct nv_pmu_perf_vfe_var_boardobjgrp_set_header *)
46 pboardobjgrppmu;
47 struct vfe_vars *pvars = (struct vfe_vars *)pboardobjgrp;
48 int status = 0;
49
50 status = boardobjgrp_pmudatainit_e32(g, pboardobjgrp, pboardobjgrppmu);
51 if (status) {
52 nvgpu_err(g,
53 "error updating pmu boardobjgrp for vfe var 0x%x",
54 status);
55 goto done;
56 }
57 pset->polling_periodms = pvars->polling_periodms;
58
59done:
60 return status;
61}
62
63static int _vfe_vars_pmudata_instget(struct gk20a *g,
64 struct nv_pmu_boardobjgrp *pmuboardobjgrp,
65 struct nv_pmu_boardobj **ppboardobjpmudata,
66 u8 idx)
67{
68 struct nv_pmu_perf_vfe_var_boardobj_grp_set *pgrp_set =
69 (struct nv_pmu_perf_vfe_var_boardobj_grp_set *)
70 pmuboardobjgrp;
71
72 nvgpu_log_info(g, " ");
73
74 /*check whether pmuboardobjgrp has a valid boardobj in index*/
75 if (idx >= CTRL_BOARDOBJGRP_E32_MAX_OBJECTS) {
76 return -EINVAL;
77 }
78
79 *ppboardobjpmudata = (struct nv_pmu_boardobj *)
80 &pgrp_set->objects[idx].data.board_obj;
81
82 nvgpu_log_info(g, " Done");
83 return 0;
84}
85
86static int _vfe_vars_pmustatus_instget(struct gk20a *g, void *pboardobjgrppmu,
87 struct nv_pmu_boardobj_query **ppboardobjpmustatus, u8 idx)
88{
89 struct nv_pmu_perf_vfe_var_boardobj_grp_get_status *pgrp_get_status =
90 (struct nv_pmu_perf_vfe_var_boardobj_grp_get_status *)
91 pboardobjgrppmu;
92
93 if (((u32)BIT(idx) &
94 pgrp_get_status->hdr.data.super.obj_mask.super.data[0]) == 0) {
95 return -EINVAL;
96 }
97
98 *ppboardobjpmustatus = (struct nv_pmu_boardobj_query *)
99 &pgrp_get_status->objects[idx].data.board_obj;
100 return 0;
101}
102
103
104int vfe_var_sw_setup(struct gk20a *g)
105{
106 u32 status;
107 struct boardobjgrp *pboardobjgrp = NULL;
108 struct vfe_vars *pvfevarobjs;
109
110 nvgpu_log_info(g, " ");
111
112 status = boardobjgrpconstruct_e32(g, &g->perf_pmu.vfe_varobjs.super);
113 if (status) {
114 nvgpu_err(g,
115 "error creating boardobjgrp for clk domain, status - 0x%x",
116 status);
117 goto done;
118 }
119
120 pboardobjgrp = &g->perf_pmu.vfe_varobjs.super.super;
121 pvfevarobjs = &g->perf_pmu.vfe_varobjs;
122
123 BOARDOBJGRP_PMU_CONSTRUCT(pboardobjgrp, PERF, VFE_VAR);
124
125 status = BOARDOBJGRP_PMU_CMD_GRP_SET_CONSTRUCT(g, pboardobjgrp,
126 perf, PERF, vfe_var, VFE_VAR);
127 if (status) {
128 nvgpu_err(g,
129 "error constructing PMU_BOARDOBJ_CMD_GRP_SET interface - 0x%x",
130 status);
131 goto done;
132 }
133
134 pboardobjgrp->pmudatainit = _vfe_vars_pmudatainit;
135 pboardobjgrp->pmudatainstget = _vfe_vars_pmudata_instget;
136 pboardobjgrp->pmustatusinstget = _vfe_vars_pmustatus_instget;
137
138 status = devinit_get_vfe_var_table(g, pvfevarobjs);
139 if (status) {
140 goto done;
141 }
142
143 status = BOARDOBJGRP_PMU_CMD_GRP_GET_STATUS_CONSTRUCT(g,
144 &g->perf_pmu.vfe_varobjs.super.super,
145 perf, PERF, vfe_var, VFE_VAR);
146 if (status) {
147 nvgpu_err(g,
148 "error constructing PMU_BOARDOBJ_CMD_GRP_GET_STATUS interface - 0x%x",
149 status);
150 goto done;
151 }
152
153done:
154 nvgpu_log_info(g, " done status %x", status);
155 return status;
156}
157
158int vfe_var_pmu_setup(struct gk20a *g)
159{
160 int status;
161 struct boardobjgrp *pboardobjgrp = NULL;
162
163 nvgpu_log_info(g, " ");
164
165 pboardobjgrp = &g->perf_pmu.vfe_varobjs.super.super;
166
167 if (!pboardobjgrp->bconstructed) {
168 return -EINVAL;
169 }
170
171 status = pboardobjgrp->pmuinithandle(g, pboardobjgrp);
172
173 nvgpu_log_info(g, "Done");
174 return status;
175}
176
177static u32 dev_init_get_vfield_info(struct gk20a *g,
178 struct vfe_var_single_sensed_fuse *pvfevar)
179{
180 u8 *vfieldtableptr = NULL;
181 u32 vfieldheadersize = VFIELD_HEADER_SIZE;
182 u8 *vfieldregtableptr = NULL;
183 u32 vfieldregheadersize = VFIELD_REG_HEADER_SIZE;
184 u32 i;
185 u32 oldindex = 0xFFFFFFFF;
186 u32 currindex;
187 struct vfield_reg_header vregheader;
188 struct vfield_reg_entry vregentry;
189 struct vfield_header vheader;
190 struct vfield_entry ventry;
191 struct ctrl_bios_vfield_register_segment *psegment = NULL;
192 u8 *psegmentcount = NULL;
193 u32 status = 0;
194
195 vfieldregtableptr = (u8 *)nvgpu_bios_get_perf_table_ptrs(g,
196 g->bios.virt_token, VP_FIELD_REGISTER);
197 if (vfieldregtableptr == NULL) {
198 status = -EINVAL;
199 goto done;
200 }
201
202 vfieldtableptr = (u8 *)nvgpu_bios_get_perf_table_ptrs(g,
203 g->bios.virt_token, VP_FIELD_TABLE);
204 if (vfieldtableptr == NULL) {
205 status = -EINVAL;
206 goto done;
207 }
208
209 memcpy(&vregheader, vfieldregtableptr, VFIELD_REG_HEADER_SIZE);
210
211 if (vregheader.version != VBIOS_VFIELD_REG_TABLE_VERSION_1_0) {
212 nvgpu_err(g, "invalid vreg header version");
213 goto done;
214 }
215
216 memcpy(&vheader, vfieldtableptr, VFIELD_HEADER_SIZE);
217
218 if (vregheader.version != VBIOS_VFIELD_TABLE_VERSION_1_0) {
219 nvgpu_err(g, "invalid vfield header version");
220 goto done;
221 }
222
223 pvfevar->vfield_info.fuse.segment_count = 0;
224 pvfevar->vfield_ver_info.fuse.segment_count = 0;
225 for (i = 0; i < (u32)vheader.count; i++) {
226 memcpy(&ventry, vfieldtableptr + vfieldheadersize +
227 (i * vheader.entry_size),
228 vheader.entry_size);
229
230 currindex = VFIELD_BIT_REG(ventry);
231 if (currindex != oldindex) {
232
233 memcpy(&vregentry, vfieldregtableptr +
234 vfieldregheadersize +
235 (currindex * vregheader.entry_size),
236 vregheader.entry_size);
237 oldindex = currindex;
238 }
239
240 if (pvfevar->vfield_info.v_field_id == ventry.strap_id) {
241 psegmentcount =
242 &(pvfevar->vfield_info.fuse.segment_count);
243 psegment =
244 &(pvfevar->vfield_info.fuse.segments[*psegmentcount]);
245 if (*psegmentcount > NV_PMU_VFE_VAR_SINGLE_SENSED_FUSE_SEGMENTS_MAX) {
246 status = -EINVAL;
247 goto done;
248 }
249 } else if (pvfevar->vfield_ver_info.v_field_id_ver == ventry.strap_id) {
250 psegmentcount =
251 &(pvfevar->vfield_ver_info.fuse.segment_count);
252 psegment =
253 &(pvfevar->vfield_ver_info.fuse.segments[*psegmentcount]);
254 if (*psegmentcount > NV_PMU_VFE_VAR_SINGLE_SENSED_FUSE_SEGMENTS_MAX) {
255 status = -EINVAL;
256 goto done;
257 }
258 } else {
259 continue;
260 }
261
262 switch (VFIELD_CODE((&vregentry))) {
263 case NV_VFIELD_DESC_CODE_REG:
264 psegment->type =
265 NV_PMU_BIOS_VFIELD_DESC_CODE_REG;
266 psegment->data.reg.addr = vregentry.reg;
267 psegment->data.reg.super.high_bit = (u8)(VFIELD_BIT_STOP(ventry));
268 psegment->data.reg.super.low_bit = (u8)(VFIELD_BIT_START(ventry));
269 break;
270
271 case NV_VFIELD_DESC_CODE_INDEX_REG:
272 psegment->type =
273 NV_PMU_BIOS_VFIELD_DESC_CODE_INDEX_REG;
274 psegment->data.index_reg.addr = vregentry.reg;
275 psegment->data.index_reg.index = vregentry.index;
276 psegment->data.index_reg.reg_index = vregentry.reg_index;
277 psegment->data.index_reg.super.high_bit = (u8)(VFIELD_BIT_STOP(ventry));
278 psegment->data.index_reg.super.low_bit = (u8)(VFIELD_BIT_START(ventry));
279 break;
280
281 default:
282 psegment->type =
283 NV_PMU_BIOS_VFIELD_DESC_CODE_INVALID;
284 status = -EINVAL;
285 goto done;
286 }
287
288 if (VFIELD_SIZE((&vregentry)) != NV_VFIELD_DESC_SIZE_DWORD) {
289 psegment->type =
290 NV_PMU_BIOS_VFIELD_DESC_CODE_INVALID;
291 return -EINVAL;
292 }
293 (*psegmentcount)++;
294 }
295
296done:
297 return status;
298}
299
300static int _vfe_var_pmudatainit_super(struct gk20a *g,
301 struct boardobj *board_obj_ptr,
302 struct nv_pmu_boardobj *ppmudata)
303{
304 int status = 0;
305 struct vfe_var *pvfe_var;
306 struct nv_pmu_vfe_var *pset;
307
308 nvgpu_log_info(g, " ");
309
310 status = boardobj_pmudatainit_super(g, board_obj_ptr, ppmudata);
311 if (status != 0) {
312 return status;
313 }
314
315 pvfe_var = (struct vfe_var *)board_obj_ptr;
316 pset = (struct nv_pmu_vfe_var *) ppmudata;
317
318 pset->out_range_min = pvfe_var->out_range_min;
319 pset->out_range_max = pvfe_var->out_range_max;
320 status = boardobjgrpmask_export(&pvfe_var->mask_dependent_vars.super,
321 pvfe_var->mask_dependent_vars.super.bitcount,
322 &pset->mask_dependent_vars.super);
323 status = boardobjgrpmask_export(&pvfe_var->mask_dependent_equs.super,
324 pvfe_var->mask_dependent_equs.super.bitcount,
325 &pset->mask_dependent_equs.super);
326 return status;
327}
328
329static int vfe_var_construct_super(struct gk20a *g,
330 struct boardobj **ppboardobj,
331 u16 size, void *pargs)
332{
333 struct vfe_var *pvfevar;
334 struct vfe_var *ptmpvar = (struct vfe_var *)pargs;
335 int status = 0;
336
337 nvgpu_log_info(g, " ");
338
339 status = boardobj_construct_super(g, ppboardobj, size, pargs);
340 if (status) {
341 return -EINVAL;
342 }
343
344 pvfevar = (struct vfe_var *)*ppboardobj;
345
346 pvfevar->super.pmudatainit =
347 _vfe_var_pmudatainit_super;
348
349 pvfevar->out_range_min = ptmpvar->out_range_min;
350 pvfevar->out_range_max = ptmpvar->out_range_max;
351 pvfevar->b_is_dynamic_valid = false;
352 status = boardobjgrpmask_e32_init(&pvfevar->mask_dependent_vars, NULL);
353 status = boardobjgrpmask_e255_init(&pvfevar->mask_dependent_equs, NULL);
354 nvgpu_log_info(g, " ");
355
356 return status;
357}
358
359static int _vfe_var_pmudatainit_derived(struct gk20a *g,
360 struct boardobj *board_obj_ptr,
361 struct nv_pmu_boardobj *ppmudata)
362{
363 int status = 0;
364
365 nvgpu_log_info(g, " ");
366
367 status = _vfe_var_pmudatainit_super(g, board_obj_ptr, ppmudata);
368
369 return status;
370}
371
372static int vfe_var_construct_derived(struct gk20a *g,
373 struct boardobj **ppboardobj,
374 u16 size, void *pargs)
375{
376 struct boardobj *ptmpobj = (struct boardobj *)pargs;
377 int status = 0;
378 struct vfe_var_derived *pvfevar;
379
380 ptmpobj->type_mask |= BIT(CTRL_PERF_VFE_VAR_TYPE_DERIVED);
381 status = vfe_var_construct_super(g, ppboardobj, size, pargs);
382 if (status) {
383 return -EINVAL;
384 }
385
386 pvfevar = (struct vfe_var_derived *)*ppboardobj;
387
388 pvfevar->super.super.pmudatainit =
389 _vfe_var_pmudatainit_derived;
390
391 return status;
392}
393
394static int _vfe_var_pmudatainit_derived_product(struct gk20a *g,
395 struct boardobj *board_obj_ptr,
396 struct nv_pmu_boardobj *ppmudata)
397{
398 int status = 0;
399 struct vfe_var_derived_product *pvfe_var_derived_product;
400 struct nv_pmu_vfe_var_derived_product *pset;
401
402 nvgpu_log_info(g, " ");
403
404 status = _vfe_var_pmudatainit_derived(g, board_obj_ptr, ppmudata);
405 if (status != 0) {
406 return status;
407 }
408
409 pvfe_var_derived_product =
410 (struct vfe_var_derived_product *)board_obj_ptr;
411 pset = (struct nv_pmu_vfe_var_derived_product *)ppmudata;
412
413 pset->var_idx0 = pvfe_var_derived_product->var_idx0;
414 pset->var_idx1 = pvfe_var_derived_product->var_idx1;
415
416 return status;
417}
418
419static int vfe_var_construct_derived_product(struct gk20a *g,
420 struct boardobj **ppboardobj,
421 u16 size, void *pargs)
422{
423 struct boardobj *ptmpobj = (struct boardobj *)pargs;
424 struct vfe_var_derived_product *pvfevar;
425 struct vfe_var_derived_product *ptmpvar =
426 (struct vfe_var_derived_product *)pargs;
427 int status = 0;
428
429 if (BOARDOBJ_GET_TYPE(pargs) != CTRL_PERF_VFE_VAR_TYPE_DERIVED_PRODUCT) {
430 return -EINVAL;
431 }
432
433 ptmpobj->type_mask |= BIT(CTRL_PERF_VFE_VAR_TYPE_DERIVED_PRODUCT);
434 status = vfe_var_construct_derived(g, ppboardobj, size, pargs);
435 if (status) {
436 return -EINVAL;
437 }
438
439 pvfevar = (struct vfe_var_derived_product *)*ppboardobj;
440
441 pvfevar->super.super.super.pmudatainit =
442 _vfe_var_pmudatainit_derived_product;
443
444 pvfevar->var_idx0 = ptmpvar->var_idx0;
445 pvfevar->var_idx1 = ptmpvar->var_idx1;
446
447
448 return status;
449}
450
451static int _vfe_var_pmudatainit_derived_sum(struct gk20a *g,
452 struct boardobj *board_obj_ptr,
453 struct nv_pmu_boardobj *ppmudata)
454{
455 int status = 0;
456 struct vfe_var_derived_sum *pvfe_var_derived_sum;
457 struct nv_pmu_vfe_var_derived_sum *pset;
458
459 nvgpu_log_info(g, " ");
460
461 status = _vfe_var_pmudatainit_derived(g, board_obj_ptr, ppmudata);
462 if (status != 0) {
463 return status;
464 }
465
466 pvfe_var_derived_sum = (struct vfe_var_derived_sum *)board_obj_ptr;
467 pset = (struct nv_pmu_vfe_var_derived_sum *)ppmudata;
468
469 pset->var_idx0 = pvfe_var_derived_sum->var_idx0;
470 pset->var_idx1 = pvfe_var_derived_sum->var_idx1;
471
472 return status;
473}
474
475static int vfe_var_construct_derived_sum(struct gk20a *g,
476 struct boardobj **ppboardobj,
477 u16 size, void *pargs)
478{
479 struct boardobj *ptmpobj = (struct boardobj *)pargs;
480 struct vfe_var_derived_sum *pvfevar;
481 struct vfe_var_derived_sum *ptmpvar =
482 (struct vfe_var_derived_sum *)pargs;
483 int status = 0;
484
485 if (BOARDOBJ_GET_TYPE(pargs) != CTRL_PERF_VFE_VAR_TYPE_DERIVED_SUM) {
486 return -EINVAL;
487 }
488
489 ptmpobj->type_mask |= BIT(CTRL_PERF_VFE_VAR_TYPE_DERIVED_SUM);
490 status = vfe_var_construct_derived(g, ppboardobj, size, pargs);
491 if (status) {
492 return -EINVAL;
493 }
494
495 pvfevar = (struct vfe_var_derived_sum *)*ppboardobj;
496
497 pvfevar->super.super.super.pmudatainit =
498 _vfe_var_pmudatainit_derived_sum;
499
500 pvfevar->var_idx0 = ptmpvar->var_idx0;
501 pvfevar->var_idx1 = ptmpvar->var_idx1;
502
503 return status;
504}
505
506static int _vfe_var_pmudatainit_single(struct gk20a *g,
507 struct boardobj *board_obj_ptr,
508 struct nv_pmu_boardobj *ppmudata)
509{
510 int status = 0;
511 struct vfe_var_single *pvfe_var_single;
512 struct nv_pmu_vfe_var_single *pset;
513
514 nvgpu_log_info(g, " ");
515
516 status = _vfe_var_pmudatainit_super(g, board_obj_ptr, ppmudata);
517 if (status != 0) {
518 return status;
519 }
520
521 pvfe_var_single = (struct vfe_var_single *)board_obj_ptr;
522 pset = (struct nv_pmu_vfe_var_single *)
523 ppmudata;
524
525 pset->override_type = pvfe_var_single->override_type;
526 pset->override_value = pvfe_var_single->override_value;
527
528 return status;
529}
530
531static int _vfe_var_pmudatainit_single_frequency(struct gk20a *g,
532 struct boardobj *board_obj_ptr,
533 struct nv_pmu_boardobj *ppmudata)
534{
535 int status = 0;
536
537 nvgpu_log_info(g, " ");
538
539 status = _vfe_var_pmudatainit_single(g, board_obj_ptr, ppmudata);
540
541 return status;
542}
543
544static u32 vfe_var_construct_single_frequency(struct gk20a *g,
545 struct boardobj **ppboardobj,
546 u16 size, void *pargs)
547{
548 struct boardobj *ptmpobj = (struct boardobj *)pargs;
549 struct vfe_var_single_frequency *pvfevar;
550 u32 status = 0;
551
552 nvgpu_log_info(g, " ");
553
554 if (BOARDOBJ_GET_TYPE(pargs) != CTRL_PERF_VFE_VAR_TYPE_SINGLE_FREQUENCY) {
555 return -EINVAL;
556 }
557
558 ptmpobj->type_mask |= BIT(CTRL_PERF_VFE_VAR_TYPE_SINGLE_FREQUENCY);
559 status = vfe_var_construct_single(g, ppboardobj, size, pargs);
560 if (status) {
561 return -EINVAL;
562 }
563
564 pvfevar = (struct vfe_var_single_frequency *)*ppboardobj;
565
566 pvfevar->super.super.super.pmudatainit =
567 _vfe_var_pmudatainit_single_frequency;
568
569 pvfevar->super.super.b_is_dynamic = false;
570 pvfevar->super.super.b_is_dynamic_valid = true;
571
572 nvgpu_log_info(g, "Done");
573 return status;
574}
575
576static int _vfe_var_pmudatainit_single_sensed(struct gk20a *g,
577 struct boardobj *board_obj_ptr,
578 struct nv_pmu_boardobj *ppmudata)
579{
580 int status = 0;
581
582 nvgpu_log_info(g, " ");
583
584 status = _vfe_var_pmudatainit_single(g, board_obj_ptr, ppmudata);
585
586 return status;
587}
588
589static int _vfe_var_pmudatainit_single_sensed_fuse(struct gk20a *g,
590 struct boardobj *board_obj_ptr,
591 struct nv_pmu_boardobj *ppmudata)
592{
593 int status = 0;
594 struct vfe_var_single_sensed_fuse *pvfe_var_single_sensed_fuse;
595 struct nv_pmu_vfe_var_single_sensed_fuse *pset;
596
597 nvgpu_log_info(g, " ");
598
599 status = _vfe_var_pmudatainit_single_sensed(g, board_obj_ptr, ppmudata);
600 if (status != 0) {
601 return status;
602 }
603
604 pvfe_var_single_sensed_fuse =
605 (struct vfe_var_single_sensed_fuse *)board_obj_ptr;
606
607 pset = (struct nv_pmu_vfe_var_single_sensed_fuse *)
608 ppmudata;
609
610 memcpy(&pset->vfield_info, &pvfe_var_single_sensed_fuse->vfield_info,
611 sizeof(struct ctrl_perf_vfe_var_single_sensed_fuse_vfield_info));
612
613 memcpy(&pset->vfield_ver_info,
614 &pvfe_var_single_sensed_fuse->vfield_ver_info,
615 sizeof(struct ctrl_perf_vfe_var_single_sensed_fuse_ver_vfield_info));
616
617 memcpy(&pset->override_info,
618 &pvfe_var_single_sensed_fuse->override_info,
619 sizeof(struct ctrl_perf_vfe_var_single_sensed_fuse_override_info));
620
621 pset->b_fuse_value_signed = pvfe_var_single_sensed_fuse->b_fuse_value_signed;
622 return status;
623}
624
625static u32 vfe_var_construct_single_sensed(struct gk20a *g,
626 struct boardobj **ppboardobj,
627 u16 size, void *pargs)
628{
629 struct boardobj *ptmpobj = (struct boardobj *)pargs;
630 struct vfe_var_single_sensed *pvfevar;
631
632 u32 status = 0;
633
634 nvgpu_log_info(g, " ");
635
636 ptmpobj->type_mask |= BIT(CTRL_PERF_VFE_VAR_TYPE_SINGLE_SENSED);
637 status = vfe_var_construct_single(g, ppboardobj, size, pargs);
638 if (status) {
639 return -EINVAL;
640 }
641
642 pvfevar = (struct vfe_var_single_sensed *)*ppboardobj;
643
644 pvfevar->super.super.super.pmudatainit =
645 _vfe_var_pmudatainit_single_sensed;
646
647 nvgpu_log_info(g, "Done");
648
649 return status;
650}
651
652static u32 vfe_var_construct_single_sensed_fuse(struct gk20a *g,
653 struct boardobj **ppboardobj,
654 u16 size, void *pargs)
655{
656 struct boardobj *ptmpobj = (struct boardobj *)pargs;
657 struct vfe_var_single_sensed_fuse *pvfevar;
658 struct vfe_var_single_sensed_fuse *ptmpvar =
659 (struct vfe_var_single_sensed_fuse *)pargs;
660 u32 status = 0;
661
662 nvgpu_log_info(g, " ");
663
664 if (BOARDOBJ_GET_TYPE(pargs) != CTRL_PERF_VFE_VAR_TYPE_SINGLE_SENSED_FUSE) {
665 return -EINVAL;
666 }
667
668 ptmpobj->type_mask |= BIT(CTRL_PERF_VFE_VAR_TYPE_SINGLE_SENSED_FUSE);
669 status = vfe_var_construct_single_sensed(g, ppboardobj, size, pargs);
670 if (status) {
671 return -EINVAL;
672 }
673
674 pvfevar = (struct vfe_var_single_sensed_fuse *)*ppboardobj;
675
676 pvfevar->super.super.super.super.pmudatainit =
677 _vfe_var_pmudatainit_single_sensed_fuse;
678
679 pvfevar->vfield_info.v_field_id = ptmpvar->vfield_info.v_field_id;
680 pvfevar->vfield_info.fuse_val_default =
681 ptmpvar->vfield_info.fuse_val_default;
682 pvfevar->vfield_info.hw_correction_scale =
683 ptmpvar->vfield_info.hw_correction_scale;
684 pvfevar->vfield_info.hw_correction_offset =
685 ptmpvar->vfield_info.hw_correction_offset;
686 pvfevar->vfield_ver_info.v_field_id_ver =
687 ptmpvar->vfield_ver_info.v_field_id_ver;
688 pvfevar->vfield_ver_info.ver_expected =
689 ptmpvar->vfield_ver_info.ver_expected;
690 pvfevar->vfield_ver_info.b_use_default_on_ver_check_fail =
691 ptmpvar->vfield_ver_info.b_use_default_on_ver_check_fail;
692 pvfevar->b_version_check_done = false;
693 pvfevar->b_fuse_value_signed =
694 ptmpvar->b_fuse_value_signed;
695 pvfevar->super.super.super.b_is_dynamic = false;
696 pvfevar->super.super.super.b_is_dynamic_valid = true;
697
698 dev_init_get_vfield_info(g, pvfevar);
699 /*check whether fuse segment got initialized*/
700 if (pvfevar->vfield_info.fuse.segment_count == 0) {
701 nvgpu_err(g, "unable to get fuse reg info %x",
702 pvfevar->vfield_info.v_field_id);
703 status = -EINVAL;
704 goto exit;
705 }
706 if (pvfevar->vfield_ver_info.fuse.segment_count == 0) {
707 nvgpu_err(g, "unable to get fuse reg info %x",
708 pvfevar->vfield_ver_info.v_field_id_ver);
709 status = -EINVAL;
710 goto exit;
711 }
712exit:
713 if (status) {
714 (*ppboardobj)->destruct(*ppboardobj);
715 }
716
717 return status;
718}
719
720static int _vfe_var_pmudatainit_single_sensed_temp(struct gk20a *g,
721 struct boardobj *board_obj_ptr,
722 struct nv_pmu_boardobj *ppmudata)
723{
724 int status = 0;
725 struct vfe_var_single_sensed_temp *pvfe_var_single_sensed_temp;
726 struct nv_pmu_vfe_var_single_sensed_temp *pset;
727
728 nvgpu_log_info(g, " ");
729
730 status = _vfe_var_pmudatainit_single_sensed(g, board_obj_ptr, ppmudata);
731 if (status != 0) {
732 return status;
733 }
734
735 pvfe_var_single_sensed_temp =
736 (struct vfe_var_single_sensed_temp *)board_obj_ptr;
737
738 pset = (struct nv_pmu_vfe_var_single_sensed_temp *)
739 ppmudata;
740 pset->therm_channel_index =
741 pvfe_var_single_sensed_temp->therm_channel_index;
742 pset->temp_hysteresis_positive =
743 pvfe_var_single_sensed_temp->temp_hysteresis_positive;
744 pset->temp_hysteresis_negative =
745 pvfe_var_single_sensed_temp->temp_hysteresis_negative;
746 pset->temp_default =
747 pvfe_var_single_sensed_temp->temp_default;
748 return status;
749}
750
751static u32 vfe_var_construct_single_sensed_temp(struct gk20a *g,
752 struct boardobj **ppboardobj,
753 u16 size, void *pargs)
754{
755 struct boardobj *ptmpobj = (struct boardobj *)pargs;
756 struct vfe_var_single_sensed_temp *pvfevar;
757 struct vfe_var_single_sensed_temp *ptmpvar =
758 (struct vfe_var_single_sensed_temp *)pargs;
759 u32 status = 0;
760
761 if (BOARDOBJ_GET_TYPE(pargs) != CTRL_PERF_VFE_VAR_TYPE_SINGLE_SENSED_TEMP) {
762 return -EINVAL;
763 }
764
765 ptmpobj->type_mask |= BIT(CTRL_PERF_VFE_VAR_TYPE_SINGLE_SENSED_TEMP);
766 status = vfe_var_construct_single_sensed(g, ppboardobj, size, pargs);
767 if (status) {
768 return -EINVAL;
769 }
770
771 pvfevar = (struct vfe_var_single_sensed_temp *)*ppboardobj;
772
773 pvfevar->super.super.super.super.pmudatainit =
774 _vfe_var_pmudatainit_single_sensed_temp;
775
776 pvfevar->therm_channel_index =
777 ptmpvar->therm_channel_index;
778 pvfevar->temp_hysteresis_positive =
779 ptmpvar->temp_hysteresis_positive;
780 pvfevar->temp_hysteresis_negative =
781 ptmpvar->temp_hysteresis_negative;
782 pvfevar->temp_default =
783 ptmpvar->temp_default;
784 pvfevar->super.super.super.b_is_dynamic = false;
785 pvfevar->super.super.super.b_is_dynamic_valid = true;
786
787 return status;
788}
789
790static int _vfe_var_pmudatainit_single_voltage(struct gk20a *g,
791 struct boardobj *board_obj_ptr,
792 struct nv_pmu_boardobj *ppmudata)
793{
794 int status = 0;
795
796 nvgpu_log_info(g, " ");
797
798 status = _vfe_var_pmudatainit_single(g, board_obj_ptr, ppmudata);
799
800 return status;
801}
802
803static int vfe_var_construct_single_voltage(struct gk20a *g,
804 struct boardobj **ppboardobj,
805 u16 size, void *pargs)
806{
807 struct boardobj *ptmpobj = (struct boardobj *)pargs;
808 struct vfe_var_single_voltage *pvfevar;
809 int status = 0;
810
811 if (BOARDOBJ_GET_TYPE(pargs) != CTRL_PERF_VFE_VAR_TYPE_SINGLE_VOLTAGE) {
812 return -EINVAL;
813 }
814
815 ptmpobj->type_mask |= BIT(CTRL_PERF_VFE_VAR_TYPE_SINGLE_VOLTAGE);
816 status = vfe_var_construct_super(g, ppboardobj, size, pargs);
817 if (status) {
818 return -EINVAL;
819 }
820
821 pvfevar = (struct vfe_var_single_voltage *)*ppboardobj;
822
823 pvfevar->super.super.super.pmudatainit =
824 _vfe_var_pmudatainit_single_voltage;
825
826 pvfevar->super.super.b_is_dynamic = false;
827 pvfevar->super.super.b_is_dynamic_valid = true;
828
829 return status;
830}
831
832static struct vfe_var *construct_vfe_var(struct gk20a *g, void *pargs)
833{
834 struct boardobj *board_obj_ptr = NULL;
835 int status;
836
837 nvgpu_log_info(g, " ");
838 switch (BOARDOBJ_GET_TYPE(pargs)) {
839 case CTRL_PERF_VFE_VAR_TYPE_DERIVED_PRODUCT:
840 status = vfe_var_construct_derived_product(g, &board_obj_ptr,
841 sizeof(struct vfe_var_derived_product), pargs);
842 break;
843
844 case CTRL_PERF_VFE_VAR_TYPE_DERIVED_SUM:
845 status = vfe_var_construct_derived_sum(g, &board_obj_ptr,
846 sizeof(struct vfe_var_derived_sum), pargs);
847 break;
848
849 case CTRL_PERF_VFE_VAR_TYPE_SINGLE_FREQUENCY:
850 status = vfe_var_construct_single_frequency(g, &board_obj_ptr,
851 sizeof(struct vfe_var_single_frequency), pargs);
852 break;
853
854 case CTRL_PERF_VFE_VAR_TYPE_SINGLE_SENSED_FUSE:
855 status = vfe_var_construct_single_sensed_fuse(g, &board_obj_ptr,
856 sizeof(struct vfe_var_single_sensed_fuse), pargs);
857 break;
858
859 case CTRL_PERF_VFE_VAR_TYPE_SINGLE_SENSED_TEMP:
860 status = vfe_var_construct_single_sensed_temp(g, &board_obj_ptr,
861 sizeof(struct vfe_var_single_sensed_temp), pargs);
862 break;
863
864 case CTRL_PERF_VFE_VAR_TYPE_SINGLE_VOLTAGE:
865 status = vfe_var_construct_single_voltage(g, &board_obj_ptr,
866 sizeof(struct vfe_var_single_voltage), pargs);
867 break;
868
869 case CTRL_PERF_VFE_VAR_TYPE_DERIVED:
870 case CTRL_PERF_VFE_VAR_TYPE_SINGLE_SENSED:
871 case CTRL_PERF_VFE_VAR_TYPE_SINGLE:
872 default:
873 return NULL;
874 }
875
876 if (status) {
877 return NULL;
878 }
879
880 nvgpu_log_info(g, "done");
881
882 return (struct vfe_var *)board_obj_ptr;
883}
884
885static int devinit_get_vfe_var_table(struct gk20a *g,
886 struct vfe_vars *pvfevarobjs)
887{
888 int status = 0;
889 u8 *vfevars_tbl_ptr = NULL;
890 struct vbios_vfe_3x_header_struct vfevars_tbl_header = { 0 };
891 struct vbios_vfe_3x_var_entry_struct var = { 0 };
892 u8 *vfevars_tbl_entry_ptr = NULL;
893 u8 *rd_offset_ptr = NULL;
894 u32 index = 0;
895 struct vfe_var *pvar;
896 u8 var_type;
897 u32 szfmt;
898 union {
899 struct boardobj board_obj;
900 struct vfe_var super;
901 struct vfe_var_derived_product derived_product;
902 struct vfe_var_derived_sum derived_sum;
903 struct vfe_var_single_sensed_fuse single_sensed_fuse;
904 struct vfe_var_single_sensed_temp single_sensed_temp;
905 } var_data;
906
907 nvgpu_log_info(g, " ");
908
909 vfevars_tbl_ptr = (u8 *)nvgpu_bios_get_perf_table_ptrs(g,
910 g->bios.perf_token,
911 CONTINUOUS_VIRTUAL_BINNING_TABLE);
912 if (vfevars_tbl_ptr == NULL) {
913 status = -EINVAL;
914 goto done;
915 }
916
917 memcpy(&vfevars_tbl_header, vfevars_tbl_ptr,
918 VBIOS_CLOCKS_TABLE_1X_HEADER_SIZE_07);
919 if (vfevars_tbl_header.header_size !=
920 VBIOS_CLOCKS_TABLE_1X_HEADER_SIZE_07){
921 status = -EINVAL;
922 goto done;
923 }
924
925 if (vfevars_tbl_header.vfe_var_entry_size ==
926 VBIOS_VFE_3X_VAR_ENTRY_SIZE_19) {
927 szfmt = VBIOS_VFE_3X_VAR_ENTRY_SIZE_19;
928 } else if (vfevars_tbl_header.vfe_var_entry_size ==
929 VBIOS_VFE_3X_VAR_ENTRY_SIZE_11) {
930 szfmt = VBIOS_VFE_3X_VAR_ENTRY_SIZE_11;
931 } else {
932 status = -EINVAL;
933 goto done;
934 }
935
936 /* Read table entries*/
937 vfevars_tbl_entry_ptr = vfevars_tbl_ptr +
938 vfevars_tbl_header.header_size;
939 for (index = 0;
940 index < vfevars_tbl_header.vfe_var_entry_count;
941 index++) {
942 rd_offset_ptr = vfevars_tbl_entry_ptr +
943 (index * vfevars_tbl_header.vfe_var_entry_size);
944 memcpy(&var, rd_offset_ptr, szfmt);
945
946 var_data.super.out_range_min = var.out_range_min;
947 var_data.super.out_range_max = var.out_range_max;
948
949 switch ((u8)var.type) {
950 case VBIOS_VFE_3X_VAR_ENTRY_TYPE_DISABLED:
951 continue;
952 break;
953
954 case VBIOS_VFE_3X_VAR_ENTRY_TYPE_SINGLE_FREQUENCY:
955 var_type = CTRL_PERF_VFE_VAR_TYPE_SINGLE_FREQUENCY;
956 break;
957
958 case VBIOS_VFE_3X_VAR_ENTRY_TYPE_SINGLE_VOLTAGE:
959 var_type = CTRL_PERF_VFE_VAR_TYPE_SINGLE_VOLTAGE;
960 break;
961
962 case VBIOS_VFE_3X_VAR_ENTRY_TYPE_SINGLE_SENSED_TEMP:
963 var_type = CTRL_PERF_VFE_VAR_TYPE_SINGLE_SENSED_TEMP;
964 var_data.single_sensed_temp.temp_default = 0x9600;
965 var_data.single_sensed_temp.therm_channel_index =
966 (u8)BIOS_GET_FIELD(var.param0,
967 VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSTEMP_TH_CH_IDX);
968 var_data.single_sensed_temp.temp_hysteresis_positive =
969 (u8)BIOS_GET_FIELD(var.param0,
970 VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSTEMP_HYS_POS) << 5;
971 var_data.single_sensed_temp.temp_hysteresis_negative =
972 (u8)BIOS_GET_FIELD(var.param0,
973 VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSTEMP_HYS_NEG) << 5;
974 break;
975
976 case VBIOS_VFE_3X_VAR_ENTRY_TYPE_SINGLE_SENSED_FUSE:
977 var_type = CTRL_PERF_VFE_VAR_TYPE_SINGLE_SENSED_FUSE;
978 var_data.single_sensed_fuse.vfield_info.v_field_id =
979 (u8)BIOS_GET_FIELD(var.param0,
980 VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSFUSE_VFIELD_ID);
981 var_data.single_sensed_fuse.vfield_ver_info.v_field_id_ver =
982 (u8)BIOS_GET_FIELD(var.param0,
983 VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSFUSE_VFIELD_ID_VER);
984 var_data.single_sensed_fuse.vfield_ver_info.ver_expected =
985 (u8)BIOS_GET_FIELD(var.param0,
986 VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSFUSE_EXPECTED_VER);
987 var_data.single_sensed_fuse.vfield_ver_info.b_use_default_on_ver_check_fail =
988 (BIOS_GET_FIELD(var.param0,
989 VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSFUSE_USE_DEFAULT_ON_VER_CHECK_FAIL) &&
990 VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSFUSE_USE_DEFAULT_ON_VER_CHECK_FAIL_YES);
991 var_data.single_sensed_fuse.b_fuse_value_signed =
992 (u8)BIOS_GET_FIELD(var.param0,
993 VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSFUSE_VALUE_SIGNED_INTEGER);
994 var_data.single_sensed_fuse.vfield_info.fuse_val_default =
995 var.param1;
996 if (szfmt >= VBIOS_VFE_3X_VAR_ENTRY_SIZE_19) {
997 var_data.single_sensed_fuse.vfield_info.hw_correction_scale =
998 (int)var.param2;
999 var_data.single_sensed_fuse.vfield_info.hw_correction_offset =
1000 var.param3;
1001 } else {
1002 var_data.single_sensed_fuse.vfield_info.hw_correction_scale =
1003 1 << 12;
1004 var_data.single_sensed_fuse.vfield_info.hw_correction_offset =
1005 0;
1006 if ((var_data.single_sensed_fuse.vfield_info.v_field_id ==
1007 VFIELD_ID_STRAP_IDDQ) ||
1008 (var_data.single_sensed_fuse.vfield_info.v_field_id ==
1009 VFIELD_ID_STRAP_IDDQ_1)) {
1010 var_data.single_sensed_fuse.vfield_info.hw_correction_scale =
1011 50 << 12;
1012 }
1013 }
1014 break;
1015
1016 case VBIOS_VFE_3X_VAR_ENTRY_TYPE_DERIVED_PRODUCT:
1017 var_type = CTRL_PERF_VFE_VAR_TYPE_DERIVED_PRODUCT;
1018 var_data.derived_product.var_idx0 =
1019 (u8)BIOS_GET_FIELD(var.param0,
1020 VBIOS_VFE_3X_VAR_ENTRY_PAR0_DPROD_VFE_VAR_IDX_0);
1021 var_data.derived_product.var_idx1 =
1022 (u8)BIOS_GET_FIELD(var.param0,
1023 VBIOS_VFE_3X_VAR_ENTRY_PAR0_DPROD_VFE_VAR_IDX_1);
1024 break;
1025
1026 case VBIOS_VFE_3X_VAR_ENTRY_TYPE_DERIVED_SUM:
1027 var_type = CTRL_PERF_VFE_VAR_TYPE_DERIVED_SUM;
1028 var_data.derived_sum.var_idx0 =
1029 (u8)BIOS_GET_FIELD(var.param0,
1030 VBIOS_VFE_3X_VAR_ENTRY_PAR0_DSUM_VFE_VAR_IDX_0);
1031 var_data.derived_sum.var_idx1 =
1032 (u8)BIOS_GET_FIELD(var.param0,
1033 VBIOS_VFE_3X_VAR_ENTRY_PAR0_DSUM_VFE_VAR_IDX_1);
1034 break;
1035 default:
1036 status = -EINVAL;
1037 goto done;
1038 }
1039 var_data.board_obj.type = var_type;
1040 var_data.board_obj.type_mask = 0;
1041
1042 pvar = construct_vfe_var(g, &var_data);
1043 if (pvar == NULL) {
1044 nvgpu_err(g,
1045 "error constructing vfe_var boardobj %d",
1046 index);
1047 status = -EINVAL;
1048 goto done;
1049 }
1050
1051 status = boardobjgrp_objinsert(&pvfevarobjs->super.super,
1052 (struct boardobj *)pvar, index);
1053 if (status) {
1054 nvgpu_err(g, "error adding vfe_var boardobj %d", index);
1055 status = -EINVAL;
1056 goto done;
1057 }
1058 }
1059 pvfevarobjs->polling_periodms = vfevars_tbl_header.polling_periodms;
1060done:
1061 nvgpu_log_info(g, "done status %x", status);
1062 return status;
1063}
1064
1065static int vfe_var_construct_single(struct gk20a *g,
1066 struct boardobj **ppboardobj,
1067 u16 size, void *pargs)
1068{
1069 struct boardobj *ptmpobj = (struct boardobj *)pargs;
1070 struct vfe_var_single *pvfevar;
1071 int status = 0;
1072
1073 nvgpu_log_info(g, " ");
1074
1075 ptmpobj->type_mask |= BIT(CTRL_PERF_VFE_VAR_TYPE_SINGLE);
1076 status = vfe_var_construct_super(g, ppboardobj, size, pargs);
1077 if (status) {
1078 return -EINVAL;
1079 }
1080
1081 pvfevar = (struct vfe_var_single *)*ppboardobj;
1082
1083 pvfevar->super.super.pmudatainit =
1084 _vfe_var_pmudatainit_single;
1085
1086 pvfevar->override_type = CTRL_PERF_VFE_VAR_SINGLE_OVERRIDE_TYPE_NONE;
1087 pvfevar->override_value = 0;
1088
1089 nvgpu_log_info(g, "Done");
1090 return status;
1091}