summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/perf/vfe_equ.c
diff options
context:
space:
mode:
authorVijayakumar Subbu <vsubbu@nvidia.com>2016-07-30 13:44:30 -0400
committerDeepak Nibade <dnibade@nvidia.com>2016-12-27 04:56:49 -0500
commit432017248e432df0619dc2df30f915a52634338f (patch)
tree40bb7a77983fb2753271bc46b346a44ebd6121cf /drivers/gpu/nvgpu/perf/vfe_equ.c
parent38ad90b4840434df4650c617a236e1b01f8a43c6 (diff)
gpu: nvgpu: Add dGPU clocks support
JIRA DNVGPU-42 Change-Id: Ic2fca9d0cf82f2823654ac5e8f0772a1eec7b3b5 Signed-off-by: Vijayakumar Subbu <vsubbu@nvidia.com> Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/1205850 (cherry picked from commit b9f5c6bc4e649162d63e33d65b725872340ca114) Reviewed-on: http://git-master/r/1227257 GVS: Gerrit_Virtual_Submit
Diffstat (limited to 'drivers/gpu/nvgpu/perf/vfe_equ.c')
-rw-r--r--drivers/gpu/nvgpu/perf/vfe_equ.c590
1 files changed, 590 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/perf/vfe_equ.c b/drivers/gpu/nvgpu/perf/vfe_equ.c
new file mode 100644
index 00000000..6630fb21
--- /dev/null
+++ b/drivers/gpu/nvgpu/perf/vfe_equ.c
@@ -0,0 +1,590 @@
1/*
2 * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 */
13
14#include "gk20a/gk20a.h"
15#include "perf.h"
16#include "vfe_equ.h"
17#include "include/bios.h"
18#include "boardobj/boardobjgrp.h"
19#include "boardobj/boardobjgrp_e255.h"
20#include "pmuif/gpmuifboardobj.h"
21#include "pmuif/gpmuifperf.h"
22#include "pmuif/gpmuifperfvfe.h"
23#include "gm206/bios_gm206.h"
24#include "ctrl/ctrlclk.h"
25#include "ctrl/ctrlvolt.h"
26#include "gk20a/pmu_gk20a.h"
27
28static struct vfe_equ *construct_vfe_equ(struct gk20a *g, void *pargs);
29static u32 devinit_get_vfe_equ_table(struct gk20a *g,
30 struct vfe_equs *pequobjs);
31
32static u32 _vfe_equs_pmudatainit(struct gk20a *g,
33 struct boardobjgrp *pboardobjgrp,
34 struct nv_pmu_boardobjgrp_super *pboardobjgrppmu)
35{
36 u32 status = 0;
37
38 status = boardobjgrp_pmudatainit_e255(g, pboardobjgrp, pboardobjgrppmu);
39 if (status) {
40 gk20a_err(dev_from_gk20a(g),
41 "error updating pmu boardobjgrp for vfe equ 0x%x",
42 status);
43 goto done;
44 }
45
46done:
47 return status;
48}
49
50static u32 _vfe_equs_pmudata_instget(struct gk20a *g,
51 struct nv_pmu_boardobjgrp *pmuboardobjgrp,
52 struct nv_pmu_boardobj **ppboardobjpmudata,
53 u8 idx)
54{
55 struct nv_pmu_perf_vfe_equ_boardobj_grp_set *pgrp_set =
56 (struct nv_pmu_perf_vfe_equ_boardobj_grp_set *)pmuboardobjgrp;
57
58 gk20a_dbg_info("");
59
60 /* check whether pmuboardobjgrp has a valid boardobj in index */
61 if (idx >= CTRL_BOARDOBJGRP_E255_MAX_OBJECTS)
62 return -EINVAL;
63
64 *ppboardobjpmudata = (struct nv_pmu_boardobj *)
65 &pgrp_set->objects[idx].data.board_obj;
66 gk20a_dbg_info(" Done");
67 return 0;
68}
69
70u32 vfe_equ_sw_setup(struct gk20a *g)
71{
72 u32 status;
73 struct boardobjgrp *pboardobjgrp = NULL;
74 struct vfe_equs *pvfeequobjs;
75
76 gk20a_dbg_info("");
77
78 status = boardobjgrpconstruct_e255(&g->perf_pmu.vfe_equobjs.super);
79 if (status) {
80 gk20a_err(dev_from_gk20a(g),
81 "error creating boardobjgrp for clk domain, status - 0x%x",
82 status);
83 goto done;
84 }
85
86 pboardobjgrp = &g->perf_pmu.vfe_equobjs.super.super;
87 pvfeequobjs = &(g->perf_pmu.vfe_equobjs);
88
89 BOARDOBJGRP_PMU_CONSTRUCT(pboardobjgrp, PERF, VFE_EQU);
90
91 status = BOARDOBJGRP_PMU_CMD_GRP_SET_CONSTRUCT(g, pboardobjgrp,
92 perf, PERF, vfe_equ, VFE_EQU);
93 if (status) {
94 gk20a_err(dev_from_gk20a(g),
95 "error constructing PMU_BOARDOBJ_CMD_GRP_SET interface - 0x%x",
96 status);
97 goto done;
98 }
99
100 pboardobjgrp->pmudatainit = _vfe_equs_pmudatainit;
101 pboardobjgrp->pmudatainstget = _vfe_equs_pmudata_instget;
102
103 status = devinit_get_vfe_equ_table(g, pvfeequobjs);
104 if (status)
105 goto done;
106
107done:
108 gk20a_dbg_info(" done status %x", status);
109 return status;
110}
111
112u32 vfe_equ_pmu_setup(struct gk20a *g)
113{
114 u32 status;
115 struct boardobjgrp *pboardobjgrp = NULL;
116
117 gk20a_dbg_info("");
118
119 pboardobjgrp = &g->perf_pmu.vfe_equobjs.super.super;
120
121 if (!pboardobjgrp->bconstructed)
122 return -EINVAL;
123
124 status = pboardobjgrp->pmuinithandle(g, pboardobjgrp);
125
126 gk20a_dbg_info("Done");
127 return status;
128}
129
130static u32 devinit_get_vfe_equ_table(struct gk20a *g,
131 struct vfe_equs *pvfeequobjs)
132{
133 u32 status = 0;
134 u8 *vfeequs_tbl_ptr = NULL;
135 struct vbios_vfe_3x_header_struct vfeequs_tbl_header = { 0 };
136 struct vbios_vfe_3x_equ_entry_struct equ = { 0 };
137 u8 *vfeequs_tbl_entry_ptr = NULL;
138 u8 *rd_offset_ptr = NULL;
139 u32 index = 0;
140 struct vfe_equ *pequ;
141 u8 equ_type = 0;
142 u32 szfmt;
143 union {
144 struct boardobj board_obj;
145 struct vfe_equ super;
146 struct vfe_equ_compare compare;
147 struct vfe_equ_minmax minmax;
148 struct vfe_equ_quadratic quadratic;
149 } equ_data;
150
151 gk20a_dbg_info("");
152
153 if (g->ops.bios.get_perf_table_ptrs) {
154 vfeequs_tbl_ptr = (u8 *)g->ops.bios.get_perf_table_ptrs(g,
155 g->bios.perf_token,
156 CONTINUOUS_VIRTUAL_BINNING_TABLE);
157 if (vfeequs_tbl_ptr == NULL) {
158 status = -EINVAL;
159 goto done;
160 }
161 }
162
163 memcpy(&vfeequs_tbl_header, vfeequs_tbl_ptr,
164 VBIOS_CLOCKS_TABLE_1X_HEADER_SIZE_07);
165 if (vfeequs_tbl_header.header_size != VBIOS_CLOCKS_TABLE_1X_HEADER_SIZE_07) {
166 status = -EINVAL;
167 goto done;
168 }
169
170 if (vfeequs_tbl_header.vfe_equ_entry_size ==
171 VBIOS_VFE_3X_EQU_ENTRY_SIZE_17)
172 szfmt = VBIOS_VFE_3X_EQU_ENTRY_SIZE_17;
173 else if (vfeequs_tbl_header.vfe_equ_entry_size ==
174 VBIOS_VFE_3X_EQU_ENTRY_SIZE_18)
175 szfmt = VBIOS_VFE_3X_EQU_ENTRY_SIZE_18;
176 else {
177 status = -EINVAL;
178 goto done;
179 }
180
181 vfeequs_tbl_entry_ptr = vfeequs_tbl_ptr +
182 vfeequs_tbl_header.header_size +
183 (vfeequs_tbl_header.vfe_var_entry_count *
184 vfeequs_tbl_header.vfe_var_entry_size);
185
186 for (index = 0;
187 index < vfeequs_tbl_header.vfe_equ_entry_count;
188 index++) {
189 memset(&equ, 0, sizeof(struct vbios_vfe_3x_equ_entry_struct));
190
191 rd_offset_ptr = vfeequs_tbl_entry_ptr +
192 (index * vfeequs_tbl_header.vfe_equ_entry_size);
193
194 memcpy(&equ, rd_offset_ptr, szfmt);
195
196 equ_data.super.var_idx = (u8)equ.var_idx;
197 equ_data.super.equ_idx_next =
198 (equ.equ_idx_next == VBIOS_VFE_3X_EQU_ENTRY_IDX_INVALID) ?
199 CTRL_BOARDOBJ_IDX_INVALID : (u8)equ.equ_idx_next;
200 equ_data.super.out_range_min = equ.out_range_min;
201 equ_data.super.out_range_max = equ.out_range_max;
202
203 switch (BIOS_GET_FIELD(equ.param3, VBIOS_VFE_3X_EQU_ENTRY_PAR3_OUTPUT_TYPE)) {
204 case VBIOS_VFE_3X_EQU_ENTRY_PAR3_OUTPUT_TYPE_UNITLESS:
205 equ_data.super.output_type =
206 CTRL_PERF_VFE_EQU_OUTPUT_TYPE_UNITLESS;
207 break;
208
209 case VBIOS_VFE_3X_EQU_ENTRY_PAR3_OUTPUT_TYPE_FREQ_MHZ:
210 equ_data.super.output_type =
211 CTRL_PERF_VFE_EQU_OUTPUT_TYPE_FREQ_MHZ;
212 break;
213
214 case VBIOS_VFE_3X_EQU_ENTRY_PAR3_OUTPUT_TYPE_VOLT_UV:
215 equ_data.super.output_type =
216 CTRL_PERF_VFE_EQU_OUTPUT_TYPE_VOLT_UV;
217 break;
218
219 case VBIOS_VFE_3X_EQU_ENTRY_PAR3_OUTPUT_TYPE_VF_GAIN:
220 equ_data.super.output_type =
221 CTRL_PERF_VFE_EQU_OUTPUT_TYPE_VF_GAIN;
222 break;
223
224 case VBIOS_VFE_3X_EQU_ENTRY_PAR3_OUTPUT_TYPE_VOLT_DELTA_UV:
225 equ_data.super.output_type =
226 CTRL_PERF_VFE_EQU_OUTPUT_TYPE_VOLT_DELTA_UV;
227 break;
228
229 default:
230 gk20a_err(dev_from_gk20a(g),
231 "unrecognized output id @vfeequ index %d",
232 index);
233 goto done;
234 }
235
236 switch ((u8)equ.type) {
237 case VBIOS_VFE_3X_EQU_ENTRY_TYPE_DISABLED:
238 case VBIOS_VFE_3X_EQU_ENTRY_TYPE_QUADRATIC_FXP:
239 case VBIOS_VFE_3X_EQU_ENTRY_TYPE_MINMAX_FXP:
240 continue;
241 break;
242
243 case VBIOS_VFE_3X_EQU_ENTRY_TYPE_QUADRATIC:
244 equ_type = CTRL_PERF_VFE_EQU_TYPE_QUADRATIC;
245 equ_data.quadratic.coeffs[0] = equ.param0;
246 equ_data.quadratic.coeffs[1] = equ.param1;
247 equ_data.quadratic.coeffs[2] = equ.param2;
248 break;
249
250 case VBIOS_VFE_3X_EQU_ENTRY_TYPE_MINMAX:
251 equ_type = CTRL_PERF_VFE_EQU_TYPE_MINMAX;
252 equ_data.minmax.b_max = BIOS_GET_FIELD(equ.param0,
253 VBIOS_VFE_3X_EQU_ENTRY_PAR0_MINMAX_CRIT) &&
254 VBIOS_VFE_3X_EQU_ENTRY_PAR0_MINMAX_CRIT_MAX;
255 equ_data.minmax.equ_idx0 = (u8)BIOS_GET_FIELD(
256 equ.param0,
257 VBIOS_VFE_3X_EQU_ENTRY_PAR0_MINMAX_VFE_EQU_IDX_0);
258 equ_data.minmax.equ_idx1 = (u8)BIOS_GET_FIELD(
259 equ.param0,
260 VBIOS_VFE_3X_EQU_ENTRY_PAR0_MINMAX_VFE_EQU_IDX_1);
261 break;
262
263 case VBIOS_VFE_3X_EQU_ENTRY_TYPE_COMPARE:
264 {
265 u8 cmp_func = (u8)BIOS_GET_FIELD(
266 equ.param1,
267 VBIOS_VFE_3X_EQU_ENTRY_PAR1_COMPARE_FUNCTION);
268 equ_type = CTRL_PERF_VFE_EQU_TYPE_COMPARE;
269
270 switch (cmp_func) {
271 case VBIOS_VFE_3X_EQU_ENTRY_PAR1_COMPARE_FUNCTION_EQUAL:
272 equ_data.compare.func_id =
273 CTRL_PERF_VFE_EQU_COMPARE_FUNCTION_EQUAL;
274 break;
275
276 case VBIOS_VFE_3X_EQU_ENTRY_PAR1_COMPARE_FUNCTION_GREATER_EQ:
277 equ_data.compare.func_id =
278 CTRL_PERF_VFE_EQU_COMPARE_FUNCTION_GREATER_EQ;
279 break;
280 case VBIOS_VFE_3X_EQU_ENTRY_PAR1_COMPARE_FUNCTION_GREATER:
281 equ_data.compare.func_id =
282 CTRL_PERF_VFE_EQU_COMPARE_FUNCTION_GREATER;
283 break;
284 default:
285 gk20a_err(dev_from_gk20a(g),
286 "invalid vfe compare index %x type %x ",
287 index, cmp_func);
288 status = -EINVAL;
289 goto done;
290 }
291 equ_data.compare.equ_idx_true = (u8)BIOS_GET_FIELD(
292 equ.param1,
293 VBIOS_VFE_3X_EQU_ENTRY_PAR1_COMPARE_VFE_EQU_IDX_TRUE);
294 equ_data.compare.equ_idx_false = (u8)BIOS_GET_FIELD(
295 equ.param1,
296 VBIOS_VFE_3X_EQU_ENTRY_PAR1_COMPARE_VFE_EQU_IDX_FALSE);
297 equ_data.compare.criteria = equ.param0;
298 break;
299 }
300 default:
301 status = -EINVAL;
302 gk20a_err(dev_from_gk20a(g),
303 "Invalid equ[%d].type = 0x%x.",
304 index, (u8)equ.type);
305 goto done;
306 }
307
308 equ_data.board_obj.type = equ_type;
309 pequ = construct_vfe_equ(g, (void *)&equ_data);
310
311 if (pequ == NULL) {
312 gk20a_err(dev_from_gk20a(g),
313 "error constructing vfe_equ boardobj %d", index);
314 status = -EINVAL;
315 goto done;
316 }
317
318 status = boardobjgrp_objinsert(&pvfeequobjs->super.super,
319 (struct boardobj *)pequ, index);
320 if (status) {
321 gk20a_err(dev_from_gk20a(g),
322 "error adding vfe_equ boardobj %d", index);
323 status = -EINVAL;
324 goto done;
325 }
326 }
327done:
328 gk20a_dbg_info(" done status %x", status);
329 return status;
330}
331
332static u32 _vfe_equ_pmudatainit_super(struct gk20a *g,
333 struct boardobj *board_obj_ptr,
334 struct nv_pmu_boardobj *ppmudata)
335{
336 u32 status = 0;
337 struct vfe_equ *pvfe_equ;
338 struct nv_pmu_vfe_equ *pset;
339
340 gk20a_dbg_info("");
341
342 status = boardobj_pmudatainit_super(g, board_obj_ptr, ppmudata);
343 if (status != 0)
344 return status;
345
346 pvfe_equ = (struct vfe_equ *)board_obj_ptr;
347
348 pset = (struct nv_pmu_vfe_equ *)
349 ppmudata;
350
351 pset->var_idx = pvfe_equ->var_idx;
352 pset->equ_idx_next = pvfe_equ->equ_idx_next;
353 pset->output_type = pvfe_equ->output_type;
354 pset->out_range_min = pvfe_equ->out_range_min;
355 pset->out_range_max = pvfe_equ->out_range_max;
356
357 return status;
358}
359
360static u32 vfe_equ_construct_super(struct gk20a *g,
361 struct boardobj **ppboardobj,
362 u16 size, void *pargs)
363{
364 struct vfe_equ *pvfeequ;
365 struct vfe_equ *ptmpequ = (struct vfe_equ *)pargs;
366 u32 status = 0;
367
368 status = boardobj_construct_super(g, ppboardobj,
369 size, pargs);
370 if (status)
371 return -EINVAL;
372
373 pvfeequ = (struct vfe_equ *)*ppboardobj;
374
375 pvfeequ->super.pmudatainit =
376 _vfe_equ_pmudatainit_super;
377
378 pvfeequ->var_idx = ptmpequ->var_idx;
379 pvfeequ->equ_idx_next = ptmpequ->equ_idx_next;
380 pvfeequ->output_type = ptmpequ->output_type;
381 pvfeequ->out_range_min = ptmpequ->out_range_min;
382 pvfeequ->out_range_max = ptmpequ->out_range_max;
383
384 return status;
385}
386
387static u32 _vfe_equ_pmudatainit_compare(struct gk20a *g,
388 struct boardobj *board_obj_ptr,
389 struct nv_pmu_boardobj *ppmudata)
390{
391 u32 status = 0;
392 struct vfe_equ_compare *pvfe_equ_compare;
393 struct nv_pmu_vfe_equ_compare *pset;
394
395 gk20a_dbg_info("");
396
397 status = _vfe_equ_pmudatainit_super(g, board_obj_ptr, ppmudata);
398 if (status != 0)
399 return status;
400
401 pvfe_equ_compare = (struct vfe_equ_compare *)board_obj_ptr;
402
403 pset = (struct nv_pmu_vfe_equ_compare *) ppmudata;
404
405 pset->func_id = pvfe_equ_compare->func_id;
406 pset->equ_idx_true = pvfe_equ_compare->equ_idx_true;
407 pset->equ_idx_false = pvfe_equ_compare->equ_idx_false;
408 pset->criteria = pvfe_equ_compare->criteria;
409
410 return status;
411}
412
413
414static u32 vfe_equ_construct_compare(struct gk20a *g,
415 struct boardobj **ppboardobj,
416 u16 size, void *pargs)
417{
418 struct boardobj *ptmpobj = (struct boardobj *)pargs;
419 struct vfe_equ_compare *pvfeequ;
420 struct vfe_equ_compare *ptmpequ =
421 (struct vfe_equ_compare *)pargs;
422 u32 status = 0;
423
424 if (BOARDOBJ_GET_TYPE(pargs) != CTRL_PERF_VFE_EQU_TYPE_COMPARE)
425 return -EINVAL;
426
427 ptmpobj->type_mask |= BIT(CTRL_PERF_VFE_EQU_TYPE_COMPARE);
428 status = vfe_equ_construct_super(g, ppboardobj, size, pargs);
429 if (status)
430 return -EINVAL;
431
432 pvfeequ = (struct vfe_equ_compare *)*ppboardobj;
433
434 pvfeequ->super.super.pmudatainit =
435 _vfe_equ_pmudatainit_compare;
436
437 pvfeequ->func_id = ptmpequ->func_id;
438 pvfeequ->equ_idx_true = ptmpequ->equ_idx_true;
439 pvfeequ->equ_idx_false = ptmpequ->equ_idx_false;
440 pvfeequ->criteria = ptmpequ->criteria;
441
442
443 return status;
444}
445
446static u32 _vfe_equ_pmudatainit_minmax(struct gk20a *g,
447 struct boardobj *board_obj_ptr,
448 struct nv_pmu_boardobj *ppmudata)
449{
450 u32 status = 0;
451 struct vfe_equ_minmax *pvfe_equ_minmax;
452 struct nv_pmu_vfe_equ_minmax *pset;
453
454 gk20a_dbg_info("");
455
456 status = _vfe_equ_pmudatainit_super(g, board_obj_ptr, ppmudata);
457 if (status != 0)
458 return status;
459
460 pvfe_equ_minmax = (struct vfe_equ_minmax *)board_obj_ptr;
461
462 pset = (struct nv_pmu_vfe_equ_minmax *)
463 ppmudata;
464
465 pset->b_max = pvfe_equ_minmax->b_max;
466 pset->equ_idx0 = pvfe_equ_minmax->equ_idx0;
467 pset->equ_idx1 = pvfe_equ_minmax->equ_idx1;
468
469 return status;
470}
471
472static u32 vfe_equ_construct_minmax(struct gk20a *g,
473 struct boardobj **ppboardobj,
474 u16 size, void *pargs)
475{
476 struct boardobj *ptmpobj = (struct boardobj *)pargs;
477 struct vfe_equ_minmax *pvfeequ;
478 struct vfe_equ_minmax *ptmpequ =
479 (struct vfe_equ_minmax *)pargs;
480 u32 status = 0;
481
482 if (BOARDOBJ_GET_TYPE(pargs) != CTRL_PERF_VFE_EQU_TYPE_MINMAX)
483 return -EINVAL;
484
485 ptmpobj->type_mask |= BIT(CTRL_PERF_VFE_EQU_TYPE_MINMAX);
486 status = vfe_equ_construct_super(g, ppboardobj, size, pargs);
487 if (status)
488 return -EINVAL;
489
490 pvfeequ = (struct vfe_equ_minmax *)*ppboardobj;
491
492 pvfeequ->super.super.pmudatainit =
493 _vfe_equ_pmudatainit_minmax;
494 pvfeequ->b_max = ptmpequ->b_max;
495 pvfeequ->equ_idx0 = ptmpequ->equ_idx0;
496 pvfeequ->equ_idx1 = ptmpequ->equ_idx1;
497
498 return status;
499}
500
501static u32 _vfe_equ_pmudatainit_quadratic(struct gk20a *g,
502 struct boardobj *board_obj_ptr,
503 struct nv_pmu_boardobj *ppmudata)
504{
505 u32 status = 0;
506 struct vfe_equ_quadratic *pvfe_equ_quadratic;
507 struct nv_pmu_vfe_equ_quadratic *pset;
508 u32 i;
509
510 gk20a_dbg_info("");
511
512 status = _vfe_equ_pmudatainit_super(g, board_obj_ptr, ppmudata);
513 if (status != 0)
514 return status;
515
516 pvfe_equ_quadratic = (struct vfe_equ_quadratic *)board_obj_ptr;
517
518 pset = (struct nv_pmu_vfe_equ_quadratic *) ppmudata;
519
520 for (i = 0; i < CTRL_PERF_VFE_EQU_QUADRATIC_COEFF_COUNT; i++)
521 pset->coeffs[i] = pvfe_equ_quadratic->coeffs[i];
522
523 return status;
524}
525
526static u32 vfe_equ_construct_quadratic(struct gk20a *g,
527 struct boardobj **ppboardobj,
528 u16 size, void *pargs)
529{
530 struct boardobj *ptmpobj = (struct boardobj *)pargs;
531 struct vfe_equ_quadratic *pvfeequ;
532 struct vfe_equ_quadratic *ptmpequ =
533 (struct vfe_equ_quadratic *)pargs;
534 u32 status = 0;
535 u32 i;
536
537 if (BOARDOBJ_GET_TYPE(pargs) != CTRL_PERF_VFE_EQU_TYPE_QUADRATIC)
538 return -EINVAL;
539
540 ptmpobj->type_mask |= BIT(CTRL_PERF_VFE_EQU_TYPE_QUADRATIC);
541 status = vfe_equ_construct_super(g, ppboardobj, size, pargs);
542 if (status)
543 return -EINVAL;
544
545 pvfeequ = (struct vfe_equ_quadratic *)*ppboardobj;
546
547 pvfeequ->super.super.pmudatainit =
548 _vfe_equ_pmudatainit_quadratic;
549
550 for (i = 0; i < CTRL_PERF_VFE_EQU_QUADRATIC_COEFF_COUNT; i++)
551 pvfeequ->coeffs[i] = ptmpequ->coeffs[i];
552
553 return status;
554}
555
556static struct vfe_equ *construct_vfe_equ(struct gk20a *g, void *pargs)
557{
558 struct boardobj *board_obj_ptr = NULL;
559 u32 status;
560
561 gk20a_dbg_info("");
562
563 switch (BOARDOBJ_GET_TYPE(pargs)) {
564 case CTRL_PERF_VFE_EQU_TYPE_COMPARE:
565 status = vfe_equ_construct_compare(g, &board_obj_ptr,
566 sizeof(struct vfe_equ_compare), pargs);
567 break;
568
569 case CTRL_PERF_VFE_EQU_TYPE_MINMAX:
570 status = vfe_equ_construct_minmax(g, &board_obj_ptr,
571 sizeof(struct vfe_equ_minmax), pargs);
572 break;
573
574 case CTRL_PERF_VFE_EQU_TYPE_QUADRATIC:
575 status = vfe_equ_construct_quadratic(g, &board_obj_ptr,
576 sizeof(struct vfe_equ_quadratic), pargs);
577 break;
578
579 default:
580 return NULL;
581
582 }
583
584 if (status)
585 return NULL;
586
587 gk20a_dbg_info(" Done");
588
589 return (struct vfe_equ *)board_obj_ptr;
590}