<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
</head>
<body>
Yes, this new interface is more common, I just save the input and send to hw backend. Smu7 and Vega can share this interface.<br>
<br>
<br>
Best Regards<br>
Rex<br>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> Alex Deucher <alexdeucher@gmail.com><br>
<b>Sent:</b> Thursday, January 11, 2018 4:18:11 AM<br>
<b>To:</b> Zhu, Rex<br>
<b>Cc:</b> amd-gfx list<br>
<b>Subject:</b> Re: [PATCH 1/2] drm/amdgpu: add custom power policy support in sysfs</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt;">
<div class="PlainText">On Wed, Jan 10, 2018 at 6:01 AM, Rex Zhu <Rex.Zhu@amd.com> wrote:<br>
> when cat pp_power_profile_mode on Vega10<br>
> NUM        MODE_NAME BUSY_SET_POINT FPS USE_RLC_BUSY MIN_ACTIVE_LEVEL<br>
>   0 3D_FULL_SCREEN :             70  60          1              3<br>
>   1   POWER_SAVING :             90  60          0              0<br>
>   2          VIDEO*:             70  60          0              0<br>
>   3             VR :             70  90          0              0<br>
>   4       COMPUTER :             30  60          0              6<br>
>   5         CUSTOM :              0   0          0              0<br>
><br>
> the result show all the profile mode we can support and custom mode.<br>
> user can echo the num(0-4) to pp_power_profile_mode to select the profile<br>
> mode or can echo "5 value value value value" to enter CUSTOM mode.<br>
> the four parameter is set_point/FPS/USER_RLC_BUSY/MIN_ACTIVE_LEVEL.<br>
><br>
<br>
Is there any way we can unify this with profile stuff implemented for<br>
smu7?  I'd like to avoid lots of haphazard interfaces to support<br>
specific use cases and asics.  It becomes a maintenance nightmare.<br>
<br>
Alex<br>
<br>
> Change-Id: I72634646a9a179ccd57f175b4c0b3f45e538a03f<br>
> Signed-off-by: Rex Zhu <Rex.Zhu@amd.com><br>
> ---<br>
>  drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h        |  8 +++<br>
>  drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c         | 81 +++++++++++++++++++++++++-<br>
>  drivers/gpu/drm/amd/include/kgd_pp_interface.h | 11 +++-<br>
>  3 files changed, 98 insertions(+), 2 deletions(-)<br>
><br>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h<br>
> index 8a8d09dd..986f1d5 100644<br>
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h<br>
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h<br>
> @@ -366,6 +366,14 @@ enum amdgpu_pcie_gen {<br>
>                         (adev)->powerplay.pp_handle, virtual_addr_low, \<br>
>                         virtual_addr_hi, mc_addr_low, mc_addr_hi, size)<br>
><br>
> +#define amdgpu_dpm_get_power_profile_mode(adev, buf) \<br>
> +               ((adev)->powerplay.pp_funcs->get_power_profile_mode(\<br>
> +                       (adev)->powerplay.pp_handle, buf))<br>
> +<br>
> +#define amdgpu_dpm_set_power_profile_mode(adev, parameter, size) \<br>
> +               ((adev)->powerplay.pp_funcs->set_power_profile_mode(\<br>
> +                       (adev)->powerplay.pp_handle, parameter, size))<br>
> +<br>
>  struct amdgpu_dpm {<br>
>         struct amdgpu_ps        *ps;<br>
>         /* number of valid power states */<br>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c<br>
> index e5ee7cf..662edca 100644<br>
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c<br>
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c<br>
> @@ -584,6 +584,73 @@ static ssize_t amdgpu_set_pp_mclk_od(struct device *dev,<br>
>         return count;<br>
>  }<br>
><br>
> +static ssize_t amdgpu_get_pp_power_profile_mode(struct device *dev,<br>
> +               struct device_attribute *attr,<br>
> +               char *buf)<br>
> +{<br>
> +       struct drm_device *ddev = dev_get_drvdata(dev);<br>
> +       struct amdgpu_device *adev = ddev->dev_private;<br>
> +<br>
> +       if (adev->powerplay.pp_funcs->get_power_profile_mode)<br>
> +               return amdgpu_dpm_get_power_profile_mode(adev, buf);<br>
> +<br>
> +       return snprintf(buf, PAGE_SIZE, "\n");<br>
> +}<br>
> +<br>
> +<br>
> +static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev,<br>
> +               struct device_attribute *attr,<br>
> +               const char *buf,<br>
> +               size_t count)<br>
> +{<br>
> +       int ret = 0xff;<br>
> +       struct drm_device *ddev = dev_get_drvdata(dev);<br>
> +       struct amdgpu_device *adev = ddev->dev_private;<br>
> +       uint32_t parameter_size = 0;<br>
> +       long parameter[64];<br>
> +       char *sub_str, buf_cpy[128];<br>
> +       char *tmp_str;<br>
> +       uint32_t i = 0;<br>
> +       char tmp[2];<br>
> +       long int profile_mode = 0;<br>
> +       const char delimiter[3] = {' ', '\n', '\0'};<br>
> +<br>
> +       tmp[0] = *(buf);<br>
> +       tmp[1] = '\0';<br>
> +       ret = kstrtol(tmp, 0, &profile_mode);<br>
> +       if (ret)<br>
> +               goto fail;<br>
> +<br>
> +       if (profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {<br>
> +               if (count < 2 || count > 127)<br>
> +                       return -EINVAL;<br>
> +               while (isspace(*++buf))<br>
> +                       i++;<br>
> +               memcpy(buf_cpy, buf, count-i);<br>
> +               tmp_str = buf_cpy;<br>
> +               while (tmp_str[0]) {<br>
> +                       sub_str = strsep(&tmp_str, delimiter);<br>
> +                       ret = kstrtol(sub_str, 0, &parameter[parameter_size]);<br>
> +                       if (ret) {<br>
> +                               count = -EINVAL;<br>
> +                               goto fail;<br>
> +                       }<br>
> +                       pr_info("value is %ld \n", parameter[parameter_size]);<br>
> +                       parameter_size++;<br>
> +                       while (isspace(*tmp_str))<br>
> +                               tmp_str++;<br>
> +               }<br>
> +       }<br>
> +       parameter[parameter_size] = profile_mode;<br>
> +       if (adev->powerplay.pp_funcs->set_power_profile_mode)<br>
> +               ret = amdgpu_dpm_set_power_profile_mode(adev, parameter, parameter_size);<br>
> +<br>
> +       if (!ret)<br>
> +               return count;<br>
> +fail:<br>
> +       return -EINVAL;<br>
> +}<br>
> +<br>
>  static ssize_t amdgpu_get_pp_power_profile(struct device *dev,<br>
>                 char *buf, struct amd_pp_profile *query)<br>
>  {<br>
> @@ -772,7 +839,9 @@ static DEVICE_ATTR(pp_gfx_power_profile, S_IRUGO | S_IWUSR,<br>
>  static DEVICE_ATTR(pp_compute_power_profile, S_IRUGO | S_IWUSR,<br>
>                 amdgpu_get_pp_compute_power_profile,<br>
>                 amdgpu_set_pp_compute_power_profile);<br>
> -<br>
> +static DEVICE_ATTR(pp_power_profile_mode, S_IRUGO | S_IWUSR,<br>
> +               amdgpu_get_pp_power_profile_mode,<br>
> +               amdgpu_set_pp_power_profile_mode);<br>
>  static ssize_t amdgpu_hwmon_show_temp(struct device *dev,<br>
>                                       struct device_attribute *attr,<br>
>                                       char *buf)<br>
> @@ -1405,6 +1474,14 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)<br>
>                 return ret;<br>
>         }<br>
><br>
> +       ret = device_create_file(adev->dev,<br>
> +                       &dev_attr_pp_power_profile_mode);<br>
> +       if (ret) {<br>
> +               DRM_ERROR("failed to create device file "<br>
> +                               "pp_power_profile_mode\n");<br>
> +               return ret;<br>
> +       }<br>
> +<br>
>         ret = amdgpu_debugfs_pm_init(adev);<br>
>         if (ret) {<br>
>                 DRM_ERROR("Failed to register debugfs file for dpm!\n");<br>
> @@ -1440,6 +1517,8 @@ void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev)<br>
>                         &dev_attr_pp_gfx_power_profile);<br>
>         device_remove_file(adev->dev,<br>
>                         &dev_attr_pp_compute_power_profile);<br>
> +       device_remove_file(adev->dev,<br>
> +                       &dev_attr_pp_power_profile_mode);<br>
>  }<br>
><br>
>  void amdgpu_pm_compute_clocks(struct amdgpu_device *adev)<br>
> diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h<br>
> index 0f89d2a8..a823c03 100644<br>
> --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h<br>
> +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h<br>
> @@ -140,7 +140,14 @@ struct amd_pp_init {<br>
>         uint32_t feature_mask;<br>
>  };<br>
><br>
> -<br>
> +enum PP_SMC_POWER_PROFILE {<br>
> +       PP_SMC_POWER_PROFILE_FULLSCREEN3D = 0x0,<br>
> +       PP_SMC_POWER_PROFILE_POWERSAVING  = 0x1,<br>
> +       PP_SMC_POWER_PROFILE_VIDEO        = 0x2,<br>
> +       PP_SMC_POWER_PROFILE_VR           = 0x3,<br>
> +       PP_SMC_POWER_PROFILE_COMPUTE      = 0x4,<br>
> +       PP_SMC_POWER_PROFILE_CUSTOM       = 0x5,<br>
> +};<br>
><br>
>  enum {<br>
>         PP_GROUP_UNKNOWN = 0,<br>
> @@ -289,6 +296,8 @@ struct amd_pm_funcs {<br>
>                                 struct pp_display_clock_request *clock);<br>
>         int (*get_display_mode_validation_clocks)(void *handle,<br>
>                 struct amd_pp_simple_clock_info *clocks);<br>
> +       int (*get_power_profile_mode)(void *handle, char *buf);<br>
> +       int (*set_power_profile_mode)(void *handle, long *input, uint32_t size);<br>
>  };<br>
><br>
>  #endif<br>
> --<br>
> 1.9.1<br>
><br>
> _______________________________________________<br>
> amd-gfx mailing list<br>
> amd-gfx@lists.freedesktop.org<br>
> <a href="https://lists.freedesktop.org/mailman/listinfo/amd-gfx">https://lists.freedesktop.org/mailman/listinfo/amd-gfx</a><br>
</div>
</span></font></div>
</body>
</html>