All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Lazar, Lijo" <lijo.lazar@amd.com>
To: Yang Wang <kevinyang.wang@amd.com>, amd-gfx@lists.freedesktop.org
Cc: alexander.deucher@amd.com, hawking.zhang@amd.com, kenneth.feng@amd.com
Subject: Re: [PATCH 3/4] drm/amd/pm: refactor user PPT policy save and restore
Date: Fri, 31 Jul 2026 10:27:24 +0530	[thread overview]
Message-ID: <c4cd5c4c-00e5-41cb-b049-8e668270bbcf@amd.com> (raw)
In-Reply-To: <2a1bf8c187a6b6a67169fda0e6551a062af56c77.1785467079.git.kevinyang.wang@amd.com>



On 31-Jul-26 8:40 AM, Yang Wang wrote:
> The existing user policy representation has three ambiguities:
> 
> - A numeric value cannot distinguish explicit zero from an unset policy.
> - One value per controller cannot preserve independent AC and DC requests.
> - Suspend-only restore misses runtime resume, GPU reset, and table reload.
> 
> Refactor policy storage and restore as follows:
> 
> - Store values and validity masks by power source and PPT controller.
> - Save writes against the active source.
> - Restore the active source after default SMU setup.
> - Reapply the target policy after live AC/DC transitions.
> - Use the target source default when no explicit request exists.
> 
> The late-init path now covers system resume, runtime resume, GPU reset,
> and custom PPTable reload. Common code owns persistent policy; PMFW
> continues to own effective current limits.
> 
> Signed-off-by: Yang Wang <kevinyang.wang@amd.com>
> ---
>   drivers/gpu/drm/amd/pm/amdgpu_dpm.c           |  2 +-
>   drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c     | 89 +++++++++++++------
>   drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h |  5 +-
>   3 files changed, 68 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
> index c3688b3b12cc..ce526db4d24a 100644
> --- a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
> +++ b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
> @@ -508,7 +508,7 @@ void amdgpu_pm_acpi_event_handler(struct amdgpu_device *adev)
>   			amdgpu_dpm_notify_ac_dc(adev);
>   
>   		if (is_support_sw_smu(adev))
> -			smu_set_ac_dc(adev->powerplay.pp_handle);
> +			smu_set_ac_dc(adev->powerplay.pp_handle, true);
>   
>   		mutex_unlock(&adev->pm.mutex);
>   	}
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
> index 99d42446cfc8..43d5dd7dce7e 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
> +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
> @@ -488,12 +488,52 @@ static void smu_set_user_clk_dependencies(struct smu_context *smu, enum smu_clk_
>   		return;
>   }
>   
> +static void smu_restore_ppt_limits(struct smu_context *smu,
> +				   bool restore_defaults)
> +{
> +	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;
> +
> +	for (i = SMU_PPT_LIMIT_PPT0; i < SMU_LIMIT_TYPE_COUNT; i++) {
> +		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];
> +			limit = range->default_value;

This should be restore the current limit before a suspend/reset and not 
the default limit. The current limit could be set through out of band 
also, user profile values won't reflect that.

Thanks,
Lijo

> +		} else {
> +			continue;
> +		}
> +
> +		ret = smu_set_ppt_limit(smu, i, limit);
> +		if (ret)
> +			dev_err(smu->adev->dev,
> +				"Failed to restore PPT%d limit: %d\n", i, ret);
> +	}
> +
> +	smu->user_dpm_profile.flags &= ~SMU_DPM_USER_PROFILE_RESTORE;
> +}
> +
>   /**
>    * smu_restore_dpm_user_profile - reinstate user dpm profile
>    *
>    * @smu:	smu_context pointer
>    *
> - * Restore saved user power limits, clock frequencies and fan settings.
> + * Restore saved user clock frequencies and fan settings.
>    */
>   static void smu_restore_dpm_user_profile(struct smu_context *smu)
>   {
> @@ -509,17 +549,6 @@ 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 limits */
> -	for (int i = SMU_PPT_LIMIT_PPT0; i < SMU_LIMIT_TYPE_COUNT; i++) {
> -		if (!smu->user_dpm_profile.ppt_limits[i])
> -			continue;
> -		ret = smu_set_ppt_limit(smu, i,
> -					    smu->user_dpm_profile.ppt_limits[i]);
> -		if (ret)
> -			dev_err(smu->adev->dev,
> -				"Failed to set %d PPT limit value\n", i);
> -	}
> -
>   	/* set the user dpm clock configurations */
>   	if (smu_dpm_ctx->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL) {
>   		enum smu_clk_type clk_type;
> @@ -932,7 +961,7 @@ static int smu_late_init(struct amdgpu_ip_block *ip_block)
>   	 * is unnecessary.
>   	 */
>   	adev->pm.ac_power = power_supply_is_system_supplied() > 0;
> -	smu_set_ac_dc(smu);
> +	smu_set_ac_dc(smu, false);
>   
>   	if ((amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 1)) ||
>   	    (amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 3)))
> @@ -967,6 +996,8 @@ static int smu_late_init(struct amdgpu_ip_block *ip_block)
>   		return ret;
>   	}
>   
> +	if (adev->in_suspend)
> +		smu_restore_ppt_limits(smu, false);
>   	smu_restore_dpm_user_profile(smu);
>   
>   	return 0;
> @@ -2746,7 +2777,7 @@ static int smu_set_watermarks_for_clock_ranges(void *handle,
>   	return smu_set_watermarks_table(smu, clock_ranges);
>   }
>   
> -int smu_set_ac_dc(struct smu_context *smu)
> +int smu_set_ac_dc(struct smu_context *smu, bool restore_ppt_policy)
>   {
>   	int ret = 0;
>   
> @@ -2754,17 +2785,22 @@ int smu_set_ac_dc(struct smu_context *smu)
>   		return -EOPNOTSUPP;
>   
>   	/* controlled by firmware */
> -	if (smu->dc_controlled_by_gpio)
> -		return 0;
> +	if (!smu->dc_controlled_by_gpio) {
> +		ret = smu_set_power_source(smu,
> +					   smu->adev->pm.ac_power ?
> +					   SMU_POWER_SOURCE_AC :
> +					   SMU_POWER_SOURCE_DC);
> +		if (ret) {
> +			dev_err(smu->adev->dev, "Failed to switch to %s mode!\n",
> +				smu->adev->pm.ac_power ? "AC" : "DC");
> +			return ret;
> +		}
> +	}
>   
> -	ret = smu_set_power_source(smu,
> -				   smu->adev->pm.ac_power ? SMU_POWER_SOURCE_AC :
> -				   SMU_POWER_SOURCE_DC);
> -	if (ret)
> -		dev_err(smu->adev->dev, "Failed to switch to %s mode!\n",
> -		       smu->adev->pm.ac_power ? "AC" : "DC");
> +	if (restore_ppt_policy)
> +		smu_restore_ppt_limits(smu, true);
>   
> -	return ret;
> +	return 0;
>   }
>   
>   const struct amd_ip_funcs smu_ip_funcs = {
> @@ -3020,8 +3056,11 @@ 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;
> -	if (!(smu->user_dpm_profile.flags & SMU_DPM_USER_PROFILE_RESTORE))
> -		smu->user_dpm_profile.ppt_limits[limit_type] = 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] |=
> +			BIT(limit_type);
> +	}
>   
>   	return 0;
>   }
> 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 3d32ee723b8e..698197a285e3 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
> +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
> @@ -251,7 +251,8 @@ enum smu_memory_pool_size {
>   
>   struct smu_user_dpm_profile {
>   	uint32_t fan_mode;
> -	uint32_t ppt_limits[SMU_LIMIT_TYPE_COUNT];
> +	uint32_t ppt_limits[SMU_POWER_SOURCE_COUNT][SMU_LIMIT_TYPE_COUNT];
> +	uint32_t ppt_limit_user_mask[SMU_POWER_SOURCE_COUNT];
>   	uint32_t fan_speed_pwm;
>   	uint32_t fan_speed_rpm;
>   	uint32_t flags;
> @@ -1953,7 +1954,7 @@ int smu_set_soft_freq_range(struct smu_context *smu, enum pp_clock_type clk_type
>   
>   int smu_set_gfx_power_up_by_imu(struct smu_context *smu);
>   
> -int smu_set_ac_dc(struct smu_context *smu);
> +int smu_set_ac_dc(struct smu_context *smu, bool restore_ppt_policy);
>   
>   int smu_set_xgmi_plpd_mode(struct smu_context *smu,
>   			   enum pp_xgmi_plpd_mode mode);


  reply	other threads:[~2026-07-31  4:57 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-31  3:10 [PATCH 0/4] drm/amd/pm: refactor PPT limit runtime policy Yang Wang
2026-07-31  3:10 ` [PATCH 1/4] drm/amd/pm: refactor PPT limits by controller and power source Yang Wang
2026-07-31  3:10 ` [PATCH 2/4] drm/amd/pm: account for OD percentage in effective PPT limits Yang Wang
2026-07-31  3:10 ` [PATCH 3/4] drm/amd/pm: refactor user PPT policy save and restore Yang Wang
2026-07-31  4:57   ` Lazar, Lijo [this message]
2026-07-31  6:51     ` Wang, Yang(Kevin)
2026-07-31  7:45       ` Lazar, Lijo
2026-07-31  8:05         ` Wang, Yang(Kevin)
2026-07-31  8:25           ` Lazar, Lijo
2026-07-31  3:10 ` [PATCH 4/4] drm/amd/pm: restore user PPT limits after GPU reset Yang Wang
2026-07-31  3:57 ` [PATCH 0/4] drm/amd/pm: refactor PPT limit runtime policy Feng, Kenneth

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=c4cd5c4c-00e5-41cb-b049-8e668270bbcf@amd.com \
    --to=lijo.lazar@amd.com \
    --cc=alexander.deucher@amd.com \
    --cc=amd-gfx@lists.freedesktop.org \
    --cc=hawking.zhang@amd.com \
    --cc=kenneth.feng@amd.com \
    --cc=kevinyang.wang@amd.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.