AMD General

Reviewed-by: Kenneth Feng <[email protected]>

-----Original Message-----
From: Wang, Yang(Kevin) <[email protected]>
Sent: Wednesday, July 1, 2026 9:56 AM
To: [email protected]
Cc: Deucher, Alexander <[email protected]>; Zhang, Hawking 
<[email protected]>; Feng, Kenneth <[email protected]>
Subject: [PATCH] drm/amd/pm: fix smu13 power limit range calculation

SMU13 reports SocketPowerLimitAc/Dc as the default power limit, but 
MsgLimits.Power may carry a different firmware bound for the same PPT 
throttler. Using only the socket limit for both min and max can therefore 
expose an incorrect power range.

Keep the socket limit as the default, but derive the range from both values:
use the lower value for the min base and the higher value for the max base 
before applying OD percentages. Keep the current limit query independent from 
the cap calculation.

Fixes: 8c658297a4db ("drm/amd/pm: fix smu13 power limit default/cap 
calculation")
Closes: https://gitlab.freedesktop.org/drm/amd/-/work_items/5419

Signed-off-by: Yang Wang <[email protected]>
---
 .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c  | 11 +++++++----  
.../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c  | 15 ++++++++-------
 2 files changed, 15 insertions(+), 11 deletions(-)

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 c984dce48310..560cc306f10f 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
@@ -2404,11 +2404,14 @@ static int smu_v13_0_0_get_power_limit(struct 
smu_context *smu,
        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;
+       uint32_t msg_limit = 
skutable->MsgLimits.Power[PPT_THROTTLER_PPT0][POWER_SOURCE_AC];
+       uint32_t min_limit = min_t(uint32_t, pp_limit, msg_limit);
+       uint32_t max_limit = max_t(uint32_t, pp_limit, msg_limit);
+       uint32_t 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);
+               ret = smu_v13_0_get_current_power_limit(smu, 
current_power_limit);
                if (ret)
                        *current_power_limit = pp_limit;
        }
@@ -2431,12 +2434,12 @@ static int smu_v13_0_0_get_power_limit(struct 
smu_context *smu,
                od_percent_upper, od_percent_lower, pp_limit);

        if (max_power_limit) {
-               *max_power_limit = pp_limit * (100 + od_percent_upper);
+               *max_power_limit = max_limit * (100 + od_percent_upper);
                *max_power_limit /= 100;
        }

        if (min_power_limit) {
-               *min_power_limit = pp_limit * (100 - od_percent_lower);
+               *min_power_limit = min_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 7d0222d3d44d..8f214400cca5 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
@@ -2386,15 +2386,16 @@ static int smu_v13_0_7_get_power_limit(struct 
smu_context *smu,
        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;
+       uint32_t msg_limit = 
skutable->MsgLimits.Power[PPT_THROTTLER_PPT0][POWER_SOURCE_AC];
+       uint32_t min_limit = min_t(uint32_t, pp_limit, msg_limit);
+       uint32_t max_limit = max_t(uint32_t, pp_limit, msg_limit);
+       uint32_t 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);
+               ret = smu_v13_0_get_current_power_limit(smu, 
current_power_limit);
                if (ret)
-                       power_limit = pp_limit;
-
-               *current_power_limit = power_limit;
+                       *current_power_limit = pp_limit;
        }

        if (default_power_limit)
@@ -2415,12 +2416,12 @@ static int smu_v13_0_7_get_power_limit(struct 
smu_context *smu,
                od_percent_upper, od_percent_lower, pp_limit);

        if (max_power_limit) {
-               *max_power_limit = pp_limit * (100 + od_percent_upper);
+               *max_power_limit = max_limit * (100 + od_percent_upper);
                *max_power_limit /= 100;
        }

        if (min_power_limit) {
-               *min_power_limit = pp_limit * (100 - od_percent_lower);
+               *min_power_limit = min_limit * (100 - od_percent_lower);
                *min_power_limit /= 100;
        }

--
2.47.3

Reply via email to