All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] drm/amdgpu: add custom power policy support in sysfs
@ 2018-01-10 11:01 Rex Zhu
       [not found] ` <1515582075-6326-1-git-send-email-Rex.Zhu-5C7GfCeVMHo@public.gmane.org>
  0 siblings, 1 reply; 8+ messages in thread
From: Rex Zhu @ 2018-01-10 11:01 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Rex Zhu

when cat pp_power_profile_mode on Vega10
NUM        MODE_NAME BUSY_SET_POINT FPS USE_RLC_BUSY MIN_ACTIVE_LEVEL
  0 3D_FULL_SCREEN :             70  60          1              3
  1   POWER_SAVING :             90  60          0              0
  2          VIDEO*:             70  60          0              0
  3             VR :             70  90          0              0
  4       COMPUTER :             30  60          0              6
  5         CUSTOM :              0   0          0              0

the result show all the profile mode we can support and custom mode.
user can echo the num(0-4) to pp_power_profile_mode to select the profile
mode or can echo "5 value value value value" to enter CUSTOM mode.
the four parameter is set_point/FPS/USER_RLC_BUSY/MIN_ACTIVE_LEVEL.

Change-Id: I72634646a9a179ccd57f175b4c0b3f45e538a03f
Signed-off-by: Rex Zhu <Rex.Zhu@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h        |  8 +++
 drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c         | 81 +++++++++++++++++++++++++-
 drivers/gpu/drm/amd/include/kgd_pp_interface.h | 11 +++-
 3 files changed, 98 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
index 8a8d09dd..986f1d5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
@@ -366,6 +366,14 @@ enum amdgpu_pcie_gen {
 			(adev)->powerplay.pp_handle, virtual_addr_low, \
 			virtual_addr_hi, mc_addr_low, mc_addr_hi, size)
 
+#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))
+
 struct amdgpu_dpm {
 	struct amdgpu_ps        *ps;
 	/* number of valid power states */
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
index e5ee7cf..662edca 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
@@ -584,6 +584,73 @@ static ssize_t amdgpu_set_pp_mclk_od(struct device *dev,
 	return count;
 }
 
+static ssize_t amdgpu_get_pp_power_profile_mode(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct drm_device *ddev = dev_get_drvdata(dev);
+	struct amdgpu_device *adev = ddev->dev_private;
+
+	if (adev->powerplay.pp_funcs->get_power_profile_mode)
+		return amdgpu_dpm_get_power_profile_mode(adev, buf);
+
+	return snprintf(buf, PAGE_SIZE, "\n");
+}
+
+
+static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t count)
+{
+	int ret = 0xff;
+	struct drm_device *ddev = dev_get_drvdata(dev);
+	struct amdgpu_device *adev = ddev->dev_private;
+	uint32_t parameter_size = 0;
+	long parameter[64];
+	char *sub_str, buf_cpy[128];
+	char *tmp_str;
+	uint32_t i = 0;
+	char tmp[2];
+	long int profile_mode = 0;
+	const char delimiter[3] = {' ', '\n', '\0'};
+
+	tmp[0] = *(buf);
+	tmp[1] = '\0';
+	ret = kstrtol(tmp, 0, &profile_mode);
+	if (ret)
+		goto fail;
+
+	if (profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {
+		if (count < 2 || count > 127)
+			return -EINVAL;
+		while (isspace(*++buf))
+			i++;
+		memcpy(buf_cpy, buf, count-i);
+		tmp_str = buf_cpy;
+		while (tmp_str[0]) {
+			sub_str = strsep(&tmp_str, delimiter);
+			ret = kstrtol(sub_str, 0, &parameter[parameter_size]);
+			if (ret) {
+				count = -EINVAL;
+				goto fail;
+			}
+			pr_info("value is %ld \n", parameter[parameter_size]);
+			parameter_size++;
+			while (isspace(*tmp_str))
+				tmp_str++;
+		}
+	}
+	parameter[parameter_size] = profile_mode;
+	if (adev->powerplay.pp_funcs->set_power_profile_mode)
+		ret = amdgpu_dpm_set_power_profile_mode(adev, parameter, parameter_size);
+
+	if (!ret)
+		return count;
+fail:
+	return -EINVAL;
+}
+
 static ssize_t amdgpu_get_pp_power_profile(struct device *dev,
 		char *buf, struct amd_pp_profile *query)
 {
@@ -772,7 +839,9 @@ static DEVICE_ATTR(pp_gfx_power_profile, S_IRUGO | S_IWUSR,
 static DEVICE_ATTR(pp_compute_power_profile, S_IRUGO | S_IWUSR,
 		amdgpu_get_pp_compute_power_profile,
 		amdgpu_set_pp_compute_power_profile);
-
+static DEVICE_ATTR(pp_power_profile_mode, S_IRUGO | S_IWUSR,
+		amdgpu_get_pp_power_profile_mode,
+		amdgpu_set_pp_power_profile_mode);
 static ssize_t amdgpu_hwmon_show_temp(struct device *dev,
 				      struct device_attribute *attr,
 				      char *buf)
@@ -1405,6 +1474,14 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
 		return ret;
 	}
 
+	ret = device_create_file(adev->dev,
+			&dev_attr_pp_power_profile_mode);
+	if (ret) {
+		DRM_ERROR("failed to create device file	"
+				"pp_power_profile_mode\n");
+		return ret;
+	}
+
 	ret = amdgpu_debugfs_pm_init(adev);
 	if (ret) {
 		DRM_ERROR("Failed to register debugfs file for dpm!\n");
@@ -1440,6 +1517,8 @@ void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev)
 			&dev_attr_pp_gfx_power_profile);
 	device_remove_file(adev->dev,
 			&dev_attr_pp_compute_power_profile);
+	device_remove_file(adev->dev,
+			&dev_attr_pp_power_profile_mode);
 }
 
 void amdgpu_pm_compute_clocks(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
index 0f89d2a8..a823c03 100644
--- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
+++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
@@ -140,7 +140,14 @@ struct amd_pp_init {
 	uint32_t feature_mask;
 };
 
-
+enum PP_SMC_POWER_PROFILE {
+	PP_SMC_POWER_PROFILE_FULLSCREEN3D = 0x0,
+	PP_SMC_POWER_PROFILE_POWERSAVING  = 0x1,
+	PP_SMC_POWER_PROFILE_VIDEO        = 0x2,
+	PP_SMC_POWER_PROFILE_VR           = 0x3,
+	PP_SMC_POWER_PROFILE_COMPUTE      = 0x4,
+	PP_SMC_POWER_PROFILE_CUSTOM       = 0x5,
+};
 
 enum {
 	PP_GROUP_UNKNOWN = 0,
@@ -289,6 +296,8 @@ struct amd_pm_funcs {
 				struct pp_display_clock_request *clock);
 	int (*get_display_mode_validation_clocks)(void *handle,
 		struct amd_pp_simple_clock_info *clocks);
+	int (*get_power_profile_mode)(void *handle, char *buf);
+	int (*set_power_profile_mode)(void *handle, long *input, uint32_t size);
 };
 
 #endif
-- 
1.9.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/2] drm/amd/pp: Add custom power profile mode support on Vega10
       [not found] ` <1515582075-6326-1-git-send-email-Rex.Zhu-5C7GfCeVMHo@public.gmane.org>
@ 2018-01-10 11:01   ` Rex Zhu
       [not found]     ` <1515582075-6326-2-git-send-email-Rex.Zhu-5C7GfCeVMHo@public.gmane.org>
  2018-01-10 20:18   ` [PATCH 1/2] drm/amdgpu: add custom power policy support in sysfs Alex Deucher
  1 sibling, 1 reply; 8+ messages in thread
From: Rex Zhu @ 2018-01-10 11:01 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Rex Zhu

Change-Id: I0a554cb6a7a56db63a8fc5af60d5c63f65e021d1
Signed-off-by: Rex Zhu <Rex.Zhu@amd.com>
---
 drivers/gpu/drm/amd/powerplay/amd_powerplay.c      | 39 +++++++++++
 drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c | 78 ++++++++++++++++++++++
 drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h |  1 +
 drivers/gpu/drm/amd/powerplay/inc/hwmgr.h          |  3 +
 4 files changed, 121 insertions(+)

diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
index 8859b67..3493292 100644
--- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
+++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
@@ -1081,6 +1081,43 @@ static int pp_dpm_get_power_profile_state(void *handle,
 	return 0;
 }
 
+static int pp_get_power_profile_mode(void *handle, char *buf)
+{
+	struct pp_hwmgr *hwmgr;
+	struct pp_instance *pp_handle = (struct pp_instance *)handle;
+
+	if (!buf || pp_check(pp_handle))
+		return -EINVAL;
+
+	hwmgr = pp_handle->hwmgr;
+
+	if (hwmgr->hwmgr_func->get_power_profile_mode == NULL) {
+		pr_info("%s was not implemented.\n", __func__);
+		return snprintf(buf, PAGE_SIZE, "\n");
+	}
+
+	return hwmgr->hwmgr_func->get_power_profile_mode(hwmgr, buf);
+}
+
+static int pp_set_power_profile_mode(void *handle, long *input, uint32_t size)
+{
+	struct pp_hwmgr *hwmgr;
+	struct pp_instance *pp_handle = (struct pp_instance *)handle;
+
+
+	if (pp_check(pp_handle))
+		return -EINVAL;
+
+	hwmgr = pp_handle->hwmgr;
+
+	if (hwmgr->hwmgr_func->set_power_profile_mode == NULL) {
+		pr_info("%s was not implemented.\n", __func__);
+		return -EINVAL;
+	}
+
+	return hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, input, size);
+}
+
 static int pp_dpm_set_power_profile_state(void *handle,
 		struct amd_pp_profile *request)
 {
@@ -1464,6 +1501,8 @@ static int pp_get_display_mode_validation_clocks(void *handle,
 	.switch_power_profile = pp_dpm_switch_power_profile,
 	.set_clockgating_by_smu = pp_set_clockgating_by_smu,
 	.notify_smu_memory_info = pp_dpm_notify_smu_memory_info,
+	.get_power_profile_mode = pp_get_power_profile_mode,
+	.set_power_profile_mode = pp_set_power_profile_mode,
 /* export to DC */
 	.get_sclk = pp_dpm_get_sclk,
 	.get_mclk = pp_dpm_get_mclk,
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
index 23b7239..e8b6c3d 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
@@ -757,6 +757,8 @@ static int vega10_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
 
 	hwmgr->backend = data;
 
+	hwmgr->power_profile_mode = PP_SMC_POWER_PROFILE_VIDEO;
+
 	vega10_set_default_registry_data(hwmgr);
 
 	data->disable_dpm_mask = 0xff;
@@ -3950,6 +3952,7 @@ static int vega10_read_sensor(struct pp_hwmgr *hwmgr, int idx,
 		ret = -EINVAL;
 		break;
 	}
+
 	return ret;
 }
 
@@ -5008,6 +5011,79 @@ static int vega10_register_thermal_interrupt(struct pp_hwmgr *hwmgr,
 	return 0;
 }
 
+static int vega10_get_power_profile_mode(struct pp_hwmgr *hwmgr, char *buf)
+{
+	struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
+	uint32_t i, size = 0;
+	uint8_t profile_mode_setting[5][4] = {{70, 60, 1, 3,},
+						{90, 60, 0, 0,},
+						{70, 60, 0, 0,},
+						{70, 90, 0, 0,},
+						{30, 60, 0, 6,},
+						};
+	char *profile_name[6] = {"3D_FULL_SCREEN",
+					"POWER_SAVING",
+					"VIDEO",
+					"VR",
+					"COMPUTER",
+					"CUSTOM"};
+	char *title[6] = {"NUM",
+			"MODE_NAME",
+			"BUSY_SET_POINT",
+			"FPS",
+			"USE_RLC_BUSY",
+			"MIN_ACTIVE_LEVEL"};
+
+	if (!buf)
+		return -EINVAL;
+
+	size += sprintf(buf + size, "%s %16s %s %s %s %s\n",title[0],
+			title[1], title[2], title[3], title[4], title[5]);
+
+	for (i = 0; i < PP_SMC_POWER_PROFILE_CUSTOM; i++)
+		size += sprintf(buf + size, "%3d %14s%s: %14d %3d %10d %14d\n",
+			i, profile_name[i], (i == hwmgr->power_profile_mode) ? "*" : " ",
+			profile_mode_setting[i][0], profile_mode_setting[i][1],
+			profile_mode_setting[i][2], profile_mode_setting[i][3]);
+	size += sprintf(buf + size, "%3d %14s%s: %14d %3d %10d %14d\n", i,
+			profile_name[i], (i == hwmgr->power_profile_mode) ? "*" : " ",
+			data->custom_profile_mode[0], data->custom_profile_mode[1],
+			data->custom_profile_mode[2], data->custom_profile_mode[3]);
+	return size;
+}
+
+static int vega10_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, uint32_t size)
+{
+	struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
+	uint8_t busy_set_point;
+	uint8_t FPS;
+	uint8_t use_rlc_busy;
+	uint8_t min_active_level;
+
+	hwmgr->power_profile_mode = input[size];
+
+	smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetWorkloadMask,
+						1<<hwmgr->power_profile_mode);
+
+	if (hwmgr->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {
+		if (size == 0 || size > 4)
+			return -EINVAL;
+
+		data->custom_profile_mode[0] = busy_set_point = input[0];
+		data->custom_profile_mode[1] = FPS = input[1];
+		data->custom_profile_mode[2] = use_rlc_busy = input[2];
+		data->custom_profile_mode[3] = min_active_level = input[3];
+		smum_send_msg_to_smc_with_parameter(hwmgr,
+					PPSMC_MSG_SetCustomGfxDpmParameters,
+					busy_set_point | FPS<<8 |
+					use_rlc_busy << 16 | min_active_level<<24);
+				pr_info("size is %d value is %x \n", size, busy_set_point | FPS<<8 |
+					use_rlc_busy << 16 | min_active_level<<24);
+	}
+
+	return 0;
+}
+
 static const struct pp_hwmgr_func vega10_hwmgr_funcs = {
 	.backend_init = vega10_hwmgr_backend_init,
 	.backend_fini = vega10_hwmgr_backend_fini,
@@ -5065,6 +5141,8 @@ static int vega10_register_thermal_interrupt(struct pp_hwmgr *hwmgr,
 	.get_thermal_temperature_range = vega10_get_thermal_temperature_range,
 	.register_internal_thermal_interrupt = vega10_register_thermal_interrupt,
 	.start_thermal_controller = vega10_start_thermal_controller,
+	.get_power_profile_mode = vega10_get_power_profile_mode,
+	.set_power_profile_mode = vega10_set_power_profile_mode,
 };
 
 int vega10_hwmgr_init(struct pp_hwmgr *hwmgr)
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h
index e8507ff..689fe9f 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h
@@ -389,6 +389,7 @@ struct vega10_hwmgr {
 	uint32_t                       config_telemetry;
 	uint32_t                       acg_loop_state;
 	uint32_t                       mem_channels;
+	uint8_t                       custom_profile_mode[4];
 };
 
 #define VEGA10_DPM2_NEAR_TDP_DEC                      10
diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
index f37f211..800d773 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
@@ -342,6 +342,8 @@ struct pp_hwmgr_func {
 					uint32_t size);
 	int (*get_thermal_temperature_range)(struct pp_hwmgr *hwmgr,
 					struct PP_TemperatureRange *range);
+	int (*get_power_profile_mode)(struct pp_hwmgr *hwmgr, char *buf);
+	int (*set_power_profile_mode)(struct pp_hwmgr *hwmgr, long *input, uint32_t size);
 };
 
 struct pp_table_func {
@@ -750,6 +752,7 @@ struct pp_hwmgr {
 	struct amd_pp_profile default_compute_power_profile;
 	enum amd_pp_profile_type current_power_profile;
 	bool en_umd_pstate;
+	uint32_t power_profile_mode;
 };
 
 struct cgs_irq_src_funcs {
-- 
1.9.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/2] drm/amd/pp: Add custom power profile mode support on Vega10
       [not found]     ` <1515582075-6326-2-git-send-email-Rex.Zhu-5C7GfCeVMHo@public.gmane.org>
@ 2018-01-10 12:12       ` Grazvydas Ignotas
  0 siblings, 0 replies; 8+ messages in thread
From: Grazvydas Ignotas @ 2018-01-10 12:12 UTC (permalink / raw)
  To: Rex Zhu; +Cc: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On Wed, Jan 10, 2018 at 1:01 PM, Rex Zhu <Rex.Zhu@amd.com> wrote:
> Change-Id: I0a554cb6a7a56db63a8fc5af60d5c63f65e021d1
> Signed-off-by: Rex Zhu <Rex.Zhu@amd.com>
> ---
>  drivers/gpu/drm/amd/powerplay/amd_powerplay.c      | 39 +++++++++++
>  drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c | 78 ++++++++++++++++++++++
>  drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h |  1 +
>  drivers/gpu/drm/amd/powerplay/inc/hwmgr.h          |  3 +
>  4 files changed, 121 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
> index 8859b67..3493292 100644
> --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
> +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
> @@ -1081,6 +1081,43 @@ static int pp_dpm_get_power_profile_state(void *handle,
>         return 0;
>  }
>
> +static int pp_get_power_profile_mode(void *handle, char *buf)
> +{
> +       struct pp_hwmgr *hwmgr;
> +       struct pp_instance *pp_handle = (struct pp_instance *)handle;
> +
> +       if (!buf || pp_check(pp_handle))
> +               return -EINVAL;
> +
> +       hwmgr = pp_handle->hwmgr;
> +
> +       if (hwmgr->hwmgr_func->get_power_profile_mode == NULL) {
> +               pr_info("%s was not implemented.\n", __func__);
> +               return snprintf(buf, PAGE_SIZE, "\n");
> +       }
> +
> +       return hwmgr->hwmgr_func->get_power_profile_mode(hwmgr, buf);
> +}
> +
> +static int pp_set_power_profile_mode(void *handle, long *input, uint32_t size)
> +{
> +       struct pp_hwmgr *hwmgr;
> +       struct pp_instance *pp_handle = (struct pp_instance *)handle;
> +
> +

Unnecessary blank line.

> +       if (pp_check(pp_handle))
> +               return -EINVAL;
> +
> +       hwmgr = pp_handle->hwmgr;
> +
> +       if (hwmgr->hwmgr_func->set_power_profile_mode == NULL) {
> +               pr_info("%s was not implemented.\n", __func__);
> +               return -EINVAL;
> +       }
> +
> +       return hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, input, size);
> +}
> +
>  static int pp_dpm_set_power_profile_state(void *handle,
>                 struct amd_pp_profile *request)
>  {
> @@ -1464,6 +1501,8 @@ static int pp_get_display_mode_validation_clocks(void *handle,
>         .switch_power_profile = pp_dpm_switch_power_profile,
>         .set_clockgating_by_smu = pp_set_clockgating_by_smu,
>         .notify_smu_memory_info = pp_dpm_notify_smu_memory_info,
> +       .get_power_profile_mode = pp_get_power_profile_mode,
> +       .set_power_profile_mode = pp_set_power_profile_mode,
>  /* export to DC */
>         .get_sclk = pp_dpm_get_sclk,
>         .get_mclk = pp_dpm_get_mclk,
> diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
> index 23b7239..e8b6c3d 100644
> --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
> +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
> @@ -757,6 +757,8 @@ static int vega10_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
>
>         hwmgr->backend = data;
>
> +       hwmgr->power_profile_mode = PP_SMC_POWER_PROFILE_VIDEO;
> +
>         vega10_set_default_registry_data(hwmgr);
>
>         data->disable_dpm_mask = 0xff;
> @@ -3950,6 +3952,7 @@ static int vega10_read_sensor(struct pp_hwmgr *hwmgr, int idx,
>                 ret = -EINVAL;
>                 break;
>         }
> +
>         return ret;
>  }
>
> @@ -5008,6 +5011,79 @@ static int vega10_register_thermal_interrupt(struct pp_hwmgr *hwmgr,
>         return 0;
>  }
>
> +static int vega10_get_power_profile_mode(struct pp_hwmgr *hwmgr, char *buf)
> +{
> +       struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
> +       uint32_t i, size = 0;
> +       uint8_t profile_mode_setting[5][4] = {{70, 60, 1, 3,},

static const, otherwise the compiler has to copy the table to stack on
every call.

> +                                               {90, 60, 0, 0,},
> +                                               {70, 60, 0, 0,},
> +                                               {70, 90, 0, 0,},
> +                                               {30, 60, 0, 6,},
> +                                               };
> +       char *profile_name[6] = {"3D_FULL_SCREEN",

static const char * const profile_name[6] = ...

Gražvydas
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] drm/amdgpu: add custom power policy support in sysfs
       [not found] ` <1515582075-6326-1-git-send-email-Rex.Zhu-5C7GfCeVMHo@public.gmane.org>
  2018-01-10 11:01   ` [PATCH 2/2] drm/amd/pp: Add custom power profile mode support on Vega10 Rex Zhu
@ 2018-01-10 20:18   ` Alex Deucher
       [not found]     ` <CADnq5_PEegETmiiS+itf-HJKYH6ZeK7DEh6yJQc1kP-o7k+raA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  1 sibling, 1 reply; 8+ messages in thread
From: Alex Deucher @ 2018-01-10 20:18 UTC (permalink / raw)
  To: Rex Zhu; +Cc: amd-gfx list

On Wed, Jan 10, 2018 at 6:01 AM, Rex Zhu <Rex.Zhu@amd.com> wrote:
> when cat pp_power_profile_mode on Vega10
> NUM        MODE_NAME BUSY_SET_POINT FPS USE_RLC_BUSY MIN_ACTIVE_LEVEL
>   0 3D_FULL_SCREEN :             70  60          1              3
>   1   POWER_SAVING :             90  60          0              0
>   2          VIDEO*:             70  60          0              0
>   3             VR :             70  90          0              0
>   4       COMPUTER :             30  60          0              6
>   5         CUSTOM :              0   0          0              0
>
> the result show all the profile mode we can support and custom mode.
> user can echo the num(0-4) to pp_power_profile_mode to select the profile
> mode or can echo "5 value value value value" to enter CUSTOM mode.
> the four parameter is set_point/FPS/USER_RLC_BUSY/MIN_ACTIVE_LEVEL.
>

Is there any way we can unify this with profile stuff implemented for
smu7?  I'd like to avoid lots of haphazard interfaces to support
specific use cases and asics.  It becomes a maintenance nightmare.

Alex

> Change-Id: I72634646a9a179ccd57f175b4c0b3f45e538a03f
> Signed-off-by: Rex Zhu <Rex.Zhu@amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h        |  8 +++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c         | 81 +++++++++++++++++++++++++-
>  drivers/gpu/drm/amd/include/kgd_pp_interface.h | 11 +++-
>  3 files changed, 98 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
> index 8a8d09dd..986f1d5 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
> @@ -366,6 +366,14 @@ enum amdgpu_pcie_gen {
>                         (adev)->powerplay.pp_handle, virtual_addr_low, \
>                         virtual_addr_hi, mc_addr_low, mc_addr_hi, size)
>
> +#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))
> +
>  struct amdgpu_dpm {
>         struct amdgpu_ps        *ps;
>         /* number of valid power states */
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> index e5ee7cf..662edca 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> @@ -584,6 +584,73 @@ static ssize_t amdgpu_set_pp_mclk_od(struct device *dev,
>         return count;
>  }
>
> +static ssize_t amdgpu_get_pp_power_profile_mode(struct device *dev,
> +               struct device_attribute *attr,
> +               char *buf)
> +{
> +       struct drm_device *ddev = dev_get_drvdata(dev);
> +       struct amdgpu_device *adev = ddev->dev_private;
> +
> +       if (adev->powerplay.pp_funcs->get_power_profile_mode)
> +               return amdgpu_dpm_get_power_profile_mode(adev, buf);
> +
> +       return snprintf(buf, PAGE_SIZE, "\n");
> +}
> +
> +
> +static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev,
> +               struct device_attribute *attr,
> +               const char *buf,
> +               size_t count)
> +{
> +       int ret = 0xff;
> +       struct drm_device *ddev = dev_get_drvdata(dev);
> +       struct amdgpu_device *adev = ddev->dev_private;
> +       uint32_t parameter_size = 0;
> +       long parameter[64];
> +       char *sub_str, buf_cpy[128];
> +       char *tmp_str;
> +       uint32_t i = 0;
> +       char tmp[2];
> +       long int profile_mode = 0;
> +       const char delimiter[3] = {' ', '\n', '\0'};
> +
> +       tmp[0] = *(buf);
> +       tmp[1] = '\0';
> +       ret = kstrtol(tmp, 0, &profile_mode);
> +       if (ret)
> +               goto fail;
> +
> +       if (profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {
> +               if (count < 2 || count > 127)
> +                       return -EINVAL;
> +               while (isspace(*++buf))
> +                       i++;
> +               memcpy(buf_cpy, buf, count-i);
> +               tmp_str = buf_cpy;
> +               while (tmp_str[0]) {
> +                       sub_str = strsep(&tmp_str, delimiter);
> +                       ret = kstrtol(sub_str, 0, &parameter[parameter_size]);
> +                       if (ret) {
> +                               count = -EINVAL;
> +                               goto fail;
> +                       }
> +                       pr_info("value is %ld \n", parameter[parameter_size]);
> +                       parameter_size++;
> +                       while (isspace(*tmp_str))
> +                               tmp_str++;
> +               }
> +       }
> +       parameter[parameter_size] = profile_mode;
> +       if (adev->powerplay.pp_funcs->set_power_profile_mode)
> +               ret = amdgpu_dpm_set_power_profile_mode(adev, parameter, parameter_size);
> +
> +       if (!ret)
> +               return count;
> +fail:
> +       return -EINVAL;
> +}
> +
>  static ssize_t amdgpu_get_pp_power_profile(struct device *dev,
>                 char *buf, struct amd_pp_profile *query)
>  {
> @@ -772,7 +839,9 @@ static DEVICE_ATTR(pp_gfx_power_profile, S_IRUGO | S_IWUSR,
>  static DEVICE_ATTR(pp_compute_power_profile, S_IRUGO | S_IWUSR,
>                 amdgpu_get_pp_compute_power_profile,
>                 amdgpu_set_pp_compute_power_profile);
> -
> +static DEVICE_ATTR(pp_power_profile_mode, S_IRUGO | S_IWUSR,
> +               amdgpu_get_pp_power_profile_mode,
> +               amdgpu_set_pp_power_profile_mode);
>  static ssize_t amdgpu_hwmon_show_temp(struct device *dev,
>                                       struct device_attribute *attr,
>                                       char *buf)
> @@ -1405,6 +1474,14 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
>                 return ret;
>         }
>
> +       ret = device_create_file(adev->dev,
> +                       &dev_attr_pp_power_profile_mode);
> +       if (ret) {
> +               DRM_ERROR("failed to create device file "
> +                               "pp_power_profile_mode\n");
> +               return ret;
> +       }
> +
>         ret = amdgpu_debugfs_pm_init(adev);
>         if (ret) {
>                 DRM_ERROR("Failed to register debugfs file for dpm!\n");
> @@ -1440,6 +1517,8 @@ void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev)
>                         &dev_attr_pp_gfx_power_profile);
>         device_remove_file(adev->dev,
>                         &dev_attr_pp_compute_power_profile);
> +       device_remove_file(adev->dev,
> +                       &dev_attr_pp_power_profile_mode);
>  }
>
>  void amdgpu_pm_compute_clocks(struct amdgpu_device *adev)
> diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> index 0f89d2a8..a823c03 100644
> --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> @@ -140,7 +140,14 @@ struct amd_pp_init {
>         uint32_t feature_mask;
>  };
>
> -
> +enum PP_SMC_POWER_PROFILE {
> +       PP_SMC_POWER_PROFILE_FULLSCREEN3D = 0x0,
> +       PP_SMC_POWER_PROFILE_POWERSAVING  = 0x1,
> +       PP_SMC_POWER_PROFILE_VIDEO        = 0x2,
> +       PP_SMC_POWER_PROFILE_VR           = 0x3,
> +       PP_SMC_POWER_PROFILE_COMPUTE      = 0x4,
> +       PP_SMC_POWER_PROFILE_CUSTOM       = 0x5,
> +};
>
>  enum {
>         PP_GROUP_UNKNOWN = 0,
> @@ -289,6 +296,8 @@ struct amd_pm_funcs {
>                                 struct pp_display_clock_request *clock);
>         int (*get_display_mode_validation_clocks)(void *handle,
>                 struct amd_pp_simple_clock_info *clocks);
> +       int (*get_power_profile_mode)(void *handle, char *buf);
> +       int (*set_power_profile_mode)(void *handle, long *input, uint32_t size);
>  };
>
>  #endif
> --
> 1.9.1
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] drm/amdgpu: add custom power policy support in sysfs
       [not found]     ` <CADnq5_PEegETmiiS+itf-HJKYH6ZeK7DEh6yJQc1kP-o7k+raA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2018-01-10 22:33       ` Zhu, Rex
  0 siblings, 0 replies; 8+ messages in thread
From: Zhu, Rex @ 2018-01-10 22:33 UTC (permalink / raw)
  To: Alex Deucher; +Cc: amd-gfx list


[-- Attachment #1.1: Type: text/plain, Size: 8898 bytes --]

Yes, this new interface is more common, I just save the input and send to hw backend. Smu7 and Vega can share this interface.


Best Regards
Rex
________________________________
From: Alex Deucher <alexdeucher-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Sent: Thursday, January 11, 2018 4:18:11 AM
To: Zhu, Rex
Cc: amd-gfx list
Subject: Re: [PATCH 1/2] drm/amdgpu: add custom power policy support in sysfs

On Wed, Jan 10, 2018 at 6:01 AM, Rex Zhu <Rex.Zhu-5C7GfCeVMHo@public.gmane.org> wrote:
> when cat pp_power_profile_mode on Vega10
> NUM        MODE_NAME BUSY_SET_POINT FPS USE_RLC_BUSY MIN_ACTIVE_LEVEL
>   0 3D_FULL_SCREEN :             70  60          1              3
>   1   POWER_SAVING :             90  60          0              0
>   2          VIDEO*:             70  60          0              0
>   3             VR :             70  90          0              0
>   4       COMPUTER :             30  60          0              6
>   5         CUSTOM :              0   0          0              0
>
> the result show all the profile mode we can support and custom mode.
> user can echo the num(0-4) to pp_power_profile_mode to select the profile
> mode or can echo "5 value value value value" to enter CUSTOM mode.
> the four parameter is set_point/FPS/USER_RLC_BUSY/MIN_ACTIVE_LEVEL.
>

Is there any way we can unify this with profile stuff implemented for
smu7?  I'd like to avoid lots of haphazard interfaces to support
specific use cases and asics.  It becomes a maintenance nightmare.

Alex

> Change-Id: I72634646a9a179ccd57f175b4c0b3f45e538a03f
> Signed-off-by: Rex Zhu <Rex.Zhu-5C7GfCeVMHo@public.gmane.org>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h        |  8 +++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c         | 81 +++++++++++++++++++++++++-
>  drivers/gpu/drm/amd/include/kgd_pp_interface.h | 11 +++-
>  3 files changed, 98 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
> index 8a8d09dd..986f1d5 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
> @@ -366,6 +366,14 @@ enum amdgpu_pcie_gen {
>                         (adev)->powerplay.pp_handle, virtual_addr_low, \
>                         virtual_addr_hi, mc_addr_low, mc_addr_hi, size)
>
> +#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))
> +
>  struct amdgpu_dpm {
>         struct amdgpu_ps        *ps;
>         /* number of valid power states */
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> index e5ee7cf..662edca 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> @@ -584,6 +584,73 @@ static ssize_t amdgpu_set_pp_mclk_od(struct device *dev,
>         return count;
>  }
>
> +static ssize_t amdgpu_get_pp_power_profile_mode(struct device *dev,
> +               struct device_attribute *attr,
> +               char *buf)
> +{
> +       struct drm_device *ddev = dev_get_drvdata(dev);
> +       struct amdgpu_device *adev = ddev->dev_private;
> +
> +       if (adev->powerplay.pp_funcs->get_power_profile_mode)
> +               return amdgpu_dpm_get_power_profile_mode(adev, buf);
> +
> +       return snprintf(buf, PAGE_SIZE, "\n");
> +}
> +
> +
> +static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev,
> +               struct device_attribute *attr,
> +               const char *buf,
> +               size_t count)
> +{
> +       int ret = 0xff;
> +       struct drm_device *ddev = dev_get_drvdata(dev);
> +       struct amdgpu_device *adev = ddev->dev_private;
> +       uint32_t parameter_size = 0;
> +       long parameter[64];
> +       char *sub_str, buf_cpy[128];
> +       char *tmp_str;
> +       uint32_t i = 0;
> +       char tmp[2];
> +       long int profile_mode = 0;
> +       const char delimiter[3] = {' ', '\n', '\0'};
> +
> +       tmp[0] = *(buf);
> +       tmp[1] = '\0';
> +       ret = kstrtol(tmp, 0, &profile_mode);
> +       if (ret)
> +               goto fail;
> +
> +       if (profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {
> +               if (count < 2 || count > 127)
> +                       return -EINVAL;
> +               while (isspace(*++buf))
> +                       i++;
> +               memcpy(buf_cpy, buf, count-i);
> +               tmp_str = buf_cpy;
> +               while (tmp_str[0]) {
> +                       sub_str = strsep(&tmp_str, delimiter);
> +                       ret = kstrtol(sub_str, 0, &parameter[parameter_size]);
> +                       if (ret) {
> +                               count = -EINVAL;
> +                               goto fail;
> +                       }
> +                       pr_info("value is %ld \n", parameter[parameter_size]);
> +                       parameter_size++;
> +                       while (isspace(*tmp_str))
> +                               tmp_str++;
> +               }
> +       }
> +       parameter[parameter_size] = profile_mode;
> +       if (adev->powerplay.pp_funcs->set_power_profile_mode)
> +               ret = amdgpu_dpm_set_power_profile_mode(adev, parameter, parameter_size);
> +
> +       if (!ret)
> +               return count;
> +fail:
> +       return -EINVAL;
> +}
> +
>  static ssize_t amdgpu_get_pp_power_profile(struct device *dev,
>                 char *buf, struct amd_pp_profile *query)
>  {
> @@ -772,7 +839,9 @@ static DEVICE_ATTR(pp_gfx_power_profile, S_IRUGO | S_IWUSR,
>  static DEVICE_ATTR(pp_compute_power_profile, S_IRUGO | S_IWUSR,
>                 amdgpu_get_pp_compute_power_profile,
>                 amdgpu_set_pp_compute_power_profile);
> -
> +static DEVICE_ATTR(pp_power_profile_mode, S_IRUGO | S_IWUSR,
> +               amdgpu_get_pp_power_profile_mode,
> +               amdgpu_set_pp_power_profile_mode);
>  static ssize_t amdgpu_hwmon_show_temp(struct device *dev,
>                                       struct device_attribute *attr,
>                                       char *buf)
> @@ -1405,6 +1474,14 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
>                 return ret;
>         }
>
> +       ret = device_create_file(adev->dev,
> +                       &dev_attr_pp_power_profile_mode);
> +       if (ret) {
> +               DRM_ERROR("failed to create device file "
> +                               "pp_power_profile_mode\n");
> +               return ret;
> +       }
> +
>         ret = amdgpu_debugfs_pm_init(adev);
>         if (ret) {
>                 DRM_ERROR("Failed to register debugfs file for dpm!\n");
> @@ -1440,6 +1517,8 @@ void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev)
>                         &dev_attr_pp_gfx_power_profile);
>         device_remove_file(adev->dev,
>                         &dev_attr_pp_compute_power_profile);
> +       device_remove_file(adev->dev,
> +                       &dev_attr_pp_power_profile_mode);
>  }
>
>  void amdgpu_pm_compute_clocks(struct amdgpu_device *adev)
> diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> index 0f89d2a8..a823c03 100644
> --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> @@ -140,7 +140,14 @@ struct amd_pp_init {
>         uint32_t feature_mask;
>  };
>
> -
> +enum PP_SMC_POWER_PROFILE {
> +       PP_SMC_POWER_PROFILE_FULLSCREEN3D = 0x0,
> +       PP_SMC_POWER_PROFILE_POWERSAVING  = 0x1,
> +       PP_SMC_POWER_PROFILE_VIDEO        = 0x2,
> +       PP_SMC_POWER_PROFILE_VR           = 0x3,
> +       PP_SMC_POWER_PROFILE_COMPUTE      = 0x4,
> +       PP_SMC_POWER_PROFILE_CUSTOM       = 0x5,
> +};
>
>  enum {
>         PP_GROUP_UNKNOWN = 0,
> @@ -289,6 +296,8 @@ struct amd_pm_funcs {
>                                 struct pp_display_clock_request *clock);
>         int (*get_display_mode_validation_clocks)(void *handle,
>                 struct amd_pp_simple_clock_info *clocks);
> +       int (*get_power_profile_mode)(void *handle, char *buf);
> +       int (*set_power_profile_mode)(void *handle, long *input, uint32_t size);
>  };
>
>  #endif
> --
> 1.9.1
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[-- Attachment #1.2: Type: text/html, Size: 19788 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: [PATCH 1/2] drm/amdgpu: add custom power policy support in sysfs
       [not found]     ` <CADnq5_N=jX2ORgxMoi8915Dw3MLPed-Mx2qOCJCFRKfBvKj3Ag-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2018-01-17  7:12       ` Zhu, Rex
  0 siblings, 0 replies; 8+ messages in thread
From: Zhu, Rex @ 2018-01-17  7:12 UTC (permalink / raw)
  To: 'Alex Deucher'; +Cc: amd-gfx list

Sure.
We should add the PP_SMC_POWER_PROFILE_AUTO in PP_SMC_POWER_PROFILE.
And will be implemented as auto wattman feature.

Best Regards
Rex
-----Original Message-----
From: Alex Deucher [mailto:alexdeucher@gmail.com] 
Sent: Tuesday, January 16, 2018 11:59 PM
To: Zhu, Rex
Cc: amd-gfx list
Subject: Re: [PATCH 1/2] drm/amdgpu: add custom power policy support in sysfs

On Tue, Jan 16, 2018 at 6:50 AM, Rex Zhu <Rex.Zhu@amd.com> wrote:
> when cat pp_power_profile_mode on Vega10
> NUM        MODE_NAME BUSY_SET_POINT FPS USE_RLC_BUSY MIN_ACTIVE_LEVEL
>   0 3D_FULL_SCREEN :             70  60          1              3
>   1   POWER_SAVING :             90  60          0              0
>   2          VIDEO*:             70  60          0              0
>   3             VR :             70  90          0              0
>   4       COMPUTER :             30  60          0              6
>   5         CUSTOM :              0   0          0              0
>
> the result show all the profile mode we can support and custom mode.
> user can echo the num(0-4) to pp_power_profile_mode to select the 
> profile mode or can echo "5 value value value value" to enter CUSTOM mode.
> the four parameter is set_point/FPS/USER_RLC_BUSY/MIN_ACTIVE_LEVEL.
>
> Change-Id: I72634646a9a179ccd57f175b4c0b3f45e538a03f
> Signed-off-by: Rex Zhu <Rex.Zhu@amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h        |  8 +++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c         | 81 +++++++++++++++++++++++++-
>  drivers/gpu/drm/amd/include/kgd_pp_interface.h | 11 +++-
>  3 files changed, 98 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
> index 8a8d09dd..986f1d5 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
> @@ -366,6 +366,14 @@ enum amdgpu_pcie_gen {
>                         (adev)->powerplay.pp_handle, virtual_addr_low, \
>                         virtual_addr_hi, mc_addr_low, mc_addr_hi, 
> size)
>
> +#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))
> +
>  struct amdgpu_dpm {
>         struct amdgpu_ps        *ps;
>         /* number of valid power states */ diff --git 
> a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> index e5ee7cf..662edca 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> @@ -584,6 +584,73 @@ static ssize_t amdgpu_set_pp_mclk_od(struct device *dev,
>         return count;
>  }
>
> +static ssize_t amdgpu_get_pp_power_profile_mode(struct device *dev,
> +               struct device_attribute *attr,
> +               char *buf)
> +{
> +       struct drm_device *ddev = dev_get_drvdata(dev);
> +       struct amdgpu_device *adev = ddev->dev_private;
> +
> +       if (adev->powerplay.pp_funcs->get_power_profile_mode)
> +               return amdgpu_dpm_get_power_profile_mode(adev, buf);
> +
> +       return snprintf(buf, PAGE_SIZE, "\n"); }
> +
> +
> +static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev,
> +               struct device_attribute *attr,
> +               const char *buf,
> +               size_t count)
> +{
> +       int ret = 0xff;
> +       struct drm_device *ddev = dev_get_drvdata(dev);
> +       struct amdgpu_device *adev = ddev->dev_private;
> +       uint32_t parameter_size = 0;
> +       long parameter[64];
> +       char *sub_str, buf_cpy[128];
> +       char *tmp_str;
> +       uint32_t i = 0;
> +       char tmp[2];
> +       long int profile_mode = 0;
> +       const char delimiter[3] = {' ', '\n', '\0'};
> +
> +       tmp[0] = *(buf);
> +       tmp[1] = '\0';
> +       ret = kstrtol(tmp, 0, &profile_mode);
> +       if (ret)
> +               goto fail;
> +
> +       if (profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {
> +               if (count < 2 || count > 127)
> +                       return -EINVAL;
> +               while (isspace(*++buf))
> +                       i++;
> +               memcpy(buf_cpy, buf, count-i);
> +               tmp_str = buf_cpy;
> +               while (tmp_str[0]) {
> +                       sub_str = strsep(&tmp_str, delimiter);
> +                       ret = kstrtol(sub_str, 0, &parameter[parameter_size]);
> +                       if (ret) {
> +                               count = -EINVAL;
> +                               goto fail;
> +                       }
> +                       pr_info("value is %ld \n", parameter[parameter_size]);
> +                       parameter_size++;
> +                       while (isspace(*tmp_str))
> +                               tmp_str++;
> +               }
> +       }
> +       parameter[parameter_size] = profile_mode;
> +       if (adev->powerplay.pp_funcs->set_power_profile_mode)
> +               ret = amdgpu_dpm_set_power_profile_mode(adev, 
> + parameter, parameter_size);
> +
> +       if (!ret)
> +               return count;
> +fail:
> +       return -EINVAL;
> +}
> +
>  static ssize_t amdgpu_get_pp_power_profile(struct device *dev,
>                 char *buf, struct amd_pp_profile *query)  { @@ -772,7 
> +839,9 @@ static DEVICE_ATTR(pp_gfx_power_profile, S_IRUGO | S_IWUSR,  
> static DEVICE_ATTR(pp_compute_power_profile, S_IRUGO | S_IWUSR,
>                 amdgpu_get_pp_compute_power_profile,
>                 amdgpu_set_pp_compute_power_profile);
> -
> +static DEVICE_ATTR(pp_power_profile_mode, S_IRUGO | S_IWUSR,
> +               amdgpu_get_pp_power_profile_mode,
> +               amdgpu_set_pp_power_profile_mode);
>  static ssize_t amdgpu_hwmon_show_temp(struct device *dev,
>                                       struct device_attribute *attr,
>                                       char *buf) @@ -1405,6 +1474,14 
> @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
>                 return ret;
>         }
>
> +       ret = device_create_file(adev->dev,
> +                       &dev_attr_pp_power_profile_mode);
> +       if (ret) {
> +               DRM_ERROR("failed to create device file "
> +                               "pp_power_profile_mode\n");
> +               return ret;
> +       }
> +
>         ret = amdgpu_debugfs_pm_init(adev);
>         if (ret) {
>                 DRM_ERROR("Failed to register debugfs file for 
> dpm!\n"); @@ -1440,6 +1517,8 @@ void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev)
>                         &dev_attr_pp_gfx_power_profile);
>         device_remove_file(adev->dev,
>                         &dev_attr_pp_compute_power_profile);
> +       device_remove_file(adev->dev,
> +                       &dev_attr_pp_power_profile_mode);
>  }
>
>  void amdgpu_pm_compute_clocks(struct amdgpu_device *adev) diff --git 
> a/drivers/gpu/drm/amd/include/kgd_pp_interface.h 
> b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> index 0f89d2a8..a823c03 100644
> --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> @@ -140,7 +140,14 @@ struct amd_pp_init {
>         uint32_t feature_mask;
>  };
>
> -
> +enum PP_SMC_POWER_PROFILE {

We probably want to add a:
PP_SMC_POWER_PROFILE_AUTO
as well.  that way when auto is selected, the driver can select the profile dynamically based on conditions in the driver.  Selecting anything else will force that profile.  With that fixed:
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>


> +       PP_SMC_POWER_PROFILE_FULLSCREEN3D = 0x0,
> +       PP_SMC_POWER_PROFILE_POWERSAVING  = 0x1,
> +       PP_SMC_POWER_PROFILE_VIDEO        = 0x2,
> +       PP_SMC_POWER_PROFILE_VR           = 0x3,
> +       PP_SMC_POWER_PROFILE_COMPUTE      = 0x4,
> +       PP_SMC_POWER_PROFILE_CUSTOM       = 0x5,
> +};
>
>  enum {
>         PP_GROUP_UNKNOWN = 0,
> @@ -289,6 +296,8 @@ struct amd_pm_funcs {
>                                 struct pp_display_clock_request *clock);
>         int (*get_display_mode_validation_clocks)(void *handle,
>                 struct amd_pp_simple_clock_info *clocks);
> +       int (*get_power_profile_mode)(void *handle, char *buf);
> +       int (*set_power_profile_mode)(void *handle, long *input, 
> + uint32_t size);
>  };
>
>  #endif
> --
> 1.9.1
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] drm/amdgpu: add custom power policy support in sysfs
       [not found] ` <1516103404-24914-1-git-send-email-Rex.Zhu-5C7GfCeVMHo@public.gmane.org>
@ 2018-01-16 15:58   ` Alex Deucher
       [not found]     ` <CADnq5_N=jX2ORgxMoi8915Dw3MLPed-Mx2qOCJCFRKfBvKj3Ag-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 8+ messages in thread
From: Alex Deucher @ 2018-01-16 15:58 UTC (permalink / raw)
  To: Rex Zhu; +Cc: amd-gfx list

On Tue, Jan 16, 2018 at 6:50 AM, Rex Zhu <Rex.Zhu@amd.com> wrote:
> when cat pp_power_profile_mode on Vega10
> NUM        MODE_NAME BUSY_SET_POINT FPS USE_RLC_BUSY MIN_ACTIVE_LEVEL
>   0 3D_FULL_SCREEN :             70  60          1              3
>   1   POWER_SAVING :             90  60          0              0
>   2          VIDEO*:             70  60          0              0
>   3             VR :             70  90          0              0
>   4       COMPUTER :             30  60          0              6
>   5         CUSTOM :              0   0          0              0
>
> the result show all the profile mode we can support and custom mode.
> user can echo the num(0-4) to pp_power_profile_mode to select the profile
> mode or can echo "5 value value value value" to enter CUSTOM mode.
> the four parameter is set_point/FPS/USER_RLC_BUSY/MIN_ACTIVE_LEVEL.
>
> Change-Id: I72634646a9a179ccd57f175b4c0b3f45e538a03f
> Signed-off-by: Rex Zhu <Rex.Zhu@amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h        |  8 +++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c         | 81 +++++++++++++++++++++++++-
>  drivers/gpu/drm/amd/include/kgd_pp_interface.h | 11 +++-
>  3 files changed, 98 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
> index 8a8d09dd..986f1d5 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
> @@ -366,6 +366,14 @@ enum amdgpu_pcie_gen {
>                         (adev)->powerplay.pp_handle, virtual_addr_low, \
>                         virtual_addr_hi, mc_addr_low, mc_addr_hi, size)
>
> +#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))
> +
>  struct amdgpu_dpm {
>         struct amdgpu_ps        *ps;
>         /* number of valid power states */
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> index e5ee7cf..662edca 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> @@ -584,6 +584,73 @@ static ssize_t amdgpu_set_pp_mclk_od(struct device *dev,
>         return count;
>  }
>
> +static ssize_t amdgpu_get_pp_power_profile_mode(struct device *dev,
> +               struct device_attribute *attr,
> +               char *buf)
> +{
> +       struct drm_device *ddev = dev_get_drvdata(dev);
> +       struct amdgpu_device *adev = ddev->dev_private;
> +
> +       if (adev->powerplay.pp_funcs->get_power_profile_mode)
> +               return amdgpu_dpm_get_power_profile_mode(adev, buf);
> +
> +       return snprintf(buf, PAGE_SIZE, "\n");
> +}
> +
> +
> +static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev,
> +               struct device_attribute *attr,
> +               const char *buf,
> +               size_t count)
> +{
> +       int ret = 0xff;
> +       struct drm_device *ddev = dev_get_drvdata(dev);
> +       struct amdgpu_device *adev = ddev->dev_private;
> +       uint32_t parameter_size = 0;
> +       long parameter[64];
> +       char *sub_str, buf_cpy[128];
> +       char *tmp_str;
> +       uint32_t i = 0;
> +       char tmp[2];
> +       long int profile_mode = 0;
> +       const char delimiter[3] = {' ', '\n', '\0'};
> +
> +       tmp[0] = *(buf);
> +       tmp[1] = '\0';
> +       ret = kstrtol(tmp, 0, &profile_mode);
> +       if (ret)
> +               goto fail;
> +
> +       if (profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {
> +               if (count < 2 || count > 127)
> +                       return -EINVAL;
> +               while (isspace(*++buf))
> +                       i++;
> +               memcpy(buf_cpy, buf, count-i);
> +               tmp_str = buf_cpy;
> +               while (tmp_str[0]) {
> +                       sub_str = strsep(&tmp_str, delimiter);
> +                       ret = kstrtol(sub_str, 0, &parameter[parameter_size]);
> +                       if (ret) {
> +                               count = -EINVAL;
> +                               goto fail;
> +                       }
> +                       pr_info("value is %ld \n", parameter[parameter_size]);
> +                       parameter_size++;
> +                       while (isspace(*tmp_str))
> +                               tmp_str++;
> +               }
> +       }
> +       parameter[parameter_size] = profile_mode;
> +       if (adev->powerplay.pp_funcs->set_power_profile_mode)
> +               ret = amdgpu_dpm_set_power_profile_mode(adev, parameter, parameter_size);
> +
> +       if (!ret)
> +               return count;
> +fail:
> +       return -EINVAL;
> +}
> +
>  static ssize_t amdgpu_get_pp_power_profile(struct device *dev,
>                 char *buf, struct amd_pp_profile *query)
>  {
> @@ -772,7 +839,9 @@ static DEVICE_ATTR(pp_gfx_power_profile, S_IRUGO | S_IWUSR,
>  static DEVICE_ATTR(pp_compute_power_profile, S_IRUGO | S_IWUSR,
>                 amdgpu_get_pp_compute_power_profile,
>                 amdgpu_set_pp_compute_power_profile);
> -
> +static DEVICE_ATTR(pp_power_profile_mode, S_IRUGO | S_IWUSR,
> +               amdgpu_get_pp_power_profile_mode,
> +               amdgpu_set_pp_power_profile_mode);
>  static ssize_t amdgpu_hwmon_show_temp(struct device *dev,
>                                       struct device_attribute *attr,
>                                       char *buf)
> @@ -1405,6 +1474,14 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
>                 return ret;
>         }
>
> +       ret = device_create_file(adev->dev,
> +                       &dev_attr_pp_power_profile_mode);
> +       if (ret) {
> +               DRM_ERROR("failed to create device file "
> +                               "pp_power_profile_mode\n");
> +               return ret;
> +       }
> +
>         ret = amdgpu_debugfs_pm_init(adev);
>         if (ret) {
>                 DRM_ERROR("Failed to register debugfs file for dpm!\n");
> @@ -1440,6 +1517,8 @@ void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev)
>                         &dev_attr_pp_gfx_power_profile);
>         device_remove_file(adev->dev,
>                         &dev_attr_pp_compute_power_profile);
> +       device_remove_file(adev->dev,
> +                       &dev_attr_pp_power_profile_mode);
>  }
>
>  void amdgpu_pm_compute_clocks(struct amdgpu_device *adev)
> diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> index 0f89d2a8..a823c03 100644
> --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> @@ -140,7 +140,14 @@ struct amd_pp_init {
>         uint32_t feature_mask;
>  };
>
> -
> +enum PP_SMC_POWER_PROFILE {

We probably want to add a:
PP_SMC_POWER_PROFILE_AUTO
as well.  that way when auto is selected, the driver can select the
profile dynamically based on conditions in the driver.  Selecting
anything else will force that profile.  With that fixed:
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>


> +       PP_SMC_POWER_PROFILE_FULLSCREEN3D = 0x0,
> +       PP_SMC_POWER_PROFILE_POWERSAVING  = 0x1,
> +       PP_SMC_POWER_PROFILE_VIDEO        = 0x2,
> +       PP_SMC_POWER_PROFILE_VR           = 0x3,
> +       PP_SMC_POWER_PROFILE_COMPUTE      = 0x4,
> +       PP_SMC_POWER_PROFILE_CUSTOM       = 0x5,
> +};
>
>  enum {
>         PP_GROUP_UNKNOWN = 0,
> @@ -289,6 +296,8 @@ struct amd_pm_funcs {
>                                 struct pp_display_clock_request *clock);
>         int (*get_display_mode_validation_clocks)(void *handle,
>                 struct amd_pp_simple_clock_info *clocks);
> +       int (*get_power_profile_mode)(void *handle, char *buf);
> +       int (*set_power_profile_mode)(void *handle, long *input, uint32_t size);
>  };
>
>  #endif
> --
> 1.9.1
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/2] drm/amdgpu: add custom power policy support in sysfs
@ 2018-01-16 11:50 Rex Zhu
       [not found] ` <1516103404-24914-1-git-send-email-Rex.Zhu-5C7GfCeVMHo@public.gmane.org>
  0 siblings, 1 reply; 8+ messages in thread
From: Rex Zhu @ 2018-01-16 11:50 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Rex Zhu

when cat pp_power_profile_mode on Vega10
NUM        MODE_NAME BUSY_SET_POINT FPS USE_RLC_BUSY MIN_ACTIVE_LEVEL
  0 3D_FULL_SCREEN :             70  60          1              3
  1   POWER_SAVING :             90  60          0              0
  2          VIDEO*:             70  60          0              0
  3             VR :             70  90          0              0
  4       COMPUTER :             30  60          0              6
  5         CUSTOM :              0   0          0              0

the result show all the profile mode we can support and custom mode.
user can echo the num(0-4) to pp_power_profile_mode to select the profile
mode or can echo "5 value value value value" to enter CUSTOM mode.
the four parameter is set_point/FPS/USER_RLC_BUSY/MIN_ACTIVE_LEVEL.

Change-Id: I72634646a9a179ccd57f175b4c0b3f45e538a03f
Signed-off-by: Rex Zhu <Rex.Zhu@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h        |  8 +++
 drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c         | 81 +++++++++++++++++++++++++-
 drivers/gpu/drm/amd/include/kgd_pp_interface.h | 11 +++-
 3 files changed, 98 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
index 8a8d09dd..986f1d5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
@@ -366,6 +366,14 @@ enum amdgpu_pcie_gen {
 			(adev)->powerplay.pp_handle, virtual_addr_low, \
 			virtual_addr_hi, mc_addr_low, mc_addr_hi, size)
 
+#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))
+
 struct amdgpu_dpm {
 	struct amdgpu_ps        *ps;
 	/* number of valid power states */
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
index e5ee7cf..662edca 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
@@ -584,6 +584,73 @@ static ssize_t amdgpu_set_pp_mclk_od(struct device *dev,
 	return count;
 }
 
+static ssize_t amdgpu_get_pp_power_profile_mode(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct drm_device *ddev = dev_get_drvdata(dev);
+	struct amdgpu_device *adev = ddev->dev_private;
+
+	if (adev->powerplay.pp_funcs->get_power_profile_mode)
+		return amdgpu_dpm_get_power_profile_mode(adev, buf);
+
+	return snprintf(buf, PAGE_SIZE, "\n");
+}
+
+
+static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t count)
+{
+	int ret = 0xff;
+	struct drm_device *ddev = dev_get_drvdata(dev);
+	struct amdgpu_device *adev = ddev->dev_private;
+	uint32_t parameter_size = 0;
+	long parameter[64];
+	char *sub_str, buf_cpy[128];
+	char *tmp_str;
+	uint32_t i = 0;
+	char tmp[2];
+	long int profile_mode = 0;
+	const char delimiter[3] = {' ', '\n', '\0'};
+
+	tmp[0] = *(buf);
+	tmp[1] = '\0';
+	ret = kstrtol(tmp, 0, &profile_mode);
+	if (ret)
+		goto fail;
+
+	if (profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {
+		if (count < 2 || count > 127)
+			return -EINVAL;
+		while (isspace(*++buf))
+			i++;
+		memcpy(buf_cpy, buf, count-i);
+		tmp_str = buf_cpy;
+		while (tmp_str[0]) {
+			sub_str = strsep(&tmp_str, delimiter);
+			ret = kstrtol(sub_str, 0, &parameter[parameter_size]);
+			if (ret) {
+				count = -EINVAL;
+				goto fail;
+			}
+			pr_info("value is %ld \n", parameter[parameter_size]);
+			parameter_size++;
+			while (isspace(*tmp_str))
+				tmp_str++;
+		}
+	}
+	parameter[parameter_size] = profile_mode;
+	if (adev->powerplay.pp_funcs->set_power_profile_mode)
+		ret = amdgpu_dpm_set_power_profile_mode(adev, parameter, parameter_size);
+
+	if (!ret)
+		return count;
+fail:
+	return -EINVAL;
+}
+
 static ssize_t amdgpu_get_pp_power_profile(struct device *dev,
 		char *buf, struct amd_pp_profile *query)
 {
@@ -772,7 +839,9 @@ static DEVICE_ATTR(pp_gfx_power_profile, S_IRUGO | S_IWUSR,
 static DEVICE_ATTR(pp_compute_power_profile, S_IRUGO | S_IWUSR,
 		amdgpu_get_pp_compute_power_profile,
 		amdgpu_set_pp_compute_power_profile);
-
+static DEVICE_ATTR(pp_power_profile_mode, S_IRUGO | S_IWUSR,
+		amdgpu_get_pp_power_profile_mode,
+		amdgpu_set_pp_power_profile_mode);
 static ssize_t amdgpu_hwmon_show_temp(struct device *dev,
 				      struct device_attribute *attr,
 				      char *buf)
@@ -1405,6 +1474,14 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
 		return ret;
 	}
 
+	ret = device_create_file(adev->dev,
+			&dev_attr_pp_power_profile_mode);
+	if (ret) {
+		DRM_ERROR("failed to create device file	"
+				"pp_power_profile_mode\n");
+		return ret;
+	}
+
 	ret = amdgpu_debugfs_pm_init(adev);
 	if (ret) {
 		DRM_ERROR("Failed to register debugfs file for dpm!\n");
@@ -1440,6 +1517,8 @@ void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev)
 			&dev_attr_pp_gfx_power_profile);
 	device_remove_file(adev->dev,
 			&dev_attr_pp_compute_power_profile);
+	device_remove_file(adev->dev,
+			&dev_attr_pp_power_profile_mode);
 }
 
 void amdgpu_pm_compute_clocks(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
index 0f89d2a8..a823c03 100644
--- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
+++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
@@ -140,7 +140,14 @@ struct amd_pp_init {
 	uint32_t feature_mask;
 };
 
-
+enum PP_SMC_POWER_PROFILE {
+	PP_SMC_POWER_PROFILE_FULLSCREEN3D = 0x0,
+	PP_SMC_POWER_PROFILE_POWERSAVING  = 0x1,
+	PP_SMC_POWER_PROFILE_VIDEO        = 0x2,
+	PP_SMC_POWER_PROFILE_VR           = 0x3,
+	PP_SMC_POWER_PROFILE_COMPUTE      = 0x4,
+	PP_SMC_POWER_PROFILE_CUSTOM       = 0x5,
+};
 
 enum {
 	PP_GROUP_UNKNOWN = 0,
@@ -289,6 +296,8 @@ struct amd_pm_funcs {
 				struct pp_display_clock_request *clock);
 	int (*get_display_mode_validation_clocks)(void *handle,
 		struct amd_pp_simple_clock_info *clocks);
+	int (*get_power_profile_mode)(void *handle, char *buf);
+	int (*set_power_profile_mode)(void *handle, long *input, uint32_t size);
 };
 
 #endif
-- 
1.9.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2018-01-17  7:12 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-01-10 11:01 [PATCH 1/2] drm/amdgpu: add custom power policy support in sysfs Rex Zhu
     [not found] ` <1515582075-6326-1-git-send-email-Rex.Zhu-5C7GfCeVMHo@public.gmane.org>
2018-01-10 11:01   ` [PATCH 2/2] drm/amd/pp: Add custom power profile mode support on Vega10 Rex Zhu
     [not found]     ` <1515582075-6326-2-git-send-email-Rex.Zhu-5C7GfCeVMHo@public.gmane.org>
2018-01-10 12:12       ` Grazvydas Ignotas
2018-01-10 20:18   ` [PATCH 1/2] drm/amdgpu: add custom power policy support in sysfs Alex Deucher
     [not found]     ` <CADnq5_PEegETmiiS+itf-HJKYH6ZeK7DEh6yJQc1kP-o7k+raA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2018-01-10 22:33       ` Zhu, Rex
2018-01-16 11:50 Rex Zhu
     [not found] ` <1516103404-24914-1-git-send-email-Rex.Zhu-5C7GfCeVMHo@public.gmane.org>
2018-01-16 15:58   ` Alex Deucher
     [not found]     ` <CADnq5_N=jX2ORgxMoi8915Dw3MLPed-Mx2qOCJCFRKfBvKj3Ag-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2018-01-17  7:12       ` Zhu, Rex

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.