summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c
diff options
context:
space:
mode:
authorEvan Quan <evan.quan@amd.com>2020-06-08 16:29:41 +0800
committerAlex Deucher <alexander.deucher@amd.com>2020-07-01 01:59:18 -0400
commit1e239fdd31cdf1729bc1e8b4538bf590bd28de57 (patch)
treeff280969d4229b84aa1b3b97f0ee376549be3dc5 /drivers/gpu/drm/amd/powerplay/arcturus_ppt.c
parentf3bc9aecebbc8f58e13477567afc697dfa6becaf (diff)
drm/amd/powerplay: maximize code sharing around power limit
Also cache the current and max power limits. Signed-off-by: Evan Quan <evan.quan@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/powerplay/arcturus_ppt.c')
-rw-r--r--drivers/gpu/drm/amd/powerplay/arcturus_ppt.c49
1 files changed, 21 insertions, 28 deletions
diff --git a/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c b/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c
index 0704a9c1d567..2c78271123f7 100644
--- a/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c
@@ -1413,40 +1413,33 @@ static int arcturus_get_power_limit(struct smu_context *smu,
uint32_t *limit,
bool cap)
{
+ struct smu_11_0_powerplay_table *powerplay_table =
+ (struct smu_11_0_powerplay_table *)smu->smu_table.power_play_table;
PPTable_t *pptable = smu->smu_table.driver_pptable;
- uint32_t asic_default_power_limit = 0;
- int ret = 0;
- int power_src;
-
- if (!smu->power_limit) {
- if (smu_feature_is_enabled(smu, SMU_FEATURE_PPT_BIT)) {
- power_src = smu_power_get_index(smu, SMU_POWER_SOURCE_AC);
- if (power_src < 0)
- return -EINVAL;
+ uint32_t power_limit, od_percent;
- ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetPptLimit,
- power_src << 16, &asic_default_power_limit);
- if (ret) {
- dev_err(smu->adev->dev, "[%s] get PPT limit failed!", __func__);
- return ret;
- }
- } else {
- /* the last hope to figure out the ppt limit */
- if (!pptable) {
- dev_err(smu->adev->dev, "Cannot get PPT limit due to pptable missing!");
- return -EINVAL;
- }
- asic_default_power_limit =
- pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0];
+ if (smu_v11_0_get_current_power_limit(smu, &power_limit)) {
+ /* the last hope to figure out the ppt limit */
+ if (!pptable) {
+ dev_err(smu->adev->dev, "Cannot get PPT limit due to pptable missing!");
+ return -EINVAL;
}
+ power_limit =
+ pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0];
+ }
+ smu->current_power_limit = power_limit;
+
+ if (smu->od_enabled) {
+ od_percent = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]);
+
+ dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_percent, power_limit);
- smu->power_limit = asic_default_power_limit;
+ power_limit *= (100 + od_percent);
+ power_limit /= 100;
}
+ smu->max_power_limit = power_limit;
- if (cap)
- *limit = smu_get_max_power_limit(smu);
- else
- *limit = smu->power_limit;
+ *limit = (cap ? smu->max_power_limit : smu->current_power_limit);
return 0;
}