Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1b5708ff authored by Rex Zhu's avatar Rex Zhu Committed by Alex Deucher
Browse files

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: default avatarRex Zhu <Rex.Zhu@amd.com>
Acked-by: default avatarJammy Zhou <Jammy.Zhou@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent ba5c2a87
Loading
Loading
Loading
Loading
+40 −6
Original line number Diff line number Diff line
@@ -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 */
+140 −75
Original line number Diff line number Diff line
@@ -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,25 +77,31 @@ 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;
	}

	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;
}
@@ -95,12 +112,23 @@ static ssize_t amdgpu_get_dpm_forced_performance_level(struct device *dev,
{
	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;

	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,
						       struct device_attribute *attr,
@@ -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);
@@ -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,6 +672,9 @@ static void amdgpu_dpm_change_power_state_locked(struct amdgpu_device *adev)

void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable)
{
	if (amdgpu_powerplay)
		amdgpu_dpm_powergate_uvd(adev, !enable);
	else {
		if (adev->pm.funcs->powergate_uvd) {
			mutex_lock(&adev->pm.mutex);
			/* enable/disable UVD */
@@ -651,18 +691,20 @@ void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable)
				adev->pm.dpm.uvd_active = false;
				mutex_unlock(&adev->pm.mutex);
			}

			amdgpu_pm_compute_clocks(adev);
		}

	}
}

void amdgpu_dpm_enable_vce(struct amdgpu_device *adev, bool enable)
{
	if (amdgpu_powerplay)
		amdgpu_dpm_powergate_vce(adev, !enable);
	else {
		if (adev->pm.funcs->powergate_vce) {
			mutex_lock(&adev->pm.mutex);
		/* enable/disable VCE */
			amdgpu_dpm_powergate_vce(adev, !enable);

			mutex_unlock(&adev->pm.mutex);
		} else {
			if (enable) {
@@ -676,19 +718,22 @@ void amdgpu_dpm_enable_vce(struct amdgpu_device *adev, bool enable)
				adev->pm.dpm.vce_active = false;
				mutex_unlock(&adev->pm.mutex);
			}

			amdgpu_pm_compute_clocks(adev);
		}
	}
}

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 (!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,9 +796,21 @@ 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;

		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);

	/* update active crtc counts */
		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) {
@@ -763,7 +823,6 @@ void amdgpu_pm_compute_clocks(struct amdgpu_device *adev)
				}
			}
		}

		/* update battery/ac status */
		if (power_supply_is_system_supplied() > 0)
			adev->pm.dpm.ac_power = true;
@@ -773,7 +832,7 @@ void amdgpu_pm_compute_clocks(struct amdgpu_device *adev)
		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);