[PATCH] drm/amdgpu/navi10: Correctly source TDPODLimit from overdrive table

Matt Coffin mcoffin13 at gmail.com
Wed Nov 6 18:03:26 UTC 2019


[Why]
Before this patch, the smu_v11_0 power limit setting function
incorrectly always thought that TDPODLimit was 0 on navi10 cards. This
meant that between 5.3 and 5.4, when the power limit started being
obeyed, one could no longer set higher power limits for navi10.

[How]
Just as for vega20, we set the power limit (and TDPODLimit) from the
powerplay table when it is written. We need to also write
smu->default_power_limit, as it is cached the first time the power limit
is fetched. This allows writing "soft" powerplay tables with higher
power limits in the OverDrive8 table, then using the hwmon sysfs
interface for setting the actual power limit.
---
 drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 9 +++++++++
 drivers/gpu/drm/amd/powerplay/smu_v11_0.c  | 4 ++--
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
index 0b461404af6b..3ac31d4f517c 100644
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
@@ -492,6 +492,7 @@ static int navi10_append_powerplay_table(struct smu_context *smu)
 
 static int navi10_store_powerplay_table(struct smu_context *smu)
 {
+	uint32_t base_power_limit;
 	struct smu_11_0_powerplay_table *powerplay_table = NULL;
 	struct smu_table_context *table_context = &smu->smu_table;
 	struct smu_baco_context *smu_baco = &smu->smu_baco;
@@ -505,6 +506,14 @@ static int navi10_store_powerplay_table(struct smu_context *smu)
 	       sizeof(PPTable_t));
 
 	table_context->thermal_controller_type = powerplay_table->thermal_controller_type;
+	table_context->TDPODLimit = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]);
+	if (smu->od_enabled) {
+		// re-calculate the default power limit from new pp_table
+		base_power_limit = powerplay_table->smc_pptable.SocketPowerLimitAc[PPT_THROTTLER_PPT0];
+		base_power_limit *= (100 + table_context->TDPODLimit);
+		base_power_limit /= 100;
+		smu->default_power_limit = base_power_limit;
+	}
 
 	mutex_lock(&smu_baco->mutex);
 	if (powerplay_table->platform_caps & SMU_11_0_PP_PLATFORM_CAP_BACO ||
diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
index c5257ae3188a..abd3912a21c9 100644
--- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
+++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
@@ -1068,8 +1068,8 @@ static int smu_v11_0_set_power_limit(struct smu_context *smu, uint32_t n)
 	int ret = 0;
 
 	if (n > smu->default_power_limit) {
-		pr_err("New power limit is over the max allowed %d\n",
-				smu->default_power_limit);
+		pr_err("New power limit (%d) is over the max allowed %d\n",
+				n, smu->default_power_limit);
 		return -EINVAL;
 	}
 
-- 
2.23.0



More information about the amd-gfx mailing list