--- /dev/null
+From 220f22e1d66c1cfb63387eb1c4210f92a357c2d9 Mon Sep 17 00:00:00 2001
+From: Yang Wang <kevinyang.wang@amd.com>
+Date: Wed, 1 Jul 2026 09:11:15 +0800
+Subject: drm/amd/pm: fix smu13 power limit range calculation
+
+From: Yang Wang <kevinyang.wang@amd.com>
+
+commit 220f22e1d66c1cfb63387eb1c4210f92a357c2d9 upstream.
+
+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: 1eaf26db9590 ("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 <kevinyang.wang@amd.com>
+Reviewed-by: Kenneth Feng <kenneth.feng@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit f45bbf0f62f266ed8422d84f347d75d5fca846a7)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 11 +++++++----
+ drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 15 ++++++++-------
+ 2 files changed, 15 insertions(+), 11 deletions(-)
+
+--- 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
+@@ -2396,11 +2396,14 @@ static int smu_v13_0_0_get_power_limit(s
+ 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;
+ }
+@@ -2423,12 +2426,12 @@ static int smu_v13_0_0_get_power_limit(s
+ 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;
+ }
+
+--- 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
+@@ -2357,15 +2357,16 @@ static int smu_v13_0_7_get_power_limit(s
+ 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)
+@@ -2386,12 +2387,12 @@ static int smu_v13_0_7_get_power_limit(s
+ 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;
+ }
+