[Public]

Patches 1 and 3 are

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

For this one, suggest splitting to two patches - one to pass the limit type and 
the other to save/restore fast ppt limit. Could add LIMIT_TYPE_COUNT to enum 
smu_ppt_limit_type and keep an array in smu_user_dpm_profile. However, this 
fast ppt limit is only there for Vangogh now.

Thanks,
Lijo
-----Original Message-----
From: Limonciello, Mario <[email protected]>
Sent: Wednesday, October 1, 2025 11:34 PM
To: Limonciello, Mario <[email protected]>; 
[email protected]
Cc: Lazar, Lijo <[email protected]>
Subject: [PATCH 2/3] drm/amd: Stop overloading power limit with limit type

When passed around internally the upper 8 bits of power limit include the limit 
type.  This is non-obvious without digging into the nuances of each function.  
Instead pass the limit type as an argument to all applicable layers.

When the limit type is passed around it is apparent that the user settings for 
power limits are only being restored for default limit not fast limit.  Save 
and restore both.

Cc: Lijo Lazar <[email protected]>
Signed-off-by: Mario Limonciello <[email protected]>
---
 .../gpu/drm/amd/include/kgd_pp_interface.h    |  2 +-
 drivers/gpu/drm/amd/pm/amdgpu_dpm.c           |  3 +-
 drivers/gpu/drm/amd/pm/amdgpu_pm.c            |  3 +-
 drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h       |  2 +-
 .../gpu/drm/amd/pm/powerplay/amd_powerplay.c  |  2 +-
 drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c     | 39 +++++++++++++------
 drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h |  3 +-
 7 files changed, 35 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h 
b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
index 20e11997437f..21a83ee87d84 100644
--- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
+++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
@@ -445,7 +445,7 @@ struct amd_pm_funcs {
                                bool gate,
                                int inst);
        int (*set_clockgating_by_smu)(void *handle, uint32_t msg_id);
-       int (*set_power_limit)(void *handle, uint32_t n);
+       int (*set_power_limit)(void *handle, uint32_t limit_type, uint32_t n);
        int (*get_power_limit)(void *handle, uint32_t *limit,
                        enum pp_power_limit_level pp_limit_level,
                        enum pp_power_type power_type);
diff --git a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c 
b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
index 71d986dd7a6e..3458a7d4892f 100644
--- a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
+++ b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
@@ -1605,6 +1605,7 @@ int amdgpu_dpm_get_power_limit(struct amdgpu_device 
*adev,  }

 int amdgpu_dpm_set_power_limit(struct amdgpu_device *adev,
+                              uint32_t limit_type,
                               uint32_t limit)
 {
        const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; @@ 
-1615,7 +1616,7 @@ int amdgpu_dpm_set_power_limit(struct amdgpu_device *adev,

        mutex_lock(&adev->pm.mutex);
        ret = pp_funcs->set_power_limit(adev->powerplay.pp_handle,
-                                       limit);
+                                       limit_type, limit);
        mutex_unlock(&adev->pm.mutex);

        return ret;
diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c 
b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
index 08cd324515ad..37428eadfd09 100644
--- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
@@ -3172,13 +3172,12 @@ static ssize_t amdgpu_hwmon_set_power_cap(struct device 
*dev,
                return err;

        value = value / 1000000; /* convert to Watt */
-       value |= limit_type << 24;

        err = amdgpu_pm_get_access(adev);
        if (err < 0)
                return err;

-       err = amdgpu_dpm_set_power_limit(adev, value);
+       err = amdgpu_dpm_set_power_limit(adev, limit_type, value);

        amdgpu_pm_put_access(adev);

diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h 
b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
index 768317ee1486..4291471187f6 100644
--- a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
+++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
@@ -555,7 +555,7 @@ int amdgpu_dpm_get_power_limit(struct amdgpu_device *adev,
                               enum pp_power_limit_level pp_limit_level,
                               enum pp_power_type power_type);  int 
amdgpu_dpm_set_power_limit(struct amdgpu_device *adev,
-                              uint32_t limit);
+                              uint32_t limit_type, uint32_t limit);
 int amdgpu_dpm_is_cclk_dpm_supported(struct amdgpu_device *adev);  int 
amdgpu_dpm_debugfs_print_current_performance_level(struct amdgpu_device *adev,
                                                       struct seq_file *m);
diff --git a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c 
b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c
index 9041002dea6a..ba72b08a0edc 100644
--- a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c
+++ b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c
@@ -952,7 +952,7 @@ static int pp_dpm_switch_power_profile(void *handle,
        return 0;
 }

-static int pp_set_power_limit(void *handle, uint32_t limit)
+static int pp_set_power_limit(void *handle, uint32_t limit_type,
+uint32_t limit)
 {
        struct pp_hwmgr *hwmgr = handle;
        uint32_t max_power_limit;
diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c 
b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
index 431333060b72..a5f40503b0b6 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
@@ -68,7 +68,7 @@ static int smu_handle_task(struct smu_context *smu,  static 
int smu_reset(struct smu_context *smu);  static int smu_set_fan_speed_pwm(void 
*handle, u32 speed);  static int smu_set_fan_control_mode(void *handle, u32 
value); -static int smu_set_power_limit(void *handle, uint32_t limit);
+static int smu_set_power_limit(void *handle, uint32_t limit_type,
+uint32_t limit);
 static int smu_set_fan_speed_rpm(void *handle, uint32_t speed);  static int 
smu_set_gfx_cgpg(struct smu_context *smu, bool enabled);  static int 
smu_set_mp1_state(void *handle, enum pp_mp1_state mp1_state); @@ -508,11 
+508,18 @@ static void smu_restore_dpm_user_profile(struct smu_context *smu)
        /* Enable restore flag */
        smu->user_dpm_profile.flags |= SMU_DPM_USER_PROFILE_RESTORE;

-       /* set the user dpm power limit */
-       if (smu->user_dpm_profile.power_limit) {
-               ret = smu_set_power_limit(smu, 
smu->user_dpm_profile.power_limit);
+       /* set the user dpm power limits */
+       if (smu->user_dpm_profile.power_limit_default) {
+               ret = smu_set_power_limit(smu, SMU_DEFAULT_PPT_LIMIT,
+                                         
smu->user_dpm_profile.power_limit_default);
                if (ret)
-                       dev_err(smu->adev->dev, "Failed to set power limit 
value\n");
+                       dev_err(smu->adev->dev, "Failed to set default power 
limit value\n");
+       }
+       if (smu->user_dpm_profile.power_limit_fast) {
+               ret = smu_set_power_limit(smu, SMU_FAST_PPT_LIMIT,
+                                         
smu->user_dpm_profile.power_limit_fast);
+               if (ret)
+                       dev_err(smu->adev->dev, "Failed to set fast power limit 
value\n");
        }

        /* set the user dpm clock configurations */ @@ -2229,7 +2236,7 @@ 
static int smu_resume(struct amdgpu_ip_block *ip_block)
        adev->pm.dpm_enabled = true;

        if (smu->current_power_limit) {
-               ret = smu_set_power_limit(smu, smu->current_power_limit);
+               ret = smu_set_power_limit(smu, SMU_DEFAULT_PPT_LIMIT,
+smu->current_power_limit);
                if (ret && ret != -EOPNOTSUPP)
                        return ret;
        }
@@ -2929,16 +2936,14 @@ int smu_get_power_limit(void *handle,
        return ret;
 }

-static int smu_set_power_limit(void *handle, uint32_t limit)
+static int smu_set_power_limit(void *handle, uint32_t limit_type,
+uint32_t limit)
 {
        struct smu_context *smu = handle;
-       uint32_t limit_type = limit >> 24;
        int ret = 0;

        if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled)
                return -EOPNOTSUPP;

-       limit &= (1<<24)-1;
        if ((limit > smu->max_power_limit) || (limit < smu->min_power_limit)) {
                dev_err(smu->adev->dev,
                        "New power limit (%d) is out of range [%d,%d]\n", @@ 
-2951,11 +2956,21 @@ static int smu_set_power_limit(void *handle, uint32_t 
limit)

        if (smu->ppt_funcs->set_power_limit) {
                ret = smu->ppt_funcs->set_power_limit(smu, limit_type, limit);
-               if (!ret && !(smu->user_dpm_profile.flags & 
SMU_DPM_USER_PROFILE_RESTORE))
-                       smu->user_dpm_profile.power_limit = limit;
+               if (ret)
+                       return ret;
+               if (!(smu->user_dpm_profile.flags & 
SMU_DPM_USER_PROFILE_RESTORE)) {
+                       switch (limit_type) {
+                       case SMU_DEFAULT_PPT_LIMIT:
+                               smu->user_dpm_profile.power_limit_default = 
limit;
+                               break;
+                       case SMU_FAST_PPT_LIMIT:
+                               smu->user_dpm_profile.power_limit_fast = limit;
+                               break;
+                       };
+               }
        }

-       return ret;
+       return 0;
 }

 static int smu_print_smuclk_levels(struct smu_context *smu, enum smu_clk_type 
clk_type, char *buf) diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h 
b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
index b52e194397e2..19689ef1db99 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
@@ -231,7 +231,8 @@ enum smu_memory_pool_size {

 struct smu_user_dpm_profile {
        uint32_t fan_mode;
-       uint32_t power_limit;
+       uint32_t power_limit_default;
+       uint32_t power_limit_fast;
        uint32_t fan_speed_pwm;
        uint32_t fan_speed_rpm;
        uint32_t flags;
--
2.51.0

Reply via email to