summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/perf/vfe_equ.c
diff options
context:
space:
mode:
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..2493061e
--- /dev/null
+++ b/drivers/gpu/nvgpu/perf/vfe_equ.c
@@ -0,0 +1,590 @@
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/bios.h>
24
25#include "gk20a/gk20a.h"
26#include "perf.h"
27#include "vfe_equ.h"
28#include "boardobj/boardobjgrp.h"
29#include "boardobj/boardobjgrp_e255.h"
30#include "ctrl/ctrlclk.h"
31#include "ctrl/ctrlvolt.h"
32
33static struct vfe_equ *construct_vfe_equ(struct gk20a *g, void *pargs);
34static u32 devinit_get_vfe_equ_table(struct gk20a *g,
35 struct vfe_equs *pequobjs);
36
37static u32 _vfe_equs_pmudatainit(struct gk20a *g,
38 struct boardobjgrp *pboardobjgrp,
39 struct nv_pmu_boardobjgrp_super *pboardobjgrppmu)
40{
41 u32 status = 0;
42
43 status = boardobjgrp_pmudatainit_e255(g, pboardobjgrp, pboardobjgrppmu);
44 if (status) {
45 nvgpu_err(g, "error updating pmu boardobjgrp for vfe equ 0x%x",
46 status);
47 goto done;
48 }
49
50done:
51 return status;
52}
53
54static u32 _vfe_equs_pmudata_instget(struct gk20a *g,
55 struct nv_pmu_boardobjgrp *pmuboardobjgrp,
56 struct nv_pmu_boardobj **ppboardobjpmudata,
57 u8 idx)
58{
59 struct nv_pmu_perf_vfe_equ_boardobj_grp_set *pgrp_set =
60 (struct nv_pmu_perf_vfe_equ_boardobj_grp_set *)pmuboardobjgrp;
61
62 gk20a_dbg_info("");
63
64 /* check whether pmuboardobjgrp has a valid boardobj in index */
65 if (idx >= CTRL_BOARDOBJGRP_E255_MAX_OBJECTS)
66 return -EINVAL;
67
68 *ppboardobjpmudata = (struct nv_pmu_boardobj *)
69 &pgrp_set->objects[idx].data.board_obj;
70 gk20a_dbg_info(" Done");
71 return 0;
72}
73
74u32 vfe_equ_sw_setup(struct gk20a *g)
75{
76 u32 status;
77 struct boardobjgrp *pboardobjgrp = NULL;
78 struct vfe_equs *pvfeequobjs;
79
80 gk20a_dbg_info("");
81
82 status = boardobjgrpconstruct_e255(g, &g->perf_pmu.vfe_equobjs.super);
83 if (status) {
84 nvgpu_err(g,
85 "error creating boardobjgrp for clk domain, status - 0x%x",
86 status);
87 goto done;
88 }
89
90 pboardobjgrp = &g->perf_pmu.vfe_equobjs.super.super;
91 pvfeequobjs = &(g->perf_pmu.vfe_equobjs);
92
93 BOARDOBJGRP_PMU_CONSTRUCT(pboardobjgrp, PERF, VFE_EQU);
94
95 status = BOARDOBJGRP_PMU_CMD_GRP_SET_CONSTRUCT(g, pboardobjgrp,
96 perf, PERF, vfe_equ, VFE_EQU);
97 if (status) {
98 nvgpu_err(g,
99 "error constructing PMU_BOARDOBJ_CMD_GRP_SET interface - 0x%x",
100 status);
101 goto done;
102 }
103
104 pboardobjgrp->pmudatainit = _vfe_equs_pmudatainit;
105 pboardobjgrp->pmudatainstget = _vfe_equs_pmudata_instget;
106
107 status = devinit_get_vfe_equ_table(g, pvfeequobjs);
108 if (status)
109 goto done;
110
111done:
112 gk20a_dbg_info(" done status %x", status);
113 return status;
114}
115
116u32 vfe_equ_pmu_setup(struct gk20a *g)
117{
118 u32 status;
119 struct boardobjgrp *pboardobjgrp = NULL;
120
121 gk20a_dbg_info("");
122
123 pboardobjgrp = &g->perf_pmu.vfe_equobjs.super.super;
124
125 if (!pboardobjgrp->bconstructed)
126 return -EINVAL;
127
128 status = pboardobjgrp->pmuinithandle(g, pboardobjgrp);
129
130 gk20a_dbg_info("Done");
131 return status;
132}
133
134static u32 devinit_get_vfe_equ_table(struct gk20a *g,
135 struct vfe_equs *pvfeequobjs)
136{
137 u32 status = 0;
138 u8 *vfeequs_tbl_ptr = NULL;
139 struct vbios_vfe_3x_header_struct vfeequs_tbl_header = { 0 };
140 struct vbios_vfe_3x_equ_entry_struct equ = { 0 };
141 u8 *vfeequs_tbl_entry_ptr = NULL;
142 u8 *rd_offset_ptr = NULL;
143 u32 index = 0;
144 struct vfe_equ *pequ;
145 u8 equ_type = 0;
146 u32 szfmt;
147 union {
148 struct boardobj board_obj;
149 struct vfe_equ super;
150 struct vfe_equ_compare compare;
151 struct vfe_equ_minmax minmax;
152 struct vfe_equ_quadratic quadratic;
153 } equ_data;
154
155 gk20a_dbg_info("");
156
157 vfeequs_tbl_ptr = (u8 *)nvgpu_bios_get_perf_table_ptrs(g,
158 g->bios.perf_token,
159 CONTINUOUS_VIRTUAL_BINNING_TABLE);
160
161 if (vfeequs_tbl_ptr == NULL) {
162 status = -EINVAL;
163 goto done;
164 }
165
166 memcpy(&vfeequs_tbl_header, vfeequs_tbl_ptr,
167 VBIOS_CLOCKS_TABLE_1X_HEADER_SIZE_07);
168 if (vfeequs_tbl_header.header_size != VBIOS_CLOCKS_TABLE_1X_HEADER_SIZE_07) {
169 status = -EINVAL;
170 goto done;
171 }
172
173 if (vfeequs_tbl_header.vfe_equ_entry_size ==
174 VBIOS_VFE_3X_EQU_ENTRY_SIZE_17)
175 szfmt = VBIOS_VFE_3X_EQU_ENTRY_SIZE_17;
176 else if (vfeequs_tbl_header.vfe_equ_entry_size ==
177 VBIOS_VFE_3X_EQU_ENTRY_SIZE_18)
178 szfmt = VBIOS_VFE_3X_EQU_ENTRY_SIZE_18;
179 else {
180 status = -EINVAL;
181 goto done;
182 }
183
184 vfeequs_tbl_entry_ptr = vfeequs_tbl_ptr +
185 vfeequs_tbl_header.header_size +
186 (vfeequs_tbl_header.vfe_var_entry_count *
187 vfeequs_tbl_header.vfe_var_entry_size);
188
189 for (index = 0;
190 index < vfeequs_tbl_header.vfe_equ_entry_count;
191 index++) {
192 memset(&equ, 0, sizeof(struct vbios_vfe_3x_equ_entry_struct));
193
194 rd_offset_ptr = vfeequs_tbl_entry_ptr +
195 (index * vfeequs_tbl_header.vfe_equ_entry_size);
196
197 memcpy(&equ, rd_offset_ptr, szfmt);
198
199 equ_data.super.var_idx = (u8)equ.var_idx;
200 equ_data.super.equ_idx_next =
201 (equ.equ_idx_next == VBIOS_VFE_3X_EQU_ENTRY_IDX_INVALID) ?
202 CTRL_BOARDOBJ_IDX_INVALID : (u8)equ.equ_idx_next;
203 equ_data.super.out_range_min = equ.out_range_min;
204 equ_data.super.out_range_max = equ.out_range_max;
205
206 switch (BIOS_GET_FIELD(equ.param3, VBIOS_VFE_3X_EQU_ENTRY_PAR3_OUTPUT_TYPE)) {
207 case VBIOS_VFE_3X_EQU_ENTRY_PAR3_OUTPUT_TYPE_UNITLESS:
208 equ_data.super.output_type =
209 CTRL_PERF_VFE_EQU_OUTPUT_TYPE_UNITLESS;
210 break;
211
212 case VBIOS_VFE_3X_EQU_ENTRY_PAR3_OUTPUT_TYPE_FREQ_MHZ:
213 equ_data.super.output_type =
214 CTRL_PERF_VFE_EQU_OUTPUT_TYPE_FREQ_MHZ;
215 break;
216
217 case VBIOS_VFE_3X_EQU_ENTRY_PAR3_OUTPUT_TYPE_VOLT_UV:
218 equ_data.super.output_type =
219 CTRL_PERF_VFE_EQU_OUTPUT_TYPE_VOLT_UV;
220 break;
221
222 case VBIOS_VFE_3X_EQU_ENTRY_PAR3_OUTPUT_TYPE_VF_GAIN:
223 equ_data.super.output_type =
224 CTRL_PERF_VFE_EQU_OUTPUT_TYPE_VF_GAIN;
225 break;
226
227 case VBIOS_VFE_3X_EQU_ENTRY_PAR3_OUTPUT_TYPE_VOLT_DELTA_UV:
228 equ_data.super.output_type =
229 CTRL_PERF_VFE_EQU_OUTPUT_TYPE_VOLT_DELTA_UV;
230 break;
231
232 default:
233 nvgpu_err(g, "unrecognized output id @vfeequ index %d",
234 index);
235 goto done;
236 }
237
238 switch ((u8)equ.type) {
239 case VBIOS_VFE_3X_EQU_ENTRY_TYPE_DISABLED:
240 case VBIOS_VFE_3X_EQU_ENTRY_TYPE_QUADRATIC_FXP:
241 case VBIOS_VFE_3X_EQU_ENTRY_TYPE_MINMAX_FXP:
242 continue;
243 break;
244
245 case VBIOS_VFE_3X_EQU_ENTRY_TYPE_QUADRATIC:
246 equ_type = CTRL_PERF_VFE_EQU_TYPE_QUADRATIC;
247 equ_data.quadratic.coeffs[0] = equ.param0;
248 equ_data.quadratic.coeffs[1] = equ.param1;
249 equ_data.quadratic.coeffs[2] = equ.param2;
250 break;
251
252 case VBIOS_VFE_3X_EQU_ENTRY_TYPE_MINMAX:
253 equ_type = CTRL_PERF_VFE_EQU_TYPE_MINMAX;
254 equ_data.minmax.b_max = BIOS_GET_FIELD(equ.param0,
255 VBIOS_VFE_3X_EQU_ENTRY_PAR0_MINMAX_CRIT) &&
256 VBIOS_VFE_3X_EQU_ENTRY_PAR0_MINMAX_CRIT_MAX;
257 equ_data.minmax.equ_idx0 = (u8)BIOS_GET_FIELD(
258 equ.param0,
259 VBIOS_VFE_3X_EQU_ENTRY_PAR0_MINMAX_VFE_EQU_IDX_0);
260 equ_data.minmax.equ_idx1 = (u8)BIOS_GET_FIELD(
261 equ.param0,
262 VBIOS_VFE_3X_EQU_ENTRY_PAR0_MINMAX_VFE_EQU_IDX_1);
263 break;
264
265 case VBIOS_VFE_3X_EQU_ENTRY_TYPE_COMPARE:
266 {
267 u8 cmp_func = (u8)BIOS_GET_FIELD(
268 equ.param1,
269 VBIOS_VFE_3X_EQU_ENTRY_PAR1_COMPARE_FUNCTION);
270 equ_type = CTRL_PERF_VFE_EQU_TYPE_COMPARE;
271
272 switch (cmp_func) {
273 case VBIOS_VFE_3X_EQU_ENTRY_PAR1_COMPARE_FUNCTION_EQUAL:
274 equ_data.compare.func_id =
275 CTRL_PERF_VFE_EQU_COMPARE_FUNCTION_EQUAL;
276 break;
277
278 case VBIOS_VFE_3X_EQU_ENTRY_PAR1_COMPARE_FUNCTION_GREATER_EQ:
279 equ_data.compare.func_id =
280 CTRL_PERF_VFE_EQU_COMPARE_FUNCTION_GREATER_EQ;
281 break;
282 case VBIOS_VFE_3X_EQU_ENTRY_PAR1_COMPARE_FUNCTION_GREATER:
283 equ_data.compare.func_id =
284 CTRL_PERF_VFE_EQU_COMPARE_FUNCTION_GREATER;
285 break;
286 default:
287 nvgpu_err(g,
288 "invalid vfe compare index %x type %x ",
289 index, cmp_func);
290 status = -EINVAL;
291 goto done;
292 }
293 equ_data.compare.equ_idx_true = (u8)BIOS_GET_FIELD(
294 equ.param1,
295 VBIOS_VFE_3X_EQU_ENTRY_PAR1_COMPARE_VFE_EQU_IDX_TRUE);
296 equ_data.compare.equ_idx_false = (u8)BIOS_GET_FIELD(
297 equ.param1,
298 VBIOS_VFE_3X_EQU_ENTRY_PAR1_COMPARE_VFE_EQU_IDX_FALSE);
299 equ_data.compare.criteria = equ.param0;
300 break;
301 }
302 default:
303 status = -EINVAL;
304 nvgpu_err(g, "Invalid equ[%d].type = 0x%x.",
305 index, (u8)equ.type);
306 goto done;
307 }
308
309 equ_data.board_obj.type = equ_type;
310 pequ = construct_vfe_equ(g, (void *)&equ_data);
311
312 if (pequ == NULL) {
313 nvgpu_err(g,
314 "error constructing vfe_equ boardobj %d", index);
315 status = -EINVAL;
316 goto done;
317 }
318
319 status = boardobjgrp_objinsert(&pvfeequobjs->super.super,
320 (struct boardobj *)pequ, index);
321 if (status) {
322 nvgpu_err(g, "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}