aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd
diff options
context:
space:
mode:
authorRex Zhu <Rex.Zhu@amd.com>2018-03-02 07:09:11 -0500
committerAlex Deucher <alexander.deucher@amd.com>2018-03-07 16:10:09 -0500
commit052fe96d93f2eb93cdb660ad7918aa0534c59c2e (patch)
tree274e4d91437750e051743af305c2a0849a07af96 /drivers/gpu/drm/amd
parenta5278e511dce23349e71d681dfa7e8c600d19603 (diff)
drm/amd/pp: Add auto power profilng switch based on workloads (v2)
Add power profiling mode dynamic switch based on the workloads. Currently, support Cumpute, VR, Video, 3D,power saving with Cumpute have highest prority, power saving have lowest prority. in manual dpm mode, driver will stop auto switch, just save the client's requests. user can set power profiling mode through sysfs. when exit manual dpm mode, driver will response the client's requests. switch based on the client's prority. v2: squash in fixes from Rex Reviewed-by: Evan Quan <evan.quan@amd.com> Signed-off-by: Rex Zhu <Rex.Zhu@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h4
-rw-r--r--drivers/gpu/drm/amd/include/kgd_pp_interface.h18
-rw-r--r--drivers/gpu/drm/amd/powerplay/amd_powerplay.c32
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c16
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm.c11
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c6
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c8
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h3
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/hwmgr.h5
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
86enum amd_pp_profile_type {
87 AMD_PP_GFX_PROFILE,
88 AMD_PP_COMPUTE_PROFILE,
89};
90
91struct 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
100enum amd_fan_ctrl_mode { 86enum 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
149enum { 134enum {
@@ -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
1079static int pp_dpm_switch_power_profile(void *handle, 1079static 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
128static 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
128int hwmgr_early_init(struct pp_instance *handle) 143int 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
699struct pp_hwmgr { 701struct 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
762struct cgs_irq_src_funcs { 767struct cgs_irq_src_funcs {