diff options
author | Rex Zhu <Rex.Zhu@amd.com> | 2018-01-29 05:04:18 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2018-02-19 14:19:44 -0500 |
commit | 6ab8555e04ecd2278fdca54c33a7ddac7d4ba5d2 (patch) | |
tree | f58109e970b10a250fdfdbbd57a3f4b4bac6a6a0 | |
parent | 71d0a89812c9749fbb48c633f91512d51433989e (diff) |
drm/amd/pp: Expose set/get_power_limit for DGPU
User can change power limit between
[0, 1] * max power limit.
Set power limit to 0, restore to max power limit.
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Rex Zhu <Rex.Zhu@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/amd/include/kgd_pp_interface.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 61 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | 3 |
7 files changed, 77 insertions, 6 deletions
diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h index 4f69fe8ca371..22c2fa30731f 100644 --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h | |||
@@ -283,6 +283,8 @@ struct amd_pm_funcs { | |||
283 | uint32_t mc_addr_low, | 283 | uint32_t mc_addr_low, |
284 | uint32_t mc_addr_hi, | 284 | uint32_t mc_addr_hi, |
285 | uint32_t size); | 285 | uint32_t size); |
286 | int (*set_power_limit)(void *handle, uint32_t n); | ||
287 | int (*get_power_limit)(void *handle, uint32_t *limit, bool default_limit); | ||
286 | /* export to DC */ | 288 | /* export to DC */ |
287 | u32 (*get_sclk)(void *handle, bool low); | 289 | u32 (*get_sclk)(void *handle, bool low); |
288 | u32 (*get_mclk)(void *handle, bool low); | 290 | u32 (*get_mclk)(void *handle, bool low); |
diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index 7c4b88aa7abb..376ed2dd52c7 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c | |||
@@ -1237,6 +1237,65 @@ static int pp_dpm_notify_smu_memory_info(void *handle, | |||
1237 | return ret; | 1237 | return ret; |
1238 | } | 1238 | } |
1239 | 1239 | ||
1240 | static int pp_set_power_limit(void *handle, uint32_t limit) | ||
1241 | { | ||
1242 | struct pp_hwmgr *hwmgr; | ||
1243 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
1244 | int ret = 0; | ||
1245 | |||
1246 | ret = pp_check(pp_handle); | ||
1247 | |||
1248 | if (ret) | ||
1249 | return ret; | ||
1250 | |||
1251 | hwmgr = pp_handle->hwmgr; | ||
1252 | |||
1253 | if (hwmgr->hwmgr_func->set_power_limit == NULL) { | ||
1254 | pr_info("%s was not implemented.\n", __func__); | ||
1255 | return -EINVAL; | ||
1256 | } | ||
1257 | |||
1258 | if (limit == 0) | ||
1259 | limit = hwmgr->default_power_limit; | ||
1260 | |||
1261 | if (limit > hwmgr->default_power_limit) | ||
1262 | return -EINVAL; | ||
1263 | |||
1264 | mutex_lock(&pp_handle->pp_lock); | ||
1265 | hwmgr->hwmgr_func->set_power_limit(hwmgr, limit); | ||
1266 | hwmgr->power_limit = limit; | ||
1267 | mutex_unlock(&pp_handle->pp_lock); | ||
1268 | return ret; | ||
1269 | } | ||
1270 | |||
1271 | static int pp_get_power_limit(void *handle, uint32_t *limit, bool default_limit) | ||
1272 | { | ||
1273 | struct pp_hwmgr *hwmgr; | ||
1274 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
1275 | int ret = 0; | ||
1276 | |||
1277 | ret = pp_check(pp_handle); | ||
1278 | |||
1279 | if (ret) | ||
1280 | return ret; | ||
1281 | |||
1282 | if (limit == NULL) | ||
1283 | return -EINVAL; | ||
1284 | |||
1285 | hwmgr = pp_handle->hwmgr; | ||
1286 | |||
1287 | mutex_lock(&pp_handle->pp_lock); | ||
1288 | |||
1289 | if (default_limit) | ||
1290 | *limit = hwmgr->default_power_limit; | ||
1291 | else | ||
1292 | *limit = hwmgr->power_limit; | ||
1293 | |||
1294 | mutex_unlock(&pp_handle->pp_lock); | ||
1295 | |||
1296 | return ret; | ||
1297 | } | ||
1298 | |||
1240 | static int pp_display_configuration_change(void *handle, | 1299 | static int pp_display_configuration_change(void *handle, |
1241 | const struct amd_pp_display_configuration *display_config) | 1300 | const struct amd_pp_display_configuration *display_config) |
1242 | { | 1301 | { |
@@ -1530,6 +1589,8 @@ const struct amd_pm_funcs pp_dpm_funcs = { | |||
1530 | .get_power_profile_mode = pp_get_power_profile_mode, | 1589 | .get_power_profile_mode = pp_get_power_profile_mode, |
1531 | .set_power_profile_mode = pp_set_power_profile_mode, | 1590 | .set_power_profile_mode = pp_set_power_profile_mode, |
1532 | .odn_edit_dpm_table = pp_odn_edit_dpm_table, | 1591 | .odn_edit_dpm_table = pp_odn_edit_dpm_table, |
1592 | .set_power_limit = pp_set_power_limit, | ||
1593 | .get_power_limit = pp_get_power_limit, | ||
1533 | /* export to DC */ | 1594 | /* export to DC */ |
1534 | .get_sclk = pp_dpm_get_sclk, | 1595 | .get_sclk = pp_dpm_get_sclk, |
1535 | .get_mclk = pp_dpm_get_mclk, | 1596 | .get_mclk = pp_dpm_get_mclk, |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c index c59cb9499e06..937971361b65 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | |||
@@ -4987,6 +4987,7 @@ static const struct pp_hwmgr_func smu7_hwmgr_funcs = { | |||
4987 | .get_max_high_clocks = smu7_get_max_high_clocks, | 4987 | .get_max_high_clocks = smu7_get_max_high_clocks, |
4988 | .get_thermal_temperature_range = smu7_get_thermal_temperature_range, | 4988 | .get_thermal_temperature_range = smu7_get_thermal_temperature_range, |
4989 | .odn_edit_dpm_table = smu7_odn_edit_dpm_table, | 4989 | .odn_edit_dpm_table = smu7_odn_edit_dpm_table, |
4990 | .set_power_limit = smu7_set_power_limit, | ||
4990 | }; | 4991 | }; |
4991 | 4992 | ||
4992 | uint8_t smu7_get_sleep_divider_id_from_clock(uint32_t clock, | 4993 | uint8_t smu7_get_sleep_divider_id_from_clock(uint32_t clock, |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c index 85ca16abb626..a93829dfd730 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c | |||
@@ -857,6 +857,8 @@ int smu7_set_power_limit(struct pp_hwmgr *hwmgr, uint32_t n) | |||
857 | { | 857 | { |
858 | struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); | 858 | struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); |
859 | 859 | ||
860 | n = (n & 0xff) << 8; | ||
861 | |||
860 | if (data->power_containment_features & | 862 | if (data->power_containment_features & |
861 | POWERCONTAINMENT_FEATURE_PkgPwrLimit) | 863 | POWERCONTAINMENT_FEATURE_PkgPwrLimit) |
862 | return smum_send_msg_to_smc_with_parameter(hwmgr, | 864 | return smum_send_msg_to_smc_with_parameter(hwmgr, |
@@ -903,12 +905,12 @@ int smu7_enable_power_containment(struct pp_hwmgr *hwmgr) | |||
903 | PP_ASSERT_WITH_CODE((0 == smc_result), | 905 | PP_ASSERT_WITH_CODE((0 == smc_result), |
904 | "Failed to enable PkgPwrTracking in SMC.", result = -1;); | 906 | "Failed to enable PkgPwrTracking in SMC.", result = -1;); |
905 | if (0 == smc_result) { | 907 | if (0 == smc_result) { |
906 | uint32_t default_limit = | 908 | hwmgr->default_power_limit = hwmgr->power_limit = |
907 | (uint32_t)(cac_table->usMaximumPowerDeliveryLimit * 256); | 909 | cac_table->usMaximumPowerDeliveryLimit; |
908 | data->power_containment_features |= | 910 | data->power_containment_features |= |
909 | POWERCONTAINMENT_FEATURE_PkgPwrLimit; | 911 | POWERCONTAINMENT_FEATURE_PkgPwrLimit; |
910 | 912 | ||
911 | if (smu7_set_power_limit(hwmgr, default_limit)) | 913 | if (smu7_set_power_limit(hwmgr, hwmgr->power_limit)) |
912 | pr_err("Failed to set Default Power Limit in SMC!"); | 914 | pr_err("Failed to set Default Power Limit in SMC!"); |
913 | } | 915 | } |
914 | } | 916 | } |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c index 341fba5f7171..d0c8ba0096fe 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c | |||
@@ -5155,6 +5155,7 @@ static const struct pp_hwmgr_func vega10_hwmgr_funcs = { | |||
5155 | .start_thermal_controller = vega10_start_thermal_controller, | 5155 | .start_thermal_controller = vega10_start_thermal_controller, |
5156 | .get_power_profile_mode = vega10_get_power_profile_mode, | 5156 | .get_power_profile_mode = vega10_get_power_profile_mode, |
5157 | .set_power_profile_mode = vega10_set_power_profile_mode, | 5157 | .set_power_profile_mode = vega10_set_power_profile_mode, |
5158 | .set_power_limit = vega10_set_power_limit, | ||
5158 | }; | 5159 | }; |
5159 | 5160 | ||
5160 | int vega10_hwmgr_init(struct pp_hwmgr *hwmgr) | 5161 | int vega10_hwmgr_init(struct pp_hwmgr *hwmgr) |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c index 598a194737a9..981c9e5431da 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c | |||
@@ -1357,10 +1357,11 @@ int vega10_enable_power_containment(struct pp_hwmgr *hwmgr) | |||
1357 | struct phm_ppt_v2_information *table_info = | 1357 | struct phm_ppt_v2_information *table_info = |
1358 | (struct phm_ppt_v2_information *)(hwmgr->pptable); | 1358 | (struct phm_ppt_v2_information *)(hwmgr->pptable); |
1359 | struct phm_tdp_table *tdp_table = table_info->tdp_table; | 1359 | struct phm_tdp_table *tdp_table = table_info->tdp_table; |
1360 | uint32_t default_pwr_limit = | ||
1361 | (uint32_t)(tdp_table->usMaximumPowerDeliveryLimit); | ||
1362 | int result = 0; | 1360 | int result = 0; |
1363 | 1361 | ||
1362 | hwmgr->default_power_limit = hwmgr->power_limit = | ||
1363 | (uint32_t)(tdp_table->usMaximumPowerDeliveryLimit); | ||
1364 | |||
1364 | if (PP_CAP(PHM_PlatformCaps_PowerContainment)) { | 1365 | if (PP_CAP(PHM_PlatformCaps_PowerContainment)) { |
1365 | if (data->smu_features[GNLD_PPT].supported) | 1366 | if (data->smu_features[GNLD_PPT].supported) |
1366 | PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr, | 1367 | PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr, |
@@ -1374,7 +1375,7 @@ int vega10_enable_power_containment(struct pp_hwmgr *hwmgr) | |||
1374 | "Attempt to enable PPT feature Failed!", | 1375 | "Attempt to enable PPT feature Failed!", |
1375 | data->smu_features[GNLD_TDC].supported = false); | 1376 | data->smu_features[GNLD_TDC].supported = false); |
1376 | 1377 | ||
1377 | result = vega10_set_power_limit(hwmgr, default_pwr_limit); | 1378 | result = vega10_set_power_limit(hwmgr, hwmgr->power_limit); |
1378 | PP_ASSERT_WITH_CODE(!result, | 1379 | PP_ASSERT_WITH_CODE(!result, |
1379 | "Failed to set Default Power Limit in SMC!", | 1380 | "Failed to set Default Power Limit in SMC!", |
1380 | return result); | 1381 | return result); |
diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h index 4d96439dd989..c0f9cea08339 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | |||
@@ -347,6 +347,7 @@ struct pp_hwmgr_func { | |||
347 | int (*odn_edit_dpm_table)(struct pp_hwmgr *hwmgr, | 347 | int (*odn_edit_dpm_table)(struct pp_hwmgr *hwmgr, |
348 | enum PP_OD_DPM_TABLE_COMMAND type, | 348 | enum PP_OD_DPM_TABLE_COMMAND type, |
349 | long *input, uint32_t size); | 349 | long *input, uint32_t size); |
350 | int (*set_power_limit)(struct pp_hwmgr *hwmgr, uint32_t n); | ||
350 | int (*set_mmhub_powergating_by_smu)(struct pp_hwmgr *hwmgr); | 351 | int (*set_mmhub_powergating_by_smu)(struct pp_hwmgr *hwmgr); |
351 | }; | 352 | }; |
352 | 353 | ||
@@ -759,6 +760,8 @@ struct pp_hwmgr { | |||
759 | uint32_t pstate_sclk; | 760 | uint32_t pstate_sclk; |
760 | uint32_t pstate_mclk; | 761 | uint32_t pstate_mclk; |
761 | bool od_enabled; | 762 | bool od_enabled; |
763 | uint32_t power_limit; | ||
764 | uint32_t default_power_limit; | ||
762 | }; | 765 | }; |
763 | 766 | ||
764 | struct cgs_irq_src_funcs { | 767 | struct cgs_irq_src_funcs { |