mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 13:11:40 +00:00
drm/amdgpu: export amd_powerplay_func to amdgpu and other ip block
Update amdgpu to deal with the new powerplay module properly. v2: squash in fixes v3: squash in Rex's power state reporting fix Signed-off-by: Rex Zhu <Rex.Zhu@amd.com> Acked-by: Jammy Zhou <Jammy.Zhou@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
ba5c2a87b0
commit
1b5708ffb1
@ -2264,20 +2264,54 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring)
|
||||
#define amdgpu_dpm_set_power_state(adev) (adev)->pm.funcs->set_power_state((adev))
|
||||
#define amdgpu_dpm_post_set_power_state(adev) (adev)->pm.funcs->post_set_power_state((adev))
|
||||
#define amdgpu_dpm_display_configuration_changed(adev) (adev)->pm.funcs->display_configuration_changed((adev))
|
||||
#define amdgpu_dpm_get_sclk(adev, l) (adev)->pm.funcs->get_sclk((adev), (l))
|
||||
#define amdgpu_dpm_get_mclk(adev, l) (adev)->pm.funcs->get_mclk((adev), (l))
|
||||
#define amdgpu_dpm_print_power_state(adev, ps) (adev)->pm.funcs->print_power_state((adev), (ps))
|
||||
#define amdgpu_dpm_debugfs_print_current_performance_level(adev, m) (adev)->pm.funcs->debugfs_print_current_performance_level((adev), (m))
|
||||
#define amdgpu_dpm_force_performance_level(adev, l) (adev)->pm.funcs->force_performance_level((adev), (l))
|
||||
#define amdgpu_dpm_vblank_too_short(adev) (adev)->pm.funcs->vblank_too_short((adev))
|
||||
#define amdgpu_dpm_powergate_uvd(adev, g) (adev)->pm.funcs->powergate_uvd((adev), (g))
|
||||
#define amdgpu_dpm_powergate_vce(adev, g) (adev)->pm.funcs->powergate_vce((adev), (g))
|
||||
#define amdgpu_dpm_enable_bapm(adev, e) (adev)->pm.funcs->enable_bapm((adev), (e))
|
||||
#define amdgpu_dpm_set_fan_control_mode(adev, m) (adev)->pm.funcs->set_fan_control_mode((adev), (m))
|
||||
#define amdgpu_dpm_get_fan_control_mode(adev) (adev)->pm.funcs->get_fan_control_mode((adev))
|
||||
#define amdgpu_dpm_set_fan_speed_percent(adev, s) (adev)->pm.funcs->set_fan_speed_percent((adev), (s))
|
||||
#define amdgpu_dpm_get_fan_speed_percent(adev, s) (adev)->pm.funcs->get_fan_speed_percent((adev), (s))
|
||||
|
||||
#define amdgpu_dpm_get_sclk(adev, l) \
|
||||
amdgpu_powerplay ? \
|
||||
(adev)->powerplay.pp_funcs->get_sclk((adev)->powerplay.pp_handle, (l)) : \
|
||||
(adev)->pm.funcs->get_sclk((adev), (l))
|
||||
|
||||
#define amdgpu_dpm_get_mclk(adev, l) \
|
||||
amdgpu_powerplay ? \
|
||||
(adev)->powerplay.pp_funcs->get_mclk((adev)->powerplay.pp_handle, (l)) : \
|
||||
(adev)->pm.funcs->get_mclk((adev), (l))
|
||||
|
||||
|
||||
#define amdgpu_dpm_force_performance_level(adev, l) \
|
||||
amdgpu_powerplay ? \
|
||||
(adev)->powerplay.pp_funcs->force_performance_level((adev)->powerplay.pp_handle, (l)) : \
|
||||
(adev)->pm.funcs->force_performance_level((adev), (l))
|
||||
|
||||
#define amdgpu_dpm_powergate_uvd(adev, g) \
|
||||
amdgpu_powerplay ? \
|
||||
(adev)->powerplay.pp_funcs->powergate_uvd((adev)->powerplay.pp_handle, (g)) : \
|
||||
(adev)->pm.funcs->powergate_uvd((adev), (g))
|
||||
|
||||
#define amdgpu_dpm_powergate_vce(adev, g) \
|
||||
amdgpu_powerplay ? \
|
||||
(adev)->powerplay.pp_funcs->powergate_vce((adev)->powerplay.pp_handle, (g)) : \
|
||||
(adev)->pm.funcs->powergate_vce((adev), (g))
|
||||
|
||||
#define amdgpu_dpm_debugfs_print_current_performance_level(adev, m) \
|
||||
amdgpu_powerplay ? \
|
||||
(adev)->powerplay.pp_funcs->print_current_performance_level((adev)->powerplay.pp_handle, (m)) : \
|
||||
(adev)->pm.funcs->debugfs_print_current_performance_level((adev), (m))
|
||||
|
||||
#define amdgpu_dpm_get_current_power_state(adev) \
|
||||
(adev)->powerplay.pp_funcs->get_current_power_state((adev)->powerplay.pp_handle)
|
||||
|
||||
#define amdgpu_dpm_get_performance_level(adev) \
|
||||
(adev)->powerplay.pp_funcs->get_performance_level((adev)->powerplay.pp_handle)
|
||||
|
||||
#define amdgpu_dpm_dispatch_task(adev, event_id, input, output) \
|
||||
(adev)->powerplay.pp_funcs->dispatch_tasks((adev)->powerplay.pp_handle, (event_id), (input), (output))
|
||||
|
||||
#define amdgpu_gds_switch(adev, r, v, d, w, a) (adev)->gds.funcs->patch_gds_switch((r), (v), (d), (w), (a))
|
||||
|
||||
/* Common functions */
|
||||
|
@ -30,10 +30,16 @@
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
|
||||
#include "amd_powerplay.h"
|
||||
|
||||
static int amdgpu_debugfs_pm_init(struct amdgpu_device *adev);
|
||||
|
||||
void amdgpu_pm_acpi_event_handler(struct amdgpu_device *adev)
|
||||
{
|
||||
if (amdgpu_powerplay)
|
||||
/* TODO */
|
||||
return;
|
||||
|
||||
if (adev->pm.dpm_enabled) {
|
||||
mutex_lock(&adev->pm.mutex);
|
||||
if (power_supply_is_system_supplied() > 0)
|
||||
@ -52,7 +58,12 @@ static ssize_t amdgpu_get_dpm_state(struct device *dev,
|
||||
{
|
||||
struct drm_device *ddev = dev_get_drvdata(dev);
|
||||
struct amdgpu_device *adev = ddev->dev_private;
|
||||
enum amd_pm_state_type pm = adev->pm.dpm.user_state;
|
||||
enum amd_pm_state_type pm;
|
||||
|
||||
if (amdgpu_powerplay) {
|
||||
pm = amdgpu_dpm_get_current_power_state(adev);
|
||||
} else
|
||||
pm = adev->pm.dpm.user_state;
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%s\n",
|
||||
(pm == POWER_STATE_TYPE_BATTERY) ? "battery" :
|
||||
@ -66,40 +77,57 @@ static ssize_t amdgpu_set_dpm_state(struct device *dev,
|
||||
{
|
||||
struct drm_device *ddev = dev_get_drvdata(dev);
|
||||
struct amdgpu_device *adev = ddev->dev_private;
|
||||
enum amd_pm_state_type state;
|
||||
|
||||
mutex_lock(&adev->pm.mutex);
|
||||
if (strncmp("battery", buf, strlen("battery")) == 0)
|
||||
adev->pm.dpm.user_state = POWER_STATE_TYPE_BATTERY;
|
||||
state = POWER_STATE_TYPE_BATTERY;
|
||||
else if (strncmp("balanced", buf, strlen("balanced")) == 0)
|
||||
adev->pm.dpm.user_state = POWER_STATE_TYPE_BALANCED;
|
||||
state = POWER_STATE_TYPE_BALANCED;
|
||||
else if (strncmp("performance", buf, strlen("performance")) == 0)
|
||||
adev->pm.dpm.user_state = POWER_STATE_TYPE_PERFORMANCE;
|
||||
state = POWER_STATE_TYPE_PERFORMANCE;
|
||||
else {
|
||||
mutex_unlock(&adev->pm.mutex);
|
||||
count = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
mutex_unlock(&adev->pm.mutex);
|
||||
|
||||
/* Can't set dpm state when the card is off */
|
||||
if (!(adev->flags & AMD_IS_PX) ||
|
||||
(ddev->switch_power_state == DRM_SWITCH_POWER_ON))
|
||||
amdgpu_pm_compute_clocks(adev);
|
||||
if (amdgpu_powerplay) {
|
||||
amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_ENABLE_USER_STATE, &state, NULL);
|
||||
} else {
|
||||
mutex_lock(&adev->pm.mutex);
|
||||
adev->pm.dpm.user_state = state;
|
||||
mutex_unlock(&adev->pm.mutex);
|
||||
|
||||
/* Can't set dpm state when the card is off */
|
||||
if (!(adev->flags & AMD_IS_PX) ||
|
||||
(ddev->switch_power_state == DRM_SWITCH_POWER_ON))
|
||||
amdgpu_pm_compute_clocks(adev);
|
||||
}
|
||||
fail:
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t amdgpu_get_dpm_forced_performance_level(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct drm_device *ddev = dev_get_drvdata(dev);
|
||||
struct amdgpu_device *adev = ddev->dev_private;
|
||||
enum amdgpu_dpm_forced_level level = adev->pm.dpm.forced_level;
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%s\n",
|
||||
(level == AMDGPU_DPM_FORCED_LEVEL_AUTO) ? "auto" :
|
||||
(level == AMDGPU_DPM_FORCED_LEVEL_LOW) ? "low" : "high");
|
||||
if (amdgpu_powerplay) {
|
||||
enum amd_dpm_forced_level level;
|
||||
|
||||
level = amdgpu_dpm_get_performance_level(adev);
|
||||
return snprintf(buf, PAGE_SIZE, "%s\n",
|
||||
(level == AMD_DPM_FORCED_LEVEL_AUTO) ? "auto" :
|
||||
(level == AMD_DPM_FORCED_LEVEL_LOW) ? "low" : "high");
|
||||
} else {
|
||||
enum amdgpu_dpm_forced_level level;
|
||||
|
||||
level = adev->pm.dpm.forced_level;
|
||||
return snprintf(buf, PAGE_SIZE, "%s\n",
|
||||
(level == AMDGPU_DPM_FORCED_LEVEL_AUTO) ? "auto" :
|
||||
(level == AMDGPU_DPM_FORCED_LEVEL_LOW) ? "low" : "high");
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev,
|
||||
@ -112,7 +140,6 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev,
|
||||
enum amdgpu_dpm_forced_level level;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&adev->pm.mutex);
|
||||
if (strncmp("low", buf, strlen("low")) == 0) {
|
||||
level = AMDGPU_DPM_FORCED_LEVEL_LOW;
|
||||
} else if (strncmp("high", buf, strlen("high")) == 0) {
|
||||
@ -123,7 +150,11 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev,
|
||||
count = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
if (adev->pm.funcs->force_performance_level) {
|
||||
|
||||
if (amdgpu_powerplay)
|
||||
amdgpu_dpm_force_performance_level(adev, level);
|
||||
else {
|
||||
mutex_lock(&adev->pm.mutex);
|
||||
if (adev->pm.dpm.thermal_active) {
|
||||
count = -EINVAL;
|
||||
goto fail;
|
||||
@ -131,6 +162,9 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev,
|
||||
ret = amdgpu_dpm_force_performance_level(adev, level);
|
||||
if (ret)
|
||||
count = -EINVAL;
|
||||
else
|
||||
adev->pm.dpm.forced_level = level;
|
||||
mutex_unlock(&adev->pm.mutex);
|
||||
}
|
||||
fail:
|
||||
mutex_unlock(&adev->pm.mutex);
|
||||
@ -197,7 +231,7 @@ static ssize_t amdgpu_hwmon_set_pwm1_enable(struct device *dev,
|
||||
int err;
|
||||
int value;
|
||||
|
||||
if(!adev->pm.funcs->set_fan_control_mode)
|
||||
if (!adev->pm.funcs->set_fan_control_mode)
|
||||
return -EINVAL;
|
||||
|
||||
err = kstrtoint(buf, 10, &value);
|
||||
@ -294,7 +328,10 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj,
|
||||
struct amdgpu_device *adev = dev_get_drvdata(dev);
|
||||
umode_t effective_mode = attr->mode;
|
||||
|
||||
/* Skip attributes if DPM is not enabled */
|
||||
if (amdgpu_powerplay)
|
||||
return 0; /* to do */
|
||||
|
||||
/* Skip limit attributes if DPM is not enabled */
|
||||
if (!adev->pm.dpm_enabled &&
|
||||
(attr == &sensor_dev_attr_temp1_crit.dev_attr.attr ||
|
||||
attr == &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr ||
|
||||
@ -635,49 +672,54 @@ done:
|
||||
|
||||
void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable)
|
||||
{
|
||||
if (adev->pm.funcs->powergate_uvd) {
|
||||
mutex_lock(&adev->pm.mutex);
|
||||
/* enable/disable UVD */
|
||||
if (amdgpu_powerplay)
|
||||
amdgpu_dpm_powergate_uvd(adev, !enable);
|
||||
mutex_unlock(&adev->pm.mutex);
|
||||
} else {
|
||||
if (enable) {
|
||||
else {
|
||||
if (adev->pm.funcs->powergate_uvd) {
|
||||
mutex_lock(&adev->pm.mutex);
|
||||
adev->pm.dpm.uvd_active = true;
|
||||
adev->pm.dpm.state = POWER_STATE_TYPE_INTERNAL_UVD;
|
||||
/* enable/disable UVD */
|
||||
amdgpu_dpm_powergate_uvd(adev, !enable);
|
||||
mutex_unlock(&adev->pm.mutex);
|
||||
} else {
|
||||
mutex_lock(&adev->pm.mutex);
|
||||
adev->pm.dpm.uvd_active = false;
|
||||
mutex_unlock(&adev->pm.mutex);
|
||||
if (enable) {
|
||||
mutex_lock(&adev->pm.mutex);
|
||||
adev->pm.dpm.uvd_active = true;
|
||||
adev->pm.dpm.state = POWER_STATE_TYPE_INTERNAL_UVD;
|
||||
mutex_unlock(&adev->pm.mutex);
|
||||
} else {
|
||||
mutex_lock(&adev->pm.mutex);
|
||||
adev->pm.dpm.uvd_active = false;
|
||||
mutex_unlock(&adev->pm.mutex);
|
||||
}
|
||||
amdgpu_pm_compute_clocks(adev);
|
||||
}
|
||||
|
||||
amdgpu_pm_compute_clocks(adev);
|
||||
}
|
||||
}
|
||||
|
||||
void amdgpu_dpm_enable_vce(struct amdgpu_device *adev, bool enable)
|
||||
{
|
||||
if (adev->pm.funcs->powergate_vce) {
|
||||
mutex_lock(&adev->pm.mutex);
|
||||
/* enable/disable VCE */
|
||||
if (amdgpu_powerplay)
|
||||
amdgpu_dpm_powergate_vce(adev, !enable);
|
||||
|
||||
mutex_unlock(&adev->pm.mutex);
|
||||
} else {
|
||||
if (enable) {
|
||||
else {
|
||||
if (adev->pm.funcs->powergate_vce) {
|
||||
mutex_lock(&adev->pm.mutex);
|
||||
adev->pm.dpm.vce_active = true;
|
||||
/* XXX select vce level based on ring/task */
|
||||
adev->pm.dpm.vce_level = AMDGPU_VCE_LEVEL_AC_ALL;
|
||||
amdgpu_dpm_powergate_vce(adev, !enable);
|
||||
mutex_unlock(&adev->pm.mutex);
|
||||
} else {
|
||||
mutex_lock(&adev->pm.mutex);
|
||||
adev->pm.dpm.vce_active = false;
|
||||
mutex_unlock(&adev->pm.mutex);
|
||||
if (enable) {
|
||||
mutex_lock(&adev->pm.mutex);
|
||||
adev->pm.dpm.vce_active = true;
|
||||
/* XXX select vce level based on ring/task */
|
||||
adev->pm.dpm.vce_level = AMDGPU_VCE_LEVEL_AC_ALL;
|
||||
mutex_unlock(&adev->pm.mutex);
|
||||
} else {
|
||||
mutex_lock(&adev->pm.mutex);
|
||||
adev->pm.dpm.vce_active = false;
|
||||
mutex_unlock(&adev->pm.mutex);
|
||||
}
|
||||
amdgpu_pm_compute_clocks(adev);
|
||||
}
|
||||
|
||||
amdgpu_pm_compute_clocks(adev);
|
||||
}
|
||||
}
|
||||
|
||||
@ -685,10 +727,13 @@ void amdgpu_pm_print_power_states(struct amdgpu_device *adev)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < adev->pm.dpm.num_ps; i++) {
|
||||
printk("== power state %d ==\n", i);
|
||||
if (amdgpu_powerplay)
|
||||
/* TO DO */
|
||||
return;
|
||||
|
||||
for (i = 0; i < adev->pm.dpm.num_ps; i++)
|
||||
amdgpu_dpm_print_power_state(adev, &adev->pm.dpm.ps[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
|
||||
@ -698,8 +743,11 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
|
||||
if (adev->pm.sysfs_initialized)
|
||||
return 0;
|
||||
|
||||
if (adev->pm.funcs->get_temperature == NULL)
|
||||
return 0;
|
||||
if (!amdgpu_powerplay) {
|
||||
if (adev->pm.funcs->get_temperature == NULL)
|
||||
return 0;
|
||||
}
|
||||
|
||||
adev->pm.int_hwmon_dev = hwmon_device_register_with_groups(adev->dev,
|
||||
DRIVER_NAME, adev,
|
||||
hwmon_groups);
|
||||
@ -748,32 +796,43 @@ void amdgpu_pm_compute_clocks(struct amdgpu_device *adev)
|
||||
if (!adev->pm.dpm_enabled)
|
||||
return;
|
||||
|
||||
mutex_lock(&adev->pm.mutex);
|
||||
if (amdgpu_powerplay) {
|
||||
int i = 0;
|
||||
|
||||
/* update active crtc counts */
|
||||
adev->pm.dpm.new_active_crtcs = 0;
|
||||
adev->pm.dpm.new_active_crtc_count = 0;
|
||||
if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
|
||||
list_for_each_entry(crtc,
|
||||
&ddev->mode_config.crtc_list, head) {
|
||||
amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
if (crtc->enabled) {
|
||||
adev->pm.dpm.new_active_crtcs |= (1 << amdgpu_crtc->crtc_id);
|
||||
adev->pm.dpm.new_active_crtc_count++;
|
||||
amdgpu_display_bandwidth_update(adev);
|
||||
mutex_lock(&adev->ring_lock);
|
||||
for (i = 0; i < AMDGPU_MAX_RINGS; i++) {
|
||||
struct amdgpu_ring *ring = adev->rings[i];
|
||||
if (ring && ring->ready)
|
||||
amdgpu_fence_wait_empty(ring);
|
||||
}
|
||||
mutex_unlock(&adev->ring_lock);
|
||||
|
||||
amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_DISPLAY_CONFIG_CHANGE, NULL, NULL);
|
||||
} else {
|
||||
mutex_lock(&adev->pm.mutex);
|
||||
adev->pm.dpm.new_active_crtcs = 0;
|
||||
adev->pm.dpm.new_active_crtc_count = 0;
|
||||
if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
|
||||
list_for_each_entry(crtc,
|
||||
&ddev->mode_config.crtc_list, head) {
|
||||
amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
if (crtc->enabled) {
|
||||
adev->pm.dpm.new_active_crtcs |= (1 << amdgpu_crtc->crtc_id);
|
||||
adev->pm.dpm.new_active_crtc_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* update battery/ac status */
|
||||
if (power_supply_is_system_supplied() > 0)
|
||||
adev->pm.dpm.ac_power = true;
|
||||
else
|
||||
adev->pm.dpm.ac_power = false;
|
||||
|
||||
amdgpu_dpm_change_power_state_locked(adev);
|
||||
|
||||
mutex_unlock(&adev->pm.mutex);
|
||||
}
|
||||
|
||||
/* update battery/ac status */
|
||||
if (power_supply_is_system_supplied() > 0)
|
||||
adev->pm.dpm.ac_power = true;
|
||||
else
|
||||
adev->pm.dpm.ac_power = false;
|
||||
|
||||
amdgpu_dpm_change_power_state_locked(adev);
|
||||
|
||||
mutex_unlock(&adev->pm.mutex);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -787,7 +846,13 @@ static int amdgpu_debugfs_pm_info(struct seq_file *m, void *data)
|
||||
struct drm_device *dev = node->minor->dev;
|
||||
struct amdgpu_device *adev = dev->dev_private;
|
||||
|
||||
if (adev->pm.dpm_enabled) {
|
||||
if (!adev->pm.dpm_enabled) {
|
||||
seq_printf(m, "dpm not enabled\n");
|
||||
return 0;
|
||||
}
|
||||
if (amdgpu_powerplay) {
|
||||
amdgpu_dpm_debugfs_print_current_performance_level(adev, m);
|
||||
} else {
|
||||
mutex_lock(&adev->pm.mutex);
|
||||
if (adev->pm.funcs->debugfs_print_current_performance_level)
|
||||
amdgpu_dpm_debugfs_print_current_performance_level(adev, m);
|
||||
|
Loading…
Reference in New Issue
Block a user