[PATCH 8/8] drm/amd/pp: Add edit/show OD clock/voltage support in sysfs
Alex Deucher
alexdeucher at gmail.com
Tue Jan 16 17:17:44 UTC 2018
On Tue, Jan 16, 2018 at 7:02 AM, Rex Zhu <Rex.Zhu at amd.com> wrote:
> when cat pp_od_clk_voltage it show
> OD_SCLK:
> 0: 300Mhz 800 mV
> 1: 466Mhz 818 mV
> 2: 751Mhz 824 mV
> 3: 1019Mhz 987 mV
> 4: 1074Mhz 1037 mV
> 5: 1126Mhz 1087 mV
> 6: 1169Mhz 1137 mV
> 7: 1206Mhz 1150 mV
> OD_MCLK:
> 0: 300Mhz 800 mV
> 1: 1650Mhz 1000 mV
>
> echo "s/m level clock voltage" to change
> sclk/mclk's clock and voltage
>
> echo "r" to restore default value.
How do the changes actually get applied? I don't see any calls to
power_state_set.
Alex
>
> Change-Id: I4d1e70aee31850694a0ff13db8bbfe2524a1d3ae
> Signed-off-by: Rex Zhu <Rex.Zhu at amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h | 4 ++
> drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 89 +++++++++++++++++++++++++-
> drivers/gpu/drm/amd/include/kgd_pp_interface.h | 1 +
> drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 19 ++++++
> 4 files changed, 112 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
> index 986f1d5..4b5755e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
> @@ -374,6 +374,10 @@ enum amdgpu_pcie_gen {
> ((adev)->powerplay.pp_funcs->set_power_profile_mode(\
> (adev)->powerplay.pp_handle, parameter, size))
>
> +#define amdgpu_dpm_odn_edit_dpm_table(adev, type, parameter, size) \
> + ((adev)->powerplay.pp_funcs->odn_edit_dpm_table(\
> + (adev)->powerplay.pp_handle, type, 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 ed9012a..f2d3987 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> @@ -360,6 +360,81 @@ static ssize_t amdgpu_set_pp_table(struct device *dev,
> return count;
> }
>
> +static ssize_t amdgpu_set_pp_od_clk_voltage(struct device *dev,
> + struct device_attribute *attr,
> + const char *buf,
> + size_t count)
> +{
> + struct drm_device *ddev = dev_get_drvdata(dev);
> + struct amdgpu_device *adev = ddev->dev_private;
> + int ret;
> + uint32_t parameter_size = 0;
> + long parameter[64];
> + char buf_cpy[128];
> + char *tmp_str;
> + char *sub_str;
> + const char delimiter[3] = {' ', '\n', '\0'};
> + uint32_t type;
> +
> + if (count > 127)
> + return -EINVAL;
> +
> + pr_info("%c \n", *buf);
> + if (*buf == 's')
> + type = 0;
> + else if (*buf == 'm')
> + type = 1;
> + else if(*buf == 'r')
> + type = 2;
> + else {
> + pr_info("===== \n");
> + return -EINVAL;
> + }
> + memcpy(buf_cpy, buf, count+1);
> +
> + tmp_str = buf_cpy;
> +
> + while (isspace(*++tmp_str));
> +
> + while (tmp_str[0]) {
> + sub_str = strsep(&tmp_str, delimiter);
> + ret = kstrtol(sub_str, 0, ¶meter[parameter_size]);
> + if (ret)
> + return -EINVAL;
> + parameter_size++;
> +
> + while (isspace(*tmp_str))
> + tmp_str++;
> + }
> +
> + if (adev->powerplay.pp_funcs->odn_edit_dpm_table)
> + ret = amdgpu_dpm_odn_edit_dpm_table(adev, type,
> + parameter, parameter_size);
> +
> + if (ret)
> + return -EINVAL;
> +
> + return count;
> +}
> +
> +static ssize_t amdgpu_get_pp_od_clk_voltage(struct device *dev,
> + struct device_attribute *attr,
> + char *buf)
> +{
> + struct drm_device *ddev = dev_get_drvdata(dev);
> + struct amdgpu_device *adev = ddev->dev_private;
> + uint32_t size = 0;
> +
> + if (adev->powerplay.pp_funcs->print_clock_levels) {
> + size = amdgpu_dpm_print_clock_levels(adev, OD_SCLK, buf);
> + size += amdgpu_dpm_print_clock_levels(adev, OD_MCLK, buf+size);
> + return size;
> + } else {
> + return snprintf(buf, PAGE_SIZE, "\n");
> + }
> +
> +}
> +
> static ssize_t amdgpu_get_pp_dpm_sclk(struct device *dev,
> struct device_attribute *attr,
> char *buf)
> @@ -842,6 +917,10 @@ static DEVICE_ATTR(pp_compute_power_profile, S_IRUGO | S_IWUSR,
> static DEVICE_ATTR(pp_power_profile_mode, S_IRUGO | S_IWUSR,
> amdgpu_get_pp_power_profile_mode,
> amdgpu_set_pp_power_profile_mode);
> +static DEVICE_ATTR(pp_od_clk_voltage, S_IRUGO | S_IWUSR,
> + amdgpu_get_pp_od_clk_voltage,
> + amdgpu_set_pp_od_clk_voltage);
> +
> static ssize_t amdgpu_hwmon_show_temp(struct device *dev,
> struct device_attribute *attr,
> char *buf)
> @@ -1481,7 +1560,13 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
> "pp_power_profile_mode\n");
> return ret;
> }
> -
> + ret = device_create_file(adev->dev,
> + &dev_attr_pp_od_clk_voltage);
> + if (ret) {
> + DRM_ERROR("failed to create device file "
> + "pp_od_clk_voltage\n");
> + return ret;
> + }
> ret = amdgpu_debugfs_pm_init(adev);
> if (ret) {
> DRM_ERROR("Failed to register debugfs file for dpm!\n");
> @@ -1519,6 +1604,8 @@ void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev)
> &dev_attr_pp_compute_power_profile);
> device_remove_file(adev->dev,
> &dev_attr_pp_power_profile_mode);
> + device_remove_file(adev->dev,
> + &dev_attr_pp_od_clk_voltage);
> }
>
> 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 fba44a5..062fc03 100644
> --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> @@ -302,6 +302,7 @@ struct amd_pm_funcs {
> 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);
> + int (*odn_edit_dpm_table)(void *handle, uint32_t type, long *input, uint32_t size);
> };
>
> #endif
> diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
> index d9cb424..854c43c 100644
> --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
> +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
> @@ -1122,6 +1122,24 @@ static int pp_set_power_profile_mode(void *handle, long *input, uint32_t size)
> return hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, input, size);
> }
>
> +static int pp_odn_edit_dpm_table(void *handle, uint32_t type, 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->odn_edit_dpm_table == NULL) {
> + pr_info("%s was not implemented.\n", __func__);
> + return -EINVAL;
> + }
> +
> + return hwmgr->hwmgr_func->odn_edit_dpm_table(hwmgr, type, input, size);
> +}
> +
> static int pp_dpm_set_power_profile_state(void *handle,
> struct amd_pp_profile *request)
> {
> @@ -1507,6 +1525,7 @@ static int pp_get_display_mode_validation_clocks(void *handle,
> .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,
> + .odn_edit_dpm_table = pp_odn_edit_dpm_table,
> /* export to DC */
> .get_sclk = pp_dpm_get_sclk,
> .get_mclk = pp_dpm_get_mclk,
> --
> 1.9.1
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
More information about the amd-gfx
mailing list