All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Lazar, Lijo" <lijo.lazar@amd.com>
To: "Quan, Evan" <Evan.Quan@amd.com>,
	"amd-gfx@lists.freedesktop.org" <amd-gfx@lists.freedesktop.org>
Cc: "Deucher, Alexander" <Alexander.Deucher@amd.com>,
	"Feng, Kenneth" <Kenneth.Feng@amd.com>,
	"Koenig, Christian" <Christian.Koenig@amd.com>
Subject: Re: [PATCH V4 02/17] drm/amd/pm: do not expose power implementation details to amdgpu_pm.c
Date: Fri, 10 Dec 2021 11:23:08 +0530	[thread overview]
Message-ID: <c8fd7a7f-309d-74c5-baa1-c387a817dac2@amd.com> (raw)
In-Reply-To: <DM6PR12MB2619A1E385175ED9D2A83863E4719@DM6PR12MB2619.namprd12.prod.outlook.com>



On 12/10/2021 10:50 AM, Quan, Evan wrote:
> [AMD Official Use Only]
> 
> 
> 
>> -----Original Message-----
>> From: Lazar, Lijo <Lijo.Lazar@amd.com>
>> Sent: Thursday, December 9, 2021 7:58 PM
>> To: Quan, Evan <Evan.Quan@amd.com>; amd-gfx@lists.freedesktop.org
>> Cc: Deucher, Alexander <Alexander.Deucher@amd.com>; Koenig, Christian
>> <Christian.Koenig@amd.com>; Feng, Kenneth <Kenneth.Feng@amd.com>
>> Subject: Re: [PATCH V4 02/17] drm/amd/pm: do not expose power
>> implementation details to amdgpu_pm.c
>>
>>
>>
>> On 12/3/2021 8:35 AM, Evan Quan wrote:
>>> amdgpu_pm.c holds all the user sysfs/hwmon interfaces. It's another
>>> client of our power APIs. It's not proper to spike into power
>>> implementation details there.
>>>
>>> Signed-off-by: Evan Quan <evan.quan@amd.com>
>>> Change-Id: I397853ddb13eacfce841366de2a623535422df9a
>>> --
>>> v1->v2:
>>>     - drop unneeded "return;" in
>> amdgpu_dpm_get_current_power_state(Guchun)
>>> ---
>>>    drivers/gpu/drm/amd/pm/amdgpu_dpm.c       | 456
>> ++++++++++++++++++-
>>>    drivers/gpu/drm/amd/pm/amdgpu_pm.c        | 519 ++++++++--------------
>>>    drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h   | 160 +++----
>>>    drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c |   3 -
>>>    4 files changed, 707 insertions(+), 431 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
>> b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
>>> index 54abdf7080de..2c789eb5d066 100644
>>> --- a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
>>> +++ b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
>>> @@ -1453,7 +1453,9 @@ static void
>> amdgpu_dpm_change_power_state_locked(struct amdgpu_device *adev)
>>>    	if (equal)
>>>    		return;
>>>
>>> -	amdgpu_dpm_set_power_state(adev);
>>> +	if (adev->powerplay.pp_funcs->set_power_state)
>>> +		adev->powerplay.pp_funcs->set_power_state(adev-
>>> powerplay.pp_handle);
>>> +
>>>    	amdgpu_dpm_post_set_power_state(adev);
>>>
>>>    	adev->pm.dpm.current_active_crtcs = adev-
>>> pm.dpm.new_active_crtcs;
>>> @@ -1704,3 +1706,455 @@ int amdgpu_dpm_get_ecc_info(struct
>> amdgpu_device *adev,
>>>
>>>    	return smu_get_ecc_info(&adev->smu, umc_ecc);
>>>    }
>>> +
>>> +struct amd_vce_state *amdgpu_dpm_get_vce_clock_state(struct
>> amdgpu_device *adev,
>>> +						     uint32_t idx)
>>> +{
>>> +	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>> +
>>> +	if (!pp_funcs->get_vce_clock_state)
>>> +		return NULL;
>>> +
>>> +	return pp_funcs->get_vce_clock_state(adev->powerplay.pp_handle,
>>> +					     idx);
>>> +}
>>> +
>>> +void amdgpu_dpm_get_current_power_state(struct amdgpu_device
>> *adev,
>>> +					enum amd_pm_state_type *state)
>>> +{
>>> +	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>> +
>>> +	if (!pp_funcs->get_current_power_state) {
>>> +		*state = adev->pm.dpm.user_state;
>>> +		return;
>>> +	}
>>> +
>>> +	*state = pp_funcs->get_current_power_state(adev-
>>> powerplay.pp_handle);
>>> +	if (*state < POWER_STATE_TYPE_DEFAULT ||
>>> +	    *state > POWER_STATE_TYPE_INTERNAL_3DPERF)
>>> +		*state = adev->pm.dpm.user_state;
>>> +}
>>> +
>>> +void amdgpu_dpm_set_power_state(struct amdgpu_device *adev,
>>> +				enum amd_pm_state_type state)
>>> +{
>>> +	adev->pm.dpm.user_state = state;
>>> +
>>> +	if (adev->powerplay.pp_funcs->dispatch_tasks)
>>> +		amdgpu_dpm_dispatch_task(adev,
>> AMD_PP_TASK_ENABLE_USER_STATE, &state);
>>> +	else
>>> +		amdgpu_pm_compute_clocks(adev);
>>> +}
>>> +
>>> +enum amd_dpm_forced_level
>> amdgpu_dpm_get_performance_level(struct amdgpu_device *adev)
>>> +{
>>> +	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>> +	enum amd_dpm_forced_level level;
>>> +
>>> +	if (pp_funcs->get_performance_level)
>>> +		level = pp_funcs->get_performance_level(adev-
>>> powerplay.pp_handle);
>>> +	else
>>> +		level = adev->pm.dpm.forced_level;
>>> +
>>> +	return level;
>>> +}
>>> +
>>> +int amdgpu_dpm_force_performance_level(struct amdgpu_device
>> *adev,
>>> +				       enum amd_dpm_forced_level level)
>>> +{
>>> +	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>> +
>>> +	if (pp_funcs->force_performance_level) {
>>> +		if (adev->pm.dpm.thermal_active)
>>> +			return -EINVAL;
>>> +
>>> +		if (pp_funcs->force_performance_level(adev-
>>> powerplay.pp_handle,
>>> +						      level))
>>> +			return -EINVAL;
>>> +	}
>>> +
>>> +	adev->pm.dpm.forced_level = level;
>>> +
>>
>> If the function is not implemented, why change the force level and
>> return success?
> [Quan, Evan] Thanks! Will update that.
>>
>>> +	return 0;
>>> +}
>>> +
>>> +int amdgpu_dpm_get_pp_num_states(struct amdgpu_device *adev,
>>> +				 struct pp_states_info *states)
>>> +{
>>> +	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>> +
>>> +	if (!pp_funcs->get_pp_num_states)
>>> +		return -EOPNOTSUPP;
>>> +
>>> +	return pp_funcs->get_pp_num_states(adev->powerplay.pp_handle,
>> states);
>>> +}
>>> +
>>> +int amdgpu_dpm_dispatch_task(struct amdgpu_device *adev,
>>> +			      enum amd_pp_task task_id,
>>> +			      enum amd_pm_state_type *user_state)
>>> +{
>>> +	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>> +
>>> +	if (!pp_funcs->dispatch_tasks)
>>> +		return -EOPNOTSUPP;
>>> +
>>> +	return pp_funcs->dispatch_tasks(adev->powerplay.pp_handle,
>> task_id, user_state);
>>> +}
>>> +
>>> +int amdgpu_dpm_get_pp_table(struct amdgpu_device *adev, char
>> **table)
>>> +{
>>> +	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>> +
>>> +	if (!pp_funcs->get_pp_table)
>>> +		return 0;
>>> +
>>> +	return pp_funcs->get_pp_table(adev->powerplay.pp_handle, table);
>>> +}
>>> +
>>> +int amdgpu_dpm_set_fine_grain_clk_vol(struct amdgpu_device *adev,
>>> +				      uint32_t type,
>>> +				      long *input,
>>> +				      uint32_t size)
>>> +{
>>> +	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>> +
>>> +	if (!pp_funcs->set_fine_grain_clk_vol)
>>> +		return 0;
>>> +
>>
>> Better for this also to return -EOPNOTSUPP. There are a few other funcs
>> below also which returns 0, instead they should return EOPNOTSUPP. Let
>> the caller decide what to do when not supported instead of returning
>> 'fake success'.
> [Quan, Evan] Yeah, I know some(this and others mentioned below) of them seem with different/weird error return code. But unfortunately, that's how the original logic.
> We need to fix them in future. But for this patch series, it is not intended to bring any real logic change.

What I meant is let the API implementation be standalone. Let it return 
EOPNOTSUPP and f that is the error code, caller retains the existing logic.

Ex:
	if (!pp_funcs->set_fine_grain_clk_vol) logic in caller is replaced by
	if (amdgpu_dpm_set_fine_grain_clk_vol() == -EOPNOTSUPP)

and then it retains the existing logic for that error code.

Thanks,
Lijo

>>
>>> +	return pp_funcs->set_fine_grain_clk_vol(adev-
>>> powerplay.pp_handle,
>>> +						type,
>>> +						input,
>>> +						size);
>>> +}
>>> +
>>> +int amdgpu_dpm_odn_edit_dpm_table(struct amdgpu_device *adev,
>>> +				  uint32_t type,
>>> +				  long *input,
>>> +				  uint32_t size)
>>> +{
>>> +	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>> +
>>> +	if (!pp_funcs->odn_edit_dpm_table)
>>> +		return 0;
>>> +
>>> +	return pp_funcs->odn_edit_dpm_table(adev-
>>> powerplay.pp_handle,
>>> +					    type,
>>> +					    input,
>>> +					    size);
>>> +}
>>> +
>>> +int amdgpu_dpm_print_clock_levels(struct amdgpu_device *adev,
>>> +				  enum pp_clock_type type,
>>> +				  char *buf)
>>> +{
>>> +	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>> +
>>> +	if (!pp_funcs->print_clock_levels)
>>> +		return 0;
>>> +
>>> +	return pp_funcs->print_clock_levels(adev->powerplay.pp_handle,
>>> +					    type,
>>> +					    buf);
>>> +}
>>> +
>>> +int amdgpu_dpm_set_ppfeature_status(struct amdgpu_device *adev,
>>> +				    uint64_t ppfeature_masks)
>>> +{
>>> +	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>> +
>>> +	if (!pp_funcs->set_ppfeature_status)
>>> +		return 0;
>>> +
>>> +	return pp_funcs->set_ppfeature_status(adev-
>>> powerplay.pp_handle,
>>> +					      ppfeature_masks);
>>> +}
>>> +
>>> +int amdgpu_dpm_get_ppfeature_status(struct amdgpu_device *adev,
>> char *buf)
>>> +{
>>> +	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>> +
>>> +	if (!pp_funcs->get_ppfeature_status)
>>> +		return 0;
>>> +
>>> +	return pp_funcs->get_ppfeature_status(adev-
>>> powerplay.pp_handle,
>>> +					      buf);
>>> +}
>>> +
>>> +int amdgpu_dpm_force_clock_level(struct amdgpu_device *adev,
>>> +				 enum pp_clock_type type,
>>> +				 uint32_t mask)
>>> +{
>>> +	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>> +
>>> +	if (!pp_funcs->force_clock_level)
>>> +		return 0;
>>> +
>>> +	return pp_funcs->force_clock_level(adev->powerplay.pp_handle,
>>> +					   type,
>>> +					   mask);
>>> +}
>>> +
>>> +int amdgpu_dpm_get_sclk_od(struct amdgpu_device *adev)
>>> +{
>>> +	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>> +
>>> +	if (!pp_funcs->get_sclk_od)
>>> +		return 0;
>>> +
>>> +	return pp_funcs->get_sclk_od(adev->powerplay.pp_handle);
>>> +}
>>> +
>>> +int amdgpu_dpm_set_sclk_od(struct amdgpu_device *adev, uint32_t
>> value)
>>> +{
>>> +	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>> +
>>> +	if (!pp_funcs->set_sclk_od)
>>> +		return -EOPNOTSUPP;
>>> +
>>> +	pp_funcs->set_sclk_od(adev->powerplay.pp_handle, value);
>>> +
>>> +	if (amdgpu_dpm_dispatch_task(adev,
>>> +				     AMD_PP_TASK_READJUST_POWER_STATE,
>>> +				     NULL) == -EOPNOTSUPP) {
>>> +		adev->pm.dpm.current_ps = adev->pm.dpm.boot_ps;
>>> +		amdgpu_pm_compute_clocks(adev);
>>> +	}
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +int amdgpu_dpm_get_mclk_od(struct amdgpu_device *adev)
>>> +{
>>> +	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>> +
>>> +	if (!pp_funcs->get_mclk_od)
>>> +		return 0;
>>> +
>>> +	return pp_funcs->get_mclk_od(adev->powerplay.pp_handle);
>>> +}
>>> +
>>> +int amdgpu_dpm_set_mclk_od(struct amdgpu_device *adev, uint32_t
>> value)
>>> +{
>>> +	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>> +
>>> +	if (!pp_funcs->set_mclk_od)
>>> +		return -EOPNOTSUPP;
>>> +
>>> +	pp_funcs->set_mclk_od(adev->powerplay.pp_handle, value);
>>> +
>>> +	if (amdgpu_dpm_dispatch_task(adev,
>>> +				     AMD_PP_TASK_READJUST_POWER_STATE,
>>> +				     NULL) == -EOPNOTSUPP) {
>>> +		adev->pm.dpm.current_ps = adev->pm.dpm.boot_ps;
>>> +		amdgpu_pm_compute_clocks(adev);
>>> +	}
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +int amdgpu_dpm_get_power_profile_mode(struct amdgpu_device
>> *adev,
>>> +				      char *buf)
>>> +{
>>> +	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>> +
>>> +	if (!pp_funcs->get_power_profile_mode)
>>> +		return -EOPNOTSUPP;
>>> +
>>> +	return pp_funcs->get_power_profile_mode(adev-
>>> powerplay.pp_handle,
>>> +						buf);
>>> +}
>>> +
>>> +int amdgpu_dpm_set_power_profile_mode(struct amdgpu_device
>> *adev,
>>> +				      long *input, uint32_t size)
>>> +{
>>> +	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>> +
>>> +	if (!pp_funcs->set_power_profile_mode)
>>> +		return 0;
>>> +
>>> +	return pp_funcs->set_power_profile_mode(adev-
>>> powerplay.pp_handle,
>>> +						input,
>>> +						size);
>>> +}
>>> +
>>> +int amdgpu_dpm_get_gpu_metrics(struct amdgpu_device *adev, void
>> **table)
>>> +{
>>> +	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>> +
>>> +	if (!pp_funcs->get_gpu_metrics)
>>> +		return 0;
>>> +
>>> +	return pp_funcs->get_gpu_metrics(adev->powerplay.pp_handle,
>> table);
>>> +}
>>> +
>>> +int amdgpu_dpm_get_fan_control_mode(struct amdgpu_device *adev,
>>> +				    uint32_t *fan_mode)
>>> +{
>>> +	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>> +
>>> +	if (!pp_funcs->get_fan_control_mode)
>>> +		return -EOPNOTSUPP;
>>> +
>>> +	*fan_mode = pp_funcs->get_fan_control_mode(adev-
>>> powerplay.pp_handle);
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +int amdgpu_dpm_set_fan_speed_pwm(struct amdgpu_device *adev,
>>> +				 uint32_t speed)
>>> +{
>>> +	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>> +
>>> +	if (!pp_funcs->set_fan_speed_pwm)
>>> +		return -EINVAL;
>>
>> To be consistent, use EOPNOTSUPP when the function is not implemented.
>> The return of EINVAL from actual function call shouldn't be mixed with this.
>>
>>> +
>>> +	return pp_funcs->set_fan_speed_pwm(adev-
>>> powerplay.pp_handle, speed);
>>> +}
>>> +
>>> +int amdgpu_dpm_get_fan_speed_pwm(struct amdgpu_device *adev,
>>> +				 uint32_t *speed)
>>> +{
>>> +	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>> +
>>> +	if (!pp_funcs->get_fan_speed_pwm)
>>> +		return -EINVAL;
>>> +
>>> +	return pp_funcs->get_fan_speed_pwm(adev-
>>> powerplay.pp_handle, speed);
>>> +}
>>> +
>>> +int amdgpu_dpm_get_fan_speed_rpm(struct amdgpu_device *adev,
>>> +				 uint32_t *speed)
>>> +{
>>> +	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>> +
>>> +	if (!pp_funcs->get_fan_speed_rpm)
>>> +		return -EINVAL;
>>> +
>>> +	return pp_funcs->get_fan_speed_rpm(adev->powerplay.pp_handle,
>> speed);
>>> +}
>>> +
>>> +int amdgpu_dpm_set_fan_speed_rpm(struct amdgpu_device *adev,
>>> +				 uint32_t speed)
>>> +{
>>> +	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>> +
>>> +	if (!pp_funcs->set_fan_speed_rpm)
>>> +		return -EINVAL;
>>> +
>>> +	return pp_funcs->set_fan_speed_rpm(adev->powerplay.pp_handle,
>> speed);
>>> +}
>>> +
>>> +int amdgpu_dpm_set_fan_control_mode(struct amdgpu_device *adev,
>>> +				    uint32_t mode)
>>> +{
>>> +	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>> +
>>> +	if (!pp_funcs->set_fan_control_mode)
>>> +		return -EOPNOTSUPP;
>>> +
>>> +	pp_funcs->set_fan_control_mode(adev->powerplay.pp_handle,
>> mode);
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +int amdgpu_dpm_get_power_limit(struct amdgpu_device *adev,
>>> +			       uint32_t *limit,
>>> +			       enum pp_power_limit_level pp_limit_level,
>>> +			       enum pp_power_type power_type)
>>> +{
>>> +	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>> +
>>> +	if (!pp_funcs->get_power_limit)
>>> +		return -ENODATA;
>>> +
>>
>> Again, this is mixing API error code based on caller's usage. In
>> standalone implementatoin, this should also just return EOPNOTSUPP.
>> hwmon API implementation can decide what to return when there is no API
>> support.
>>
>>> +	return pp_funcs->get_power_limit(adev->powerplay.pp_handle,
>>> +					 limit,
>>> +					 pp_limit_level,
>>> +					 power_type);
>>> +}
>>> +
>>> +int amdgpu_dpm_set_power_limit(struct amdgpu_device *adev,
>>> +			       uint32_t limit)
>>> +{
>>> +	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>> +
>>> +	if (!pp_funcs->set_power_limit)
>>> +		return -EINVAL;
>>> +
>>> +	return pp_funcs->set_power_limit(adev->powerplay.pp_handle,
>> limit);
>>> +}
>>> +
>>> +int amdgpu_dpm_is_cclk_dpm_supported(struct amdgpu_device *adev)
>>> +{
>>> +	if (!is_support_sw_smu(adev))
>>> +		return false;
>>> +
>>> +	return is_support_cclk_dpm(adev);
>>> +}
>>> +
>>> +int amdgpu_dpm_debugfs_print_current_performance_level(struct
>> amdgpu_device *adev,
>>> +						       struct seq_file *m)
>>> +{
>>> +	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>> +
>>> +	if (!pp_funcs->debugfs_print_current_performance_level)
>>> +		return -EOPNOTSUPP;
>>> +
>>> +	pp_funcs->debugfs_print_current_performance_level(adev-
>>> powerplay.pp_handle,
>>> +							  m);
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +int amdgpu_dpm_get_smu_prv_buf_details(struct amdgpu_device
>> *adev,
>>> +				       void **addr,
>>> +				       size_t *size)
>>> +{
>>> +	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>> +
>>> +	if (!pp_funcs->get_smu_prv_buf_details)
>>> +		return -ENOSYS;
>>> +
>>> +	return pp_funcs->get_smu_prv_buf_details(adev-
>>> powerplay.pp_handle,
>>> +						 addr,
>>> +						 size);
>>> +}
>>> +
>>> +int amdgpu_dpm_is_overdrive_supported(struct amdgpu_device *adev)
>>> +{
>>> +	struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle;
>>> +
>>> +	if ((is_support_sw_smu(adev) && adev->smu.od_enabled) ||
>>> +	    (is_support_sw_smu(adev) && adev->smu.is_apu) ||
>>> +		(!is_support_sw_smu(adev) && hwmgr->od_enabled))
>>> +		return true;
>>> +
>>> +	return false;
>>> +}
>>> +
>>> +int amdgpu_dpm_set_pp_table(struct amdgpu_device *adev,
>>> +			    const char *buf,
>>> +			    size_t size)
>>> +{
>>> +	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>> +
>>> +	if (!pp_funcs->set_pp_table)
>>> +		return -EOPNOTSUPP;
>>> +
>>> +	return pp_funcs->set_pp_table(adev->powerplay.pp_handle,
>>> +				      buf,
>>> +				      size);
>>> +}
>>> +
>>> +int amdgpu_dpm_get_num_cpu_cores(struct amdgpu_device *adev)
>>> +{
>>> +	return adev->smu.cpu_core_num;
>>> +}
>>> +
>>> +void amdgpu_dpm_stb_debug_fs_init(struct amdgpu_device *adev)
>>> +{
>>> +	if (!is_support_sw_smu(adev))
>>> +		return;
>>> +
>>> +	amdgpu_smu_stb_debug_fs_init(adev);
>>> +}
>>> diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
>> b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
>>> index 082539c70fd4..3382d30b5d90 100644
>>> --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
>>> +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
>>> @@ -34,7 +34,6 @@
>>>    #include <linux/nospec.h>
>>>    #include <linux/pm_runtime.h>
>>>    #include <asm/processor.h>
>>> -#include "hwmgr.h"
>>>
>>>    static const struct cg_flag_name clocks[] = {
>>>    	{AMD_CG_SUPPORT_GFX_FGCG, "Graphics Fine Grain Clock
>> Gating"},
>>> @@ -132,7 +131,6 @@ static ssize_t
>> amdgpu_get_power_dpm_state(struct device *dev,
>>>    {
>>>    	struct drm_device *ddev = dev_get_drvdata(dev);
>>>    	struct amdgpu_device *adev = drm_to_adev(ddev);
>>> -	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>>    	enum amd_pm_state_type pm;
>>>    	int ret;
>>>
>>> @@ -147,11 +145,7 @@ static ssize_t
>> amdgpu_get_power_dpm_state(struct device *dev,
>>>    		return ret;
>>>    	}
>>>
>>> -	if (pp_funcs->get_current_power_state) {
>>> -		pm = amdgpu_dpm_get_current_power_state(adev);
>>> -	} else {
>>> -		pm = adev->pm.dpm.user_state;
>>> -	}
>>> +	amdgpu_dpm_get_current_power_state(adev, &pm);
>>>
>>>    	pm_runtime_mark_last_busy(ddev->dev);
>>>    	pm_runtime_put_autosuspend(ddev->dev);
>>> @@ -191,19 +185,8 @@ static ssize_t
>> amdgpu_set_power_dpm_state(struct device *dev,
>>>    		return ret;
>>>    	}
>>>
>>> -	if (is_support_sw_smu(adev)) {
>>> -		mutex_lock(&adev->pm.mutex);
>>> -		adev->pm.dpm.user_state = state;
>>> -		mutex_unlock(&adev->pm.mutex);
>>
>> Here the code just sets the state and exits. However, when moved to
>> refactored function, it is calling pm_compute_clocks.
> [Quan, Evan] Thanks! Will fix this.
> 
> BR
> Evan
>>
>>> -	} else if (adev->powerplay.pp_funcs->dispatch_tasks) {
>>> -		amdgpu_dpm_dispatch_task(adev,
>> AMD_PP_TASK_ENABLE_USER_STATE, &state);
>>> -	} else {
>>> -		mutex_lock(&adev->pm.mutex);
>>> -		adev->pm.dpm.user_state = state;
>>> -		mutex_unlock(&adev->pm.mutex);
>>> +	amdgpu_dpm_set_power_state(adev, state);
>>>
>>> -		amdgpu_pm_compute_clocks(adev);
>>> -	}
>>>    	pm_runtime_mark_last_busy(ddev->dev);
>>>    	pm_runtime_put_autosuspend(ddev->dev);
>>>
>>> @@ -290,10 +273,7 @@ static ssize_t
>> amdgpu_get_power_dpm_force_performance_level(struct device *dev,
>>>    		return ret;
>>>    	}
>>>
>>> -	if (adev->powerplay.pp_funcs->get_performance_level)
>>> -		level = amdgpu_dpm_get_performance_level(adev);
>>> -	else
>>> -		level = adev->pm.dpm.forced_level;
>>> +	level = amdgpu_dpm_get_performance_level(adev);
>>>
>>>    	pm_runtime_mark_last_busy(ddev->dev);
>>>    	pm_runtime_put_autosuspend(ddev->dev);
>>> @@ -318,7 +298,6 @@ static ssize_t
>> amdgpu_set_power_dpm_force_performance_level(struct device *dev,
>>>    {
>>>    	struct drm_device *ddev = dev_get_drvdata(dev);
>>>    	struct amdgpu_device *adev = drm_to_adev(ddev);
>>> -	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>>    	enum amd_dpm_forced_level level;
>>>    	enum amd_dpm_forced_level current_level;
>>>    	int ret = 0;
>>> @@ -358,11 +337,7 @@ static ssize_t
>> amdgpu_set_power_dpm_force_performance_level(struct device *dev,
>>>    		return ret;
>>>    	}
>>>
>>> -	if (pp_funcs->get_performance_level)
>>> -		current_level =
>> amdgpu_dpm_get_performance_level(adev);
>>> -	else
>>> -		current_level = adev->pm.dpm.forced_level;
>>> -
>>> +	current_level = amdgpu_dpm_get_performance_level(adev);
>>>    	if (current_level == level) {
>>>    		pm_runtime_mark_last_busy(ddev->dev);
>>>    		pm_runtime_put_autosuspend(ddev->dev);
>>> @@ -390,25 +365,12 @@ static ssize_t
>> amdgpu_set_power_dpm_force_performance_level(struct device *dev,
>>>    		return -EINVAL;
>>>    	}
>>>
>>> -	if (pp_funcs->force_performance_level) {
>>> -		mutex_lock(&adev->pm.mutex);
>>> -		if (adev->pm.dpm.thermal_active) {
>>> -			mutex_unlock(&adev->pm.mutex);
>>> -			pm_runtime_mark_last_busy(ddev->dev);
>>> -			pm_runtime_put_autosuspend(ddev->dev);
>>> -			return -EINVAL;
>>> -		}
>>> -		ret = amdgpu_dpm_force_performance_level(adev, level);
>>> -		if (ret) {
>>> -			mutex_unlock(&adev->pm.mutex);
>>> -			pm_runtime_mark_last_busy(ddev->dev);
>>> -			pm_runtime_put_autosuspend(ddev->dev);
>>> -			return -EINVAL;
>>> -		} else {
>>> -			adev->pm.dpm.forced_level = level;
>>> -		}
>>> -		mutex_unlock(&adev->pm.mutex);
>>> +	if (amdgpu_dpm_force_performance_level(adev, level)) {
>>> +		pm_runtime_mark_last_busy(ddev->dev);
>>> +		pm_runtime_put_autosuspend(ddev->dev);
>>> +		return -EINVAL;
>>>    	}
>>> +
>>>    	pm_runtime_mark_last_busy(ddev->dev);
>>>    	pm_runtime_put_autosuspend(ddev->dev);
>>>
>>> @@ -421,7 +383,6 @@ static ssize_t amdgpu_get_pp_num_states(struct
>> device *dev,
>>>    {
>>>    	struct drm_device *ddev = dev_get_drvdata(dev);
>>>    	struct amdgpu_device *adev = drm_to_adev(ddev);
>>> -	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>>    	struct pp_states_info data;
>>>    	uint32_t i;
>>>    	int buf_len, ret;
>>> @@ -437,11 +398,8 @@ static ssize_t amdgpu_get_pp_num_states(struct
>> device *dev,
>>>    		return ret;
>>>    	}
>>>
>>> -	if (pp_funcs->get_pp_num_states) {
>>> -		amdgpu_dpm_get_pp_num_states(adev, &data);
>>> -	} else {
>>> +	if (amdgpu_dpm_get_pp_num_states(adev, &data))
>>>    		memset(&data, 0, sizeof(data));
>>> -	}
>>>
>>>    	pm_runtime_mark_last_busy(ddev->dev);
>>>    	pm_runtime_put_autosuspend(ddev->dev);
>>> @@ -463,7 +421,6 @@ static ssize_t amdgpu_get_pp_cur_state(struct
>> device *dev,
>>>    {
>>>    	struct drm_device *ddev = dev_get_drvdata(dev);
>>>    	struct amdgpu_device *adev = drm_to_adev(ddev);
>>> -	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>>    	struct pp_states_info data = {0};
>>>    	enum amd_pm_state_type pm = 0;
>>>    	int i = 0, ret = 0;
>>> @@ -479,15 +436,16 @@ static ssize_t amdgpu_get_pp_cur_state(struct
>> device *dev,
>>>    		return ret;
>>>    	}
>>>
>>> -	if (pp_funcs->get_current_power_state
>>> -		 && pp_funcs->get_pp_num_states) {
>>> -		pm = amdgpu_dpm_get_current_power_state(adev);
>>> -		amdgpu_dpm_get_pp_num_states(adev, &data);
>>> -	}
>>> +	amdgpu_dpm_get_current_power_state(adev, &pm);
>>> +
>>> +	ret = amdgpu_dpm_get_pp_num_states(adev, &data);
>>>
>>>    	pm_runtime_mark_last_busy(ddev->dev);
>>>    	pm_runtime_put_autosuspend(ddev->dev);
>>>
>>> +	if (ret)
>>> +		return ret;
>>> +
>>>    	for (i = 0; i < data.nums; i++) {
>>>    		if (pm == data.states[i])
>>>    			break;
>>> @@ -525,6 +483,7 @@ static ssize_t amdgpu_set_pp_force_state(struct
>> device *dev,
>>>    	struct drm_device *ddev = dev_get_drvdata(dev);
>>>    	struct amdgpu_device *adev = drm_to_adev(ddev);
>>>    	enum amd_pm_state_type state = 0;
>>> +	struct pp_states_info data;
>>>    	unsigned long idx;
>>>    	int ret;
>>>
>>> @@ -533,41 +492,49 @@ static ssize_t amdgpu_set_pp_force_state(struct
>> device *dev,
>>>    	if (adev->in_suspend && !adev->in_runpm)
>>>    		return -EPERM;
>>>
>>> -	if (strlen(buf) == 1)
>>> -		adev->pp_force_state_enabled = false;
>>> -	else if (is_support_sw_smu(adev))
>>> -		adev->pp_force_state_enabled = false;
>>> -	else if (adev->powerplay.pp_funcs->dispatch_tasks &&
>>> -			adev->powerplay.pp_funcs->get_pp_num_states) {
>>> -		struct pp_states_info data;
>>> -
>>> -		ret = kstrtoul(buf, 0, &idx);
>>> -		if (ret || idx >= ARRAY_SIZE(data.states))
>>> -			return -EINVAL;
>>> +	adev->pp_force_state_enabled = false;
>>>
>>> -		idx = array_index_nospec(idx, ARRAY_SIZE(data.states));
>>> +	if (strlen(buf) == 1)
>>> +		return count;
>>>
>>> -		amdgpu_dpm_get_pp_num_states(adev, &data);
>>> -		state = data.states[idx];
>>> +	ret = kstrtoul(buf, 0, &idx);
>>> +	if (ret || idx >= ARRAY_SIZE(data.states))
>>> +		return -EINVAL;
>>>
>>> -		ret = pm_runtime_get_sync(ddev->dev);
>>> -		if (ret < 0) {
>>> -			pm_runtime_put_autosuspend(ddev->dev);
>>> -			return ret;
>>> -		}
>>> +	idx = array_index_nospec(idx, ARRAY_SIZE(data.states));
>>>
>>> -		/* only set user selected power states */
>>> -		if (state != POWER_STATE_TYPE_INTERNAL_BOOT &&
>>> -		    state != POWER_STATE_TYPE_DEFAULT) {
>>> -			amdgpu_dpm_dispatch_task(adev,
>>> -
>> 	AMD_PP_TASK_ENABLE_USER_STATE, &state);
>>> -			adev->pp_force_state_enabled = true;
>>> -		}
>>> -		pm_runtime_mark_last_busy(ddev->dev);
>>> +	ret = pm_runtime_get_sync(ddev->dev);
>>> +	if (ret < 0) {
>>>    		pm_runtime_put_autosuspend(ddev->dev);
>>> +		return ret;
>>> +	}
>>> +
>>> +	ret = amdgpu_dpm_get_pp_num_states(adev, &data);
>>> +	if (ret)
>>> +		goto err_out;
>>> +
>>> +	state = data.states[idx];
>>> +
>>> +	/* only set user selected power states */
>>> +	if (state != POWER_STATE_TYPE_INTERNAL_BOOT &&
>>> +	    state != POWER_STATE_TYPE_DEFAULT) {
>>> +		ret = amdgpu_dpm_dispatch_task(adev,
>>> +				AMD_PP_TASK_ENABLE_USER_STATE,
>> &state);
>>> +		if (ret)
>>> +			goto err_out;
>>> +
>>> +		adev->pp_force_state_enabled = true;
>>>    	}
>>>
>>> +	pm_runtime_mark_last_busy(ddev->dev);
>>> +	pm_runtime_put_autosuspend(ddev->dev);
>>> +
>>>    	return count;
>>> +
>>> +err_out:
>>> +	pm_runtime_mark_last_busy(ddev->dev);
>>> +	pm_runtime_put_autosuspend(ddev->dev);
>>> +	return ret;
>>>    }
>>>
>>>    /**
>>> @@ -601,17 +568,13 @@ static ssize_t amdgpu_get_pp_table(struct device
>> *dev,
>>>    		return ret;
>>>    	}
>>>
>>> -	if (adev->powerplay.pp_funcs->get_pp_table) {
>>> -		size = amdgpu_dpm_get_pp_table(adev, &table);
>>> -		pm_runtime_mark_last_busy(ddev->dev);
>>> -		pm_runtime_put_autosuspend(ddev->dev);
>>> -		if (size < 0)
>>> -			return size;
>>> -	} else {
>>> -		pm_runtime_mark_last_busy(ddev->dev);
>>> -		pm_runtime_put_autosuspend(ddev->dev);
>>> -		return 0;
>>> -	}
>>> +	size = amdgpu_dpm_get_pp_table(adev, &table);
>>> +
>>> +	pm_runtime_mark_last_busy(ddev->dev);
>>> +	pm_runtime_put_autosuspend(ddev->dev);
>>> +
>>> +	if (size <= 0)
>>> +		return size;
>>>
>>>    	if (size >= PAGE_SIZE)
>>>    		size = PAGE_SIZE - 1;
>>> @@ -642,15 +605,13 @@ static ssize_t amdgpu_set_pp_table(struct device
>> *dev,
>>>    	}
>>>
>>>    	ret = amdgpu_dpm_set_pp_table(adev, buf, count);
>>> -	if (ret) {
>>> -		pm_runtime_mark_last_busy(ddev->dev);
>>> -		pm_runtime_put_autosuspend(ddev->dev);
>>> -		return ret;
>>> -	}
>>>
>>>    	pm_runtime_mark_last_busy(ddev->dev);
>>>    	pm_runtime_put_autosuspend(ddev->dev);
>>>
>>> +	if (ret)
>>> +		return ret;
>>> +
>>>    	return count;
>>>    }
>>>
>>> @@ -866,46 +827,32 @@ static ssize_t
>> amdgpu_set_pp_od_clk_voltage(struct device *dev,
>>>    		return ret;
>>>    	}
>>>
>>> -	if (adev->powerplay.pp_funcs->set_fine_grain_clk_vol) {
>>> -		ret = amdgpu_dpm_set_fine_grain_clk_vol(adev, type,
>>> -							parameter,
>>> -							parameter_size);
>>> -		if (ret) {
>>> -			pm_runtime_mark_last_busy(ddev->dev);
>>> -			pm_runtime_put_autosuspend(ddev->dev);
>>> -			return -EINVAL;
>>> -		}
>>> -	}
>>> +	if (amdgpu_dpm_set_fine_grain_clk_vol(adev,
>>> +					      type,
>>> +					      parameter,
>>> +					      parameter_size))
>>> +		goto err_out;
>>>
>>> -	if (adev->powerplay.pp_funcs->odn_edit_dpm_table) {
>>> -		ret = amdgpu_dpm_odn_edit_dpm_table(adev, type,
>>> -						    parameter,
>> parameter_size);
>>> -		if (ret) {
>>> -			pm_runtime_mark_last_busy(ddev->dev);
>>> -			pm_runtime_put_autosuspend(ddev->dev);
>>> -			return -EINVAL;
>>> -		}
>>> -	}
>>> +	if (amdgpu_dpm_odn_edit_dpm_table(adev, type,
>>> +					  parameter, parameter_size))
>>> +		goto err_out;
>>>
>>
>> This is one example of returning 'fake success' effect. If the function
>> is not implemented it proceeds. There is no need to proceed if there is
>> no support.
>>
>>
>> Thanks,
>> Lijo
>>
>>>    	if (type == PP_OD_COMMIT_DPM_TABLE) {
>>> -		if (adev->powerplay.pp_funcs->dispatch_tasks) {
>>> -			amdgpu_dpm_dispatch_task(adev,
>>> -
>> AMD_PP_TASK_READJUST_POWER_STATE,
>>> -						 NULL);
>>> -			pm_runtime_mark_last_busy(ddev->dev);
>>> -			pm_runtime_put_autosuspend(ddev->dev);
>>> -			return count;
>>> -		} else {
>>> -			pm_runtime_mark_last_busy(ddev->dev);
>>> -			pm_runtime_put_autosuspend(ddev->dev);
>>> -			return -EINVAL;
>>> -		}
>>> +		if (amdgpu_dpm_dispatch_task(adev,
>>> +
>> AMD_PP_TASK_READJUST_POWER_STATE,
>>> +					     NULL))
>>> +			goto err_out;
>>>    	}
>>>
>>>    	pm_runtime_mark_last_busy(ddev->dev);
>>>    	pm_runtime_put_autosuspend(ddev->dev);
>>>
>>>    	return count;
>>> +
>>> +err_out:
>>> +	pm_runtime_mark_last_busy(ddev->dev);
>>> +	pm_runtime_put_autosuspend(ddev->dev);
>>> +	return -EINVAL;
>>>    }
>>>
>>>    static ssize_t amdgpu_get_pp_od_clk_voltage(struct device *dev,
>>> @@ -928,8 +875,8 @@ static ssize_t
>> amdgpu_get_pp_od_clk_voltage(struct device *dev,
>>>    		return ret;
>>>    	}
>>>
>>> -	if (adev->powerplay.pp_funcs->print_clock_levels) {
>>> -		size = amdgpu_dpm_print_clock_levels(adev, OD_SCLK, buf);
>>> +	size = amdgpu_dpm_print_clock_levels(adev, OD_SCLK, buf);
>>> +	if (size > 0) {
>>>    		size += amdgpu_dpm_print_clock_levels(adev, OD_MCLK,
>> buf+size);
>>>    		size += amdgpu_dpm_print_clock_levels(adev,
>> OD_VDDC_CURVE, buf+size);
>>>    		size += amdgpu_dpm_print_clock_levels(adev,
>> OD_VDDGFX_OFFSET, buf+size);
>>> @@ -985,17 +932,14 @@ static ssize_t amdgpu_set_pp_features(struct
>> device *dev,
>>>    		return ret;
>>>    	}
>>>
>>> -	if (adev->powerplay.pp_funcs->set_ppfeature_status) {
>>> -		ret = amdgpu_dpm_set_ppfeature_status(adev,
>> featuremask);
>>> -		if (ret) {
>>> -			pm_runtime_mark_last_busy(ddev->dev);
>>> -			pm_runtime_put_autosuspend(ddev->dev);
>>> -			return -EINVAL;
>>> -		}
>>> -	}
>>> +	ret = amdgpu_dpm_set_ppfeature_status(adev, featuremask);
>>> +
>>>    	pm_runtime_mark_last_busy(ddev->dev);
>>>    	pm_runtime_put_autosuspend(ddev->dev);
>>>
>>> +	if (ret)
>>> +		return -EINVAL;
>>> +
>>>    	return count;
>>>    }
>>>
>>> @@ -1019,9 +963,8 @@ static ssize_t amdgpu_get_pp_features(struct
>> device *dev,
>>>    		return ret;
>>>    	}
>>>
>>> -	if (adev->powerplay.pp_funcs->get_ppfeature_status)
>>> -		size = amdgpu_dpm_get_ppfeature_status(adev, buf);
>>> -	else
>>> +	size = amdgpu_dpm_get_ppfeature_status(adev, buf);
>>> +	if (size <= 0)
>>>    		size = sysfs_emit(buf, "\n");
>>>
>>>    	pm_runtime_mark_last_busy(ddev->dev);
>>> @@ -1080,9 +1023,8 @@ static ssize_t amdgpu_get_pp_dpm_clock(struct
>> device *dev,
>>>    		return ret;
>>>    	}
>>>
>>> -	if (adev->powerplay.pp_funcs->print_clock_levels)
>>> -		size = amdgpu_dpm_print_clock_levels(adev, type, buf);
>>> -	else
>>> +	size = amdgpu_dpm_print_clock_levels(adev, type, buf);
>>> +	if (size <= 0)
>>>    		size = sysfs_emit(buf, "\n");
>>>
>>>    	pm_runtime_mark_last_busy(ddev->dev);
>>> @@ -1151,10 +1093,7 @@ static ssize_t amdgpu_set_pp_dpm_clock(struct
>> device *dev,
>>>    		return ret;
>>>    	}
>>>
>>> -	if (adev->powerplay.pp_funcs->force_clock_level)
>>> -		ret = amdgpu_dpm_force_clock_level(adev, type, mask);
>>> -	else
>>> -		ret = 0;
>>> +	ret = amdgpu_dpm_force_clock_level(adev, type, mask);
>>>
>>>    	pm_runtime_mark_last_busy(ddev->dev);
>>>    	pm_runtime_put_autosuspend(ddev->dev);
>>> @@ -1305,10 +1244,7 @@ static ssize_t amdgpu_get_pp_sclk_od(struct
>> device *dev,
>>>    		return ret;
>>>    	}
>>>
>>> -	if (is_support_sw_smu(adev))
>>> -		value = 0;
>>> -	else if (adev->powerplay.pp_funcs->get_sclk_od)
>>> -		value = amdgpu_dpm_get_sclk_od(adev);
>>> +	value = amdgpu_dpm_get_sclk_od(adev);
>>>
>>>    	pm_runtime_mark_last_busy(ddev->dev);
>>>    	pm_runtime_put_autosuspend(ddev->dev);
>>> @@ -1342,19 +1278,7 @@ static ssize_t amdgpu_set_pp_sclk_od(struct
>> device *dev,
>>>    		return ret;
>>>    	}
>>>
>>> -	if (is_support_sw_smu(adev)) {
>>> -		value = 0;
>>> -	} else {
>>> -		if (adev->powerplay.pp_funcs->set_sclk_od)
>>> -			amdgpu_dpm_set_sclk_od(adev, (uint32_t)value);
>>> -
>>> -		if (adev->powerplay.pp_funcs->dispatch_tasks) {
>>> -			amdgpu_dpm_dispatch_task(adev,
>> AMD_PP_TASK_READJUST_POWER_STATE, NULL);
>>> -		} else {
>>> -			adev->pm.dpm.current_ps = adev-
>>> pm.dpm.boot_ps;
>>> -			amdgpu_pm_compute_clocks(adev);
>>> -		}
>>> -	}
>>> +	amdgpu_dpm_set_sclk_od(adev, (uint32_t)value);
>>>
>>>    	pm_runtime_mark_last_busy(ddev->dev);
>>>    	pm_runtime_put_autosuspend(ddev->dev);
>>> @@ -1382,10 +1306,7 @@ static ssize_t amdgpu_get_pp_mclk_od(struct
>> device *dev,
>>>    		return ret;
>>>    	}
>>>
>>> -	if (is_support_sw_smu(adev))
>>> -		value = 0;
>>> -	else if (adev->powerplay.pp_funcs->get_mclk_od)
>>> -		value = amdgpu_dpm_get_mclk_od(adev);
>>> +	value = amdgpu_dpm_get_mclk_od(adev);
>>>
>>>    	pm_runtime_mark_last_busy(ddev->dev);
>>>    	pm_runtime_put_autosuspend(ddev->dev);
>>> @@ -1419,19 +1340,7 @@ static ssize_t amdgpu_set_pp_mclk_od(struct
>> device *dev,
>>>    		return ret;
>>>    	}
>>>
>>> -	if (is_support_sw_smu(adev)) {
>>> -		value = 0;
>>> -	} else {
>>> -		if (adev->powerplay.pp_funcs->set_mclk_od)
>>> -			amdgpu_dpm_set_mclk_od(adev, (uint32_t)value);
>>> -
>>> -		if (adev->powerplay.pp_funcs->dispatch_tasks) {
>>> -			amdgpu_dpm_dispatch_task(adev,
>> AMD_PP_TASK_READJUST_POWER_STATE, NULL);
>>> -		} else {
>>> -			adev->pm.dpm.current_ps = adev-
>>> pm.dpm.boot_ps;
>>> -			amdgpu_pm_compute_clocks(adev);
>>> -		}
>>> -	}
>>> +	amdgpu_dpm_set_mclk_od(adev, (uint32_t)value);
>>>
>>>    	pm_runtime_mark_last_busy(ddev->dev);
>>>    	pm_runtime_put_autosuspend(ddev->dev);
>>> @@ -1479,9 +1388,8 @@ static ssize_t
>> amdgpu_get_pp_power_profile_mode(struct device *dev,
>>>    		return ret;
>>>    	}
>>>
>>> -	if (adev->powerplay.pp_funcs->get_power_profile_mode)
>>> -		size = amdgpu_dpm_get_power_profile_mode(adev, buf);
>>> -	else
>>> +	size = amdgpu_dpm_get_power_profile_mode(adev, buf);
>>> +	if (size <= 0)
>>>    		size = sysfs_emit(buf, "\n");
>>>
>>>    	pm_runtime_mark_last_busy(ddev->dev);
>>> @@ -1545,8 +1453,7 @@ static ssize_t
>> amdgpu_set_pp_power_profile_mode(struct device *dev,
>>>    		return ret;
>>>    	}
>>>
>>> -	if (adev->powerplay.pp_funcs->set_power_profile_mode)
>>> -		ret = amdgpu_dpm_set_power_profile_mode(adev,
>> parameter, parameter_size);
>>> +	ret = amdgpu_dpm_set_power_profile_mode(adev, parameter,
>> parameter_size);
>>>
>>>    	pm_runtime_mark_last_busy(ddev->dev);
>>>    	pm_runtime_put_autosuspend(ddev->dev);
>>> @@ -1812,9 +1719,7 @@ static ssize_t amdgpu_get_gpu_metrics(struct
>> device *dev,
>>>    		return ret;
>>>    	}
>>>
>>> -	if (adev->powerplay.pp_funcs->get_gpu_metrics)
>>> -		size = amdgpu_dpm_get_gpu_metrics(adev, &gpu_metrics);
>>> -
>>> +	size = amdgpu_dpm_get_gpu_metrics(adev, &gpu_metrics);
>>>    	if (size <= 0)
>>>    		goto out;
>>>
>>> @@ -2053,7 +1958,6 @@ static int default_attr_update(struct
>> amdgpu_device *adev, struct amdgpu_device_
>>>    {
>>>    	struct device_attribute *dev_attr = &attr->dev_attr;
>>>    	const char *attr_name = dev_attr->attr.name;
>>> -	struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle;
>>>    	enum amd_asic_type asic_type = adev->asic_type;
>>>
>>>    	if (!(attr->flags & mask)) {
>>> @@ -2076,9 +1980,7 @@ static int default_attr_update(struct
>> amdgpu_device *adev, struct amdgpu_device_
>>>    			*states = ATTR_STATE_UNSUPPORTED;
>>>    	} else if (DEVICE_ATTR_IS(pp_od_clk_voltage)) {
>>>    		*states = ATTR_STATE_UNSUPPORTED;
>>> -		if ((is_support_sw_smu(adev) && adev->smu.od_enabled)
>> ||
>>> -		    (is_support_sw_smu(adev) && adev->smu.is_apu) ||
>>> -			(!is_support_sw_smu(adev) && hwmgr-
>>> od_enabled))
>>> +		if (amdgpu_dpm_is_overdrive_supported(adev))
>>>    			*states = ATTR_STATE_SUPPORTED;
>>>    	} else if (DEVICE_ATTR_IS(mem_busy_percent)) {
>>>    		if (adev->flags & AMD_IS_APU || asic_type == CHIP_VEGA10)
>>> @@ -2105,8 +2007,7 @@ static int default_attr_update(struct
>> amdgpu_device *adev, struct amdgpu_device_
>>>    		if (!(asic_type == CHIP_VANGOGH || asic_type ==
>> CHIP_SIENNA_CICHLID))
>>>    			*states = ATTR_STATE_UNSUPPORTED;
>>>    	} else if (DEVICE_ATTR_IS(pp_power_profile_mode)) {
>>> -		if (!adev->powerplay.pp_funcs->get_power_profile_mode
>> ||
>>> -		    amdgpu_dpm_get_power_profile_mode(adev, NULL) == -
>> EOPNOTSUPP)
>>> +		if (amdgpu_dpm_get_power_profile_mode(adev, NULL) ==
>> -EOPNOTSUPP)
>>>    			*states = ATTR_STATE_UNSUPPORTED;
>>>    	}
>>>
>>> @@ -2389,17 +2290,14 @@ static ssize_t
>> amdgpu_hwmon_get_pwm1_enable(struct device *dev,
>>>    		return ret;
>>>    	}
>>>
>>> -	if (!adev->powerplay.pp_funcs->get_fan_control_mode) {
>>> -		pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
>>> -		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
>>> -		return -EINVAL;
>>> -	}
>>> -
>>> -	pwm_mode = amdgpu_dpm_get_fan_control_mode(adev);
>>> +	ret = amdgpu_dpm_get_fan_control_mode(adev, &pwm_mode);
>>>
>>>    	pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
>>>    	pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
>>>
>>> +	if (ret)
>>> +		return -EINVAL;
>>> +
>>>    	return sysfs_emit(buf, "%u\n", pwm_mode);
>>>    }
>>>
>>> @@ -2427,17 +2325,14 @@ static ssize_t
>> amdgpu_hwmon_set_pwm1_enable(struct device *dev,
>>>    		return ret;
>>>    	}
>>>
>>> -	if (!adev->powerplay.pp_funcs->set_fan_control_mode) {
>>> -		pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
>>> -		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
>>> -		return -EINVAL;
>>> -	}
>>> -
>>> -	amdgpu_dpm_set_fan_control_mode(adev, value);
>>> +	ret = amdgpu_dpm_set_fan_control_mode(adev, value);
>>>
>>>    	pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
>>>    	pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
>>>
>>> +	if (ret)
>>> +		return -EINVAL;
>>> +
>>>    	return count;
>>>    }
>>>
>>> @@ -2469,32 +2364,29 @@ static ssize_t
>> amdgpu_hwmon_set_pwm1(struct device *dev,
>>>    	if (adev->in_suspend && !adev->in_runpm)
>>>    		return -EPERM;
>>>
>>> +	err = kstrtou32(buf, 10, &value);
>>> +	if (err)
>>> +		return err;
>>> +
>>>    	err = pm_runtime_get_sync(adev_to_drm(adev)->dev);
>>>    	if (err < 0) {
>>>    		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
>>>    		return err;
>>>    	}
>>>
>>> -	pwm_mode = amdgpu_dpm_get_fan_control_mode(adev);
>>> +	err = amdgpu_dpm_get_fan_control_mode(adev, &pwm_mode);
>>> +	if (err)
>>> +		goto out;
>>> +
>>>    	if (pwm_mode != AMD_FAN_CTRL_MANUAL) {
>>>    		pr_info("manual fan speed control should be enabled
>> first\n");
>>> -		pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
>>> -		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
>>> -		return -EINVAL;
>>> +		err = -EINVAL;
>>> +		goto out;
>>>    	}
>>>
>>> -	err = kstrtou32(buf, 10, &value);
>>> -	if (err) {
>>> -		pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
>>> -		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
>>> -		return err;
>>> -	}
>>> -
>>> -	if (adev->powerplay.pp_funcs->set_fan_speed_pwm)
>>> -		err = amdgpu_dpm_set_fan_speed_pwm(adev, value);
>>> -	else
>>> -		err = -EINVAL;
>>> +	err = amdgpu_dpm_set_fan_speed_pwm(adev, value);
>>>
>>> +out:
>>>    	pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
>>>    	pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
>>>
>>> @@ -2523,10 +2415,7 @@ static ssize_t
>> amdgpu_hwmon_get_pwm1(struct device *dev,
>>>    		return err;
>>>    	}
>>>
>>> -	if (adev->powerplay.pp_funcs->get_fan_speed_pwm)
>>> -		err = amdgpu_dpm_get_fan_speed_pwm(adev, &speed);
>>> -	else
>>> -		err = -EINVAL;
>>> +	err = amdgpu_dpm_get_fan_speed_pwm(adev, &speed);
>>>
>>>    	pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
>>>    	pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
>>> @@ -2556,10 +2445,7 @@ static ssize_t
>> amdgpu_hwmon_get_fan1_input(struct device *dev,
>>>    		return err;
>>>    	}
>>>
>>> -	if (adev->powerplay.pp_funcs->get_fan_speed_rpm)
>>> -		err = amdgpu_dpm_get_fan_speed_rpm(adev, &speed);
>>> -	else
>>> -		err = -EINVAL;
>>> +	err = amdgpu_dpm_get_fan_speed_rpm(adev, &speed);
>>>
>>>    	pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
>>>    	pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
>>> @@ -2653,10 +2539,7 @@ static ssize_t
>> amdgpu_hwmon_get_fan1_target(struct device *dev,
>>>    		return err;
>>>    	}
>>>
>>> -	if (adev->powerplay.pp_funcs->get_fan_speed_rpm)
>>> -		err = amdgpu_dpm_get_fan_speed_rpm(adev, &rpm);
>>> -	else
>>> -		err = -EINVAL;
>>> +	err = amdgpu_dpm_get_fan_speed_rpm(adev, &rpm);
>>>
>>>    	pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
>>>    	pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
>>> @@ -2681,32 +2564,28 @@ static ssize_t
>> amdgpu_hwmon_set_fan1_target(struct device *dev,
>>>    	if (adev->in_suspend && !adev->in_runpm)
>>>    		return -EPERM;
>>>
>>> +	err = kstrtou32(buf, 10, &value);
>>> +	if (err)
>>> +		return err;
>>> +
>>>    	err = pm_runtime_get_sync(adev_to_drm(adev)->dev);
>>>    	if (err < 0) {
>>>    		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
>>>    		return err;
>>>    	}
>>>
>>> -	pwm_mode = amdgpu_dpm_get_fan_control_mode(adev);
>>> +	err = amdgpu_dpm_get_fan_control_mode(adev, &pwm_mode);
>>> +	if (err)
>>> +		goto out;
>>>
>>>    	if (pwm_mode != AMD_FAN_CTRL_MANUAL) {
>>> -		pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
>>> -		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
>>> -		return -ENODATA;
>>> -	}
>>> -
>>> -	err = kstrtou32(buf, 10, &value);
>>> -	if (err) {
>>> -		pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
>>> -		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
>>> -		return err;
>>> +		err = -ENODATA;
>>> +		goto out;
>>>    	}
>>>
>>> -	if (adev->powerplay.pp_funcs->set_fan_speed_rpm)
>>> -		err = amdgpu_dpm_set_fan_speed_rpm(adev, value);
>>> -	else
>>> -		err = -EINVAL;
>>> +	err = amdgpu_dpm_set_fan_speed_rpm(adev, value);
>>>
>>> +out:
>>>    	pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
>>>    	pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
>>>
>>> @@ -2735,17 +2614,14 @@ static ssize_t
>> amdgpu_hwmon_get_fan1_enable(struct device *dev,
>>>    		return ret;
>>>    	}
>>>
>>> -	if (!adev->powerplay.pp_funcs->get_fan_control_mode) {
>>> -		pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
>>> -		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
>>> -		return -EINVAL;
>>> -	}
>>> -
>>> -	pwm_mode = amdgpu_dpm_get_fan_control_mode(adev);
>>> +	ret = amdgpu_dpm_get_fan_control_mode(adev, &pwm_mode);
>>>
>>>    	pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
>>>    	pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
>>>
>>> +	if (ret)
>>> +		return -EINVAL;
>>> +
>>>    	return sysfs_emit(buf, "%i\n", pwm_mode ==
>> AMD_FAN_CTRL_AUTO ? 0 : 1);
>>>    }
>>>
>>> @@ -2781,16 +2657,14 @@ static ssize_t
>> amdgpu_hwmon_set_fan1_enable(struct device *dev,
>>>    		return err;
>>>    	}
>>>
>>> -	if (!adev->powerplay.pp_funcs->set_fan_control_mode) {
>>> -		pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
>>> -		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
>>> -		return -EINVAL;
>>> -	}
>>> -	amdgpu_dpm_set_fan_control_mode(adev, pwm_mode);
>>> +	err = amdgpu_dpm_set_fan_control_mode(adev, pwm_mode);
>>>
>>>    	pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
>>>    	pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
>>>
>>> +	if (err)
>>> +		return -EINVAL;
>>> +
>>>    	return count;
>>>    }
>>>
>>> @@ -2926,7 +2800,6 @@ static ssize_t
>> amdgpu_hwmon_show_power_cap_generic(struct device *dev,
>>>    					enum pp_power_limit_level
>> pp_limit_level)
>>>    {
>>>    	struct amdgpu_device *adev = dev_get_drvdata(dev);
>>> -	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>>    	enum pp_power_type power_type = to_sensor_dev_attr(attr)-
>>> index;
>>>    	uint32_t limit;
>>>    	ssize_t size;
>>> @@ -2937,16 +2810,13 @@ static ssize_t
>> amdgpu_hwmon_show_power_cap_generic(struct device *dev,
>>>    	if (adev->in_suspend && !adev->in_runpm)
>>>    		return -EPERM;
>>>
>>> -	if ( !(pp_funcs && pp_funcs->get_power_limit))
>>> -		return -ENODATA;
>>> -
>>>    	r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
>>>    	if (r < 0) {
>>>    		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
>>>    		return r;
>>>    	}
>>>
>>> -	r = pp_funcs->get_power_limit(adev->powerplay.pp_handle, &limit,
>>> +	r = amdgpu_dpm_get_power_limit(adev, &limit,
>>>    				      pp_limit_level, power_type);
>>>
>>>    	if (!r)
>>> @@ -3001,7 +2871,6 @@ static ssize_t
>> amdgpu_hwmon_set_power_cap(struct device *dev,
>>>    		size_t count)
>>>    {
>>>    	struct amdgpu_device *adev = dev_get_drvdata(dev);
>>> -	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>>    	int limit_type = to_sensor_dev_attr(attr)->index;
>>>    	int err;
>>>    	u32 value;
>>> @@ -3027,10 +2896,7 @@ static ssize_t
>> amdgpu_hwmon_set_power_cap(struct device *dev,
>>>    		return err;
>>>    	}
>>>
>>> -	if (pp_funcs && pp_funcs->set_power_limit)
>>> -		err = pp_funcs->set_power_limit(adev-
>>> powerplay.pp_handle, value);
>>> -	else
>>> -		err = -EINVAL;
>>> +	err = amdgpu_dpm_set_power_limit(adev, value);
>>>
>>>    	pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
>>>    	pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
>>> @@ -3303,6 +3169,7 @@ static umode_t hwmon_attributes_visible(struct
>> kobject *kobj,
>>>    	struct device *dev = kobj_to_dev(kobj);
>>>    	struct amdgpu_device *adev = dev_get_drvdata(dev);
>>>    	umode_t effective_mode = attr->mode;
>>> +	uint32_t speed = 0;
>>>
>>>    	/* under multi-vf mode, the hwmon attributes are all not supported
>> */
>>>    	if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev))
>>> @@ -3367,20 +3234,18 @@ static umode_t
>> hwmon_attributes_visible(struct kobject *kobj,
>>>    	     attr == &sensor_dev_attr_fan1_enable.dev_attr.attr))
>>>    		return 0;
>>>
>>> -	if (!is_support_sw_smu(adev)) {
>>> -		/* mask fan attributes if we have no bindings for this asic to
>> expose */
>>> -		if ((!adev->powerplay.pp_funcs->get_fan_speed_pwm &&
>>> -		     attr == &sensor_dev_attr_pwm1.dev_attr.attr) || /* can't
>> query fan */
>>> -		    (!adev->powerplay.pp_funcs->get_fan_control_mode &&
>>> -		     attr == &sensor_dev_attr_pwm1_enable.dev_attr.attr))
>> /* can't query state */
>>> -			effective_mode &= ~S_IRUGO;
>>> +	/* mask fan attributes if we have no bindings for this asic to expose
>> */
>>> +	if (((amdgpu_dpm_get_fan_speed_pwm(adev, &speed) == -EINVAL)
>> &&
>>> +	      attr == &sensor_dev_attr_pwm1.dev_attr.attr) || /* can't query
>> fan */
>>> +	    ((amdgpu_dpm_get_fan_control_mode(adev, &speed) == -
>> EOPNOTSUPP) &&
>>> +	     attr == &sensor_dev_attr_pwm1_enable.dev_attr.attr)) /* can't
>> query state */
>>> +		effective_mode &= ~S_IRUGO;
>>>
>>> -		if ((!adev->powerplay.pp_funcs->set_fan_speed_pwm &&
>>> -		     attr == &sensor_dev_attr_pwm1.dev_attr.attr) || /* can't
>> manage fan */
>>> -		    (!adev->powerplay.pp_funcs->set_fan_control_mode &&
>>> -		     attr == &sensor_dev_attr_pwm1_enable.dev_attr.attr))
>> /* can't manage state */
>>> -			effective_mode &= ~S_IWUSR;
>>> -	}
>>> +	if (((amdgpu_dpm_set_fan_speed_pwm(adev, speed) == -EINVAL)
>> &&
>>> +	      attr == &sensor_dev_attr_pwm1.dev_attr.attr) || /* can't
>> manage fan */
>>> +	      ((amdgpu_dpm_set_fan_control_mode(adev, speed) == -
>> EOPNOTSUPP) &&
>>> +	      attr == &sensor_dev_attr_pwm1_enable.dev_attr.attr)) /* can't
>> manage state */
>>> +		effective_mode &= ~S_IWUSR;
>>>
>>>    	if (((adev->family == AMDGPU_FAMILY_SI) ||
>>>    		 ((adev->flags & AMD_IS_APU) &&
>>> @@ -3397,22 +3262,20 @@ static umode_t
>> hwmon_attributes_visible(struct kobject *kobj,
>>>    	    (attr == &sensor_dev_attr_power1_average.dev_attr.attr))
>>>    		return 0;
>>>
>>> -	if (!is_support_sw_smu(adev)) {
>>> -		/* hide max/min values if we can't both query and manage
>> the fan */
>>> -		if ((!adev->powerplay.pp_funcs->set_fan_speed_pwm &&
>>> -		     !adev->powerplay.pp_funcs->get_fan_speed_pwm) &&
>>> -		     (!adev->powerplay.pp_funcs->set_fan_speed_rpm &&
>>> -		     !adev->powerplay.pp_funcs->get_fan_speed_rpm) &&
>>> -		    (attr == &sensor_dev_attr_pwm1_max.dev_attr.attr ||
>>> -		     attr == &sensor_dev_attr_pwm1_min.dev_attr.attr))
>>> -			return 0;
>>> +	/* hide max/min values if we can't both query and manage the fan */
>>> +	if (((amdgpu_dpm_set_fan_speed_pwm(adev, speed) == -EINVAL)
>> &&
>>> +	      (amdgpu_dpm_get_fan_speed_pwm(adev, &speed) == -EINVAL)
>> &&
>>> +	      (amdgpu_dpm_set_fan_speed_rpm(adev, speed) == -EINVAL)
>> &&
>>> +	      (amdgpu_dpm_get_fan_speed_rpm(adev, &speed) == -EINVAL))
>> &&
>>> +	    (attr == &sensor_dev_attr_pwm1_max.dev_attr.attr ||
>>> +	     attr == &sensor_dev_attr_pwm1_min.dev_attr.attr))
>>> +		return 0;
>>>
>>> -		if ((!adev->powerplay.pp_funcs->set_fan_speed_rpm &&
>>> -		     !adev->powerplay.pp_funcs->get_fan_speed_rpm) &&
>>> -		    (attr == &sensor_dev_attr_fan1_max.dev_attr.attr ||
>>> -		     attr == &sensor_dev_attr_fan1_min.dev_attr.attr))
>>> -			return 0;
>>> -	}
>>> +	if ((amdgpu_dpm_set_fan_speed_rpm(adev, speed) == -EINVAL)
>> &&
>>> +	     (amdgpu_dpm_get_fan_speed_rpm(adev, &speed) == -EINVAL)
>> &&
>>> +	     (attr == &sensor_dev_attr_fan1_max.dev_attr.attr ||
>>> +	     attr == &sensor_dev_attr_fan1_min.dev_attr.attr))
>>> +		return 0;
>>>
>>>    	if ((adev->family == AMDGPU_FAMILY_SI ||	/* not implemented
>> yet */
>>>    	     adev->family == AMDGPU_FAMILY_KV) &&	/* not implemented
>> yet */
>>> @@ -3542,14 +3405,15 @@ static void
>> amdgpu_debugfs_prints_cpu_info(struct seq_file *m,
>>>    	uint16_t *p_val;
>>>    	uint32_t size;
>>>    	int i;
>>> +	uint32_t num_cpu_cores =
>> amdgpu_dpm_get_num_cpu_cores(adev);
>>>
>>> -	if (is_support_cclk_dpm(adev)) {
>>> -		p_val = kcalloc(adev->smu.cpu_core_num, sizeof(uint16_t),
>>> +	if (amdgpu_dpm_is_cclk_dpm_supported(adev)) {
>>> +		p_val = kcalloc(num_cpu_cores, sizeof(uint16_t),
>>>    				GFP_KERNEL);
>>>
>>>    		if (!amdgpu_dpm_read_sensor(adev,
>> AMDGPU_PP_SENSOR_CPU_CLK,
>>>    					    (void *)p_val, &size)) {
>>> -			for (i = 0; i < adev->smu.cpu_core_num; i++)
>>> +			for (i = 0; i < num_cpu_cores; i++)
>>>    				seq_printf(m, "\t%u MHz (CPU%d)\n",
>>>    					   *(p_val + i), i);
>>>    		}
>>> @@ -3677,27 +3541,11 @@ static int
>> amdgpu_debugfs_pm_info_show(struct seq_file *m, void *unused)
>>>    		return r;
>>>    	}
>>>
>>> -	if (!adev->pm.dpm_enabled) {
>>> -		seq_printf(m, "dpm not enabled\n");
>>> -		pm_runtime_mark_last_busy(dev->dev);
>>> -		pm_runtime_put_autosuspend(dev->dev);
>>> -		return 0;
>>> -	}
>>> -
>>> -	if (!is_support_sw_smu(adev) &&
>>> -	    adev->powerplay.pp_funcs-
>>> debugfs_print_current_performance_level) {
>>> -		mutex_lock(&adev->pm.mutex);
>>> -		if (adev->powerplay.pp_funcs-
>>> debugfs_print_current_performance_level)
>>> -			adev->powerplay.pp_funcs-
>>> debugfs_print_current_performance_level(adev, m);
>>> -		else
>>> -			seq_printf(m, "Debugfs support not implemented
>> for this asic\n");
>>> -		mutex_unlock(&adev->pm.mutex);
>>> -		r = 0;
>>> -	} else {
>>> +	if (amdgpu_dpm_debugfs_print_current_performance_level(adev,
>> m)) {
>>>    		r = amdgpu_debugfs_pm_info_pp(m, adev);
>>> +		if (r)
>>> +			goto out;
>>>    	}
>>> -	if (r)
>>> -		goto out;
>>>
>>>    	amdgpu_device_ip_get_clockgating_state(adev, &flags);
>>>
>>> @@ -3723,21 +3571,18 @@ static ssize_t
>> amdgpu_pm_prv_buffer_read(struct file *f, char __user *buf,
>>>    					 size_t size, loff_t *pos)
>>>    {
>>>    	struct amdgpu_device *adev = file_inode(f)->i_private;
>>> -	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
>>> -	void *pp_handle = adev->powerplay.pp_handle;
>>>    	size_t smu_prv_buf_size;
>>>    	void *smu_prv_buf;
>>> +	int ret = 0;
>>>
>>>    	if (amdgpu_in_reset(adev))
>>>    		return -EPERM;
>>>    	if (adev->in_suspend && !adev->in_runpm)
>>>    		return -EPERM;
>>>
>>> -	if (pp_funcs && pp_funcs->get_smu_prv_buf_details)
>>> -		pp_funcs->get_smu_prv_buf_details(pp_handle,
>> &smu_prv_buf,
>>> -						  &smu_prv_buf_size);
>>> -	else
>>> -		return -ENOSYS;
>>> +	ret = amdgpu_dpm_get_smu_prv_buf_details(adev, &smu_prv_buf,
>> &smu_prv_buf_size);
>>> +	if (ret)
>>> +		return ret;
>>>
>>>    	if (!smu_prv_buf || !smu_prv_buf_size)
>>>    		return -EINVAL;
>>> @@ -3770,6 +3615,6 @@ void amdgpu_debugfs_pm_init(struct
>> amdgpu_device *adev)
>>>
>> &amdgpu_debugfs_pm_prv_buffer_fops,
>>>    					 adev->pm.smu_prv_buffer_size);
>>>
>>> -	amdgpu_smu_stb_debug_fs_init(adev);
>>> +	amdgpu_dpm_stb_debug_fs_init(adev);
>>>    #endif
>>>    }
>>> diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
>> b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
>>> index 7289d379a9fb..039c40b1d0cb 100644
>>> --- a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
>>> +++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
>>> @@ -262,9 +262,6 @@ enum amdgpu_pcie_gen {
>>>    #define amdgpu_dpm_pre_set_power_state(adev) \
>>>    		((adev)->powerplay.pp_funcs-
>>> pre_set_power_state((adev)->powerplay.pp_handle))
>>>
>>> -#define amdgpu_dpm_set_power_state(adev) \
>>> -		((adev)->powerplay.pp_funcs->set_power_state((adev)-
>>> powerplay.pp_handle))
>>> -
>>>    #define amdgpu_dpm_post_set_power_state(adev) \
>>>    		((adev)->powerplay.pp_funcs-
>>> post_set_power_state((adev)->powerplay.pp_handle))
>>>
>>> @@ -280,100 +277,13 @@ enum amdgpu_pcie_gen {
>>>    #define amdgpu_dpm_enable_bapm(adev, e) \
>>>    		((adev)->powerplay.pp_funcs->enable_bapm((adev)-
>>> powerplay.pp_handle, (e)))
>>>
>>> -#define amdgpu_dpm_set_fan_control_mode(adev, m) \
>>> -		((adev)->powerplay.pp_funcs-
>>> set_fan_control_mode((adev)->powerplay.pp_handle, (m)))
>>> -
>>> -#define amdgpu_dpm_get_fan_control_mode(adev) \
>>> -		((adev)->powerplay.pp_funcs-
>>> get_fan_control_mode((adev)->powerplay.pp_handle))
>>> -
>>> -#define amdgpu_dpm_set_fan_speed_pwm(adev, s) \
>>> -		((adev)->powerplay.pp_funcs-
>>> set_fan_speed_pwm((adev)->powerplay.pp_handle, (s)))
>>> -
>>> -#define amdgpu_dpm_get_fan_speed_pwm(adev, s) \
>>> -		((adev)->powerplay.pp_funcs-
>>> get_fan_speed_pwm((adev)->powerplay.pp_handle, (s)))
>>> -
>>> -#define amdgpu_dpm_get_fan_speed_rpm(adev, s) \
>>> -		((adev)->powerplay.pp_funcs-
>>> get_fan_speed_rpm)((adev)->powerplay.pp_handle, (s))
>>> -
>>> -#define amdgpu_dpm_set_fan_speed_rpm(adev, s) \
>>> -		((adev)->powerplay.pp_funcs-
>>> set_fan_speed_rpm)((adev)->powerplay.pp_handle, (s))
>>> -
>>> -#define amdgpu_dpm_force_performance_level(adev, l) \
>>> -		((adev)->powerplay.pp_funcs-
>>> force_performance_level((adev)->powerplay.pp_handle, (l)))
>>> -
>>> -#define amdgpu_dpm_get_current_power_state(adev) \
>>> -		((adev)->powerplay.pp_funcs-
>>> get_current_power_state((adev)->powerplay.pp_handle))
>>> -
>>> -#define amdgpu_dpm_get_pp_num_states(adev, data) \
>>> -		((adev)->powerplay.pp_funcs->get_pp_num_states((adev)-
>>> powerplay.pp_handle, data))
>>> -
>>> -#define amdgpu_dpm_get_pp_table(adev, table) \
>>> -		((adev)->powerplay.pp_funcs->get_pp_table((adev)-
>>> powerplay.pp_handle, table))
>>> -
>>> -#define amdgpu_dpm_set_pp_table(adev, buf, size) \
>>> -		((adev)->powerplay.pp_funcs->set_pp_table((adev)-
>>> powerplay.pp_handle, buf, size))
>>> -
>>> -#define amdgpu_dpm_print_clock_levels(adev, type, buf) \
>>> -		((adev)->powerplay.pp_funcs->print_clock_levels((adev)-
>>> powerplay.pp_handle, type, buf))
>>> -
>>> -#define amdgpu_dpm_force_clock_level(adev, type, level) \
>>> -		((adev)->powerplay.pp_funcs->force_clock_level((adev)-
>>> powerplay.pp_handle, type, level))
>>> -
>>> -#define amdgpu_dpm_get_sclk_od(adev) \
>>> -		((adev)->powerplay.pp_funcs->get_sclk_od((adev)-
>>> powerplay.pp_handle))
>>> -
>>> -#define amdgpu_dpm_set_sclk_od(adev, value) \
>>> -		((adev)->powerplay.pp_funcs->set_sclk_od((adev)-
>>> powerplay.pp_handle, value))
>>> -
>>> -#define amdgpu_dpm_get_mclk_od(adev) \
>>> -		((adev)->powerplay.pp_funcs->get_mclk_od((adev)-
>>> powerplay.pp_handle))
>>> -
>>> -#define amdgpu_dpm_set_mclk_od(adev, value) \
>>> -		((adev)->powerplay.pp_funcs->set_mclk_od((adev)-
>>> powerplay.pp_handle, value))
>>> -
>>> -#define amdgpu_dpm_dispatch_task(adev, task_id, user_state)
>> 	\
>>> -		((adev)->powerplay.pp_funcs->dispatch_tasks)((adev)-
>>> powerplay.pp_handle, (task_id), (user_state))
>>> -
>>>    #define amdgpu_dpm_check_state_equal(adev, cps, rps, equal) \
>>>    		((adev)->powerplay.pp_funcs->check_state_equal((adev)-
>>> powerplay.pp_handle, (cps), (rps), (equal)))
>>>
>>> -#define amdgpu_dpm_get_vce_clock_state(adev, i)
>> 		\
>>> -		((adev)->powerplay.pp_funcs->get_vce_clock_state((adev)-
>>> powerplay.pp_handle, (i)))
>>> -
>>> -#define amdgpu_dpm_get_performance_level(adev)
>> 		\
>>> -		((adev)->powerplay.pp_funcs-
>>> get_performance_level((adev)->powerplay.pp_handle))
>>> -
>>>    #define amdgpu_dpm_reset_power_profile_state(adev, request) \
>>>    		((adev)->powerplay.pp_funcs-
>>> reset_power_profile_state(\
>>>    			(adev)->powerplay.pp_handle, request))
>>>
>>> -#define amdgpu_dpm_get_power_profile_mode(adev, buf) \
>>> -		((adev)->powerplay.pp_funcs->get_power_profile_mode(\
>>> -			(adev)->powerplay.pp_handle, buf))
>>> -
>>> -#define amdgpu_dpm_set_power_profile_mode(adev, parameter, size)
>> \
>>> -		((adev)->powerplay.pp_funcs->set_power_profile_mode(\
>>> -			(adev)->powerplay.pp_handle, parameter, size))
>>> -
>>> -#define amdgpu_dpm_set_fine_grain_clk_vol(adev, type, parameter,
>> size) \
>>> -		((adev)->powerplay.pp_funcs->set_fine_grain_clk_vol(\
>>> -			(adev)->powerplay.pp_handle, type, parameter,
>> size))
>>> -
>>> -#define amdgpu_dpm_odn_edit_dpm_table(adev, type, parameter, size)
>> \
>>> -		((adev)->powerplay.pp_funcs->odn_edit_dpm_table(\
>>> -			(adev)->powerplay.pp_handle, type, parameter,
>> size))
>>> -
>>> -#define amdgpu_dpm_get_ppfeature_status(adev, buf) \
>>> -		((adev)->powerplay.pp_funcs->get_ppfeature_status(\
>>> -			(adev)->powerplay.pp_handle, (buf)))
>>> -
>>> -#define amdgpu_dpm_set_ppfeature_status(adev, ppfeatures) \
>>> -		((adev)->powerplay.pp_funcs->set_ppfeature_status(\
>>> -			(adev)->powerplay.pp_handle, (ppfeatures)))
>>> -
>>> -#define amdgpu_dpm_get_gpu_metrics(adev, table) \
>>> -		((adev)->powerplay.pp_funcs->get_gpu_metrics((adev)-
>>> powerplay.pp_handle, table))
>>> -
>>>    struct amdgpu_dpm {
>>>    	struct amdgpu_ps        *ps;
>>>    	/* number of valid power states */
>>> @@ -598,4 +508,74 @@ void amdgpu_dpm_gfx_state_change(struct
>> amdgpu_device *adev,
>>>    				 enum gfx_change_state state);
>>>    int amdgpu_dpm_get_ecc_info(struct amdgpu_device *adev,
>>>    			    void *umc_ecc);
>>> +struct amd_vce_state *amdgpu_dpm_get_vce_clock_state(struct
>> amdgpu_device *adev,
>>> +						     uint32_t idx);
>>> +void amdgpu_dpm_get_current_power_state(struct amdgpu_device
>> *adev, enum amd_pm_state_type *state);
>>> +void amdgpu_dpm_set_power_state(struct amdgpu_device *adev,
>>> +				enum amd_pm_state_type state);
>>> +enum amd_dpm_forced_level
>> amdgpu_dpm_get_performance_level(struct amdgpu_device *adev);
>>> +int amdgpu_dpm_force_performance_level(struct amdgpu_device
>> *adev,
>>> +				       enum amd_dpm_forced_level level);
>>> +int amdgpu_dpm_get_pp_num_states(struct amdgpu_device *adev,
>>> +				 struct pp_states_info *states);
>>> +int amdgpu_dpm_dispatch_task(struct amdgpu_device *adev,
>>> +			      enum amd_pp_task task_id,
>>> +			      enum amd_pm_state_type *user_state);
>>> +int amdgpu_dpm_get_pp_table(struct amdgpu_device *adev, char
>> **table);
>>> +int amdgpu_dpm_set_fine_grain_clk_vol(struct amdgpu_device *adev,
>>> +				      uint32_t type,
>>> +				      long *input,
>>> +				      uint32_t size);
>>> +int amdgpu_dpm_odn_edit_dpm_table(struct amdgpu_device *adev,
>>> +				  uint32_t type,
>>> +				  long *input,
>>> +				  uint32_t size);
>>> +int amdgpu_dpm_print_clock_levels(struct amdgpu_device *adev,
>>> +				  enum pp_clock_type type,
>>> +				  char *buf);
>>> +int amdgpu_dpm_set_ppfeature_status(struct amdgpu_device *adev,
>>> +				    uint64_t ppfeature_masks);
>>> +int amdgpu_dpm_get_ppfeature_status(struct amdgpu_device *adev,
>> char *buf);
>>> +int amdgpu_dpm_force_clock_level(struct amdgpu_device *adev,
>>> +				 enum pp_clock_type type,
>>> +				 uint32_t mask);
>>> +int amdgpu_dpm_get_sclk_od(struct amdgpu_device *adev);
>>> +int amdgpu_dpm_set_sclk_od(struct amdgpu_device *adev, uint32_t
>> value);
>>> +int amdgpu_dpm_get_mclk_od(struct amdgpu_device *adev);
>>> +int amdgpu_dpm_set_mclk_od(struct amdgpu_device *adev, uint32_t
>> value);
>>> +int amdgpu_dpm_get_power_profile_mode(struct amdgpu_device
>> *adev,
>>> +				      char *buf);
>>> +int amdgpu_dpm_set_power_profile_mode(struct amdgpu_device
>> *adev,
>>> +				      long *input, uint32_t size);
>>> +int amdgpu_dpm_get_gpu_metrics(struct amdgpu_device *adev, void
>> **table);
>>> +int amdgpu_dpm_get_fan_control_mode(struct amdgpu_device *adev,
>>> +				    uint32_t *fan_mode);
>>> +int amdgpu_dpm_set_fan_speed_pwm(struct amdgpu_device *adev,
>>> +				 uint32_t speed);
>>> +int amdgpu_dpm_get_fan_speed_pwm(struct amdgpu_device *adev,
>>> +				 uint32_t *speed);
>>> +int amdgpu_dpm_get_fan_speed_rpm(struct amdgpu_device *adev,
>>> +				 uint32_t *speed);
>>> +int amdgpu_dpm_set_fan_speed_rpm(struct amdgpu_device *adev,
>>> +				 uint32_t speed);
>>> +int amdgpu_dpm_set_fan_control_mode(struct amdgpu_device *adev,
>>> +				    uint32_t mode);
>>> +int amdgpu_dpm_get_power_limit(struct amdgpu_device *adev,
>>> +			       uint32_t *limit,
>>> +			       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);
>>> +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);
>>> +int amdgpu_dpm_get_smu_prv_buf_details(struct amdgpu_device
>> *adev,
>>> +				       void **addr,
>>> +				       size_t *size);
>>> +int amdgpu_dpm_is_overdrive_supported(struct amdgpu_device *adev);
>>> +int amdgpu_dpm_set_pp_table(struct amdgpu_device *adev,
>>> +			    const char *buf,
>>> +			    size_t size);
>>> +int amdgpu_dpm_get_num_cpu_cores(struct amdgpu_device *adev);
>>> +void amdgpu_dpm_stb_debug_fs_init(struct amdgpu_device *adev);
>>>    #endif
>>> diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
>> b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
>>> index d8cd7c8c4479..51358383f672 100644
>>> --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
>>> +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
>>> @@ -470,9 +470,6 @@ bool is_support_cclk_dpm(struct amdgpu_device
>> *adev)
>>>    {
>>>    	struct smu_context *smu = &adev->smu;
>>>
>>> -	if (!is_support_sw_smu(adev))
>>> -		return false;
>>> -
>>>    	if (!smu_feature_is_enabled(smu, SMU_FEATURE_CCLK_DPM_BIT))
>>>    		return false;
>>>
>>>

  reply	other threads:[~2021-12-10  5:53 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-03  3:05 [PATCH V4 01/17] drm/amd/pm: do not expose implementation details to other blocks out of power Evan Quan
2021-12-03  3:05 ` [PATCH V4 02/17] drm/amd/pm: do not expose power implementation details to amdgpu_pm.c Evan Quan
2021-12-09 11:57   ` Lazar, Lijo
2021-12-10  5:20     ` Quan, Evan
2021-12-10  5:53       ` Lazar, Lijo [this message]
2021-12-10 16:46         ` Quan, Evan
2021-12-03  3:05 ` [PATCH V4 03/17] drm/amd/pm: do not expose power implementation details to display Evan Quan
2021-12-09 12:05   ` Lazar, Lijo
2021-12-10  7:03     ` Quan, Evan
2021-12-03  3:05 ` [PATCH V4 04/17] drm/amd/pm: do not expose those APIs used internally only in amdgpu_dpm.c Evan Quan
2021-12-03  3:05 ` [PATCH V4 05/17] drm/amd/pm: do not expose those APIs used internally only in si_dpm.c Evan Quan
2021-12-09 12:08   ` Lazar, Lijo
2021-12-10  7:07     ` Quan, Evan
2021-12-03  3:05 ` [PATCH V4 06/17] drm/amd/pm: do not expose the API used internally only in kv_dpm.c Evan Quan
2021-12-03  3:05 ` [PATCH V4 07/17] drm/amd/pm: create a new holder for those APIs used only by legacy ASICs(si/kv) Evan Quan
2021-12-03  3:05 ` [PATCH V4 08/17] drm/amd/pm: move pp_force_state_enabled member to amdgpu_pm structure Evan Quan
2021-12-03  3:05 ` [PATCH V4 09/17] drm/amd/pm: optimize the amdgpu_pm_compute_clocks() implementations Evan Quan
2021-12-09 12:32   ` Lazar, Lijo
2021-12-10  8:46     ` Quan, Evan
2021-12-03  3:05 ` [PATCH V4 10/17] drm/amd/pm: move those code piece used by Stoney only to smu8_hwmgr.c Evan Quan
2021-12-03  3:05 ` [PATCH V4 11/17] drm/amd/pm: correct the usage for amdgpu_dpm_dispatch_task() Evan Quan
2021-12-09 12:37   ` Lazar, Lijo
2021-12-10  9:51     ` Quan, Evan
2021-12-03  3:05 ` [PATCH V4 12/17] drm/amd/pm: drop redundant or unused APIs and data structures Evan Quan
2021-12-03  3:05 ` [PATCH V4 13/17] drm/amd/pm: do not expose the smu_context structure used internally in power Evan Quan
2021-12-03  3:05 ` [PATCH V4 14/17] drm/amd/pm: relocate the power related headers Evan Quan
2021-12-09 12:40   ` Lazar, Lijo
2021-12-10  9:52     ` Quan, Evan
2021-12-03  3:05 ` [PATCH V4 15/17] drm/amd/pm: drop unnecessary gfxoff controls Evan Quan
2021-12-03  3:05 ` [PATCH V4 16/17] drm/amd/pm: revise the performance level setting APIs Evan Quan
2021-12-03  3:05 ` [PATCH V4 17/17] drm/amd/pm: unified lock protections in amdgpu_dpm.c Evan Quan
2021-12-06  6:51   ` Quan, Evan
2021-12-08  2:45   ` Quan, Evan
2022-03-31  2:28   ` Arthur Marsh
2022-03-31  3:16     ` Quan, Evan
2022-03-31  4:27       ` Arthur Marsh
2022-04-01  7:18         ` Quan, Evan
2022-04-01  8:49           ` Arthur Marsh
2022-04-01  8:56             ` Christian König
2022-04-01  9:19               ` Quan, Evan
2022-04-01 12:18                 ` Arthur Marsh
2022-04-02  1:31                   ` Quan, Evan
2022-04-08 12:24                     ` Quan, Evan
2022-04-08 13:47                       ` Arthur Marsh
2022-04-04 12:06     ` Regression: No signal when loading amdgpu, and system lockup (was: [PATCH V4 17/17] drm/amd/pm: unified lock protections in amdgpu_dpm.c) Paul Menzel
2022-04-04 12:06       ` Paul Menzel

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=c8fd7a7f-309d-74c5-baa1-c387a817dac2@amd.com \
    --to=lijo.lazar@amd.com \
    --cc=Alexander.Deucher@amd.com \
    --cc=Christian.Koenig@amd.com \
    --cc=Evan.Quan@amd.com \
    --cc=Kenneth.Feng@amd.com \
    --cc=amd-gfx@lists.freedesktop.org \
    /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.