1 /* 2 * Copyright 2015 Advanced Micro Devices, Inc. 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 */ 23 #include "pp_debug.h" 24 #include <linux/types.h> 25 #include <linux/kernel.h> 26 #include <linux/gfp.h> 27 #include <linux/slab.h> 28 #include <linux/firmware.h> 29 #include "amd_shared.h" 30 #include "amd_powerplay.h" 31 #include "power_state.h" 32 #include "amdgpu.h" 33 #include "hwmgr.h" 34 #include "amdgpu_dpm_internal.h" 35 #include "amdgpu_display.h" 36 37 static const struct amd_pm_funcs pp_dpm_funcs; 38 39 static int amd_powerplay_create(struct amdgpu_device *adev) 40 { 41 struct pp_hwmgr *hwmgr; 42 43 if (adev == NULL) 44 return -EINVAL; 45 46 hwmgr = kzalloc(sizeof(struct pp_hwmgr), GFP_KERNEL); 47 if (hwmgr == NULL) 48 return -ENOMEM; 49 50 hwmgr->adev = adev; 51 hwmgr->not_vf = !amdgpu_sriov_vf(adev); 52 hwmgr->device = amdgpu_cgs_create_device(adev); 53 mutex_init(&hwmgr->msg_lock); 54 hwmgr->chip_family = adev->family; 55 hwmgr->chip_id = adev->asic_type; 56 hwmgr->feature_mask = adev->pm.pp_feature; 57 hwmgr->display_config = &adev->pm.pm_display_cfg; 58 adev->powerplay.pp_handle = hwmgr; 59 adev->powerplay.pp_funcs = &pp_dpm_funcs; 60 return 0; 61 } 62 63 64 static void amd_powerplay_destroy(struct amdgpu_device *adev) 65 { 66 struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; 67 68 mutex_destroy(&hwmgr->msg_lock); 69 70 kfree(hwmgr->hardcode_pp_table); 71 hwmgr->hardcode_pp_table = NULL; 72 73 kfree(hwmgr); 74 hwmgr = NULL; 75 } 76 77 static int pp_early_init(void *handle) 78 { 79 int ret; 80 struct amdgpu_device *adev = handle; 81 82 ret = amd_powerplay_create(adev); 83 84 if (ret != 0) 85 return ret; 86 87 ret = hwmgr_early_init(adev->powerplay.pp_handle); 88 if (ret) 89 return -EINVAL; 90 91 return 0; 92 } 93 94 static int pp_sw_init(void *handle) 95 { 96 struct amdgpu_device *adev = handle; 97 struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; 98 int ret = 0; 99 100 ret = hwmgr_sw_init(hwmgr); 101 102 pr_debug("powerplay sw init %s\n", ret ? "failed" : "successfully"); 103 104 return ret; 105 } 106 107 static int pp_sw_fini(void *handle) 108 { 109 struct amdgpu_device *adev = handle; 110 struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; 111 112 hwmgr_sw_fini(hwmgr); 113 114 release_firmware(adev->pm.fw); 115 adev->pm.fw = NULL; 116 117 return 0; 118 } 119 120 static int pp_hw_init(void *handle) 121 { 122 int ret = 0; 123 struct amdgpu_device *adev = handle; 124 struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; 125 126 ret = hwmgr_hw_init(hwmgr); 127 128 if (ret) 129 pr_err("powerplay hw init failed\n"); 130 131 return ret; 132 } 133 134 static int pp_hw_fini(void *handle) 135 { 136 struct amdgpu_device *adev = handle; 137 struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; 138 139 hwmgr_hw_fini(hwmgr); 140 141 return 0; 142 } 143 144 static void pp_reserve_vram_for_smu(struct amdgpu_device *adev) 145 { 146 int r = -EINVAL; 147 void *cpu_ptr = NULL; 148 uint64_t gpu_addr; 149 struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; 150 151 if (amdgpu_bo_create_kernel(adev, adev->pm.smu_prv_buffer_size, 152 PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT, 153 &adev->pm.smu_prv_buffer, 154 &gpu_addr, 155 &cpu_ptr)) { 156 DRM_ERROR("amdgpu: failed to create smu prv buffer\n"); 157 return; 158 } 159 160 if (hwmgr->hwmgr_func->notify_cac_buffer_info) 161 r = hwmgr->hwmgr_func->notify_cac_buffer_info(hwmgr, 162 lower_32_bits((unsigned long)cpu_ptr), 163 upper_32_bits((unsigned long)cpu_ptr), 164 lower_32_bits(gpu_addr), 165 upper_32_bits(gpu_addr), 166 adev->pm.smu_prv_buffer_size); 167 168 if (r) { 169 amdgpu_bo_free_kernel(&adev->pm.smu_prv_buffer, NULL, NULL); 170 adev->pm.smu_prv_buffer = NULL; 171 DRM_ERROR("amdgpu: failed to notify SMU buffer address\n"); 172 } 173 } 174 175 static int pp_late_init(void *handle) 176 { 177 struct amdgpu_device *adev = handle; 178 struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; 179 180 if (hwmgr && hwmgr->pm_en) 181 hwmgr_handle_task(hwmgr, 182 AMD_PP_TASK_COMPLETE_INIT, NULL); 183 if (adev->pm.smu_prv_buffer_size != 0) 184 pp_reserve_vram_for_smu(adev); 185 186 return 0; 187 } 188 189 static void pp_late_fini(void *handle) 190 { 191 struct amdgpu_device *adev = handle; 192 193 if (adev->pm.smu_prv_buffer) 194 amdgpu_bo_free_kernel(&adev->pm.smu_prv_buffer, NULL, NULL); 195 amd_powerplay_destroy(adev); 196 } 197 198 199 static bool pp_is_idle(void *handle) 200 { 201 return false; 202 } 203 204 static int pp_wait_for_idle(void *handle) 205 { 206 return 0; 207 } 208 209 static int pp_sw_reset(void *handle) 210 { 211 return 0; 212 } 213 214 static int pp_set_powergating_state(void *handle, 215 enum amd_powergating_state state) 216 { 217 return 0; 218 } 219 220 static int pp_suspend(void *handle) 221 { 222 struct amdgpu_device *adev = handle; 223 struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; 224 225 return hwmgr_suspend(hwmgr); 226 } 227 228 static int pp_resume(void *handle) 229 { 230 struct amdgpu_device *adev = handle; 231 struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; 232 233 return hwmgr_resume(hwmgr); 234 } 235 236 static int pp_set_clockgating_state(void *handle, 237 enum amd_clockgating_state state) 238 { 239 return 0; 240 } 241 242 static const struct amd_ip_funcs pp_ip_funcs = { 243 .name = "powerplay", 244 .early_init = pp_early_init, 245 .late_init = pp_late_init, 246 .sw_init = pp_sw_init, 247 .sw_fini = pp_sw_fini, 248 .hw_init = pp_hw_init, 249 .hw_fini = pp_hw_fini, 250 .late_fini = pp_late_fini, 251 .suspend = pp_suspend, 252 .resume = pp_resume, 253 .is_idle = pp_is_idle, 254 .wait_for_idle = pp_wait_for_idle, 255 .soft_reset = pp_sw_reset, 256 .set_clockgating_state = pp_set_clockgating_state, 257 .set_powergating_state = pp_set_powergating_state, 258 }; 259 260 const struct amdgpu_ip_block_version pp_smu_ip_block = 261 { 262 .type = AMD_IP_BLOCK_TYPE_SMC, 263 .major = 1, 264 .minor = 0, 265 .rev = 0, 266 .funcs = &pp_ip_funcs, 267 }; 268 269 /* This interface only be supported On Vi, 270 * because only smu7/8 can help to load gfx/sdma fw, 271 * smu need to be enabled before load other ip's fw. 272 * so call start smu to load smu7 fw and other ip's fw 273 */ 274 static int pp_dpm_load_fw(void *handle) 275 { 276 struct pp_hwmgr *hwmgr = handle; 277 278 if (!hwmgr || !hwmgr->smumgr_funcs || !hwmgr->smumgr_funcs->start_smu) 279 return -EINVAL; 280 281 if (hwmgr->smumgr_funcs->start_smu(hwmgr)) { 282 pr_err("fw load failed\n"); 283 return -EINVAL; 284 } 285 286 return 0; 287 } 288 289 static int pp_dpm_fw_loading_complete(void *handle) 290 { 291 return 0; 292 } 293 294 static int pp_set_clockgating_by_smu(void *handle, uint32_t msg_id) 295 { 296 struct pp_hwmgr *hwmgr = handle; 297 298 if (!hwmgr || !hwmgr->pm_en) 299 return -EINVAL; 300 301 if (hwmgr->hwmgr_func->update_clock_gatings == NULL) { 302 pr_info_ratelimited("%s was not implemented.\n", __func__); 303 return 0; 304 } 305 306 return hwmgr->hwmgr_func->update_clock_gatings(hwmgr, &msg_id); 307 } 308 309 static void pp_dpm_en_umd_pstate(struct pp_hwmgr *hwmgr, 310 enum amd_dpm_forced_level *level) 311 { 312 uint32_t profile_mode_mask = AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD | 313 AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK | 314 AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK | 315 AMD_DPM_FORCED_LEVEL_PROFILE_PEAK; 316 317 if (!(hwmgr->dpm_level & profile_mode_mask)) { 318 /* enter umd pstate, save current level, disable gfx cg*/ 319 if (*level & profile_mode_mask) { 320 hwmgr->saved_dpm_level = hwmgr->dpm_level; 321 hwmgr->en_umd_pstate = true; 322 } 323 } else { 324 /* exit umd pstate, restore level, enable gfx cg*/ 325 if (!(*level & profile_mode_mask)) { 326 if (*level == AMD_DPM_FORCED_LEVEL_PROFILE_EXIT) 327 *level = hwmgr->saved_dpm_level; 328 hwmgr->en_umd_pstate = false; 329 } 330 } 331 } 332 333 static int pp_dpm_force_performance_level(void *handle, 334 enum amd_dpm_forced_level level) 335 { 336 struct pp_hwmgr *hwmgr = handle; 337 338 if (!hwmgr || !hwmgr->pm_en) 339 return -EINVAL; 340 341 if (level == hwmgr->dpm_level) 342 return 0; 343 344 pp_dpm_en_umd_pstate(hwmgr, &level); 345 hwmgr->request_dpm_level = level; 346 hwmgr_handle_task(hwmgr, AMD_PP_TASK_READJUST_POWER_STATE, NULL); 347 348 return 0; 349 } 350 351 static enum amd_dpm_forced_level pp_dpm_get_performance_level( 352 void *handle) 353 { 354 struct pp_hwmgr *hwmgr = handle; 355 356 if (!hwmgr || !hwmgr->pm_en) 357 return -EINVAL; 358 359 return hwmgr->dpm_level; 360 } 361 362 static uint32_t pp_dpm_get_sclk(void *handle, bool low) 363 { 364 struct pp_hwmgr *hwmgr = handle; 365 366 if (!hwmgr || !hwmgr->pm_en) 367 return 0; 368 369 if (hwmgr->hwmgr_func->get_sclk == NULL) { 370 pr_info_ratelimited("%s was not implemented.\n", __func__); 371 return 0; 372 } 373 return hwmgr->hwmgr_func->get_sclk(hwmgr, low); 374 } 375 376 static uint32_t pp_dpm_get_mclk(void *handle, bool low) 377 { 378 struct pp_hwmgr *hwmgr = handle; 379 380 if (!hwmgr || !hwmgr->pm_en) 381 return 0; 382 383 if (hwmgr->hwmgr_func->get_mclk == NULL) { 384 pr_info_ratelimited("%s was not implemented.\n", __func__); 385 return 0; 386 } 387 return hwmgr->hwmgr_func->get_mclk(hwmgr, low); 388 } 389 390 static void pp_dpm_powergate_vce(void *handle, bool gate) 391 { 392 struct pp_hwmgr *hwmgr = handle; 393 394 if (!hwmgr || !hwmgr->pm_en) 395 return; 396 397 if (hwmgr->hwmgr_func->powergate_vce == NULL) { 398 pr_info_ratelimited("%s was not implemented.\n", __func__); 399 return; 400 } 401 hwmgr->hwmgr_func->powergate_vce(hwmgr, gate); 402 } 403 404 static void pp_dpm_powergate_uvd(void *handle, bool gate) 405 { 406 struct pp_hwmgr *hwmgr = handle; 407 408 if (!hwmgr || !hwmgr->pm_en) 409 return; 410 411 if (hwmgr->hwmgr_func->powergate_uvd == NULL) { 412 pr_info_ratelimited("%s was not implemented.\n", __func__); 413 return; 414 } 415 hwmgr->hwmgr_func->powergate_uvd(hwmgr, gate); 416 } 417 418 static int pp_dpm_dispatch_tasks(void *handle, enum amd_pp_task task_id, 419 enum amd_pm_state_type *user_state) 420 { 421 struct pp_hwmgr *hwmgr = handle; 422 423 if (!hwmgr || !hwmgr->pm_en) 424 return -EINVAL; 425 426 return hwmgr_handle_task(hwmgr, task_id, user_state); 427 } 428 429 static enum amd_pm_state_type pp_dpm_get_current_power_state(void *handle) 430 { 431 struct pp_hwmgr *hwmgr = handle; 432 struct pp_power_state *state; 433 enum amd_pm_state_type pm_type; 434 435 if (!hwmgr || !hwmgr->pm_en || !hwmgr->current_ps) 436 return -EINVAL; 437 438 state = hwmgr->current_ps; 439 440 switch (state->classification.ui_label) { 441 case PP_StateUILabel_Battery: 442 pm_type = POWER_STATE_TYPE_BATTERY; 443 break; 444 case PP_StateUILabel_Balanced: 445 pm_type = POWER_STATE_TYPE_BALANCED; 446 break; 447 case PP_StateUILabel_Performance: 448 pm_type = POWER_STATE_TYPE_PERFORMANCE; 449 break; 450 default: 451 if (state->classification.flags & PP_StateClassificationFlag_Boot) 452 pm_type = POWER_STATE_TYPE_INTERNAL_BOOT; 453 else 454 pm_type = POWER_STATE_TYPE_DEFAULT; 455 break; 456 } 457 458 return pm_type; 459 } 460 461 static int pp_dpm_set_fan_control_mode(void *handle, uint32_t mode) 462 { 463 struct pp_hwmgr *hwmgr = handle; 464 465 if (!hwmgr || !hwmgr->pm_en) 466 return -EOPNOTSUPP; 467 468 if (hwmgr->hwmgr_func->set_fan_control_mode == NULL) 469 return -EOPNOTSUPP; 470 471 if (mode == U32_MAX) 472 return -EINVAL; 473 474 hwmgr->hwmgr_func->set_fan_control_mode(hwmgr, mode); 475 476 return 0; 477 } 478 479 static int pp_dpm_get_fan_control_mode(void *handle, uint32_t *fan_mode) 480 { 481 struct pp_hwmgr *hwmgr = handle; 482 483 if (!hwmgr || !hwmgr->pm_en) 484 return -EOPNOTSUPP; 485 486 if (hwmgr->hwmgr_func->get_fan_control_mode == NULL) 487 return -EOPNOTSUPP; 488 489 if (!fan_mode) 490 return -EINVAL; 491 492 *fan_mode = hwmgr->hwmgr_func->get_fan_control_mode(hwmgr); 493 return 0; 494 } 495 496 static int pp_dpm_set_fan_speed_pwm(void *handle, uint32_t speed) 497 { 498 struct pp_hwmgr *hwmgr = handle; 499 500 if (!hwmgr || !hwmgr->pm_en) 501 return -EOPNOTSUPP; 502 503 if (hwmgr->hwmgr_func->set_fan_speed_pwm == NULL) 504 return -EOPNOTSUPP; 505 506 if (speed == U32_MAX) 507 return -EINVAL; 508 509 return hwmgr->hwmgr_func->set_fan_speed_pwm(hwmgr, speed); 510 } 511 512 static int pp_dpm_get_fan_speed_pwm(void *handle, uint32_t *speed) 513 { 514 struct pp_hwmgr *hwmgr = handle; 515 516 if (!hwmgr || !hwmgr->pm_en) 517 return -EOPNOTSUPP; 518 519 if (hwmgr->hwmgr_func->get_fan_speed_pwm == NULL) 520 return -EOPNOTSUPP; 521 522 if (!speed) 523 return -EINVAL; 524 525 return hwmgr->hwmgr_func->get_fan_speed_pwm(hwmgr, speed); 526 } 527 528 static int pp_dpm_get_fan_speed_rpm(void *handle, uint32_t *rpm) 529 { 530 struct pp_hwmgr *hwmgr = handle; 531 532 if (!hwmgr || !hwmgr->pm_en) 533 return -EOPNOTSUPP; 534 535 if (hwmgr->hwmgr_func->get_fan_speed_rpm == NULL) 536 return -EOPNOTSUPP; 537 538 if (!rpm) 539 return -EINVAL; 540 541 return hwmgr->hwmgr_func->get_fan_speed_rpm(hwmgr, rpm); 542 } 543 544 static int pp_dpm_set_fan_speed_rpm(void *handle, uint32_t rpm) 545 { 546 struct pp_hwmgr *hwmgr = handle; 547 548 if (!hwmgr || !hwmgr->pm_en) 549 return -EOPNOTSUPP; 550 551 if (hwmgr->hwmgr_func->set_fan_speed_rpm == NULL) 552 return -EOPNOTSUPP; 553 554 if (rpm == U32_MAX) 555 return -EINVAL; 556 557 return hwmgr->hwmgr_func->set_fan_speed_rpm(hwmgr, rpm); 558 } 559 560 static int pp_dpm_get_pp_num_states(void *handle, 561 struct pp_states_info *data) 562 { 563 struct pp_hwmgr *hwmgr = handle; 564 int i; 565 566 memset(data, 0, sizeof(*data)); 567 568 if (!hwmgr || !hwmgr->pm_en ||!hwmgr->ps) 569 return -EINVAL; 570 571 data->nums = hwmgr->num_ps; 572 573 for (i = 0; i < hwmgr->num_ps; i++) { 574 struct pp_power_state *state = (struct pp_power_state *) 575 ((unsigned long)hwmgr->ps + i * hwmgr->ps_size); 576 switch (state->classification.ui_label) { 577 case PP_StateUILabel_Battery: 578 data->states[i] = POWER_STATE_TYPE_BATTERY; 579 break; 580 case PP_StateUILabel_Balanced: 581 data->states[i] = POWER_STATE_TYPE_BALANCED; 582 break; 583 case PP_StateUILabel_Performance: 584 data->states[i] = POWER_STATE_TYPE_PERFORMANCE; 585 break; 586 default: 587 if (state->classification.flags & PP_StateClassificationFlag_Boot) 588 data->states[i] = POWER_STATE_TYPE_INTERNAL_BOOT; 589 else 590 data->states[i] = POWER_STATE_TYPE_DEFAULT; 591 } 592 } 593 return 0; 594 } 595 596 static int pp_dpm_get_pp_table(void *handle, char **table) 597 { 598 struct pp_hwmgr *hwmgr = handle; 599 600 if (!hwmgr || !hwmgr->pm_en ||!hwmgr->soft_pp_table) 601 return -EINVAL; 602 603 *table = (char *)hwmgr->soft_pp_table; 604 return hwmgr->soft_pp_table_size; 605 } 606 607 static int amd_powerplay_reset(void *handle) 608 { 609 struct pp_hwmgr *hwmgr = handle; 610 int ret; 611 612 ret = hwmgr_hw_fini(hwmgr); 613 if (ret) 614 return ret; 615 616 ret = hwmgr_hw_init(hwmgr); 617 if (ret) 618 return ret; 619 620 return hwmgr_handle_task(hwmgr, AMD_PP_TASK_COMPLETE_INIT, NULL); 621 } 622 623 static int pp_dpm_set_pp_table(void *handle, const char *buf, size_t size) 624 { 625 struct pp_hwmgr *hwmgr = handle; 626 int ret = -ENOMEM; 627 628 if (!hwmgr || !hwmgr->pm_en) 629 return -EINVAL; 630 631 if (!hwmgr->hardcode_pp_table) { 632 hwmgr->hardcode_pp_table = kmemdup(hwmgr->soft_pp_table, 633 hwmgr->soft_pp_table_size, 634 GFP_KERNEL); 635 if (!hwmgr->hardcode_pp_table) 636 return ret; 637 } 638 639 memcpy(hwmgr->hardcode_pp_table, buf, size); 640 641 hwmgr->soft_pp_table = hwmgr->hardcode_pp_table; 642 643 ret = amd_powerplay_reset(handle); 644 if (ret) 645 return ret; 646 647 if (hwmgr->hwmgr_func->avfs_control) 648 ret = hwmgr->hwmgr_func->avfs_control(hwmgr, false); 649 650 return ret; 651 } 652 653 static int pp_dpm_force_clock_level(void *handle, 654 enum pp_clock_type type, uint32_t mask) 655 { 656 struct pp_hwmgr *hwmgr = handle; 657 658 if (!hwmgr || !hwmgr->pm_en) 659 return -EINVAL; 660 661 if (hwmgr->hwmgr_func->force_clock_level == NULL) { 662 pr_info_ratelimited("%s was not implemented.\n", __func__); 663 return 0; 664 } 665 666 if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) { 667 pr_debug("force clock level is for dpm manual mode only.\n"); 668 return -EINVAL; 669 } 670 671 return hwmgr->hwmgr_func->force_clock_level(hwmgr, type, mask); 672 } 673 674 static int pp_dpm_emit_clock_levels(void *handle, 675 enum pp_clock_type type, 676 char *buf, 677 int *offset) 678 { 679 struct pp_hwmgr *hwmgr = handle; 680 681 if (!hwmgr || !hwmgr->pm_en) 682 return -EOPNOTSUPP; 683 684 if (!hwmgr->hwmgr_func->emit_clock_levels) 685 return -ENOENT; 686 687 return hwmgr->hwmgr_func->emit_clock_levels(hwmgr, type, buf, offset); 688 } 689 690 static int pp_dpm_print_clock_levels(void *handle, 691 enum pp_clock_type type, char *buf) 692 { 693 struct pp_hwmgr *hwmgr = handle; 694 695 if (!hwmgr || !hwmgr->pm_en) 696 return -EINVAL; 697 698 if (hwmgr->hwmgr_func->print_clock_levels == NULL) { 699 pr_info_ratelimited("%s was not implemented.\n", __func__); 700 return 0; 701 } 702 return hwmgr->hwmgr_func->print_clock_levels(hwmgr, type, buf); 703 } 704 705 static int pp_dpm_get_sclk_od(void *handle) 706 { 707 struct pp_hwmgr *hwmgr = handle; 708 709 if (!hwmgr || !hwmgr->pm_en) 710 return -EINVAL; 711 712 if (hwmgr->hwmgr_func->get_sclk_od == NULL) { 713 pr_info_ratelimited("%s was not implemented.\n", __func__); 714 return 0; 715 } 716 return hwmgr->hwmgr_func->get_sclk_od(hwmgr); 717 } 718 719 static int pp_dpm_set_sclk_od(void *handle, uint32_t value) 720 { 721 struct pp_hwmgr *hwmgr = handle; 722 723 if (!hwmgr || !hwmgr->pm_en) 724 return -EINVAL; 725 726 if (hwmgr->hwmgr_func->set_sclk_od == NULL) { 727 pr_info_ratelimited("%s was not implemented.\n", __func__); 728 return 0; 729 } 730 731 return hwmgr->hwmgr_func->set_sclk_od(hwmgr, value); 732 } 733 734 static int pp_dpm_get_mclk_od(void *handle) 735 { 736 struct pp_hwmgr *hwmgr = handle; 737 738 if (!hwmgr || !hwmgr->pm_en) 739 return -EINVAL; 740 741 if (hwmgr->hwmgr_func->get_mclk_od == NULL) { 742 pr_info_ratelimited("%s was not implemented.\n", __func__); 743 return 0; 744 } 745 return hwmgr->hwmgr_func->get_mclk_od(hwmgr); 746 } 747 748 static int pp_dpm_set_mclk_od(void *handle, uint32_t value) 749 { 750 struct pp_hwmgr *hwmgr = handle; 751 752 if (!hwmgr || !hwmgr->pm_en) 753 return -EINVAL; 754 755 if (hwmgr->hwmgr_func->set_mclk_od == NULL) { 756 pr_info_ratelimited("%s was not implemented.\n", __func__); 757 return 0; 758 } 759 return hwmgr->hwmgr_func->set_mclk_od(hwmgr, value); 760 } 761 762 static int pp_dpm_read_sensor(void *handle, int idx, 763 void *value, int *size) 764 { 765 struct pp_hwmgr *hwmgr = handle; 766 767 if (!hwmgr || !hwmgr->pm_en || !value) 768 return -EINVAL; 769 770 switch (idx) { 771 case AMDGPU_PP_SENSOR_STABLE_PSTATE_SCLK: 772 *((uint32_t *)value) = hwmgr->pstate_sclk; 773 return 0; 774 case AMDGPU_PP_SENSOR_STABLE_PSTATE_MCLK: 775 *((uint32_t *)value) = hwmgr->pstate_mclk; 776 return 0; 777 case AMDGPU_PP_SENSOR_MIN_FAN_RPM: 778 *((uint32_t *)value) = hwmgr->thermal_controller.fanInfo.ulMinRPM; 779 return 0; 780 case AMDGPU_PP_SENSOR_MAX_FAN_RPM: 781 *((uint32_t *)value) = hwmgr->thermal_controller.fanInfo.ulMaxRPM; 782 return 0; 783 default: 784 return hwmgr->hwmgr_func->read_sensor(hwmgr, idx, value, size); 785 } 786 } 787 788 static struct amd_vce_state* 789 pp_dpm_get_vce_clock_state(void *handle, unsigned idx) 790 { 791 struct pp_hwmgr *hwmgr = handle; 792 793 if (!hwmgr || !hwmgr->pm_en) 794 return NULL; 795 796 if (idx < hwmgr->num_vce_state_tables) 797 return &hwmgr->vce_states[idx]; 798 return NULL; 799 } 800 801 static int pp_get_power_profile_mode(void *handle, char *buf) 802 { 803 struct pp_hwmgr *hwmgr = handle; 804 805 if (!hwmgr || !hwmgr->pm_en || !hwmgr->hwmgr_func->get_power_profile_mode) 806 return -EOPNOTSUPP; 807 if (!buf) 808 return -EINVAL; 809 810 return hwmgr->hwmgr_func->get_power_profile_mode(hwmgr, buf); 811 } 812 813 static int pp_set_power_profile_mode(void *handle, long *input, uint32_t size) 814 { 815 struct pp_hwmgr *hwmgr = handle; 816 817 if (!hwmgr || !hwmgr->pm_en || !hwmgr->hwmgr_func->set_power_profile_mode) 818 return -EOPNOTSUPP; 819 820 if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) { 821 pr_debug("power profile setting is for manual dpm mode only.\n"); 822 return -EINVAL; 823 } 824 825 return hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, input, size); 826 } 827 828 static int pp_set_fine_grain_clk_vol(void *handle, uint32_t type, long *input, uint32_t size) 829 { 830 struct pp_hwmgr *hwmgr = handle; 831 832 if (!hwmgr || !hwmgr->pm_en) 833 return -EINVAL; 834 835 if (hwmgr->hwmgr_func->set_fine_grain_clk_vol == NULL) 836 return 0; 837 838 return hwmgr->hwmgr_func->set_fine_grain_clk_vol(hwmgr, type, input, size); 839 } 840 841 static int pp_odn_edit_dpm_table(void *handle, enum PP_OD_DPM_TABLE_COMMAND type, 842 long *input, uint32_t size) 843 { 844 struct pp_hwmgr *hwmgr = handle; 845 846 if (!hwmgr || !hwmgr->pm_en) 847 return -EINVAL; 848 849 if (hwmgr->hwmgr_func->odn_edit_dpm_table == NULL) { 850 pr_info_ratelimited("%s was not implemented.\n", __func__); 851 return 0; 852 } 853 854 return hwmgr->hwmgr_func->odn_edit_dpm_table(hwmgr, type, input, size); 855 } 856 857 static int pp_dpm_set_mp1_state(void *handle, enum pp_mp1_state mp1_state) 858 { 859 struct pp_hwmgr *hwmgr = handle; 860 861 if (!hwmgr) 862 return -EINVAL; 863 864 if (!hwmgr->pm_en) 865 return 0; 866 867 if (hwmgr->hwmgr_func->set_mp1_state) 868 return hwmgr->hwmgr_func->set_mp1_state(hwmgr, mp1_state); 869 870 return 0; 871 } 872 873 static int pp_dpm_switch_power_profile(void *handle, 874 enum PP_SMC_POWER_PROFILE type, bool en) 875 { 876 struct pp_hwmgr *hwmgr = handle; 877 long workload; 878 uint32_t index; 879 880 if (!hwmgr || !hwmgr->pm_en) 881 return -EINVAL; 882 883 if (hwmgr->hwmgr_func->set_power_profile_mode == NULL) { 884 pr_info_ratelimited("%s was not implemented.\n", __func__); 885 return -EINVAL; 886 } 887 888 if (!(type < PP_SMC_POWER_PROFILE_CUSTOM)) 889 return -EINVAL; 890 891 if (!en) { 892 hwmgr->workload_mask &= ~(1 << hwmgr->workload_prority[type]); 893 index = fls(hwmgr->workload_mask); 894 index = index > 0 && index <= Workload_Policy_Max ? index - 1 : 0; 895 workload = hwmgr->workload_setting[index]; 896 } else { 897 hwmgr->workload_mask |= (1 << hwmgr->workload_prority[type]); 898 index = fls(hwmgr->workload_mask); 899 index = index <= Workload_Policy_Max ? index - 1 : 0; 900 workload = hwmgr->workload_setting[index]; 901 } 902 903 if (type == PP_SMC_POWER_PROFILE_COMPUTE && 904 hwmgr->hwmgr_func->disable_power_features_for_compute_performance) { 905 if (hwmgr->hwmgr_func->disable_power_features_for_compute_performance(hwmgr, en)) 906 return -EINVAL; 907 } 908 909 if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) 910 hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, &workload, 0); 911 912 return 0; 913 } 914 915 static int pp_set_power_limit(void *handle, uint32_t limit) 916 { 917 struct pp_hwmgr *hwmgr = handle; 918 uint32_t max_power_limit; 919 920 if (!hwmgr || !hwmgr->pm_en) 921 return -EINVAL; 922 923 if (hwmgr->hwmgr_func->set_power_limit == NULL) { 924 pr_info_ratelimited("%s was not implemented.\n", __func__); 925 return -EINVAL; 926 } 927 928 if (limit == 0) 929 limit = hwmgr->default_power_limit; 930 931 max_power_limit = hwmgr->default_power_limit; 932 if (hwmgr->od_enabled) { 933 max_power_limit *= (100 + hwmgr->platform_descriptor.TDPODLimit); 934 max_power_limit /= 100; 935 } 936 937 if (limit > max_power_limit) 938 return -EINVAL; 939 940 hwmgr->hwmgr_func->set_power_limit(hwmgr, limit); 941 hwmgr->power_limit = limit; 942 return 0; 943 } 944 945 static int pp_get_power_limit(void *handle, uint32_t *limit, 946 enum pp_power_limit_level pp_limit_level, 947 enum pp_power_type power_type) 948 { 949 struct pp_hwmgr *hwmgr = handle; 950 int ret = 0; 951 952 if (!hwmgr || !hwmgr->pm_en ||!limit) 953 return -EINVAL; 954 955 if (power_type != PP_PWR_TYPE_SUSTAINED) 956 return -EOPNOTSUPP; 957 958 switch (pp_limit_level) { 959 case PP_PWR_LIMIT_CURRENT: 960 *limit = hwmgr->power_limit; 961 break; 962 case PP_PWR_LIMIT_DEFAULT: 963 *limit = hwmgr->default_power_limit; 964 break; 965 case PP_PWR_LIMIT_MAX: 966 *limit = hwmgr->default_power_limit; 967 if (hwmgr->od_enabled) { 968 *limit *= (100 + hwmgr->platform_descriptor.TDPODLimit); 969 *limit /= 100; 970 } 971 break; 972 default: 973 ret = -EOPNOTSUPP; 974 break; 975 } 976 977 return ret; 978 } 979 980 static int pp_display_configuration_change(void *handle, 981 const struct amd_pp_display_configuration *display_config) 982 { 983 struct pp_hwmgr *hwmgr = handle; 984 985 if (!hwmgr || !hwmgr->pm_en) 986 return -EINVAL; 987 988 phm_store_dal_configuration_data(hwmgr, display_config); 989 return 0; 990 } 991 992 static int pp_get_display_power_level(void *handle, 993 struct amd_pp_simple_clock_info *output) 994 { 995 struct pp_hwmgr *hwmgr = handle; 996 997 if (!hwmgr || !hwmgr->pm_en ||!output) 998 return -EINVAL; 999 1000 return phm_get_dal_power_level(hwmgr, output); 1001 } 1002 1003 static int pp_get_current_clocks(void *handle, 1004 struct amd_pp_clock_info *clocks) 1005 { 1006 struct amd_pp_simple_clock_info simple_clocks = { 0 }; 1007 struct pp_clock_info hw_clocks; 1008 struct pp_hwmgr *hwmgr = handle; 1009 int ret = 0; 1010 1011 if (!hwmgr || !hwmgr->pm_en) 1012 return -EINVAL; 1013 1014 phm_get_dal_power_level(hwmgr, &simple_clocks); 1015 1016 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, 1017 PHM_PlatformCaps_PowerContainment)) 1018 ret = phm_get_clock_info(hwmgr, &hwmgr->current_ps->hardware, 1019 &hw_clocks, PHM_PerformanceLevelDesignation_PowerContainment); 1020 else 1021 ret = phm_get_clock_info(hwmgr, &hwmgr->current_ps->hardware, 1022 &hw_clocks, PHM_PerformanceLevelDesignation_Activity); 1023 1024 if (ret) { 1025 pr_debug("Error in phm_get_clock_info \n"); 1026 return -EINVAL; 1027 } 1028 1029 clocks->min_engine_clock = hw_clocks.min_eng_clk; 1030 clocks->max_engine_clock = hw_clocks.max_eng_clk; 1031 clocks->min_memory_clock = hw_clocks.min_mem_clk; 1032 clocks->max_memory_clock = hw_clocks.max_mem_clk; 1033 clocks->min_bus_bandwidth = hw_clocks.min_bus_bandwidth; 1034 clocks->max_bus_bandwidth = hw_clocks.max_bus_bandwidth; 1035 1036 clocks->max_engine_clock_in_sr = hw_clocks.max_eng_clk; 1037 clocks->min_engine_clock_in_sr = hw_clocks.min_eng_clk; 1038 1039 if (simple_clocks.level == 0) 1040 clocks->max_clocks_state = PP_DAL_POWERLEVEL_7; 1041 else 1042 clocks->max_clocks_state = simple_clocks.level; 1043 1044 if (0 == phm_get_current_shallow_sleep_clocks(hwmgr, &hwmgr->current_ps->hardware, &hw_clocks)) { 1045 clocks->max_engine_clock_in_sr = hw_clocks.max_eng_clk; 1046 clocks->min_engine_clock_in_sr = hw_clocks.min_eng_clk; 1047 } 1048 return 0; 1049 } 1050 1051 static int pp_get_clock_by_type(void *handle, enum amd_pp_clock_type type, struct amd_pp_clocks *clocks) 1052 { 1053 struct pp_hwmgr *hwmgr = handle; 1054 1055 if (!hwmgr || !hwmgr->pm_en) 1056 return -EINVAL; 1057 1058 if (clocks == NULL) 1059 return -EINVAL; 1060 1061 return phm_get_clock_by_type(hwmgr, type, clocks); 1062 } 1063 1064 static int pp_get_clock_by_type_with_latency(void *handle, 1065 enum amd_pp_clock_type type, 1066 struct pp_clock_levels_with_latency *clocks) 1067 { 1068 struct pp_hwmgr *hwmgr = handle; 1069 1070 if (!hwmgr || !hwmgr->pm_en ||!clocks) 1071 return -EINVAL; 1072 1073 return phm_get_clock_by_type_with_latency(hwmgr, type, clocks); 1074 } 1075 1076 static int pp_get_clock_by_type_with_voltage(void *handle, 1077 enum amd_pp_clock_type type, 1078 struct pp_clock_levels_with_voltage *clocks) 1079 { 1080 struct pp_hwmgr *hwmgr = handle; 1081 1082 if (!hwmgr || !hwmgr->pm_en ||!clocks) 1083 return -EINVAL; 1084 1085 return phm_get_clock_by_type_with_voltage(hwmgr, type, clocks); 1086 } 1087 1088 static int pp_set_watermarks_for_clocks_ranges(void *handle, 1089 void *clock_ranges) 1090 { 1091 struct pp_hwmgr *hwmgr = handle; 1092 1093 if (!hwmgr || !hwmgr->pm_en || !clock_ranges) 1094 return -EINVAL; 1095 1096 return phm_set_watermarks_for_clocks_ranges(hwmgr, 1097 clock_ranges); 1098 } 1099 1100 static int pp_display_clock_voltage_request(void *handle, 1101 struct pp_display_clock_request *clock) 1102 { 1103 struct pp_hwmgr *hwmgr = handle; 1104 1105 if (!hwmgr || !hwmgr->pm_en ||!clock) 1106 return -EINVAL; 1107 1108 return phm_display_clock_voltage_request(hwmgr, clock); 1109 } 1110 1111 static int pp_get_display_mode_validation_clocks(void *handle, 1112 struct amd_pp_simple_clock_info *clocks) 1113 { 1114 struct pp_hwmgr *hwmgr = handle; 1115 int ret = 0; 1116 1117 if (!hwmgr || !hwmgr->pm_en ||!clocks) 1118 return -EINVAL; 1119 1120 clocks->level = PP_DAL_POWERLEVEL_7; 1121 1122 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DynamicPatchPowerState)) 1123 ret = phm_get_max_high_clocks(hwmgr, clocks); 1124 1125 return ret; 1126 } 1127 1128 static int pp_dpm_powergate_mmhub(void *handle) 1129 { 1130 struct pp_hwmgr *hwmgr = handle; 1131 1132 if (!hwmgr || !hwmgr->pm_en) 1133 return -EINVAL; 1134 1135 if (hwmgr->hwmgr_func->powergate_mmhub == NULL) { 1136 pr_info_ratelimited("%s was not implemented.\n", __func__); 1137 return 0; 1138 } 1139 1140 return hwmgr->hwmgr_func->powergate_mmhub(hwmgr); 1141 } 1142 1143 static int pp_dpm_powergate_gfx(void *handle, bool gate) 1144 { 1145 struct pp_hwmgr *hwmgr = handle; 1146 1147 if (!hwmgr || !hwmgr->pm_en) 1148 return 0; 1149 1150 if (hwmgr->hwmgr_func->powergate_gfx == NULL) { 1151 pr_info_ratelimited("%s was not implemented.\n", __func__); 1152 return 0; 1153 } 1154 1155 return hwmgr->hwmgr_func->powergate_gfx(hwmgr, gate); 1156 } 1157 1158 static void pp_dpm_powergate_acp(void *handle, bool gate) 1159 { 1160 struct pp_hwmgr *hwmgr = handle; 1161 1162 if (!hwmgr || !hwmgr->pm_en) 1163 return; 1164 1165 if (hwmgr->hwmgr_func->powergate_acp == NULL) { 1166 pr_info_ratelimited("%s was not implemented.\n", __func__); 1167 return; 1168 } 1169 1170 hwmgr->hwmgr_func->powergate_acp(hwmgr, gate); 1171 } 1172 1173 static void pp_dpm_powergate_sdma(void *handle, bool gate) 1174 { 1175 struct pp_hwmgr *hwmgr = handle; 1176 1177 if (!hwmgr) 1178 return; 1179 1180 if (hwmgr->hwmgr_func->powergate_sdma == NULL) { 1181 pr_info_ratelimited("%s was not implemented.\n", __func__); 1182 return; 1183 } 1184 1185 hwmgr->hwmgr_func->powergate_sdma(hwmgr, gate); 1186 } 1187 1188 static int pp_set_powergating_by_smu(void *handle, 1189 uint32_t block_type, bool gate) 1190 { 1191 int ret = 0; 1192 1193 switch (block_type) { 1194 case AMD_IP_BLOCK_TYPE_UVD: 1195 case AMD_IP_BLOCK_TYPE_VCN: 1196 pp_dpm_powergate_uvd(handle, gate); 1197 break; 1198 case AMD_IP_BLOCK_TYPE_VCE: 1199 pp_dpm_powergate_vce(handle, gate); 1200 break; 1201 case AMD_IP_BLOCK_TYPE_GMC: 1202 /* 1203 * For now, this is only used on PICASSO. 1204 * And only "gate" operation is supported. 1205 */ 1206 if (gate) 1207 pp_dpm_powergate_mmhub(handle); 1208 break; 1209 case AMD_IP_BLOCK_TYPE_GFX: 1210 ret = pp_dpm_powergate_gfx(handle, gate); 1211 break; 1212 case AMD_IP_BLOCK_TYPE_ACP: 1213 pp_dpm_powergate_acp(handle, gate); 1214 break; 1215 case AMD_IP_BLOCK_TYPE_SDMA: 1216 pp_dpm_powergate_sdma(handle, gate); 1217 break; 1218 default: 1219 break; 1220 } 1221 return ret; 1222 } 1223 1224 static int pp_notify_smu_enable_pwe(void *handle) 1225 { 1226 struct pp_hwmgr *hwmgr = handle; 1227 1228 if (!hwmgr || !hwmgr->pm_en) 1229 return -EINVAL; 1230 1231 if (hwmgr->hwmgr_func->smus_notify_pwe == NULL) { 1232 pr_info_ratelimited("%s was not implemented.\n", __func__); 1233 return -EINVAL; 1234 } 1235 1236 hwmgr->hwmgr_func->smus_notify_pwe(hwmgr); 1237 1238 return 0; 1239 } 1240 1241 static int pp_enable_mgpu_fan_boost(void *handle) 1242 { 1243 struct pp_hwmgr *hwmgr = handle; 1244 1245 if (!hwmgr) 1246 return -EINVAL; 1247 1248 if (!hwmgr->pm_en || 1249 hwmgr->hwmgr_func->enable_mgpu_fan_boost == NULL) 1250 return 0; 1251 1252 hwmgr->hwmgr_func->enable_mgpu_fan_boost(hwmgr); 1253 1254 return 0; 1255 } 1256 1257 static int pp_set_min_deep_sleep_dcefclk(void *handle, uint32_t clock) 1258 { 1259 struct pp_hwmgr *hwmgr = handle; 1260 1261 if (!hwmgr || !hwmgr->pm_en) 1262 return -EINVAL; 1263 1264 if (hwmgr->hwmgr_func->set_min_deep_sleep_dcefclk == NULL) { 1265 pr_debug("%s was not implemented.\n", __func__); 1266 return -EINVAL; 1267 } 1268 1269 hwmgr->hwmgr_func->set_min_deep_sleep_dcefclk(hwmgr, clock); 1270 1271 return 0; 1272 } 1273 1274 static int pp_set_hard_min_dcefclk_by_freq(void *handle, uint32_t clock) 1275 { 1276 struct pp_hwmgr *hwmgr = handle; 1277 1278 if (!hwmgr || !hwmgr->pm_en) 1279 return -EINVAL; 1280 1281 if (hwmgr->hwmgr_func->set_hard_min_dcefclk_by_freq == NULL) { 1282 pr_debug("%s was not implemented.\n", __func__); 1283 return -EINVAL; 1284 } 1285 1286 hwmgr->hwmgr_func->set_hard_min_dcefclk_by_freq(hwmgr, clock); 1287 1288 return 0; 1289 } 1290 1291 static int pp_set_hard_min_fclk_by_freq(void *handle, uint32_t clock) 1292 { 1293 struct pp_hwmgr *hwmgr = handle; 1294 1295 if (!hwmgr || !hwmgr->pm_en) 1296 return -EINVAL; 1297 1298 if (hwmgr->hwmgr_func->set_hard_min_fclk_by_freq == NULL) { 1299 pr_debug("%s was not implemented.\n", __func__); 1300 return -EINVAL; 1301 } 1302 1303 hwmgr->hwmgr_func->set_hard_min_fclk_by_freq(hwmgr, clock); 1304 1305 return 0; 1306 } 1307 1308 static int pp_set_active_display_count(void *handle, uint32_t count) 1309 { 1310 struct pp_hwmgr *hwmgr = handle; 1311 1312 if (!hwmgr || !hwmgr->pm_en) 1313 return -EINVAL; 1314 1315 return phm_set_active_display_count(hwmgr, count); 1316 } 1317 1318 static int pp_get_asic_baco_capability(void *handle, bool *cap) 1319 { 1320 struct pp_hwmgr *hwmgr = handle; 1321 1322 *cap = false; 1323 if (!hwmgr) 1324 return -EINVAL; 1325 1326 if (!(hwmgr->not_vf && amdgpu_dpm) || 1327 !hwmgr->hwmgr_func->get_asic_baco_capability) 1328 return 0; 1329 1330 hwmgr->hwmgr_func->get_asic_baco_capability(hwmgr, cap); 1331 1332 return 0; 1333 } 1334 1335 static int pp_get_asic_baco_state(void *handle, int *state) 1336 { 1337 struct pp_hwmgr *hwmgr = handle; 1338 1339 if (!hwmgr) 1340 return -EINVAL; 1341 1342 if (!hwmgr->pm_en || !hwmgr->hwmgr_func->get_asic_baco_state) 1343 return 0; 1344 1345 hwmgr->hwmgr_func->get_asic_baco_state(hwmgr, (enum BACO_STATE *)state); 1346 1347 return 0; 1348 } 1349 1350 static int pp_set_asic_baco_state(void *handle, int state) 1351 { 1352 struct pp_hwmgr *hwmgr = handle; 1353 1354 if (!hwmgr) 1355 return -EINVAL; 1356 1357 if (!(hwmgr->not_vf && amdgpu_dpm) || 1358 !hwmgr->hwmgr_func->set_asic_baco_state) 1359 return 0; 1360 1361 hwmgr->hwmgr_func->set_asic_baco_state(hwmgr, (enum BACO_STATE)state); 1362 1363 return 0; 1364 } 1365 1366 static int pp_get_ppfeature_status(void *handle, char *buf) 1367 { 1368 struct pp_hwmgr *hwmgr = handle; 1369 1370 if (!hwmgr || !hwmgr->pm_en || !buf) 1371 return -EINVAL; 1372 1373 if (hwmgr->hwmgr_func->get_ppfeature_status == NULL) { 1374 pr_info_ratelimited("%s was not implemented.\n", __func__); 1375 return -EINVAL; 1376 } 1377 1378 return hwmgr->hwmgr_func->get_ppfeature_status(hwmgr, buf); 1379 } 1380 1381 static int pp_set_ppfeature_status(void *handle, uint64_t ppfeature_masks) 1382 { 1383 struct pp_hwmgr *hwmgr = handle; 1384 1385 if (!hwmgr || !hwmgr->pm_en) 1386 return -EINVAL; 1387 1388 if (hwmgr->hwmgr_func->set_ppfeature_status == NULL) { 1389 pr_info_ratelimited("%s was not implemented.\n", __func__); 1390 return -EINVAL; 1391 } 1392 1393 return hwmgr->hwmgr_func->set_ppfeature_status(hwmgr, ppfeature_masks); 1394 } 1395 1396 static int pp_asic_reset_mode_2(void *handle) 1397 { 1398 struct pp_hwmgr *hwmgr = handle; 1399 1400 if (!hwmgr || !hwmgr->pm_en) 1401 return -EINVAL; 1402 1403 if (hwmgr->hwmgr_func->asic_reset == NULL) { 1404 pr_info_ratelimited("%s was not implemented.\n", __func__); 1405 return -EINVAL; 1406 } 1407 1408 return hwmgr->hwmgr_func->asic_reset(hwmgr, SMU_ASIC_RESET_MODE_2); 1409 } 1410 1411 static int pp_smu_i2c_bus_access(void *handle, bool acquire) 1412 { 1413 struct pp_hwmgr *hwmgr = handle; 1414 1415 if (!hwmgr || !hwmgr->pm_en) 1416 return -EINVAL; 1417 1418 if (hwmgr->hwmgr_func->smu_i2c_bus_access == NULL) { 1419 pr_info_ratelimited("%s was not implemented.\n", __func__); 1420 return -EINVAL; 1421 } 1422 1423 return hwmgr->hwmgr_func->smu_i2c_bus_access(hwmgr, acquire); 1424 } 1425 1426 static int pp_set_df_cstate(void *handle, enum pp_df_cstate state) 1427 { 1428 struct pp_hwmgr *hwmgr = handle; 1429 1430 if (!hwmgr) 1431 return -EINVAL; 1432 1433 if (!hwmgr->pm_en || !hwmgr->hwmgr_func->set_df_cstate) 1434 return 0; 1435 1436 hwmgr->hwmgr_func->set_df_cstate(hwmgr, state); 1437 1438 return 0; 1439 } 1440 1441 static int pp_set_xgmi_pstate(void *handle, uint32_t pstate) 1442 { 1443 struct pp_hwmgr *hwmgr = handle; 1444 1445 if (!hwmgr) 1446 return -EINVAL; 1447 1448 if (!hwmgr->pm_en || !hwmgr->hwmgr_func->set_xgmi_pstate) 1449 return 0; 1450 1451 hwmgr->hwmgr_func->set_xgmi_pstate(hwmgr, pstate); 1452 1453 return 0; 1454 } 1455 1456 static ssize_t pp_get_gpu_metrics(void *handle, void **table) 1457 { 1458 struct pp_hwmgr *hwmgr = handle; 1459 1460 if (!hwmgr) 1461 return -EINVAL; 1462 1463 if (!hwmgr->pm_en || !hwmgr->hwmgr_func->get_gpu_metrics) 1464 return -EOPNOTSUPP; 1465 1466 return hwmgr->hwmgr_func->get_gpu_metrics(hwmgr, table); 1467 } 1468 1469 static int pp_gfx_state_change_set(void *handle, uint32_t state) 1470 { 1471 struct pp_hwmgr *hwmgr = handle; 1472 1473 if (!hwmgr || !hwmgr->pm_en) 1474 return -EINVAL; 1475 1476 if (hwmgr->hwmgr_func->gfx_state_change == NULL) { 1477 pr_info_ratelimited("%s was not implemented.\n", __func__); 1478 return -EINVAL; 1479 } 1480 1481 hwmgr->hwmgr_func->gfx_state_change(hwmgr, state); 1482 return 0; 1483 } 1484 1485 static int pp_get_prv_buffer_details(void *handle, void **addr, size_t *size) 1486 { 1487 struct pp_hwmgr *hwmgr = handle; 1488 struct amdgpu_device *adev = hwmgr->adev; 1489 int err; 1490 1491 if (!addr || !size) 1492 return -EINVAL; 1493 1494 *addr = NULL; 1495 *size = 0; 1496 if (adev->pm.smu_prv_buffer) { 1497 err = amdgpu_bo_kmap(adev->pm.smu_prv_buffer, addr); 1498 if (err) 1499 return err; 1500 *size = adev->pm.smu_prv_buffer_size; 1501 } 1502 1503 return 0; 1504 } 1505 1506 static void pp_pm_compute_clocks(void *handle) 1507 { 1508 struct pp_hwmgr *hwmgr = handle; 1509 struct amdgpu_device *adev = hwmgr->adev; 1510 1511 if (!adev->dc_enabled) { 1512 amdgpu_dpm_get_active_displays(adev); 1513 adev->pm.pm_display_cfg.num_display = adev->pm.dpm.new_active_crtc_count; 1514 adev->pm.pm_display_cfg.vrefresh = amdgpu_dpm_get_vrefresh(adev); 1515 adev->pm.pm_display_cfg.min_vblank_time = amdgpu_dpm_get_vblank_time(adev); 1516 /* we have issues with mclk switching with 1517 * refresh rates over 120 hz on the non-DC code. 1518 */ 1519 if (adev->pm.pm_display_cfg.vrefresh > 120) 1520 adev->pm.pm_display_cfg.min_vblank_time = 0; 1521 1522 pp_display_configuration_change(handle, 1523 &adev->pm.pm_display_cfg); 1524 } 1525 1526 pp_dpm_dispatch_tasks(handle, 1527 AMD_PP_TASK_DISPLAY_CONFIG_CHANGE, 1528 NULL); 1529 } 1530 1531 static const struct amd_pm_funcs pp_dpm_funcs = { 1532 .load_firmware = pp_dpm_load_fw, 1533 .wait_for_fw_loading_complete = pp_dpm_fw_loading_complete, 1534 .force_performance_level = pp_dpm_force_performance_level, 1535 .get_performance_level = pp_dpm_get_performance_level, 1536 .get_current_power_state = pp_dpm_get_current_power_state, 1537 .dispatch_tasks = pp_dpm_dispatch_tasks, 1538 .set_fan_control_mode = pp_dpm_set_fan_control_mode, 1539 .get_fan_control_mode = pp_dpm_get_fan_control_mode, 1540 .set_fan_speed_pwm = pp_dpm_set_fan_speed_pwm, 1541 .get_fan_speed_pwm = pp_dpm_get_fan_speed_pwm, 1542 .get_fan_speed_rpm = pp_dpm_get_fan_speed_rpm, 1543 .set_fan_speed_rpm = pp_dpm_set_fan_speed_rpm, 1544 .get_pp_num_states = pp_dpm_get_pp_num_states, 1545 .get_pp_table = pp_dpm_get_pp_table, 1546 .set_pp_table = pp_dpm_set_pp_table, 1547 .force_clock_level = pp_dpm_force_clock_level, 1548 .emit_clock_levels = pp_dpm_emit_clock_levels, 1549 .print_clock_levels = pp_dpm_print_clock_levels, 1550 .get_sclk_od = pp_dpm_get_sclk_od, 1551 .set_sclk_od = pp_dpm_set_sclk_od, 1552 .get_mclk_od = pp_dpm_get_mclk_od, 1553 .set_mclk_od = pp_dpm_set_mclk_od, 1554 .read_sensor = pp_dpm_read_sensor, 1555 .get_vce_clock_state = pp_dpm_get_vce_clock_state, 1556 .switch_power_profile = pp_dpm_switch_power_profile, 1557 .set_clockgating_by_smu = pp_set_clockgating_by_smu, 1558 .set_powergating_by_smu = pp_set_powergating_by_smu, 1559 .get_power_profile_mode = pp_get_power_profile_mode, 1560 .set_power_profile_mode = pp_set_power_profile_mode, 1561 .set_fine_grain_clk_vol = pp_set_fine_grain_clk_vol, 1562 .odn_edit_dpm_table = pp_odn_edit_dpm_table, 1563 .set_mp1_state = pp_dpm_set_mp1_state, 1564 .set_power_limit = pp_set_power_limit, 1565 .get_power_limit = pp_get_power_limit, 1566 /* export to DC */ 1567 .get_sclk = pp_dpm_get_sclk, 1568 .get_mclk = pp_dpm_get_mclk, 1569 .display_configuration_change = pp_display_configuration_change, 1570 .get_display_power_level = pp_get_display_power_level, 1571 .get_current_clocks = pp_get_current_clocks, 1572 .get_clock_by_type = pp_get_clock_by_type, 1573 .get_clock_by_type_with_latency = pp_get_clock_by_type_with_latency, 1574 .get_clock_by_type_with_voltage = pp_get_clock_by_type_with_voltage, 1575 .set_watermarks_for_clocks_ranges = pp_set_watermarks_for_clocks_ranges, 1576 .display_clock_voltage_request = pp_display_clock_voltage_request, 1577 .get_display_mode_validation_clocks = pp_get_display_mode_validation_clocks, 1578 .notify_smu_enable_pwe = pp_notify_smu_enable_pwe, 1579 .enable_mgpu_fan_boost = pp_enable_mgpu_fan_boost, 1580 .set_active_display_count = pp_set_active_display_count, 1581 .set_min_deep_sleep_dcefclk = pp_set_min_deep_sleep_dcefclk, 1582 .set_hard_min_dcefclk_by_freq = pp_set_hard_min_dcefclk_by_freq, 1583 .set_hard_min_fclk_by_freq = pp_set_hard_min_fclk_by_freq, 1584 .get_asic_baco_capability = pp_get_asic_baco_capability, 1585 .get_asic_baco_state = pp_get_asic_baco_state, 1586 .set_asic_baco_state = pp_set_asic_baco_state, 1587 .get_ppfeature_status = pp_get_ppfeature_status, 1588 .set_ppfeature_status = pp_set_ppfeature_status, 1589 .asic_reset_mode_2 = pp_asic_reset_mode_2, 1590 .smu_i2c_bus_access = pp_smu_i2c_bus_access, 1591 .set_df_cstate = pp_set_df_cstate, 1592 .set_xgmi_pstate = pp_set_xgmi_pstate, 1593 .get_gpu_metrics = pp_get_gpu_metrics, 1594 .gfx_state_change_set = pp_gfx_state_change_set, 1595 .get_smu_prv_buf_details = pp_get_prv_buffer_details, 1596 .pm_compute_clocks = pp_pm_compute_clocks, 1597 }; 1598