On 19-May-26 9:48 AM, Yang Wang wrote:
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 <[email protected]>
---
  .../drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c  | 32 +++++++++++--------
  .../drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c  | 32 +++++++++++--------
  2 files changed, 36 insertions(+), 28 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 30d9cfac0d89..9e74a5c4be43 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
@@ -2391,28 +2391,32 @@ 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)
+                       power_limit = pp_limit;

<nit> power_limit may no longer be required. Could use current_power_limit directly.

Reviewed-by: Lijo Lazar <[email protected]>

Thanks,
Lijo
- 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 &&
@@ -2426,15 +2430,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 d253ce367476..481908913dde 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
@@ -2373,28 +2373,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 &&
@@ -2408,15 +2412,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;
        }

Reply via email to