diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/nvgpu/include/bios.h | 14 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/pmgr/pwrpolicy.c | 390 |
2 files changed, 207 insertions, 197 deletions
diff --git a/drivers/gpu/nvgpu/include/bios.h b/drivers/gpu/nvgpu/include/bios.h index 097e90ec..bcb24343 100644 --- a/drivers/gpu/nvgpu/include/bios.h +++ b/drivers/gpu/nvgpu/include/bios.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * vbios tables support | 2 | * vbios tables support |
3 | * | 3 | * |
4 | * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. | 4 | * Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms and conditions of the GNU General Public License, | 7 | * under the terms and conditions of the GNU General Public License, |
@@ -510,7 +510,7 @@ struct pwr_sensors_2x_header { | |||
510 | u8 table_entry_size; | 510 | u8 table_entry_size; |
511 | u8 num_table_entries; | 511 | u8 num_table_entries; |
512 | u32 ba_script_pointer; | 512 | u32 ba_script_pointer; |
513 | }; | 513 | } __packed; |
514 | 514 | ||
515 | #define VBIOS_POWER_SENSORS_2X_ENTRY_SIZE_15 0x00000015 | 515 | #define VBIOS_POWER_SENSORS_2X_ENTRY_SIZE_15 0x00000015 |
516 | 516 | ||
@@ -521,7 +521,7 @@ struct pwr_sensors_2x_entry { | |||
521 | u32 sensor_param1; | 521 | u32 sensor_param1; |
522 | u32 sensor_param2; | 522 | u32 sensor_param2; |
523 | u32 sensor_param3; | 523 | u32 sensor_param3; |
524 | }; | 524 | } __packed; |
525 | 525 | ||
526 | #define NV_VBIOS_POWER_SENSORS_2X_ENTRY_FLAGS0_CLASS_MASK 0xF | 526 | #define NV_VBIOS_POWER_SENSORS_2X_ENTRY_FLAGS0_CLASS_MASK 0xF |
527 | #define NV_VBIOS_POWER_SENSORS_2X_ENTRY_FLAGS0_CLASS_SHIFT 0 | 527 | #define NV_VBIOS_POWER_SENSORS_2X_ENTRY_FLAGS0_CLASS_SHIFT 0 |
@@ -560,7 +560,7 @@ struct pwr_topology_2x_header { | |||
560 | u8 num_table_entries; | 560 | u8 num_table_entries; |
561 | u8 rel_entry_size; | 561 | u8 rel_entry_size; |
562 | u8 num_rel_entries; | 562 | u8 num_rel_entries; |
563 | }; | 563 | } __packed; |
564 | 564 | ||
565 | #define VBIOS_POWER_TOPOLOGY_2X_ENTRY_SIZE_16 0x00000016 | 565 | #define VBIOS_POWER_TOPOLOGY_2X_ENTRY_SIZE_16 0x00000016 |
566 | 566 | ||
@@ -572,7 +572,7 @@ struct pwr_topology_2x_entry { | |||
572 | u32 curr_corr_offset; | 572 | u32 curr_corr_offset; |
573 | u32 param1; | 573 | u32 param1; |
574 | u32 param2; | 574 | u32 param2; |
575 | }; | 575 | } __packed; |
576 | 576 | ||
577 | #define NV_VBIOS_POWER_TOPOLOGY_2X_ENTRY_FLAGS0_CLASS_MASK 0xF | 577 | #define NV_VBIOS_POWER_TOPOLOGY_2X_ENTRY_FLAGS0_CLASS_MASK 0xF |
578 | #define NV_VBIOS_POWER_TOPOLOGY_2X_ENTRY_FLAGS0_CLASS_SHIFT 0 | 578 | #define NV_VBIOS_POWER_TOPOLOGY_2X_ENTRY_FLAGS0_CLASS_SHIFT 0 |
@@ -609,7 +609,7 @@ struct pwr_policy_3x_header_struct { | |||
609 | u8 sm_bus_policy_idx; | 609 | u8 sm_bus_policy_idx; |
610 | u8 table_viol_entry_size; | 610 | u8 table_viol_entry_size; |
611 | u8 num_table_viol_entries; | 611 | u8 num_table_viol_entries; |
612 | }; | 612 | } __packed; |
613 | 613 | ||
614 | #define VBIOS_POWER_POLICY_3X_ENTRY_SIZE_2E 0x0000002E | 614 | #define VBIOS_POWER_POLICY_3X_ENTRY_SIZE_2E 0x0000002E |
615 | 615 | ||
@@ -631,7 +631,7 @@ struct pwr_policy_3x_entry_struct { | |||
631 | u16 ratio_max; | 631 | u16 ratio_max; |
632 | u8 sample_mult; | 632 | u8 sample_mult; |
633 | u32 filter_param; | 633 | u32 filter_param; |
634 | }; | 634 | } __packed; |
635 | 635 | ||
636 | #define NV_VBIOS_POWER_POLICY_3X_ENTRY_FLAGS0_CLASS_MASK 0xF | 636 | #define NV_VBIOS_POWER_POLICY_3X_ENTRY_FLAGS0_CLASS_MASK 0xF |
637 | #define NV_VBIOS_POWER_POLICY_3X_ENTRY_FLAGS0_CLASS_SHIFT 0 | 637 | #define NV_VBIOS_POWER_POLICY_3X_ENTRY_FLAGS0_CLASS_SHIFT 0 |
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, |