Re: [PATCH] drm/amd/pm: Track current PPT limit for restore
"Lazar, Lijo" <[email protected]> Fri, 7 Aug 2026 10:20:12 +0530
| Newsgroups | org.freedesktop.lists.amd-gfx |
|---|---|
| Message-ID | <[email protected]> |
On 06-Aug-26 1:32 PM, Lazar, Lijo wrote: > > > On 06-Aug-26 1:26 PM, Wang, Yang(Kevin) wrote: >> AMD General >> >>> Driver triggers resets which could relaod the whole FW. In such cases >>> driver >>> remains responsible for restoring the last known power limit. The >>> current >>> method doesn't do that. >> >> No, the original code already contains this restore logic, include >> suspend/resume + gpu recovery, and save/restore logic has been >> verified on Navi21 and Navi48 ASICs. >> >> And the if no user edit power limit from user side, the driver will >> skip restore power limit, in this case, the driver will use default >> value after firmware reloading. >> >> btw, your change will break gpu od + power limit logic in navi3x/navi4x. > > This patch doesn't break that. Whatever user has set as the last limit > will be the current limit in Navi3x/Navi4x case. That will be restored. > If user hasn't edited limit, current limit will be equivalent to default > limit and then it's not set again. > Hi Kevin, Does this address your concern? Thanks, Lijo >> >> So What issue you have facing now ? >> > > Driver remains responsible for restoring the state triggered by inband > actions like suspend/resume or reset as OOB doesn't monitor everything. > In such cases, driver being the inband owner needs to restore the proper > state after the event. > > Thanks, > Lijo >> Best Regards, >> Kevin >> >>> -----Original Message----- >>> From: Lazar, Lijo <[email protected]> >>> Sent: Thursday, August 6, 2026 3:48 PM >>> To: Wang, Yang(Kevin) <[email protected]>; amd- >>> [email protected] >>> Cc: Zhang, Hawking <[email protected]>; Deucher, Alexander >>> <[email protected]>; Kamal, Asad <[email protected]> >>> Subject: Re: [PATCH] drm/amd/pm: Track current PPT limit for restore >>> >>> >>> >>> On 06-Aug-26 1:03 PM, Wang, Yang(Kevin) wrote: >>>> AMD General >>>> >>>> I do not agree with adding a read-to-cache path for the current PPT >>>> limit. >>>> >>>> The current limit is PMFW runtime state. A read of that state must >>>> remain an >>> observation; it must not implicitly create or update driver-owned >>> persistent >>> policy. >>>> This separation is intentional: the driver keeps immutable >>>> capabilities from >>> the PPTable and restores only limits that it successfully programmed >>> itself. >>>> >>>> Caching a value returned by GetPptLimit would turn a potentially >>>> transient >>> or out-of-band PMFW state into a value that the driver replays after >>> suspend >>> or reset. >>>> >>>> There is no ownership, notification, or synchronization mechanism that >>> makes such a cache authoritative, so it can only become stale. >>>> and the existing user_dpm_profile policy *CACHE ALREADY* handles the >>> supported driver-owned update path. >>>> >>> >>> The existing path also doesn't have any synchronization with out-of- >>> band, so >>> the same argument holds. i.e., it overwrites whatever set by external >>> source. >>>> If no bug fix or feature improve, please drop this patch. >>> >>> Driver triggers resets which could relaod the whole FW. In such cases >>> driver >>> remains responsible for restoring the last known power limit. The >>> current >>> method doesn't do that. >>> >>> I will add a bug fix tag as the previous patch doesn't restore the >>> current limit >>> properly. >>> >>> Thanks, >>> Lijo >>> >>>> >>>> Best Regards, >>>> Kevin >>>> >>>>> -----Original Message----- >>>>> From: Lazar, Lijo <[email protected]> >>>>> Sent: Thursday, August 6, 2026 2:14 PM >>>>> To: [email protected] >>>>> Cc: Zhang, Hawking <[email protected]>; Deucher, Alexander >>>>> <[email protected]>; Kamal, Asad <[email protected]>; >>> Wang, >>>>> Yang(Kevin) <[email protected]> >>>>> Subject: [PATCH] drm/amd/pm: Track current PPT limit for restore >>>>> >>>>> Cache the applied PPT limit in the ppt limit range and refresh it on >>>>> every get and set. Initialize with the default value on fresh load; a >>>>> value equal to default is treated as unset. >>>>> >>>>> On suspend or reset recovery, restore the cached current limit when >>>>> it differs from the default, falling back to the default otherwise. >>>>> This replaces the user- mask based restore, covering limits changed >>>>> outside the user profile path as well. >>>>> >>>>> Signed-off-by: Lijo Lazar <[email protected]> >>>>> --- >>>>> drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 39 >>> +++++++++++++---- >>>>> -- >>>>> drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h | 1 + >>>>> 2 files changed, 29 insertions(+), 11 deletions(-) >>>>> >>>>> diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c >>>>> b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c >>>>> index f45cd4e31415..7edd919a7832 100644 >>>>> --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c >>>>> +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c >>>>> @@ -495,16 +495,11 @@ static void smu_restore_ppt_limits(struct >>>>> smu_context *smu, { >>>>> enum smu_power_src_type power_source; >>>>> struct smu_ppt_limit_range *range; >>>>> - uint32_t restore_mask; >>>>> uint32_t limit; >>>>> int i, ret; >>>>> >>>>> power_source = smu->adev->pm.ac_power ? >>>>> SMU_POWER_SOURCE_AC : SMU_POWER_SOURCE_DC; >>>>> - restore_mask = smu- >>>>>> user_dpm_profile.ppt_limit_user_mask[power_source] & >>>>> - smu->ppt_limits.supported_mask; >>>>> - if (!restore_mask && !restore_defaults) >>>>> - return; >>>>> >>>>> smu->user_dpm_profile.flags |= SMU_DPM_USER_PROFILE_RESTORE; >>>>> >>>>> @@ -512,14 +507,14 @@ static void smu_restore_ppt_limits(struct >>>>> smu_context *smu, >>>>> if (!(smu->ppt_limits.supported_mask & BIT(i))) >>>>> continue; >>>>> >>>>> - if (restore_mask & BIT(i)) { >>>>> - limit = smu- >>>>>> user_dpm_profile.ppt_limits[power_source][i]; >>>>> - } else if (restore_defaults) { >>>>> - range = &smu->ppt_limits.range[power_source][i]; >>>>> + range = &smu->ppt_limits.range[power_source][i]; >>>>> + if (range->current_value && >>>>> + range->current_value != range->default_value) >>>>> + limit = range->current_value; >>>>> + else if (restore_defaults) >>>>> limit = range->default_value; >>>>> - } else { >>>>> + else >>>>> continue; >>>>> - } >>>>> >>>>> ret = smu_set_ppt_limit(smu, i, limit); >>>>> if (ret) >>>>> @@ -875,6 +870,21 @@ static int smu_early_init(struct amdgpu_ip_block >>>>> *ip_block) >>>>> return smu_init_microcode(smu); >>>>> } >>>>> >>>>> +static void smu_init_ppt_limits_current(struct smu_context *smu) { >>>>> + struct smu_ppt_limit_range *range; >>>>> + int i, j; >>>>> + >>>>> + for (i = SMU_POWER_SOURCE_AC; i < SMU_POWER_SOURCE_COUNT; >>>>> i++) { >>>>> + for (j = SMU_PPT_LIMIT_PPT0; j < SMU_LIMIT_TYPE_COUNT; >>>>> j++) { >>>>> + if (!(smu->ppt_limits.supported_mask & BIT(j))) >>>>> + continue; >>>>> + range = &smu->ppt_limits.range[i][j]; >>>>> + range->current_value = range->default_value; >>>>> + } >>>>> + } >>>>> +} >>>>> + >>>>> static int smu_set_default_dpm_table(struct smu_context *smu) { >>>>> struct amdgpu_device *adev = smu->adev; @@ -1911,6 +1921,9 @@ >>>>> static int smu_smc_hw_setup(struct smu_context *smu) >>>>> if (ret) >>>>> dev_err(adev->dev, "Error during wbrf init call\n"); >>>>> >>>>> + if (!adev->in_suspend && !amdgpu_reset_in_recovery(adev)) >>>>> + smu_init_ppt_limits_current(smu); >>>>> + >>>>> return ret; >>>>> } >>>>> >>>>> @@ -2999,6 +3012,9 @@ int smu_get_ppt_limit(void *handle, >>>>> switch (limit_level) { >>>>> case SMU_PPT_LIMIT_CURRENT: >>>>> ret = smu_get_asic_ppt_limit(smu, limit_type, limit); >>>>> + if (!ret) >>>>> + smu- >>>>>> ppt_limits.range[power_source][limit_type].current_value = >>>>> + *limit; >>>>> break; >>>>> case SMU_PPT_LIMIT_DEFAULT: >>>>> *limit = smu- >>>>>> ppt_limits.range[power_source][limit_type].default_value; >>>>> @@ -3061,6 +3077,7 @@ static int smu_set_ppt_limit(void *handle, >>>>> uint32_t limit_type, uint32_t limit) >>>>> ret = smu->ppt_funcs->set_ppt_limit(smu, limit_type, limit); >>>>> if (ret) >>>>> return ret; >>>>> + range->current_value = limit; >>>>> if (!(smu->user_dpm_profile.flags & >>>>> SMU_DPM_USER_PROFILE_RESTORE)) { >>>>> smu- >>>>>> user_dpm_profile.ppt_limits[power_source][limit_type] = limit; >>>>> >>>>> smu->user_dpm_profile.ppt_limit_user_mask[power_source] >>>>> |= 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 92658eb3886d..5222b48eba25 100644 >>>>> --- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h >>>>> +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h >>>>> @@ -229,6 +229,7 @@ enum smu_ppt_limit_level { >>>>> >>>>> struct smu_ppt_limit_range { >>>>> uint32_t default_value; >>>>> + uint32_t current_value; >>>>> uint32_t min; >>>>> uint32_t max; >>>>> uint32_t od_min; >>>>> -- >>>>> 2.49.0 >>>> >> >