diff options
| author | Yang Wang <kevinyang.wang@amd.com> | 2026-07-30 09:50:40 +0800 |
|---|---|---|
| committer | Alex Deucher <alexander.deucher@amd.com> | 2026-08-06 09:26:02 -0400 |
| commit | 25f4a46b0c8acd77c9065b50a1fe48af27d91fdf (patch) | |
| tree | d6f85acd430342bf8b3be9446f85cf7d383bc090 | |
| parent | d95700604fbc6fd7534303796d005e6efbd1d591 (diff) | |
| download | linux-next-25f4a46b0c8acd77c9065b50a1fe48af27d91fdf.tar.gz linux-next-25f4a46b0c8acd77c9065b50a1fe48af27d91fdf.zip | |
drm/amd/pm: derive stable PPT limits from PPTable
GetPptLimit reports mutable PMFW runtime state. Using that value for
static capabilities causes two externally visible problems:
- A userspace override changes the default reported through hwmon.
- A firmware reset changes the advertised minimum or maximum range.
Derive platform defaults and supported ranges from the driver PPTable
for Sienna Cichlid, Navi10, Arcturus, and Aldebaran. Reserve PMFW queries
for the effective current limit.
Runtime policy can no longer redefine immutable platform capabilities.
Signed-off-by: Yang Wang <kevinyang.wang@amd.com>
Reviewed-by: Kenneth Feng <kenneth.feng@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
4 files changed, 53 insertions, 40 deletions
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c index e7628f4f1de4..978f86ac12fb 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c @@ -1266,24 +1266,25 @@ static int arcturus_get_power_limit(struct smu_context *smu, uint32_t *min_power_limit) { PPTable_t *pptable = smu->smu_table.driver_pptable; - uint32_t power_limit; + uint32_t current_limit, default_limit; - 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]; + if (!pptable) { + dev_err(smu->adev->dev, + "Cannot get PPT limit due to pptable missing!"); + return -EINVAL; } + default_limit = pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0]; + + if (smu_v11_0_get_current_power_limit(smu, ¤t_limit)) + current_limit = default_limit; + if (current_power_limit) - *current_power_limit = power_limit; + *current_power_limit = current_limit; if (default_power_limit) - *default_power_limit = power_limit; + *default_power_limit = default_limit; if (max_power_limit) - *max_power_limit = power_limit; + *max_power_limit = default_limit; /* * No lower bound is imposed on the limit. Any unreasonable limit set * will result in frequent throttling. diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c index 9f8ab4e097dd..a47d49dd3ff0 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c @@ -2144,22 +2144,26 @@ static int navi10_get_power_limit(struct smu_context *smu, (struct smu_11_0_powerplay_table *)smu->smu_table.power_play_table; struct smu_11_0_overdrive_table *od_settings = smu->od_settings; PPTable_t *pptable = smu->smu_table.driver_pptable; - uint32_t power_limit, od_percent_upper = 0, od_percent_lower = 0; + uint32_t current_limit, default_limit; + uint32_t od_percent_upper = 0, od_percent_lower = 0; - 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]; + if (!pptable) { + dev_err(smu->adev->dev, + "Cannot get PPT limit due to pptable missing!"); + return -EINVAL; } + default_limit = smu->adev->pm.ac_power ? + pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0] : + pptable->SocketPowerLimitDc[PPT_THROTTLER_PPT0]; + + if (smu_v11_0_get_current_power_limit(smu, ¤t_limit)) + current_limit = default_limit; + if (current_power_limit) - *current_power_limit = power_limit; + *current_power_limit = current_limit; if (default_power_limit) - *default_power_limit = power_limit; + *default_power_limit = default_limit; if (powerplay_table) { if (smu->od_enabled && @@ -2173,15 +2177,15 @@ static int navi10_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, default_limit); if (max_power_limit) { - *max_power_limit = power_limit * (100 + od_percent_upper); + *max_power_limit = default_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 = default_limit * (100 - od_percent_lower); *min_power_limit /= 100; } diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c index cef6287524d4..b90878c2c8ef 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c @@ -633,20 +633,24 @@ static int sienna_cichlid_get_power_limit(struct smu_context *smu, struct smu_11_0_7_powerplay_table *powerplay_table = (struct smu_11_0_7_powerplay_table *)smu->smu_table.power_play_table; struct smu_11_0_7_overdrive_table *od_settings = smu->od_settings; - uint32_t power_limit, od_percent_upper = 0, od_percent_lower = 0; - uint16_t *table_member; + uint32_t current_limit, default_limit; + uint32_t od_percent_upper = 0, od_percent_lower = 0; + u16 *power_limit_ac, *power_limit_dc; - GET_PPTABLE_MEMBER(SocketPowerLimitAc, &table_member); + GET_PPTABLE_MEMBER(SocketPowerLimitAc, &power_limit_ac); + GET_PPTABLE_MEMBER(SocketPowerLimitDc, &power_limit_dc); - if (smu_v11_0_get_current_power_limit(smu, &power_limit)) { - power_limit = - table_member[PPT_THROTTLER_PPT0]; - } + default_limit = smu->adev->pm.ac_power ? + power_limit_ac[PPT_THROTTLER_PPT0] : + power_limit_dc[PPT_THROTTLER_PPT0]; + + if (smu_v11_0_get_current_power_limit(smu, ¤t_limit)) + current_limit = default_limit; if (current_power_limit) - *current_power_limit = power_limit; + *current_power_limit = current_limit; if (default_power_limit) - *default_power_limit = power_limit; + *default_power_limit = default_limit; if (powerplay_table) { if (smu->od_enabled && @@ -660,15 +664,15 @@ static int sienna_cichlid_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, default_limit); if (max_power_limit) { - *max_power_limit = power_limit * (100 + od_percent_upper); + *max_power_limit = default_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 = default_limit * (100 - od_percent_lower); *min_power_limit /= 100; } return 0; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c index cbdfde79cb9e..5dee4cdbb971 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c @@ -1156,8 +1156,12 @@ static int aldebaran_get_power_limit(struct smu_context *smu, if (current_power_limit) *current_power_limit = power_limit; - if (default_power_limit) - *default_power_limit = power_limit; + if (default_power_limit) { + if (pptable) + *default_power_limit = pptable->PptLimit; + else + *default_power_limit = power_limit; + } if (max_power_limit) { if (pptable) |
