Commit 6e58941c authored by Eric Huang's avatar Eric Huang Committed by Alex Deucher
Browse files

drm/amd/pm: add a new sysfs entry for default power limit



Driver doesn't keep the default bootup power limit and expose it
to user. As requested we add it in driver.

Signed-off-by: default avatarEric Huang <jinhuieric.huang@amd.com>
Reviewed-by: default avatarEvan Quan <evan.quan@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 616cf23b
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -288,7 +288,8 @@ struct amd_pm_funcs {
				uint32_t block_type, bool gate);
	int (*set_clockgating_by_smu)(void *handle, uint32_t msg_id);
	int (*set_power_limit)(void *handle, uint32_t n);
	int (*get_power_limit)(void *handle, uint32_t *limit, bool default_limit);
	int (*get_power_limit)(void *handle, uint32_t *limit, uint32_t *max_limit,
			bool default_limit);
	int (*get_power_profile_mode)(void *handle, char *buf);
	int (*set_power_profile_mode)(void *handle, long *input, uint32_t size);
	int (*set_fine_grain_clk_vol)(void *handle, uint32_t type, long *input, uint32_t size);
+49 −4
Original line number Diff line number Diff line
@@ -2613,6 +2613,7 @@ static ssize_t amdgpu_hwmon_show_power_cap_max(struct device *dev,
	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
	int limit_type = to_sensor_dev_attr(attr)->index;
	uint32_t limit = limit_type << 24;
	uint32_t max_limit = 0;
	ssize_t size;
	int r;

@@ -2629,8 +2630,9 @@ static ssize_t amdgpu_hwmon_show_power_cap_max(struct device *dev,
		smu_get_power_limit(&adev->smu, &limit, SMU_PPT_LIMIT_MAX);
		size = snprintf(buf, PAGE_SIZE, "%u\n", limit * 1000000);
	} else if (pp_funcs && pp_funcs->get_power_limit) {
		pp_funcs->get_power_limit(adev->powerplay.pp_handle, &limit, true);
		size = snprintf(buf, PAGE_SIZE, "%u\n", limit * 1000000);
		pp_funcs->get_power_limit(adev->powerplay.pp_handle,
				&limit, &max_limit, true);
		size = snprintf(buf, PAGE_SIZE, "%u\n", max_limit * 1000000);
	} else {
		size = snprintf(buf, PAGE_SIZE, "\n");
	}
@@ -2665,7 +2667,8 @@ static ssize_t amdgpu_hwmon_show_power_cap(struct device *dev,
		smu_get_power_limit(&adev->smu, &limit, SMU_PPT_LIMIT_CURRENT);
		size = snprintf(buf, PAGE_SIZE, "%u\n", limit * 1000000);
	} else if (pp_funcs && pp_funcs->get_power_limit) {
		pp_funcs->get_power_limit(adev->powerplay.pp_handle, &limit, false);
		pp_funcs->get_power_limit(adev->powerplay.pp_handle,
				&limit, NULL, false);
		size = snprintf(buf, PAGE_SIZE, "%u\n", limit * 1000000);
	} else {
		size = snprintf(buf, PAGE_SIZE, "\n");
@@ -2677,6 +2680,42 @@ static ssize_t amdgpu_hwmon_show_power_cap(struct device *dev,
	return size;
}

static ssize_t amdgpu_hwmon_show_power_cap_default(struct device *dev,
					 struct device_attribute *attr,
					 char *buf)
{
	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;
	uint32_t limit = limit_type << 24;
	ssize_t size;
	int r;

	if (amdgpu_in_reset(adev))
		return -EPERM;

	r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
	if (r < 0) {
		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
		return r;
	}

	if (is_support_sw_smu(adev)) {
		smu_get_power_limit(&adev->smu, &limit, SMU_PPT_LIMIT_DEFAULT);
		size = snprintf(buf, PAGE_SIZE, "%u\n", limit * 1000000);
	} else if (pp_funcs && pp_funcs->get_power_limit) {
		pp_funcs->get_power_limit(adev->powerplay.pp_handle,
				&limit, NULL, true);
		size = snprintf(buf, PAGE_SIZE, "%u\n", limit * 1000000);
	} else {
		size = snprintf(buf, PAGE_SIZE, "\n");
	}

	pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
	pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);

	return size;
}
static ssize_t amdgpu_hwmon_show_power_label(struct device *dev,
					 struct device_attribute *attr,
					 char *buf)
@@ -2919,11 +2958,13 @@ static SENSOR_DEVICE_ATTR(power1_average, S_IRUGO, amdgpu_hwmon_show_power_avg,
static SENSOR_DEVICE_ATTR(power1_cap_max, S_IRUGO, amdgpu_hwmon_show_power_cap_max, NULL, 0);
static SENSOR_DEVICE_ATTR(power1_cap_min, S_IRUGO, amdgpu_hwmon_show_power_cap_min, NULL, 0);
static SENSOR_DEVICE_ATTR(power1_cap, S_IRUGO | S_IWUSR, amdgpu_hwmon_show_power_cap, amdgpu_hwmon_set_power_cap, 0);
static SENSOR_DEVICE_ATTR(power1_cap_default, S_IRUGO, amdgpu_hwmon_show_power_cap_default, NULL, 0);
static SENSOR_DEVICE_ATTR(power1_label, S_IRUGO, amdgpu_hwmon_show_power_label, NULL, 0);
static SENSOR_DEVICE_ATTR(power2_average, S_IRUGO, amdgpu_hwmon_show_power_avg, NULL, 1);
static SENSOR_DEVICE_ATTR(power2_cap_max, S_IRUGO, amdgpu_hwmon_show_power_cap_max, NULL, 1);
static SENSOR_DEVICE_ATTR(power2_cap_min, S_IRUGO, amdgpu_hwmon_show_power_cap_min, NULL, 1);
static SENSOR_DEVICE_ATTR(power2_cap, S_IRUGO | S_IWUSR, amdgpu_hwmon_show_power_cap, amdgpu_hwmon_set_power_cap, 1);
static SENSOR_DEVICE_ATTR(power2_cap_default, S_IRUGO, amdgpu_hwmon_show_power_cap_default, NULL, 1);
static SENSOR_DEVICE_ATTR(power2_label, S_IRUGO, amdgpu_hwmon_show_power_label, NULL, 1);
static SENSOR_DEVICE_ATTR(freq1_input, S_IRUGO, amdgpu_hwmon_show_sclk, NULL, 0);
static SENSOR_DEVICE_ATTR(freq1_label, S_IRUGO, amdgpu_hwmon_show_sclk_label, NULL, 0);
@@ -2963,11 +3004,13 @@ static struct attribute *hwmon_attributes[] = {
	&sensor_dev_attr_power1_cap_max.dev_attr.attr,
	&sensor_dev_attr_power1_cap_min.dev_attr.attr,
	&sensor_dev_attr_power1_cap.dev_attr.attr,
	&sensor_dev_attr_power1_cap_default.dev_attr.attr,
	&sensor_dev_attr_power1_label.dev_attr.attr,
	&sensor_dev_attr_power2_average.dev_attr.attr,
	&sensor_dev_attr_power2_cap_max.dev_attr.attr,
	&sensor_dev_attr_power2_cap_min.dev_attr.attr,
	&sensor_dev_attr_power2_cap.dev_attr.attr,
	&sensor_dev_attr_power2_cap_default.dev_attr.attr,
	&sensor_dev_attr_power2_label.dev_attr.attr,
	&sensor_dev_attr_freq1_input.dev_attr.attr,
	&sensor_dev_attr_freq1_label.dev_attr.attr,
@@ -3066,7 +3109,8 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj,
	      (adev->asic_type != CHIP_VANGOGH))) &&	/* not implemented yet */
	    (attr == &sensor_dev_attr_power1_cap_max.dev_attr.attr ||
	     attr == &sensor_dev_attr_power1_cap_min.dev_attr.attr||
	     attr == &sensor_dev_attr_power1_cap.dev_attr.attr))
	     attr == &sensor_dev_attr_power1_cap.dev_attr.attr ||
	     attr == &sensor_dev_attr_power1_cap_default.dev_attr.attr))
		return 0;

	if (((adev->family == AMDGPU_FAMILY_SI) ||
@@ -3132,6 +3176,7 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj,
		 attr == &sensor_dev_attr_power2_cap_max.dev_attr.attr ||
	     attr == &sensor_dev_attr_power2_cap_min.dev_attr.attr ||
		 attr == &sensor_dev_attr_power2_cap.dev_attr.attr ||
		 attr == &sensor_dev_attr_power2_cap_default.dev_attr.attr ||
		 attr == &sensor_dev_attr_power2_label.dev_attr.attr ||
		 attr == &sensor_dev_attr_power1_label.dev_attr.attr))
		return 0;
+2 −0
Original line number Diff line number Diff line
@@ -171,6 +171,7 @@ enum smu_ppt_limit_level
{
	SMU_PPT_LIMIT_MIN = -1,
	SMU_PPT_LIMIT_CURRENT,
	SMU_PPT_LIMIT_DEFAULT,
	SMU_PPT_LIMIT_MAX,
};

@@ -446,6 +447,7 @@ struct smu_context

	bool od_enabled;
	uint32_t current_power_limit;
	uint32_t default_power_limit;
	uint32_t max_power_limit;

	/* soft pptable */
+1 −0
Original line number Diff line number Diff line
@@ -141,6 +141,7 @@ struct smu_11_5_power_context {
	enum smu_11_0_power_state power_state;

	uint32_t	current_fast_ppt_limit;
	uint32_t	default_fast_ppt_limit;
	uint32_t	max_fast_ppt_limit;
};

+8 −4
Original line number Diff line number Diff line
@@ -1034,7 +1034,8 @@ static int pp_set_power_limit(void *handle, uint32_t limit)
	return 0;
}

static int pp_get_power_limit(void *handle, uint32_t *limit, bool default_limit)
static int pp_get_power_limit(void *handle, uint32_t *limit,
		uint32_t *max_limit, bool default_limit)
{
	struct pp_hwmgr *hwmgr = handle;

@@ -1045,9 +1046,12 @@ static int pp_get_power_limit(void *handle, uint32_t *limit, bool default_limit)

	if (default_limit) {
		*limit = hwmgr->default_power_limit;
		if (max_limit) {
			*max_limit = *limit;
			if (hwmgr->od_enabled) {
			*limit *= (100 + hwmgr->platform_descriptor.TDPODLimit);
			*limit /= 100;
				*max_limit *= (100 + hwmgr->platform_descriptor.TDPODLimit);
				*max_limit /= 100;
			}
		}
	}
	else
Loading