|
37 | 37 | #define amdgpu_dpm_enable_bapm(adev, e) \ |
38 | 38 | ((adev)->powerplay.pp_funcs->enable_bapm((adev)->powerplay.pp_handle, (e))) |
39 | 39 |
|
40 | | -static void amdgpu_dpm_get_active_displays(struct amdgpu_device *adev) |
41 | | -{ |
42 | | - struct drm_device *ddev = adev_to_drm(adev); |
43 | | - struct drm_crtc *crtc; |
44 | | - struct amdgpu_crtc *amdgpu_crtc; |
45 | | - |
46 | | - adev->pm.dpm.new_active_crtcs = 0; |
47 | | - adev->pm.dpm.new_active_crtc_count = 0; |
48 | | - if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) { |
49 | | - list_for_each_entry(crtc, |
50 | | - &ddev->mode_config.crtc_list, head) { |
51 | | - amdgpu_crtc = to_amdgpu_crtc(crtc); |
52 | | - if (amdgpu_crtc->enabled) { |
53 | | - adev->pm.dpm.new_active_crtcs |= (1 << amdgpu_crtc->crtc_id); |
54 | | - adev->pm.dpm.new_active_crtc_count++; |
55 | | - } |
56 | | - } |
57 | | - } |
58 | | -} |
59 | | - |
60 | | -u32 amdgpu_dpm_get_vblank_time(struct amdgpu_device *adev) |
61 | | -{ |
62 | | - struct drm_device *dev = adev_to_drm(adev); |
63 | | - struct drm_crtc *crtc; |
64 | | - struct amdgpu_crtc *amdgpu_crtc; |
65 | | - u32 vblank_in_pixels; |
66 | | - u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */ |
67 | | - |
68 | | - if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) { |
69 | | - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
70 | | - amdgpu_crtc = to_amdgpu_crtc(crtc); |
71 | | - if (crtc->enabled && amdgpu_crtc->enabled && amdgpu_crtc->hw_mode.clock) { |
72 | | - vblank_in_pixels = |
73 | | - amdgpu_crtc->hw_mode.crtc_htotal * |
74 | | - (amdgpu_crtc->hw_mode.crtc_vblank_end - |
75 | | - amdgpu_crtc->hw_mode.crtc_vdisplay + |
76 | | - (amdgpu_crtc->v_border * 2)); |
77 | | - |
78 | | - vblank_time_us = vblank_in_pixels * 1000 / amdgpu_crtc->hw_mode.clock; |
79 | | - break; |
80 | | - } |
81 | | - } |
82 | | - } |
83 | | - |
84 | | - return vblank_time_us; |
85 | | -} |
86 | | - |
87 | | -static u32 amdgpu_dpm_get_vrefresh(struct amdgpu_device *adev) |
88 | | -{ |
89 | | - struct drm_device *dev = adev_to_drm(adev); |
90 | | - struct drm_crtc *crtc; |
91 | | - struct amdgpu_crtc *amdgpu_crtc; |
92 | | - u32 vrefresh = 0; |
93 | | - |
94 | | - if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) { |
95 | | - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
96 | | - amdgpu_crtc = to_amdgpu_crtc(crtc); |
97 | | - if (crtc->enabled && amdgpu_crtc->enabled && amdgpu_crtc->hw_mode.clock) { |
98 | | - vrefresh = drm_mode_vrefresh(&amdgpu_crtc->hw_mode); |
99 | | - break; |
100 | | - } |
101 | | - } |
102 | | - } |
103 | | - |
104 | | - return vrefresh; |
105 | | -} |
106 | | - |
107 | 40 | int amdgpu_dpm_get_sclk(struct amdgpu_device *adev, bool low) |
108 | 41 | { |
109 | 42 | const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; |
@@ -432,140 +365,49 @@ int amdgpu_dpm_read_sensor(struct amdgpu_device *adev, enum amd_pp_sensors senso |
432 | 365 | return ret; |
433 | 366 | } |
434 | 367 |
|
435 | | -void amdgpu_dpm_thermal_work_handler(struct work_struct *work) |
436 | | -{ |
437 | | - struct amdgpu_device *adev = |
438 | | - container_of(work, struct amdgpu_device, |
439 | | - pm.dpm.thermal.work); |
440 | | - /* switch to the thermal state */ |
441 | | - enum amd_pm_state_type dpm_state = POWER_STATE_TYPE_INTERNAL_THERMAL; |
442 | | - int temp, size = sizeof(temp); |
443 | | - |
444 | | - if (!adev->pm.dpm_enabled) |
445 | | - return; |
446 | | - |
447 | | - if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_TEMP, |
448 | | - (void *)&temp, &size)) { |
449 | | - if (temp < adev->pm.dpm.thermal.min_temp) |
450 | | - /* switch back the user state */ |
451 | | - dpm_state = adev->pm.dpm.user_state; |
452 | | - } else { |
453 | | - if (adev->pm.dpm.thermal.high_to_low) |
454 | | - /* switch back the user state */ |
455 | | - dpm_state = adev->pm.dpm.user_state; |
456 | | - } |
457 | | - mutex_lock(&adev->pm.mutex); |
458 | | - if (dpm_state == POWER_STATE_TYPE_INTERNAL_THERMAL) |
459 | | - adev->pm.dpm.thermal_active = true; |
460 | | - else |
461 | | - adev->pm.dpm.thermal_active = false; |
462 | | - adev->pm.dpm.state = dpm_state; |
463 | | - mutex_unlock(&adev->pm.mutex); |
464 | | - |
465 | | - amdgpu_dpm_compute_clocks(adev); |
466 | | -} |
467 | | - |
468 | 368 | void amdgpu_dpm_compute_clocks(struct amdgpu_device *adev) |
469 | 369 | { |
470 | | - int i = 0; |
| 370 | + const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; |
471 | 371 |
|
472 | 372 | if (!adev->pm.dpm_enabled) |
473 | 373 | return; |
474 | 374 |
|
475 | | - if (adev->mode_info.num_crtc) |
476 | | - amdgpu_display_bandwidth_update(adev); |
477 | | - |
478 | | - for (i = 0; i < AMDGPU_MAX_RINGS; i++) { |
479 | | - struct amdgpu_ring *ring = adev->rings[i]; |
480 | | - if (ring && ring->sched.ready) |
481 | | - amdgpu_fence_wait_empty(ring); |
482 | | - } |
| 375 | + if (!pp_funcs->pm_compute_clocks) |
| 376 | + return; |
483 | 377 |
|
484 | | - if ((adev->family == AMDGPU_FAMILY_SI) || |
485 | | - (adev->family == AMDGPU_FAMILY_KV)) { |
486 | | - mutex_lock(&adev->pm.mutex); |
487 | | - amdgpu_dpm_get_active_displays(adev); |
488 | | - adev->powerplay.pp_funcs->change_power_state(adev->powerplay.pp_handle); |
489 | | - mutex_unlock(&adev->pm.mutex); |
490 | | - } else { |
491 | | - if (!amdgpu_device_has_dc_support(adev)) { |
492 | | - mutex_lock(&adev->pm.mutex); |
493 | | - amdgpu_dpm_get_active_displays(adev); |
494 | | - adev->pm.pm_display_cfg.num_display = adev->pm.dpm.new_active_crtc_count; |
495 | | - adev->pm.pm_display_cfg.vrefresh = amdgpu_dpm_get_vrefresh(adev); |
496 | | - adev->pm.pm_display_cfg.min_vblank_time = amdgpu_dpm_get_vblank_time(adev); |
497 | | - /* we have issues with mclk switching with |
498 | | - * refresh rates over 120 hz on the non-DC code. |
499 | | - */ |
500 | | - if (adev->pm.pm_display_cfg.vrefresh > 120) |
501 | | - adev->pm.pm_display_cfg.min_vblank_time = 0; |
502 | | - if (adev->powerplay.pp_funcs->display_configuration_change) |
503 | | - adev->powerplay.pp_funcs->display_configuration_change( |
504 | | - adev->powerplay.pp_handle, |
505 | | - &adev->pm.pm_display_cfg); |
506 | | - mutex_unlock(&adev->pm.mutex); |
507 | | - } |
508 | | - amdgpu_dpm_dispatch_task(adev, AMD_PP_TASK_DISPLAY_CONFIG_CHANGE, NULL); |
509 | | - } |
| 378 | + pp_funcs->pm_compute_clocks(adev->powerplay.pp_handle); |
510 | 379 | } |
511 | 380 |
|
512 | 381 | void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable) |
513 | 382 | { |
514 | 383 | int ret = 0; |
515 | 384 |
|
516 | | - if (adev->family == AMDGPU_FAMILY_SI) { |
517 | | - mutex_lock(&adev->pm.mutex); |
518 | | - if (enable) { |
519 | | - adev->pm.dpm.uvd_active = true; |
520 | | - adev->pm.dpm.state = POWER_STATE_TYPE_INTERNAL_UVD; |
521 | | - } else { |
522 | | - adev->pm.dpm.uvd_active = false; |
523 | | - } |
524 | | - mutex_unlock(&adev->pm.mutex); |
| 385 | + ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_UVD, !enable); |
| 386 | + if (ret) |
| 387 | + DRM_ERROR("Dpm %s uvd failed, ret = %d. \n", |
| 388 | + enable ? "enable" : "disable", ret); |
525 | 389 |
|
526 | | - amdgpu_dpm_compute_clocks(adev); |
527 | | - } else { |
528 | | - ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_UVD, !enable); |
529 | | - if (ret) |
530 | | - DRM_ERROR("Dpm %s uvd failed, ret = %d. \n", |
531 | | - enable ? "enable" : "disable", ret); |
532 | | - |
533 | | - /* enable/disable Low Memory PState for UVD (4k videos) */ |
534 | | - if (adev->asic_type == CHIP_STONEY && |
535 | | - adev->uvd.decode_image_width >= WIDTH_4K) { |
536 | | - struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; |
537 | | - |
538 | | - if (hwmgr && hwmgr->hwmgr_func && |
539 | | - hwmgr->hwmgr_func->update_nbdpm_pstate) |
540 | | - hwmgr->hwmgr_func->update_nbdpm_pstate(hwmgr, |
541 | | - !enable, |
542 | | - true); |
543 | | - } |
| 390 | + /* enable/disable Low Memory PState for UVD (4k videos) */ |
| 391 | + if (adev->asic_type == CHIP_STONEY && |
| 392 | + adev->uvd.decode_image_width >= WIDTH_4K) { |
| 393 | + struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; |
| 394 | + |
| 395 | + if (hwmgr && hwmgr->hwmgr_func && |
| 396 | + hwmgr->hwmgr_func->update_nbdpm_pstate) |
| 397 | + hwmgr->hwmgr_func->update_nbdpm_pstate(hwmgr, |
| 398 | + !enable, |
| 399 | + true); |
544 | 400 | } |
545 | 401 | } |
546 | 402 |
|
547 | 403 | void amdgpu_dpm_enable_vce(struct amdgpu_device *adev, bool enable) |
548 | 404 | { |
549 | 405 | int ret = 0; |
550 | 406 |
|
551 | | - if (adev->family == AMDGPU_FAMILY_SI) { |
552 | | - mutex_lock(&adev->pm.mutex); |
553 | | - if (enable) { |
554 | | - adev->pm.dpm.vce_active = true; |
555 | | - /* XXX select vce level based on ring/task */ |
556 | | - adev->pm.dpm.vce_level = AMD_VCE_LEVEL_AC_ALL; |
557 | | - } else { |
558 | | - adev->pm.dpm.vce_active = false; |
559 | | - } |
560 | | - mutex_unlock(&adev->pm.mutex); |
561 | | - |
562 | | - amdgpu_dpm_compute_clocks(adev); |
563 | | - } else { |
564 | | - ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_VCE, !enable); |
565 | | - if (ret) |
566 | | - DRM_ERROR("Dpm %s vce failed, ret = %d. \n", |
567 | | - enable ? "enable" : "disable", ret); |
568 | | - } |
| 407 | + ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_VCE, !enable); |
| 408 | + if (ret) |
| 409 | + DRM_ERROR("Dpm %s vce failed, ret = %d. \n", |
| 410 | + enable ? "enable" : "disable", ret); |
569 | 411 | } |
570 | 412 |
|
571 | 413 | void amdgpu_dpm_enable_jpeg(struct amdgpu_device *adev, bool enable) |
|
0 commit comments