diff options
author | Thomas Fleury <tfleury@nvidia.com> | 2017-01-18 18:08:38 -0500 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2017-01-23 08:53:55 -0500 |
commit | a86122e01a3b27652f2dea8cbdadd47ed6b3d216 (patch) | |
tree | 3e1abfe166ec22a7307cd02ff35da233ac4735a4 /drivers/gpu/nvgpu/pmgr | |
parent | 8b4aadaaddce14bcf4109dd9f835993865c60b3b (diff) |
gpu: nvgpu: read overcurrent policy from VBIOS
Since pwr_sensors, pwr_topology_ and pwr_policy_* tables in bios.h
are not defined as packed, nvgpu driver is not able to find hw
threshold pwr_policy table in VBIOS and ends up hard coding the HW
thershold policy.
Changed definitions to packed, and explicitly unpack structures
when parsing the power policy table. Removed the function that
did the hard coding.
Jira DNVGPU-206
Change-Id: Idc2b5b5c86ddfe735631190dda10218cc462be3b
Signed-off-by: Thomas Fleury <tfleury@nvidia.com>
Reviewed-on: http://git-master/r/1290303
GVS: Gerrit_Virtual_Submit
Reviewed-by: Vijayakumar Subbu <vsubbu@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/pmgr')
-rw-r--r-- | drivers/gpu/nvgpu/pmgr/pwrpolicy.c | 390 |
1 files changed, 200 insertions, 190 deletions
diff --git a/drivers/gpu/nvgpu/pmgr/pwrpolicy.c b/drivers/gpu/nvgpu/pmgr/pwrpolicy.c index cce3bd5e..1e7e19a3 100644 --- a/drivers/gpu/nvgpu/pmgr/pwrpolicy.c +++ b/drivers/gpu/nvgpu/pmgr/pwrpolicy.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. | 2 | * Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 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, | 5 | * under the terms and conditions of the GNU General Public License, |
@@ -262,6 +262,11 @@ static struct boardobj *construct_pwr_policy(struct gk20a *g, | |||
262 | pwrpolicyhwthreshold = (struct pwr_policy_hw_threshold*)board_obj_ptr; | 262 | pwrpolicyhwthreshold = (struct pwr_policy_hw_threshold*)board_obj_ptr; |
263 | pwrpolicy = (struct pwr_policy *)board_obj_ptr; | 263 | pwrpolicy = (struct pwr_policy *)board_obj_ptr; |
264 | 264 | ||
265 | gk20a_dbg_fn("min=%u rated=%u max=%u", | ||
266 | pwrpolicyparams->limit_min, | ||
267 | pwrpolicyparams->limit_rated, | ||
268 | pwrpolicyparams->limit_max); | ||
269 | |||
265 | /* Set Super class interfaces */ | 270 | /* Set Super class interfaces */ |
266 | board_obj_ptr->pmudatainit = _pwr_domains_pmudatainit_hw_threshold; | 271 | board_obj_ptr->pmudatainit = _pwr_domains_pmudatainit_hw_threshold; |
267 | 272 | ||
@@ -351,53 +356,6 @@ static struct boardobj *construct_pwr_policy(struct gk20a *g, | |||
351 | return board_obj_ptr; | 356 | return board_obj_ptr; |
352 | } | 357 | } |
353 | 358 | ||
354 | static u32 _pwr_policy_construct_WAR_policy(struct gk20a *g, | ||
355 | struct pmgr_pwr_policy *ppwrpolicyobjs, | ||
356 | union pwr_policy_data_union *ppwrpolicydata, | ||
357 | u16 pwr_policy_size, | ||
358 | u32 hw_threshold_policy_index, | ||
359 | u32 obj_index) | ||
360 | { | ||
361 | u32 status = 0; | ||
362 | struct boardobj *boardobj; | ||
363 | |||
364 | if (!(hw_threshold_policy_index & 0x1)) { | ||
365 | /* CRIT policy */ | ||
366 | ppwrpolicydata->pwrpolicy.limit_min = 1000; | ||
367 | ppwrpolicydata->pwrpolicy.limit_rated = 20000; | ||
368 | ppwrpolicydata->pwrpolicy.limit_max = 20000; | ||
369 | ppwrpolicydata->hw_threshold.threshold_idx = 0; | ||
370 | } else { | ||
371 | /* WARN policy */ | ||
372 | ppwrpolicydata->pwrpolicy.limit_min = 1000; | ||
373 | ppwrpolicydata->pwrpolicy.limit_rated = 11600; | ||
374 | ppwrpolicydata->pwrpolicy.limit_max = 11600; | ||
375 | ppwrpolicydata->hw_threshold.threshold_idx = 1; | ||
376 | } | ||
377 | |||
378 | boardobj = construct_pwr_policy(g, ppwrpolicydata, | ||
379 | pwr_policy_size, ppwrpolicydata->boardobj.type); | ||
380 | |||
381 | if (!boardobj) { | ||
382 | gk20a_err(dev_from_gk20a(g), | ||
383 | "unable to create pwr policy for type %d", ppwrpolicydata->boardobj.type); | ||
384 | status = -EINVAL; | ||
385 | goto done; | ||
386 | } | ||
387 | |||
388 | status = boardobjgrp_objinsert(&ppwrpolicyobjs->pwr_policies.super, | ||
389 | boardobj, obj_index); | ||
390 | |||
391 | if (status) { | ||
392 | gk20a_err(dev_from_gk20a(g), | ||
393 | "unable to insert pwr policy boardobj for %d", obj_index); | ||
394 | status = -EINVAL; | ||
395 | goto done; | ||
396 | } | ||
397 | done: | ||
398 | return status; | ||
399 | } | ||
400 | |||
401 | static u32 _pwr_policy_construct_WAR_SW_Threshold_policy(struct gk20a *g, | 359 | static u32 _pwr_policy_construct_WAR_SW_Threshold_policy(struct gk20a *g, |
402 | struct pmgr_pwr_policy *ppwrpolicyobjs, | 360 | struct pmgr_pwr_policy *ppwrpolicyobjs, |
403 | union pwr_policy_data_union *ppwrpolicydata, | 361 | union pwr_policy_data_union *ppwrpolicydata, |
@@ -447,15 +405,114 @@ done: | |||
447 | return status; | 405 | return status; |
448 | } | 406 | } |
449 | 407 | ||
408 | struct pwr_policy_3x_header_unpacked { | ||
409 | u8 version; | ||
410 | u8 header_size; | ||
411 | u8 table_entry_size; | ||
412 | u8 num_table_entries; | ||
413 | u16 base_sample_period; | ||
414 | u16 min_client_sample_period; | ||
415 | u8 table_rel_entry_size; | ||
416 | u8 num_table_rel_entries; | ||
417 | u8 tgp_policy_idx; | ||
418 | u8 rtp_policy_idx; | ||
419 | u8 mxm_policy_idx; | ||
420 | u8 dnotifier_policy_idx; | ||
421 | u32 d2_limit; | ||
422 | u32 d3_limit; | ||
423 | u32 d4_limit; | ||
424 | u32 d5_limit; | ||
425 | u8 low_sampling_mult; | ||
426 | u8 pwr_tgt_policy_idx; | ||
427 | u8 pwr_tgt_floor_policy_idx; | ||
428 | u8 sm_bus_policy_idx; | ||
429 | u8 table_viol_entry_size; | ||
430 | u8 num_table_viol_entries; | ||
431 | }; | ||
432 | |||
433 | #define __UNPACK_FIELD(unpacked, packed, field) \ | ||
434 | __builtin_memcpy(&unpacked->field, &packed->field, \ | ||
435 | sizeof(unpacked->field)) | ||
436 | |||
437 | static inline void devinit_unpack_pwr_policy_header( | ||
438 | struct pwr_policy_3x_header_unpacked *unpacked, | ||
439 | struct pwr_policy_3x_header_struct *packed) | ||
440 | { | ||
441 | __UNPACK_FIELD(unpacked, packed, version); | ||
442 | __UNPACK_FIELD(unpacked, packed, header_size); | ||
443 | __UNPACK_FIELD(unpacked, packed, table_entry_size); | ||
444 | __UNPACK_FIELD(unpacked, packed, num_table_entries); | ||
445 | __UNPACK_FIELD(unpacked, packed, base_sample_period); | ||
446 | __UNPACK_FIELD(unpacked, packed, min_client_sample_period); | ||
447 | __UNPACK_FIELD(unpacked, packed, table_rel_entry_size); | ||
448 | __UNPACK_FIELD(unpacked, packed, num_table_rel_entries); | ||
449 | __UNPACK_FIELD(unpacked, packed, tgp_policy_idx); | ||
450 | __UNPACK_FIELD(unpacked, packed, rtp_policy_idx); | ||
451 | __UNPACK_FIELD(unpacked, packed, mxm_policy_idx); | ||
452 | __UNPACK_FIELD(unpacked, packed, dnotifier_policy_idx); | ||
453 | __UNPACK_FIELD(unpacked, packed, d2_limit); | ||
454 | __UNPACK_FIELD(unpacked, packed, d3_limit); | ||
455 | __UNPACK_FIELD(unpacked, packed, d4_limit); | ||
456 | __UNPACK_FIELD(unpacked, packed, d5_limit); | ||
457 | __UNPACK_FIELD(unpacked, packed, low_sampling_mult); | ||
458 | __UNPACK_FIELD(unpacked, packed, pwr_tgt_policy_idx); | ||
459 | __UNPACK_FIELD(unpacked, packed, pwr_tgt_floor_policy_idx); | ||
460 | __UNPACK_FIELD(unpacked, packed, sm_bus_policy_idx); | ||
461 | __UNPACK_FIELD(unpacked, packed, table_viol_entry_size); | ||
462 | __UNPACK_FIELD(unpacked, packed, num_table_viol_entries); | ||
463 | } | ||
464 | |||
465 | struct pwr_policy_3x_entry_unpacked { | ||
466 | u8 flags0; | ||
467 | u8 ch_idx; | ||
468 | u32 limit_min; | ||
469 | u32 limit_rated; | ||
470 | u32 limit_max; | ||
471 | u32 param0; | ||
472 | u32 param1; | ||
473 | u32 param2; | ||
474 | u32 param3; | ||
475 | u32 limit_batt; | ||
476 | u8 flags1; | ||
477 | u8 past_length; | ||
478 | u8 next_length; | ||
479 | u16 ratio_min; | ||
480 | u16 ratio_max; | ||
481 | u8 sample_mult; | ||
482 | u32 filter_param; | ||
483 | }; | ||
484 | |||
485 | static inline void devinit_unpack_pwr_policy_entry( | ||
486 | struct pwr_policy_3x_entry_unpacked *unpacked, | ||
487 | struct pwr_policy_3x_entry_struct *packed) | ||
488 | { | ||
489 | __UNPACK_FIELD(unpacked, packed, flags0); | ||
490 | __UNPACK_FIELD(unpacked, packed, ch_idx); | ||
491 | __UNPACK_FIELD(unpacked, packed, limit_min); | ||
492 | __UNPACK_FIELD(unpacked, packed, limit_rated); | ||
493 | __UNPACK_FIELD(unpacked, packed, limit_max); | ||
494 | __UNPACK_FIELD(unpacked, packed, param0); | ||
495 | __UNPACK_FIELD(unpacked, packed, param1); | ||
496 | __UNPACK_FIELD(unpacked, packed, param2); | ||
497 | __UNPACK_FIELD(unpacked, packed, param3); | ||
498 | __UNPACK_FIELD(unpacked, packed, limit_batt); | ||
499 | __UNPACK_FIELD(unpacked, packed, flags1); | ||
500 | __UNPACK_FIELD(unpacked, packed, past_length); | ||
501 | __UNPACK_FIELD(unpacked, packed, next_length); | ||
502 | __UNPACK_FIELD(unpacked, packed, ratio_min); | ||
503 | __UNPACK_FIELD(unpacked, packed, ratio_max); | ||
504 | __UNPACK_FIELD(unpacked, packed, sample_mult); | ||
505 | __UNPACK_FIELD(unpacked, packed, filter_param); | ||
506 | } | ||
507 | |||
450 | static u32 devinit_get_pwr_policy_table(struct gk20a *g, | 508 | static u32 devinit_get_pwr_policy_table(struct gk20a *g, |
451 | struct pmgr_pwr_policy *ppwrpolicyobjs) | 509 | struct pmgr_pwr_policy *ppwrpolicyobjs) |
452 | { | 510 | { |
453 | u32 status = 0; | 511 | u32 status = 0; |
454 | u8 *pwr_policy_table_ptr = NULL; | 512 | u8 *ptr = NULL; |
455 | u8 *curr_pwr_policy_table_ptr = NULL; | ||
456 | struct boardobj *boardobj; | 513 | struct boardobj *boardobj; |
457 | struct pwr_policy_3x_header_struct pwr_policy_table_header = { 0 }; | 514 | struct pwr_policy_3x_header_struct *packed_hdr; |
458 | struct pwr_policy_3x_entry_struct pwr_policy_table_entry = { 0 }; | 515 | struct pwr_policy_3x_header_unpacked hdr; |
459 | u32 index; | 516 | u32 index; |
460 | u32 obj_index = 0; | 517 | u32 obj_index = 0; |
461 | u16 pwr_policy_size; | 518 | u16 pwr_policy_size; |
@@ -469,162 +526,130 @@ static u32 devinit_get_pwr_policy_table(struct gk20a *g, | |||
469 | if (!g->ops.bios.get_perf_table_ptrs) | 526 | if (!g->ops.bios.get_perf_table_ptrs) |
470 | return -EINVAL; | 527 | return -EINVAL; |
471 | 528 | ||
472 | pwr_policy_table_ptr = (u8 *)g->ops.bios.get_perf_table_ptrs(g, | 529 | ptr = (u8 *)g->ops.bios.get_perf_table_ptrs(g, |
473 | g->bios.perf_token, POWER_CAPPING_TABLE); | 530 | g->bios.perf_token, POWER_CAPPING_TABLE); |
474 | if (pwr_policy_table_ptr == NULL) { | 531 | if (ptr == NULL) { |
475 | status = -EINVAL; | 532 | status = -EINVAL; |
476 | goto done; | 533 | goto done; |
477 | } | 534 | } |
478 | 535 | ||
479 | memcpy(&pwr_policy_table_header.version, | 536 | packed_hdr = (struct pwr_policy_3x_header_struct *)ptr; |
480 | (pwr_policy_table_ptr), | ||
481 | 14); | ||
482 | 537 | ||
483 | memcpy(&pwr_policy_table_header.d2_limit, | 538 | if (packed_hdr->version != |
484 | (pwr_policy_table_ptr + 14), | ||
485 | (VBIOS_POWER_POLICY_3X_ENTRY_SIZE_2E - 14)); | ||
486 | |||
487 | if (pwr_policy_table_header.version != | ||
488 | VBIOS_POWER_POLICY_VERSION_3X) { | 539 | VBIOS_POWER_POLICY_VERSION_3X) { |
489 | status = -EINVAL; | 540 | status = -EINVAL; |
490 | goto done; | 541 | goto done; |
491 | } | 542 | } |
492 | 543 | ||
493 | if (pwr_policy_table_header.header_size < | 544 | if (packed_hdr->header_size < |
494 | VBIOS_POWER_POLICY_3X_HEADER_SIZE_25) { | 545 | VBIOS_POWER_POLICY_3X_HEADER_SIZE_25) { |
495 | status = -EINVAL; | 546 | status = -EINVAL; |
496 | goto done; | 547 | goto done; |
497 | } | 548 | } |
498 | 549 | ||
499 | if (pwr_policy_table_header.table_entry_size != | 550 | if (packed_hdr->table_entry_size != |
500 | VBIOS_POWER_POLICY_3X_ENTRY_SIZE_2E) { | 551 | VBIOS_POWER_POLICY_3X_ENTRY_SIZE_2E) { |
501 | status = -EINVAL; | 552 | status = -EINVAL; |
502 | goto done; | 553 | goto done; |
503 | } | 554 | } |
504 | 555 | ||
505 | curr_pwr_policy_table_ptr = (pwr_policy_table_ptr + | 556 | /* unpack power policy table header */ |
506 | VBIOS_POWER_POLICY_3X_HEADER_SIZE_25); | 557 | devinit_unpack_pwr_policy_header(&hdr, packed_hdr); |
507 | 558 | ||
508 | for (index = 0; index < pwr_policy_table_header.num_table_entries; | 559 | ptr += VBIOS_POWER_POLICY_3X_HEADER_SIZE_25; |
509 | index++) { | ||
510 | u8 class_type; | ||
511 | 560 | ||
512 | curr_pwr_policy_table_ptr += (pwr_policy_table_header.table_entry_size * index); | 561 | for (index = 0; index < hdr.num_table_entries; |
562 | index++, ptr += (u32)hdr.table_entry_size) { | ||
513 | 563 | ||
514 | pwr_policy_table_entry.flags0 = *curr_pwr_policy_table_ptr; | 564 | struct pwr_policy_3x_entry_struct *packed_entry; |
515 | pwr_policy_table_entry.ch_idx = *(curr_pwr_policy_table_ptr + 1); | 565 | struct pwr_policy_3x_entry_unpacked entry; |
516 | 566 | ||
517 | memcpy(&pwr_policy_table_entry.limit_min, | 567 | u8 class_type; |
518 | (curr_pwr_policy_table_ptr + 2), | ||
519 | 35); | ||
520 | |||
521 | memcpy(&pwr_policy_table_entry.ratio_min, | ||
522 | (curr_pwr_policy_table_ptr + 2 + 35), | ||
523 | 4); | ||
524 | |||
525 | pwr_policy_table_entry.sample_mult = | ||
526 | *(curr_pwr_policy_table_ptr + 2 + 35 + 4); | ||
527 | 568 | ||
528 | memcpy(&pwr_policy_table_entry.filter_param, | 569 | packed_entry = (struct pwr_policy_3x_entry_struct *)ptr; |
529 | (curr_pwr_policy_table_ptr + 2 + 35 + 4 + 1), | ||
530 | 4); | ||
531 | 570 | ||
532 | class_type = (u8)BIOS_GET_FIELD( | 571 | class_type = (u8)BIOS_GET_FIELD( |
533 | pwr_policy_table_entry.flags0, | 572 | packed_entry->flags0, |
534 | NV_VBIOS_POWER_POLICY_3X_ENTRY_FLAGS0_CLASS); | 573 | NV_VBIOS_POWER_POLICY_3X_ENTRY_FLAGS0_CLASS); |
535 | 574 | ||
536 | if (class_type == NV_VBIOS_POWER_POLICY_3X_ENTRY_FLAGS0_CLASS_HW_THRESHOLD) { | 575 | if (class_type != NV_VBIOS_POWER_POLICY_3X_ENTRY_FLAGS0_CLASS_HW_THRESHOLD) |
537 | ppwrpolicyobjs->version = CTRL_PMGR_PWR_POLICY_TABLE_VERSION_3X; | ||
538 | ppwrpolicyobjs->base_sample_period = (u16) | ||
539 | pwr_policy_table_header.base_sample_period; | ||
540 | ppwrpolicyobjs->min_client_sample_period = (u16) | ||
541 | pwr_policy_table_header.min_client_sample_period; | ||
542 | ppwrpolicyobjs->low_sampling_mult = | ||
543 | pwr_policy_table_header.low_sampling_mult; | ||
544 | |||
545 | ppwrpolicyobjs->policy_idxs[1] = | ||
546 | (u8)pwr_policy_table_header.tgp_policy_idx; | ||
547 | ppwrpolicyobjs->policy_idxs[0] = | ||
548 | (u8)pwr_policy_table_header.rtp_policy_idx; | ||
549 | ppwrpolicyobjs->policy_idxs[2] = | ||
550 | pwr_policy_table_header.mxm_policy_idx; | ||
551 | ppwrpolicyobjs->policy_idxs[3] = | ||
552 | pwr_policy_table_header.dnotifier_policy_idx; | ||
553 | ppwrpolicyobjs->ext_limits[0].limit = | ||
554 | pwr_policy_table_header.d2_limit; | ||
555 | ppwrpolicyobjs->ext_limits[1].limit = | ||
556 | pwr_policy_table_header.d3_limit; | ||
557 | ppwrpolicyobjs->ext_limits[2].limit = | ||
558 | pwr_policy_table_header.d4_limit; | ||
559 | ppwrpolicyobjs->ext_limits[3].limit = | ||
560 | pwr_policy_table_header.d5_limit; | ||
561 | ppwrpolicyobjs->policy_idxs[4] = | ||
562 | pwr_policy_table_header.pwr_tgt_policy_idx; | ||
563 | ppwrpolicyobjs->policy_idxs[5] = | ||
564 | pwr_policy_table_header.pwr_tgt_floor_policy_idx; | ||
565 | ppwrpolicyobjs->policy_idxs[6] = | ||
566 | pwr_policy_table_header.sm_bus_policy_idx; | ||
567 | |||
568 | integral_control = (bool)BIOS_GET_FIELD( | ||
569 | pwr_policy_table_entry.flags1, | ||
570 | NV_VBIOS_POWER_POLICY_3X_ENTRY_FLAGS1_INTEGRAL_CONTROL); | ||
571 | |||
572 | if (integral_control == 0x01) { | ||
573 | pwr_policy_data.pwrpolicy.integral.past_sample_count = (u8) | ||
574 | pwr_policy_table_entry.past_length; | ||
575 | pwr_policy_data.pwrpolicy.integral.next_sample_count = (u8) | ||
576 | pwr_policy_table_entry.next_length; | ||
577 | pwr_policy_data.pwrpolicy.integral.ratio_limit_max = (u16) | ||
578 | pwr_policy_table_entry.ratio_max; | ||
579 | pwr_policy_data.pwrpolicy.integral.ratio_limit_min = (u16) | ||
580 | pwr_policy_table_entry.ratio_min; | ||
581 | } else { | ||
582 | memset(&(pwr_policy_data.pwrpolicy.integral), 0x0, | ||
583 | sizeof(struct ctrl_pmgr_pwr_policy_info_integral)); | ||
584 | } | ||
585 | pwr_policy_data.hw_threshold.threshold_idx = (u8) | ||
586 | BIOS_GET_FIELD( | ||
587 | pwr_policy_table_entry.param0, | ||
588 | NV_VBIOS_POWER_POLICY_3X_ENTRY_PARAM0_HW_THRESHOLD_THRES_IDX); | ||
589 | |||
590 | pwr_policy_data.hw_threshold.b_use_low_threshold = | ||
591 | BIOS_GET_FIELD( | ||
592 | pwr_policy_table_entry.param0, | ||
593 | NV_VBIOS_POWER_POLICY_3X_ENTRY_PARAM0_HW_THRESHOLD_LOW_THRESHOLD_USE); | ||
594 | |||
595 | if (pwr_policy_data.hw_threshold.b_use_low_threshold) { | ||
596 | pwr_policy_data.hw_threshold.low_threshold_idx = (u8) | ||
597 | BIOS_GET_FIELD( | ||
598 | pwr_policy_table_entry.param0, | ||
599 | NV_VBIOS_POWER_POLICY_3X_ENTRY_PARAM0_HW_THRESHOLD_LOW_THRESHOLD_IDX); | ||
600 | |||
601 | pwr_policy_data.hw_threshold.low_threshold_value = (u16) | ||
602 | BIOS_GET_FIELD( | ||
603 | pwr_policy_table_entry.param1, | ||
604 | NV_VBIOS_POWER_POLICY_3X_ENTRY_PARAM1_HW_THRESHOLD_LOW_THRESHOLD_VAL); | ||
605 | } | ||
606 | |||
607 | pwr_policy_size = sizeof(struct pwr_policy_hw_threshold); | ||
608 | } else | ||
609 | continue; | 576 | continue; |
610 | 577 | ||
578 | /* unpack power policy table entry */ | ||
579 | devinit_unpack_pwr_policy_entry(&entry, packed_entry); | ||
580 | |||
581 | ppwrpolicyobjs->version = | ||
582 | CTRL_PMGR_PWR_POLICY_TABLE_VERSION_3X; | ||
583 | ppwrpolicyobjs->base_sample_period = hdr.base_sample_period; | ||
584 | ppwrpolicyobjs->min_client_sample_period = | ||
585 | hdr.min_client_sample_period; | ||
586 | ppwrpolicyobjs->low_sampling_mult = hdr.low_sampling_mult; | ||
587 | |||
588 | ppwrpolicyobjs->policy_idxs[1] = hdr.tgp_policy_idx; | ||
589 | ppwrpolicyobjs->policy_idxs[0] = hdr.rtp_policy_idx; | ||
590 | ppwrpolicyobjs->policy_idxs[2] = hdr.mxm_policy_idx; | ||
591 | ppwrpolicyobjs->policy_idxs[3] = hdr.dnotifier_policy_idx; | ||
592 | ppwrpolicyobjs->ext_limits[0].limit = hdr.d2_limit; | ||
593 | ppwrpolicyobjs->ext_limits[1].limit = hdr.d3_limit; | ||
594 | ppwrpolicyobjs->ext_limits[2].limit = hdr.d4_limit; | ||
595 | ppwrpolicyobjs->ext_limits[3].limit = hdr.d5_limit; | ||
596 | ppwrpolicyobjs->policy_idxs[4] = hdr.pwr_tgt_policy_idx; | ||
597 | ppwrpolicyobjs->policy_idxs[5] = hdr.pwr_tgt_floor_policy_idx; | ||
598 | ppwrpolicyobjs->policy_idxs[6] = hdr.sm_bus_policy_idx; | ||
599 | |||
600 | integral_control = (bool)BIOS_GET_FIELD(entry.flags1, | ||
601 | NV_VBIOS_POWER_POLICY_3X_ENTRY_FLAGS1_INTEGRAL_CONTROL); | ||
602 | |||
603 | if (integral_control == 0x01) { | ||
604 | pwr_policy_data.pwrpolicy.integral.past_sample_count = | ||
605 | entry.past_length; | ||
606 | pwr_policy_data.pwrpolicy.integral.next_sample_count = | ||
607 | entry.next_length; | ||
608 | pwr_policy_data.pwrpolicy.integral.ratio_limit_max = | ||
609 | entry.ratio_max; | ||
610 | pwr_policy_data.pwrpolicy.integral.ratio_limit_min = | ||
611 | entry.ratio_min; | ||
612 | } else { | ||
613 | memset(&(pwr_policy_data.pwrpolicy.integral), 0x0, | ||
614 | sizeof(struct ctrl_pmgr_pwr_policy_info_integral)); | ||
615 | } | ||
616 | pwr_policy_data.hw_threshold.threshold_idx = (u8) | ||
617 | BIOS_GET_FIELD(entry.param0, | ||
618 | NV_VBIOS_POWER_POLICY_3X_ENTRY_PARAM0_HW_THRESHOLD_THRES_IDX); | ||
619 | |||
620 | pwr_policy_data.hw_threshold.b_use_low_threshold = | ||
621 | BIOS_GET_FIELD(entry.param0, | ||
622 | NV_VBIOS_POWER_POLICY_3X_ENTRY_PARAM0_HW_THRESHOLD_LOW_THRESHOLD_USE); | ||
623 | |||
624 | if (pwr_policy_data.hw_threshold.b_use_low_threshold) { | ||
625 | pwr_policy_data.hw_threshold.low_threshold_idx = (u8) | ||
626 | BIOS_GET_FIELD(entry.param0, | ||
627 | NV_VBIOS_POWER_POLICY_3X_ENTRY_PARAM0_HW_THRESHOLD_LOW_THRESHOLD_IDX); | ||
628 | |||
629 | pwr_policy_data.hw_threshold.low_threshold_value = (u16) | ||
630 | BIOS_GET_FIELD(entry.param1, | ||
631 | NV_VBIOS_POWER_POLICY_3X_ENTRY_PARAM1_HW_THRESHOLD_LOW_THRESHOLD_VAL); | ||
632 | } | ||
633 | |||
634 | pwr_policy_size = sizeof(struct pwr_policy_hw_threshold); | ||
635 | |||
611 | /* Initialize data for the parent class */ | 636 | /* Initialize data for the parent class */ |
612 | pwr_policy_data.boardobj.type = CTRL_PMGR_PWR_POLICY_TYPE_HW_THRESHOLD; | 637 | pwr_policy_data.boardobj.type = |
613 | pwr_policy_data.pwrpolicy.ch_idx = (u8)pwr_policy_table_entry.ch_idx; | 638 | CTRL_PMGR_PWR_POLICY_TYPE_HW_THRESHOLD; |
639 | pwr_policy_data.pwrpolicy.ch_idx = entry.ch_idx; | ||
614 | pwr_policy_data.pwrpolicy.limit_unit = (u8) | 640 | pwr_policy_data.pwrpolicy.limit_unit = (u8) |
615 | BIOS_GET_FIELD( | 641 | BIOS_GET_FIELD(entry.flags0, |
616 | pwr_policy_table_entry.flags0, | ||
617 | NV_VBIOS_POWER_POLICY_3X_ENTRY_FLAGS0_LIMIT_UNIT); | 642 | NV_VBIOS_POWER_POLICY_3X_ENTRY_FLAGS0_LIMIT_UNIT); |
618 | pwr_policy_data.pwrpolicy.filter_type = (u8) | 643 | pwr_policy_data.pwrpolicy.filter_type = (u8) |
619 | BIOS_GET_FIELD( | 644 | BIOS_GET_FIELD(entry.flags1, |
620 | pwr_policy_table_entry.flags1, | ||
621 | NV_VBIOS_POWER_POLICY_3X_ENTRY_FLAGS1_FILTER_TYPE); | 645 | NV_VBIOS_POWER_POLICY_3X_ENTRY_FLAGS1_FILTER_TYPE); |
622 | pwr_policy_data.pwrpolicy.limit_min = pwr_policy_table_entry.limit_min; | ||
623 | pwr_policy_data.pwrpolicy.limit_rated = pwr_policy_table_entry.limit_rated; | ||
624 | pwr_policy_data.pwrpolicy.limit_max = pwr_policy_table_entry.limit_max; | ||
625 | pwr_policy_data.pwrpolicy.limit_batt = pwr_policy_table_entry.limit_batt; | ||
626 | 646 | ||
627 | pwr_policy_data.pwrpolicy.sample_mult = (u8)pwr_policy_table_entry.sample_mult; | 647 | pwr_policy_data.pwrpolicy.limit_min = entry.limit_min; |
648 | pwr_policy_data.pwrpolicy.limit_rated = entry.limit_rated; | ||
649 | pwr_policy_data.pwrpolicy.limit_max = entry.limit_max; | ||
650 | pwr_policy_data.pwrpolicy.limit_batt = entry.limit_batt; | ||
651 | |||
652 | pwr_policy_data.pwrpolicy.sample_mult = (u8)entry.sample_mult; | ||
628 | 653 | ||
629 | /* Filled the entry.filterParam value in the filterParam */ | 654 | /* Filled the entry.filterParam value in the filterParam */ |
630 | pwr_policy_data.pwrpolicy.filter_param.block.block_size = 0; | 655 | pwr_policy_data.pwrpolicy.filter_param.block.block_size = 0; |
@@ -635,11 +660,12 @@ static u32 devinit_get_pwr_policy_table(struct gk20a *g, | |||
635 | BIT(pwr_policy_data.hw_threshold.threshold_idx); | 660 | BIT(pwr_policy_data.hw_threshold.threshold_idx); |
636 | 661 | ||
637 | boardobj = construct_pwr_policy(g, &pwr_policy_data, | 662 | boardobj = construct_pwr_policy(g, &pwr_policy_data, |
638 | pwr_policy_size, pwr_policy_data.boardobj.type); | 663 | pwr_policy_size, pwr_policy_data.boardobj.type); |
639 | 664 | ||
640 | if (!boardobj) { | 665 | if (!boardobj) { |
641 | gk20a_err(dev_from_gk20a(g), | 666 | gk20a_err(dev_from_gk20a(g), |
642 | "unable to create pwr policy for %d type %d", index, pwr_policy_data.boardobj.type); | 667 | "unable to create pwr policy for %d type %d", |
668 | index, pwr_policy_data.boardobj.type); | ||
643 | status = -EINVAL; | 669 | status = -EINVAL; |
644 | goto done; | 670 | goto done; |
645 | } | 671 | } |
@@ -649,7 +675,8 @@ static u32 devinit_get_pwr_policy_table(struct gk20a *g, | |||
649 | 675 | ||
650 | if (status) { | 676 | if (status) { |
651 | gk20a_err(dev_from_gk20a(g), | 677 | gk20a_err(dev_from_gk20a(g), |
652 | "unable to insert pwr policy boardobj for %d", index); | 678 | "unable to insert pwr policy boardobj for %d", |
679 | index); | ||
653 | status = -EINVAL; | 680 | status = -EINVAL; |
654 | goto done; | 681 | goto done; |
655 | } | 682 | } |
@@ -657,23 +684,6 @@ static u32 devinit_get_pwr_policy_table(struct gk20a *g, | |||
657 | ++obj_index; | 684 | ++obj_index; |
658 | } | 685 | } |
659 | 686 | ||
660 | if (hw_threshold_policy_index && | ||
661 | (hw_threshold_policy_index < 0x3)) { | ||
662 | status = _pwr_policy_construct_WAR_policy(g, | ||
663 | ppwrpolicyobjs, | ||
664 | &pwr_policy_data, | ||
665 | pwr_policy_size, | ||
666 | hw_threshold_policy_index, | ||
667 | obj_index); | ||
668 | if (status) { | ||
669 | gk20a_err(dev_from_gk20a(g), | ||
670 | "unable to construct_WAR_policy"); | ||
671 | status = -EINVAL; | ||
672 | goto done; | ||
673 | } | ||
674 | ++obj_index; | ||
675 | } | ||
676 | |||
677 | if (!sw_threshold_policy_index) { | 687 | if (!sw_threshold_policy_index) { |
678 | status = _pwr_policy_construct_WAR_SW_Threshold_policy(g, | 688 | status = _pwr_policy_construct_WAR_SW_Threshold_policy(g, |
679 | ppwrpolicyobjs, | 689 | ppwrpolicyobjs, |