2 * Copyright 2015 Advanced Micro Devices, Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
25 #include <linux/delay.h>
26 #include <linux/kernel.h>
27 #include <linux/slab.h>
28 #include <linux/types.h>
29 #include <linux/pci.h>
30 #include <drm/amdgpu_drm.h>
31 #include "power_state.h"
37 extern const struct pp_smumgr_func ci_smu_funcs
;
38 extern const struct pp_smumgr_func smu8_smu_funcs
;
39 extern const struct pp_smumgr_func iceland_smu_funcs
;
40 extern const struct pp_smumgr_func tonga_smu_funcs
;
41 extern const struct pp_smumgr_func fiji_smu_funcs
;
42 extern const struct pp_smumgr_func polaris10_smu_funcs
;
43 extern const struct pp_smumgr_func vegam_smu_funcs
;
44 extern const struct pp_smumgr_func vega10_smu_funcs
;
45 extern const struct pp_smumgr_func vega12_smu_funcs
;
46 extern const struct pp_smumgr_func smu10_smu_funcs
;
47 extern const struct pp_smumgr_func vega20_smu_funcs
;
49 extern int smu7_init_function_pointers(struct pp_hwmgr
*hwmgr
);
50 extern int smu8_init_function_pointers(struct pp_hwmgr
*hwmgr
);
51 extern int vega10_hwmgr_init(struct pp_hwmgr
*hwmgr
);
52 extern int vega12_hwmgr_init(struct pp_hwmgr
*hwmgr
);
53 extern int vega20_hwmgr_init(struct pp_hwmgr
*hwmgr
);
54 extern int smu10_init_function_pointers(struct pp_hwmgr
*hwmgr
);
56 static int polaris_set_asic_special_caps(struct pp_hwmgr
*hwmgr
);
57 static void hwmgr_init_default_caps(struct pp_hwmgr
*hwmgr
);
58 static int hwmgr_set_user_specify_caps(struct pp_hwmgr
*hwmgr
);
59 static int fiji_set_asic_special_caps(struct pp_hwmgr
*hwmgr
);
60 static int tonga_set_asic_special_caps(struct pp_hwmgr
*hwmgr
);
61 static int topaz_set_asic_special_caps(struct pp_hwmgr
*hwmgr
);
62 static int ci_set_asic_special_caps(struct pp_hwmgr
*hwmgr
);
65 static void hwmgr_init_workload_prority(struct pp_hwmgr
*hwmgr
)
67 hwmgr
->workload_prority
[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT
] = 0;
68 hwmgr
->workload_prority
[PP_SMC_POWER_PROFILE_FULLSCREEN3D
] = 1;
69 hwmgr
->workload_prority
[PP_SMC_POWER_PROFILE_POWERSAVING
] = 2;
70 hwmgr
->workload_prority
[PP_SMC_POWER_PROFILE_VIDEO
] = 3;
71 hwmgr
->workload_prority
[PP_SMC_POWER_PROFILE_VR
] = 4;
72 hwmgr
->workload_prority
[PP_SMC_POWER_PROFILE_COMPUTE
] = 5;
74 hwmgr
->workload_setting
[0] = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT
;
75 hwmgr
->workload_setting
[1] = PP_SMC_POWER_PROFILE_FULLSCREEN3D
;
76 hwmgr
->workload_setting
[2] = PP_SMC_POWER_PROFILE_POWERSAVING
;
77 hwmgr
->workload_setting
[3] = PP_SMC_POWER_PROFILE_VIDEO
;
78 hwmgr
->workload_setting
[4] = PP_SMC_POWER_PROFILE_VR
;
79 hwmgr
->workload_setting
[5] = PP_SMC_POWER_PROFILE_COMPUTE
;
82 int hwmgr_early_init(struct pp_hwmgr
*hwmgr
)
87 hwmgr
->usec_timeout
= AMD_MAX_USEC_TIMEOUT
;
88 hwmgr
->pp_table_version
= PP_TABLE_V1
;
89 hwmgr
->dpm_level
= AMD_DPM_FORCED_LEVEL_AUTO
;
90 hwmgr
->request_dpm_level
= AMD_DPM_FORCED_LEVEL_AUTO
;
91 hwmgr_init_default_caps(hwmgr
);
92 hwmgr_set_user_specify_caps(hwmgr
);
93 hwmgr
->fan_ctrl_is_in_default_mode
= true;
94 hwmgr_init_workload_prority(hwmgr
);
96 switch (hwmgr
->chip_family
) {
97 case AMDGPU_FAMILY_CI
:
98 hwmgr
->smumgr_funcs
= &ci_smu_funcs
;
99 ci_set_asic_special_caps(hwmgr
);
100 hwmgr
->feature_mask
&= ~(PP_VBI_TIME_SUPPORT_MASK
|
101 PP_ENABLE_GFX_CG_THRU_SMU
|
103 hwmgr
->pp_table_version
= PP_TABLE_V0
;
104 hwmgr
->od_enabled
= false;
105 smu7_init_function_pointers(hwmgr
);
107 case AMDGPU_FAMILY_CZ
:
108 hwmgr
->od_enabled
= false;
109 hwmgr
->smumgr_funcs
= &smu8_smu_funcs
;
110 hwmgr
->feature_mask
&= ~PP_GFXOFF_MASK
;
111 smu8_init_function_pointers(hwmgr
);
113 case AMDGPU_FAMILY_VI
:
114 hwmgr
->feature_mask
&= ~PP_GFXOFF_MASK
;
115 switch (hwmgr
->chip_id
) {
117 hwmgr
->smumgr_funcs
= &iceland_smu_funcs
;
118 topaz_set_asic_special_caps(hwmgr
);
119 hwmgr
->feature_mask
&= ~ (PP_VBI_TIME_SUPPORT_MASK
|
120 PP_ENABLE_GFX_CG_THRU_SMU
);
121 hwmgr
->pp_table_version
= PP_TABLE_V0
;
122 hwmgr
->od_enabled
= false;
125 hwmgr
->smumgr_funcs
= &tonga_smu_funcs
;
126 tonga_set_asic_special_caps(hwmgr
);
127 hwmgr
->feature_mask
&= ~PP_VBI_TIME_SUPPORT_MASK
;
130 hwmgr
->smumgr_funcs
= &fiji_smu_funcs
;
131 fiji_set_asic_special_caps(hwmgr
);
132 hwmgr
->feature_mask
&= ~ (PP_VBI_TIME_SUPPORT_MASK
|
133 PP_ENABLE_GFX_CG_THRU_SMU
);
138 hwmgr
->smumgr_funcs
= &polaris10_smu_funcs
;
139 polaris_set_asic_special_caps(hwmgr
);
140 hwmgr
->feature_mask
&= ~(PP_UVD_HANDSHAKE_MASK
);
143 hwmgr
->smumgr_funcs
= &vegam_smu_funcs
;
144 polaris_set_asic_special_caps(hwmgr
);
145 hwmgr
->feature_mask
&= ~(PP_UVD_HANDSHAKE_MASK
);
150 smu7_init_function_pointers(hwmgr
);
152 case AMDGPU_FAMILY_AI
:
153 switch (hwmgr
->chip_id
) {
155 hwmgr
->feature_mask
&= ~PP_GFXOFF_MASK
;
156 hwmgr
->smumgr_funcs
= &vega10_smu_funcs
;
157 vega10_hwmgr_init(hwmgr
);
160 hwmgr
->smumgr_funcs
= &vega12_smu_funcs
;
161 vega12_hwmgr_init(hwmgr
);
164 hwmgr
->feature_mask
&= ~PP_GFXOFF_MASK
;
165 hwmgr
->smumgr_funcs
= &vega20_smu_funcs
;
166 vega20_hwmgr_init(hwmgr
);
172 case AMDGPU_FAMILY_RV
:
173 switch (hwmgr
->chip_id
) {
175 hwmgr
->od_enabled
= false;
176 hwmgr
->smumgr_funcs
= &smu10_smu_funcs
;
177 smu10_init_function_pointers(hwmgr
);
190 int hwmgr_sw_init(struct pp_hwmgr
*hwmgr
)
192 if (!hwmgr
|| !hwmgr
->smumgr_funcs
|| !hwmgr
->smumgr_funcs
->smu_init
)
195 phm_register_irq_handlers(hwmgr
);
197 return hwmgr
->smumgr_funcs
->smu_init(hwmgr
);
201 int hwmgr_sw_fini(struct pp_hwmgr
*hwmgr
)
203 if (hwmgr
&& hwmgr
->smumgr_funcs
&& hwmgr
->smumgr_funcs
->smu_fini
)
204 hwmgr
->smumgr_funcs
->smu_fini(hwmgr
);
209 int hwmgr_hw_init(struct pp_hwmgr
*hwmgr
)
216 if (!hwmgr
->pptable_func
||
217 !hwmgr
->pptable_func
->pptable_init
||
218 !hwmgr
->hwmgr_func
->backend_init
) {
219 hwmgr
->pm_en
= false;
220 pr_info("dpm not supported \n");
224 ret
= hwmgr
->pptable_func
->pptable_init(hwmgr
);
228 ((struct amdgpu_device
*)hwmgr
->adev
)->pm
.no_fan
=
229 hwmgr
->thermal_controller
.fanInfo
.bNoFan
;
231 ret
= hwmgr
->hwmgr_func
->backend_init(hwmgr
);
234 /* make sure dc limits are valid */
235 if ((hwmgr
->dyn_state
.max_clock_voltage_on_dc
.sclk
== 0) ||
236 (hwmgr
->dyn_state
.max_clock_voltage_on_dc
.mclk
== 0))
237 hwmgr
->dyn_state
.max_clock_voltage_on_dc
=
238 hwmgr
->dyn_state
.max_clock_voltage_on_ac
;
240 ret
= psm_init_power_state_table(hwmgr
);
244 ret
= phm_setup_asic(hwmgr
);
248 ret
= phm_enable_dynamic_state_management(hwmgr
);
251 ret
= phm_start_thermal_controller(hwmgr
);
252 ret
|= psm_set_performance_states(hwmgr
);
256 ((struct amdgpu_device
*)hwmgr
->adev
)->pm
.dpm_enabled
= true;
260 if (hwmgr
->hwmgr_func
->backend_fini
)
261 hwmgr
->hwmgr_func
->backend_fini(hwmgr
);
263 if (hwmgr
->pptable_func
->pptable_fini
)
264 hwmgr
->pptable_func
->pptable_fini(hwmgr
);
269 int hwmgr_hw_fini(struct pp_hwmgr
*hwmgr
)
271 if (!hwmgr
|| !hwmgr
->pm_en
)
274 phm_stop_thermal_controller(hwmgr
);
275 psm_set_boot_states(hwmgr
);
276 psm_adjust_power_state_dynamic(hwmgr
, false, NULL
);
277 phm_disable_dynamic_state_management(hwmgr
);
278 phm_disable_clock_power_gatings(hwmgr
);
280 if (hwmgr
->hwmgr_func
->backend_fini
)
281 hwmgr
->hwmgr_func
->backend_fini(hwmgr
);
282 if (hwmgr
->pptable_func
->pptable_fini
)
283 hwmgr
->pptable_func
->pptable_fini(hwmgr
);
284 return psm_fini_power_state_table(hwmgr
);
287 int hwmgr_suspend(struct pp_hwmgr
*hwmgr
)
291 if (!hwmgr
|| !hwmgr
->pm_en
)
294 phm_disable_smc_firmware_ctf(hwmgr
);
295 ret
= psm_set_boot_states(hwmgr
);
298 ret
= psm_adjust_power_state_dynamic(hwmgr
, false, NULL
);
301 ret
= phm_power_down_asic(hwmgr
);
306 int hwmgr_resume(struct pp_hwmgr
*hwmgr
)
316 ret
= phm_setup_asic(hwmgr
);
320 ret
= phm_enable_dynamic_state_management(hwmgr
);
323 ret
= phm_start_thermal_controller(hwmgr
);
324 ret
|= psm_set_performance_states(hwmgr
);
328 ret
= psm_adjust_power_state_dynamic(hwmgr
, false, NULL
);
333 static enum PP_StateUILabel
power_state_convert(enum amd_pm_state_type state
)
336 case POWER_STATE_TYPE_BATTERY
:
337 return PP_StateUILabel_Battery
;
338 case POWER_STATE_TYPE_BALANCED
:
339 return PP_StateUILabel_Balanced
;
340 case POWER_STATE_TYPE_PERFORMANCE
:
341 return PP_StateUILabel_Performance
;
343 return PP_StateUILabel_None
;
347 int hwmgr_handle_task(struct pp_hwmgr
*hwmgr
, enum amd_pp_task task_id
,
348 enum amd_pm_state_type
*user_state
)
356 case AMD_PP_TASK_DISPLAY_CONFIG_CHANGE
:
357 ret
= phm_pre_display_configuration_changed(hwmgr
);
360 ret
= phm_set_cpu_power_state(hwmgr
);
363 ret
= psm_set_performance_states(hwmgr
);
366 ret
= psm_adjust_power_state_dynamic(hwmgr
, false, NULL
);
368 case AMD_PP_TASK_ENABLE_USER_STATE
:
370 enum PP_StateUILabel requested_ui_label
;
371 struct pp_power_state
*requested_ps
= NULL
;
373 if (user_state
== NULL
) {
378 requested_ui_label
= power_state_convert(*user_state
);
379 ret
= psm_set_user_performance_state(hwmgr
, requested_ui_label
, &requested_ps
);
382 ret
= psm_adjust_power_state_dynamic(hwmgr
, false, requested_ps
);
385 case AMD_PP_TASK_COMPLETE_INIT
:
386 case AMD_PP_TASK_READJUST_POWER_STATE
:
387 ret
= psm_adjust_power_state_dynamic(hwmgr
, false, NULL
);
395 void hwmgr_init_default_caps(struct pp_hwmgr
*hwmgr
)
397 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
, PHM_PlatformCaps_PCIEPerformanceRequest
);
399 phm_cap_set(hwmgr
->platform_descriptor
.platformCaps
, PHM_PlatformCaps_UVDDPM
);
400 phm_cap_set(hwmgr
->platform_descriptor
.platformCaps
, PHM_PlatformCaps_VCEDPM
);
402 #if defined(CONFIG_ACPI)
403 if (amdgpu_acpi_is_pcie_performance_request_supported(hwmgr
->adev
))
404 phm_cap_set(hwmgr
->platform_descriptor
.platformCaps
, PHM_PlatformCaps_PCIEPerformanceRequest
);
407 phm_cap_set(hwmgr
->platform_descriptor
.platformCaps
,
408 PHM_PlatformCaps_DynamicPatchPowerState
);
410 phm_cap_set(hwmgr
->platform_descriptor
.platformCaps
,
411 PHM_PlatformCaps_EnableSMU7ThermalManagement
);
413 phm_cap_set(hwmgr
->platform_descriptor
.platformCaps
,
414 PHM_PlatformCaps_DynamicPowerManagement
);
416 phm_cap_set(hwmgr
->platform_descriptor
.platformCaps
,
417 PHM_PlatformCaps_SMC
);
419 phm_cap_set(hwmgr
->platform_descriptor
.platformCaps
,
420 PHM_PlatformCaps_DynamicUVDState
);
422 phm_cap_set(hwmgr
->platform_descriptor
.platformCaps
,
423 PHM_PlatformCaps_FanSpeedInTableIsRPM
);
427 int hwmgr_set_user_specify_caps(struct pp_hwmgr
*hwmgr
)
429 if (hwmgr
->feature_mask
& PP_SCLK_DEEP_SLEEP_MASK
)
430 phm_cap_set(hwmgr
->platform_descriptor
.platformCaps
,
431 PHM_PlatformCaps_SclkDeepSleep
);
433 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
434 PHM_PlatformCaps_SclkDeepSleep
);
436 if (hwmgr
->feature_mask
& PP_POWER_CONTAINMENT_MASK
) {
437 phm_cap_set(hwmgr
->platform_descriptor
.platformCaps
,
438 PHM_PlatformCaps_PowerContainment
);
439 phm_cap_set(hwmgr
->platform_descriptor
.platformCaps
,
440 PHM_PlatformCaps_CAC
);
442 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
443 PHM_PlatformCaps_PowerContainment
);
444 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
445 PHM_PlatformCaps_CAC
);
448 if (hwmgr
->feature_mask
& PP_OVERDRIVE_MASK
)
449 hwmgr
->od_enabled
= true;
454 int polaris_set_asic_special_caps(struct pp_hwmgr
*hwmgr
)
456 phm_cap_set(hwmgr
->platform_descriptor
.platformCaps
,
457 PHM_PlatformCaps_EVV
);
458 phm_cap_set(hwmgr
->platform_descriptor
.platformCaps
,
459 PHM_PlatformCaps_SQRamping
);
460 phm_cap_set(hwmgr
->platform_descriptor
.platformCaps
,
461 PHM_PlatformCaps_RegulatorHot
);
463 phm_cap_set(hwmgr
->platform_descriptor
.platformCaps
,
464 PHM_PlatformCaps_AutomaticDCTransition
);
466 if (hwmgr
->chip_id
!= CHIP_POLARIS10
)
467 phm_cap_set(hwmgr
->platform_descriptor
.platformCaps
,
468 PHM_PlatformCaps_SPLLShutdownSupport
);
470 if (hwmgr
->chip_id
!= CHIP_POLARIS11
) {
471 phm_cap_set(hwmgr
->platform_descriptor
.platformCaps
,
472 PHM_PlatformCaps_DBRamping
);
473 phm_cap_set(hwmgr
->platform_descriptor
.platformCaps
,
474 PHM_PlatformCaps_TDRamping
);
475 phm_cap_set(hwmgr
->platform_descriptor
.platformCaps
,
476 PHM_PlatformCaps_TCPRamping
);
481 int fiji_set_asic_special_caps(struct pp_hwmgr
*hwmgr
)
483 phm_cap_set(hwmgr
->platform_descriptor
.platformCaps
,
484 PHM_PlatformCaps_EVV
);
485 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
486 PHM_PlatformCaps_SQRamping
);
487 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
488 PHM_PlatformCaps_DBRamping
);
489 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
490 PHM_PlatformCaps_TDRamping
);
491 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
492 PHM_PlatformCaps_TCPRamping
);
496 int tonga_set_asic_special_caps(struct pp_hwmgr
*hwmgr
)
498 phm_cap_set(hwmgr
->platform_descriptor
.platformCaps
,
499 PHM_PlatformCaps_EVV
);
500 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
501 PHM_PlatformCaps_SQRamping
);
502 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
503 PHM_PlatformCaps_DBRamping
);
504 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
505 PHM_PlatformCaps_TDRamping
);
506 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
507 PHM_PlatformCaps_TCPRamping
);
509 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
510 PHM_PlatformCaps_UVDPowerGating
);
511 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
512 PHM_PlatformCaps_VCEPowerGating
);
516 int topaz_set_asic_special_caps(struct pp_hwmgr
*hwmgr
)
518 phm_cap_set(hwmgr
->platform_descriptor
.platformCaps
,
519 PHM_PlatformCaps_EVV
);
520 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
521 PHM_PlatformCaps_SQRamping
);
522 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
523 PHM_PlatformCaps_DBRamping
);
524 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
525 PHM_PlatformCaps_TDRamping
);
526 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
527 PHM_PlatformCaps_TCPRamping
);
531 int ci_set_asic_special_caps(struct pp_hwmgr
*hwmgr
)
533 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
534 PHM_PlatformCaps_SQRamping
);
535 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
536 PHM_PlatformCaps_DBRamping
);
537 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
538 PHM_PlatformCaps_TDRamping
);
539 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
540 PHM_PlatformCaps_TCPRamping
);
541 phm_cap_set(hwmgr
->platform_descriptor
.platformCaps
,
542 PHM_PlatformCaps_MemorySpreadSpectrumSupport
);
543 phm_cap_set(hwmgr
->platform_descriptor
.platformCaps
,
544 PHM_PlatformCaps_EngineSpreadSpectrumSupport
);