From: Yang Wang Date: Tue, 19 May 2026 03:18:12 +0000 (+0800) Subject: drm/amd/pm: fix smu13 power limit default/cap calculation X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=bb204f19e4a115f094a6a3c4d82fcf48862d0766;p=thirdparty%2Flinux.git drm/amd/pm: fix smu13 power limit default/cap calculation smu_v13_0_0_get_power_limit() and smu_v13_0_7_get_power_limit() mix runtime power_limit with PP table limits when reporting default/min/max. When current power limit query succeeds, default_power_limit was set to the runtime value instead of the PP table default, and min/max could be derived from inconsistent bases (MsgLimits/runtime), leading to incorrect cap info. Use SocketPowerLimitAc/Dc as the PP default base (pp_limit), keep current_power_limit as runtime value, and derive min/max from pp_limit with OD percentages. Closes: https://gitlab.freedesktop.org/drm/amd/-/work_items/5227 Signed-off-by: Yang Wang Reviewed-by: Kenneth Feng Reviewed-by: Lijo Lazar Signed-off-by: Alex Deucher (cherry picked from commit 1eaf26db95901ca70737503a89b831dd763c8453) Cc: stable@vger.kernel.org --- diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c index fa861ec4d700..7f8d4bb47d02 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c @@ -2390,28 +2390,30 @@ static int smu_v13_0_0_enable_mgpu_fan_boost(struct smu_context *smu) } static int smu_v13_0_0_get_power_limit(struct smu_context *smu, - uint32_t *current_power_limit, - uint32_t *default_power_limit, - uint32_t *max_power_limit, - uint32_t *min_power_limit) + uint32_t *current_power_limit, + uint32_t *default_power_limit, + uint32_t *max_power_limit, + uint32_t *min_power_limit) { struct smu_table_context *table_context = &smu->smu_table; struct smu_13_0_0_powerplay_table *powerplay_table = (struct smu_13_0_0_powerplay_table *)table_context->power_play_table; PPTable_t *pptable = table_context->driver_pptable; SkuTable_t *skutable = &pptable->SkuTable; - uint32_t power_limit, od_percent_upper = 0, od_percent_lower = 0; - uint32_t msg_limit = skutable->MsgLimits.Power[PPT_THROTTLER_PPT0][POWER_SOURCE_AC]; - - if (smu_v13_0_get_current_power_limit(smu, &power_limit)) - power_limit = smu->adev->pm.ac_power ? + uint32_t pp_limit = smu->adev->pm.ac_power ? skutable->SocketPowerLimitAc[PPT_THROTTLER_PPT0] : skutable->SocketPowerLimitDc[PPT_THROTTLER_PPT0]; + uint32_t power_limit = 0, od_percent_upper = 0, od_percent_lower = 0; + int ret; + + if (current_power_limit) { + ret = smu_v13_0_get_current_power_limit(smu, &power_limit); + if (ret) + *current_power_limit = pp_limit; + } - if (current_power_limit) - *current_power_limit = power_limit; if (default_power_limit) - *default_power_limit = power_limit; + *default_power_limit = pp_limit; if (powerplay_table) { if (smu->od_enabled && @@ -2425,15 +2427,15 @@ static int smu_v13_0_0_get_power_limit(struct smu_context *smu, } dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n", - od_percent_upper, od_percent_lower, power_limit); + od_percent_upper, od_percent_lower, pp_limit); if (max_power_limit) { - *max_power_limit = msg_limit * (100 + od_percent_upper); + *max_power_limit = pp_limit * (100 + od_percent_upper); *max_power_limit /= 100; } if (min_power_limit) { - *min_power_limit = power_limit * (100 - od_percent_lower); + *min_power_limit = pp_limit * (100 - od_percent_lower); *min_power_limit /= 100; } diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c index 5abf2b0703c6..0f774b0920ce 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c @@ -2372,28 +2372,32 @@ static int smu_v13_0_7_enable_mgpu_fan_boost(struct smu_context *smu) } static int smu_v13_0_7_get_power_limit(struct smu_context *smu, - uint32_t *current_power_limit, - uint32_t *default_power_limit, - uint32_t *max_power_limit, - uint32_t *min_power_limit) + uint32_t *current_power_limit, + uint32_t *default_power_limit, + uint32_t *max_power_limit, + uint32_t *min_power_limit) { struct smu_table_context *table_context = &smu->smu_table; struct smu_13_0_7_powerplay_table *powerplay_table = (struct smu_13_0_7_powerplay_table *)table_context->power_play_table; PPTable_t *pptable = table_context->driver_pptable; SkuTable_t *skutable = &pptable->SkuTable; - uint32_t power_limit, od_percent_upper = 0, od_percent_lower = 0; - uint32_t msg_limit = skutable->MsgLimits.Power[PPT_THROTTLER_PPT0][POWER_SOURCE_AC]; - - if (smu_v13_0_get_current_power_limit(smu, &power_limit)) - power_limit = smu->adev->pm.ac_power ? + uint32_t pp_limit = smu->adev->pm.ac_power ? skutable->SocketPowerLimitAc[PPT_THROTTLER_PPT0] : skutable->SocketPowerLimitDc[PPT_THROTTLER_PPT0]; + uint32_t power_limit = 0, od_percent_upper = 0, od_percent_lower = 0; + int ret; + + if (current_power_limit) { + ret = smu_v13_0_get_current_power_limit(smu, &power_limit); + if (ret) + power_limit = pp_limit; - if (current_power_limit) *current_power_limit = power_limit; + } + if (default_power_limit) - *default_power_limit = power_limit; + *default_power_limit = pp_limit; if (powerplay_table) { if (smu->od_enabled && @@ -2407,15 +2411,15 @@ static int smu_v13_0_7_get_power_limit(struct smu_context *smu, } dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n", - od_percent_upper, od_percent_lower, power_limit); + od_percent_upper, od_percent_lower, pp_limit); if (max_power_limit) { - *max_power_limit = msg_limit * (100 + od_percent_upper); + *max_power_limit = pp_limit * (100 + od_percent_upper); *max_power_limit /= 100; } if (min_power_limit) { - *min_power_limit = power_limit * (100 - od_percent_lower); + *min_power_limit = pp_limit * (100 - od_percent_lower); *min_power_limit /= 100; }