summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvan Quan <evan.quan@amd.com>2021-11-22 11:05:22 +0800
committerAlex Deucher <alexander.deucher@amd.com>2022-01-14 17:51:14 -0500
commit79c65f3fcbb1288b84473d45e6d001820a971d54 (patch)
treec4ff9df5434597b2f9733f09c4ec9b2c3b1eafd5
parentbc143d8b8387ff0a22e4ef8e2375e63aa24bc311 (diff)
downloadlinux-79c65f3fcbb1288b84473d45e6d001820a971d54.tar.gz
linux-79c65f3fcbb1288b84473d45e6d001820a971d54.tar.bz2
linux-79c65f3fcbb1288b84473d45e6d001820a971d54.zip
drm/amd/pm: do not expose power implementation details to amdgpu_pm.c
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> Reviewed-by: Lijo Lazar <lijo.lazar@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/pm/amdgpu_dpm.c461
-rw-r--r--drivers/gpu/drm/amd/pm/amdgpu_pm.c519
-rw-r--r--drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h160
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c3
4 files changed, 712 insertions, 431 deletions
diff --git a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
index 73f3d2912f13..494cf1459d0f 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,460 @@ 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 (is_support_sw_smu(adev))
+ return;
+
+ if (amdgpu_dpm_dispatch_task(adev,
+ AMD_PP_TASK_ENABLE_USER_STATE,
+ &state) == -EOPNOTSUPP)
+ 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;
+ }
+
+ 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;
+
+ 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 (is_support_sw_smu(adev))
+ return 0;
+
+ if (pp_funcs->set_sclk_od)
+ 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 (is_support_sw_smu(adev))
+ return 0;
+
+ if (pp_funcs->set_mclk_od)
+ 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;
+
+ 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;
+
+ 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 e2cae97f4ff1..b16bb67b93f1 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);
- } 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;
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)
@@ -2106,8 +2008,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;
}
@@ -2396,17 +2297,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);
}
@@ -2434,17 +2332,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;
}
@@ -2476,32 +2371,29 @@ static ssize_t amdgpu_hwmon_set_pwm1(struct device *dev,
if (adev->in_suspend && !adev->in_runpm)