diff options
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/include/kgd_pp_interface.h | 18 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 32 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | 5 |
9 files changed, 66 insertions, 37 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h index 9c373f8f465c..643d008410c6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h | |||
@@ -341,9 +341,9 @@ enum amdgpu_pcie_gen { | |||
341 | ((adev)->powerplay.pp_funcs->reset_power_profile_state(\ | 341 | ((adev)->powerplay.pp_funcs->reset_power_profile_state(\ |
342 | (adev)->powerplay.pp_handle, request)) | 342 | (adev)->powerplay.pp_handle, request)) |
343 | 343 | ||
344 | #define amdgpu_dpm_switch_power_profile(adev, type) \ | 344 | #define amdgpu_dpm_switch_power_profile(adev, type, en) \ |
345 | ((adev)->powerplay.pp_funcs->switch_power_profile(\ | 345 | ((adev)->powerplay.pp_funcs->switch_power_profile(\ |
346 | (adev)->powerplay.pp_handle, type)) | 346 | (adev)->powerplay.pp_handle, type, en)) |
347 | 347 | ||
348 | #define amdgpu_dpm_set_clockgating_by_smu(adev, msg_id) \ | 348 | #define amdgpu_dpm_set_clockgating_by_smu(adev, msg_id) \ |
349 | ((adev)->powerplay.pp_funcs->set_clockgating_by_smu(\ | 349 | ((adev)->powerplay.pp_funcs->set_clockgating_by_smu(\ |
diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h index e482daf394d3..15bd0f9acf73 100644 --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h | |||
@@ -83,20 +83,6 @@ enum amd_vce_level { | |||
83 | AMD_VCE_LEVEL_DC_GP_HIGH = 5, /* DC, general purpose queue, 1080 >= res > 720 */ | 83 | AMD_VCE_LEVEL_DC_GP_HIGH = 5, /* DC, general purpose queue, 1080 >= res > 720 */ |
84 | }; | 84 | }; |
85 | 85 | ||
86 | enum amd_pp_profile_type { | ||
87 | AMD_PP_GFX_PROFILE, | ||
88 | AMD_PP_COMPUTE_PROFILE, | ||
89 | }; | ||
90 | |||
91 | struct amd_pp_profile { | ||
92 | enum amd_pp_profile_type type; | ||
93 | uint32_t min_sclk; | ||
94 | uint32_t min_mclk; | ||
95 | uint16_t activity_threshold; | ||
96 | uint8_t up_hyst; | ||
97 | uint8_t down_hyst; | ||
98 | }; | ||
99 | |||
100 | enum amd_fan_ctrl_mode { | 86 | enum amd_fan_ctrl_mode { |
101 | AMD_FAN_CTRL_NONE = 0, | 87 | AMD_FAN_CTRL_NONE = 0, |
102 | AMD_FAN_CTRL_MANUAL = 1, | 88 | AMD_FAN_CTRL_MANUAL = 1, |
@@ -143,7 +129,6 @@ enum PP_SMC_POWER_PROFILE { | |||
143 | PP_SMC_POWER_PROFILE_VR = 0x3, | 129 | PP_SMC_POWER_PROFILE_VR = 0x3, |
144 | PP_SMC_POWER_PROFILE_COMPUTE = 0x4, | 130 | PP_SMC_POWER_PROFILE_COMPUTE = 0x4, |
145 | PP_SMC_POWER_PROFILE_CUSTOM = 0x5, | 131 | PP_SMC_POWER_PROFILE_CUSTOM = 0x5, |
146 | PP_SMC_POWER_PROFILE_AUTO = 0x6, | ||
147 | }; | 132 | }; |
148 | 133 | ||
149 | enum { | 134 | enum { |
@@ -252,8 +237,7 @@ struct amd_pm_funcs { | |||
252 | int (*get_pp_table)(void *handle, char **table); | 237 | int (*get_pp_table)(void *handle, char **table); |
253 | int (*set_pp_table)(void *handle, const char *buf, size_t size); | 238 | int (*set_pp_table)(void *handle, const char *buf, size_t size); |
254 | void (*debugfs_print_current_performance_level)(void *handle, struct seq_file *m); | 239 | void (*debugfs_print_current_performance_level)(void *handle, struct seq_file *m); |
255 | int (*switch_power_profile)(void *handle, | 240 | int (*switch_power_profile)(void *handle, enum PP_SMC_POWER_PROFILE type, bool en); |
256 | enum amd_pp_profile_type type); | ||
257 | /* export to amdgpu */ | 241 | /* export to amdgpu */ |
258 | void (*powergate_uvd)(void *handle, bool gate); | 242 | void (*powergate_uvd)(void *handle, bool gate); |
259 | void (*powergate_vce)(void *handle, bool gate); | 243 | void (*powergate_vce)(void *handle, bool gate); |
diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index a8705b5ad264..b989bf3542d6 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c | |||
@@ -1077,22 +1077,44 @@ static int pp_odn_edit_dpm_table(void *handle, uint32_t type, long *input, uint3 | |||
1077 | } | 1077 | } |
1078 | 1078 | ||
1079 | static int pp_dpm_switch_power_profile(void *handle, | 1079 | static int pp_dpm_switch_power_profile(void *handle, |
1080 | enum amd_pp_profile_type type) | 1080 | enum PP_SMC_POWER_PROFILE type, bool en) |
1081 | { | 1081 | { |
1082 | struct pp_hwmgr *hwmgr; | 1082 | struct pp_hwmgr *hwmgr; |
1083 | struct amd_pp_profile request = {0}; | ||
1084 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | 1083 | struct pp_instance *pp_handle = (struct pp_instance *)handle; |
1084 | long workload; | ||
1085 | uint32_t index; | ||
1085 | 1086 | ||
1086 | if (pp_check(pp_handle)) | 1087 | if (pp_check(pp_handle)) |
1087 | return -EINVAL; | 1088 | return -EINVAL; |
1088 | 1089 | ||
1089 | hwmgr = pp_handle->hwmgr; | 1090 | hwmgr = pp_handle->hwmgr; |
1090 | 1091 | ||
1091 | if (hwmgr->current_power_profile != type) { | 1092 | if (hwmgr->hwmgr_func->set_power_profile_mode == NULL) { |
1092 | request.type = type; | 1093 | pr_info("%s was not implemented.\n", __func__); |
1093 | pp_dpm_set_power_profile_state(handle, &request); | 1094 | return -EINVAL; |
1095 | } | ||
1096 | |||
1097 | if (!(type < PP_SMC_POWER_PROFILE_CUSTOM)) | ||
1098 | return -EINVAL; | ||
1099 | |||
1100 | mutex_lock(&pp_handle->pp_lock); | ||
1101 | |||
1102 | if (!en) { | ||
1103 | hwmgr->workload_mask &= ~(1 << hwmgr->workload_prority[type]); | ||
1104 | index = fls(hwmgr->workload_mask); | ||
1105 | index = index > 0 && index <= Workload_Policy_Max ? index - 1 : 0; | ||
1106 | workload = hwmgr->workload_setting[index]; | ||
1107 | } else { | ||
1108 | hwmgr->workload_mask |= (1 << hwmgr->workload_prority[type]); | ||
1109 | index = fls(hwmgr->workload_mask); | ||
1110 | index = index <= Workload_Policy_Max ? index - 1 : 0; | ||
1111 | workload = hwmgr->workload_setting[index]; | ||
1094 | } | 1112 | } |
1095 | 1113 | ||
1114 | if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) | ||
1115 | hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, &workload, 0); | ||
1116 | mutex_unlock(&pp_handle->pp_lock); | ||
1117 | |||
1096 | return 0; | 1118 | return 0; |
1097 | } | 1119 | } |
1098 | 1120 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c index aea107643859..4b6cf795243c 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c | |||
@@ -125,6 +125,21 @@ static const struct cgs_irq_src_funcs thermal_irq_src[3] = { | |||
125 | { .handler = phm_ctf_irq } | 125 | { .handler = phm_ctf_irq } |
126 | }; | 126 | }; |
127 | 127 | ||
128 | static void hwmgr_init_workload_prority(struct pp_hwmgr *hwmgr) | ||
129 | { | ||
130 | hwmgr->workload_prority[PP_SMC_POWER_PROFILE_FULLSCREEN3D] = 2; | ||
131 | hwmgr->workload_prority[PP_SMC_POWER_PROFILE_POWERSAVING] = 0; | ||
132 | hwmgr->workload_prority[PP_SMC_POWER_PROFILE_VIDEO] = 1; | ||
133 | hwmgr->workload_prority[PP_SMC_POWER_PROFILE_VR] = 3; | ||
134 | hwmgr->workload_prority[PP_SMC_POWER_PROFILE_COMPUTE] = 4; | ||
135 | |||
136 | hwmgr->workload_setting[0] = PP_SMC_POWER_PROFILE_POWERSAVING; | ||
137 | hwmgr->workload_setting[1] = PP_SMC_POWER_PROFILE_VIDEO; | ||
138 | hwmgr->workload_setting[2] = PP_SMC_POWER_PROFILE_FULLSCREEN3D; | ||
139 | hwmgr->workload_setting[3] = PP_SMC_POWER_PROFILE_VR; | ||
140 | hwmgr->workload_setting[4] = PP_SMC_POWER_PROFILE_COMPUTE; | ||
141 | } | ||
142 | |||
128 | int hwmgr_early_init(struct pp_instance *handle) | 143 | int hwmgr_early_init(struct pp_instance *handle) |
129 | { | 144 | { |
130 | struct pp_hwmgr *hwmgr; | 145 | struct pp_hwmgr *hwmgr; |
@@ -151,6 +166,7 @@ int hwmgr_early_init(struct pp_instance *handle) | |||
151 | hwmgr_set_user_specify_caps(hwmgr); | 166 | hwmgr_set_user_specify_caps(hwmgr); |
152 | hwmgr->fan_ctrl_is_in_default_mode = true; | 167 | hwmgr->fan_ctrl_is_in_default_mode = true; |
153 | hwmgr->reload_fw = 1; | 168 | hwmgr->reload_fw = 1; |
169 | hwmgr_init_workload_prority(hwmgr); | ||
154 | 170 | ||
155 | switch (hwmgr->chip_family) { | 171 | switch (hwmgr->chip_family) { |
156 | case AMDGPU_FAMILY_CI: | 172 | case AMDGPU_FAMILY_CI: |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm.c b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm.c index ed3bd1502c0d..d0ef8f9c1361 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm.c | |||
@@ -220,6 +220,8 @@ int psm_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, bool skip, | |||
220 | struct pp_power_state *pcurrent; | 220 | struct pp_power_state *pcurrent; |
221 | struct pp_power_state *requested; | 221 | struct pp_power_state *requested; |
222 | bool equal; | 222 | bool equal; |
223 | uint32_t index; | ||
224 | long workload; | ||
223 | 225 | ||
224 | if (skip) | 226 | if (skip) |
225 | return 0; | 227 | return 0; |
@@ -247,6 +249,15 @@ int psm_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, bool skip, | |||
247 | if (!phm_force_dpm_levels(hwmgr, hwmgr->request_dpm_level)) | 249 | if (!phm_force_dpm_levels(hwmgr, hwmgr->request_dpm_level)) |
248 | hwmgr->dpm_level = hwmgr->request_dpm_level; | 250 | hwmgr->dpm_level = hwmgr->request_dpm_level; |
249 | 251 | ||
252 | if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) { | ||
253 | index = fls(hwmgr->workload_mask); | ||
254 | index = index > 0 && index <= Workload_Policy_Max ? index - 1 : 0; | ||
255 | workload = hwmgr->workload_setting[index]; | ||
256 | |||
257 | if (hwmgr->power_profile_mode != workload && hwmgr->hwmgr_func->set_power_profile_mode) | ||
258 | hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, &workload, 0); | ||
259 | } | ||
260 | |||
250 | return 0; | 261 | return 0; |
251 | } | 262 | } |
252 | 263 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c index 58e2e0a10b3d..d8c205cf8f12 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | |||
@@ -1510,6 +1510,9 @@ static void smu7_init_dpm_defaults(struct pp_hwmgr *hwmgr) | |||
1510 | data->current_profile_setting.mclk_up_hyst = 0; | 1510 | data->current_profile_setting.mclk_up_hyst = 0; |
1511 | data->current_profile_setting.mclk_down_hyst = 100; | 1511 | data->current_profile_setting.mclk_down_hyst = 100; |
1512 | data->current_profile_setting.mclk_activity = SMU7_MCLK_TARGETACTIVITY_DFLT; | 1512 | data->current_profile_setting.mclk_activity = SMU7_MCLK_TARGETACTIVITY_DFLT; |
1513 | hwmgr->workload_mask = 1 << hwmgr->workload_prority[PP_SMC_POWER_PROFILE_FULLSCREEN3D]; | ||
1514 | hwmgr->power_profile_mode = PP_SMC_POWER_PROFILE_FULLSCREEN3D; | ||
1515 | hwmgr->default_power_profile_mode = PP_SMC_POWER_PROFILE_FULLSCREEN3D; | ||
1513 | 1516 | ||
1514 | if (hwmgr->chip_id == CHIP_POLARIS12 || hwmgr->is_kicker) { | 1517 | if (hwmgr->chip_id == CHIP_POLARIS12 || hwmgr->is_kicker) { |
1515 | uint8_t tmp1, tmp2; | 1518 | uint8_t tmp1, tmp2; |
@@ -2466,9 +2469,6 @@ static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr) | |||
2466 | smu7_patch_voltage_workaround(hwmgr); | 2469 | smu7_patch_voltage_workaround(hwmgr); |
2467 | smu7_init_dpm_defaults(hwmgr); | 2470 | smu7_init_dpm_defaults(hwmgr); |
2468 | 2471 | ||
2469 | hwmgr->power_profile_mode = PP_SMC_POWER_PROFILE_FULLSCREEN3D; | ||
2470 | hwmgr->default_power_profile_mode = PP_SMC_POWER_PROFILE_FULLSCREEN3D; | ||
2471 | |||
2472 | /* Get leakage voltage based on leakage ID. */ | 2472 | /* Get leakage voltage based on leakage ID. */ |
2473 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, | 2473 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, |
2474 | PHM_PlatformCaps_EVV)) { | 2474 | PHM_PlatformCaps_EVV)) { |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c index d90a0f1dbb55..f23861f2c685 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c | |||
@@ -766,13 +766,12 @@ static int vega10_hwmgr_backend_init(struct pp_hwmgr *hwmgr) | |||
766 | 766 | ||
767 | hwmgr->backend = data; | 767 | hwmgr->backend = data; |
768 | 768 | ||
769 | hwmgr->workload_mask = 1 << hwmgr->workload_prority[PP_SMC_POWER_PROFILE_VIDEO]; | ||
769 | hwmgr->power_profile_mode = PP_SMC_POWER_PROFILE_VIDEO; | 770 | hwmgr->power_profile_mode = PP_SMC_POWER_PROFILE_VIDEO; |
770 | hwmgr->default_power_profile_mode = PP_SMC_POWER_PROFILE_VIDEO; | 771 | hwmgr->default_power_profile_mode = PP_SMC_POWER_PROFILE_VIDEO; |
771 | 772 | ||
772 | vega10_set_default_registry_data(hwmgr); | 773 | vega10_set_default_registry_data(hwmgr); |
773 | |||
774 | data->disable_dpm_mask = 0xff; | 774 | data->disable_dpm_mask = 0xff; |
775 | data->workload_mask = 0xff; | ||
776 | 775 | ||
777 | /* need to set voltage control types before EVV patching */ | 776 | /* need to set voltage control types before EVV patching */ |
778 | data->vddc_control = VEGA10_VOLTAGE_CONTROL_NONE; | 777 | data->vddc_control = VEGA10_VOLTAGE_CONTROL_NONE; |
@@ -4187,11 +4186,6 @@ static int vega10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr, | |||
4187 | break; | 4186 | break; |
4188 | case AMD_DPM_FORCED_LEVEL_AUTO: | 4187 | case AMD_DPM_FORCED_LEVEL_AUTO: |
4189 | ret = vega10_unforce_dpm_levels(hwmgr); | 4188 | ret = vega10_unforce_dpm_levels(hwmgr); |
4190 | if (hwmgr->default_power_profile_mode != hwmgr->power_profile_mode) { | ||
4191 | smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetWorkloadMask, | ||
4192 | 1 << hwmgr->default_power_profile_mode); | ||
4193 | hwmgr->power_profile_mode = hwmgr->default_power_profile_mode; | ||
4194 | } | ||
4195 | break; | 4189 | break; |
4196 | case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD: | 4190 | case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD: |
4197 | case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK: | 4191 | case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK: |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h index de3219fff2db..8f6c2cb962da 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h | |||
@@ -374,9 +374,6 @@ struct vega10_hwmgr { | |||
374 | /* ---- Overdrive next setting ---- */ | 374 | /* ---- Overdrive next setting ---- */ |
375 | uint32_t apply_overdrive_next_settings_mask; | 375 | uint32_t apply_overdrive_next_settings_mask; |
376 | 376 | ||
377 | /* ---- Workload Mask ---- */ | ||
378 | uint32_t workload_mask; | ||
379 | |||
380 | /* ---- SMU9 ---- */ | 377 | /* ---- SMU9 ---- */ |
381 | struct smu_features smu_features[GNLD_FEATURES_MAX]; | 378 | struct smu_features smu_features[GNLD_FEATURES_MAX]; |
382 | struct vega10_smc_state_table smc_state_table; | 379 | struct vega10_smc_state_table smc_state_table; |
diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h index 65224dbb550d..94df6eed5384 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | |||
@@ -696,6 +696,8 @@ enum PP_TABLE_VERSION { | |||
696 | /** | 696 | /** |
697 | * The main hardware manager structure. | 697 | * The main hardware manager structure. |
698 | */ | 698 | */ |
699 | #define Workload_Policy_Max 5 | ||
700 | |||
699 | struct pp_hwmgr { | 701 | struct pp_hwmgr { |
700 | void *adev; | 702 | void *adev; |
701 | uint32_t chip_family; | 703 | uint32_t chip_family; |
@@ -757,6 +759,9 @@ struct pp_hwmgr { | |||
757 | bool od_enabled; | 759 | bool od_enabled; |
758 | uint32_t power_limit; | 760 | uint32_t power_limit; |
759 | uint32_t default_power_limit; | 761 | uint32_t default_power_limit; |
762 | uint32_t workload_mask; | ||
763 | uint32_t workload_prority[Workload_Policy_Max]; | ||
764 | uint32_t workload_setting[Workload_Policy_Max]; | ||
760 | }; | 765 | }; |
761 | 766 | ||
762 | struct cgs_irq_src_funcs { | 767 | struct cgs_irq_src_funcs { |