Add sysfs interface for arbitrary clock setting pp_sclk - amdgpu_set_pp_sclk Signed-off-by: Chengming Gui <Jack.Gui@xxxxxxx> --- drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 42 +++++++++++++++++++++++++++++++ drivers/gpu/drm/amd/powerplay/smu_v11_0.c | 9 +++++-- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index b03b1eb..e32a1e1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -1036,6 +1036,40 @@ static ssize_t amdgpu_read_mask(const char *buf, size_t count, uint32_t *mask) return 0; } +static ssize_t amdgpu_set_pp_sclk(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 value; + + if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) + return -EINVAL; + + ret = pm_runtime_get_sync(ddev->dev); + if (ret < 0) + return ret; + + ret = kstrtou32(buf, 0, &value); + if (ret < 0) + return ret; + if (is_support_sw_smu(adev)) + ret = smu_set_soft_freq_range(&adev->smu, SMU_SCLK, value, value); + else + return 0; + + pm_runtime_mark_last_busy(ddev->dev); + pm_runtime_put_autosuspend(ddev->dev); + + if (ret) + return -EINVAL; + + return count; +} + static ssize_t amdgpu_set_pp_dpm_sclk(struct device *dev, struct device_attribute *attr, const char *buf, @@ -1797,6 +1831,8 @@ static DEVICE_ATTR(pp_force_state, S_IRUGO | S_IWUSR, static DEVICE_ATTR(pp_table, S_IRUGO | S_IWUSR, amdgpu_get_pp_table, amdgpu_set_pp_table); +static DEVICE_ATTR(pp_sclk, S_IWUSR, + NULL, amdgpu_set_pp_sclk); static DEVICE_ATTR(pp_dpm_sclk, S_IRUGO | S_IWUSR, amdgpu_get_pp_dpm_sclk, amdgpu_set_pp_dpm_sclk); @@ -3288,6 +3324,12 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev) return ret; } + ret = device_create_file(adev->dev, &dev_attr_pp_sclk); + if (ret) { + DRM_ERROR("failed to create device file pp_sclk\n"); + return ret; + } + ret = device_create_file(adev->dev, &dev_attr_pp_dpm_sclk); if (ret) { DRM_ERROR("failed to create device file pp_dpm_sclk\n"); diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c index b06c057..9d15acf 100644 --- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c +++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c @@ -1799,12 +1799,17 @@ int smu_v11_0_set_soft_freq_limited_range(struct smu_context *smu, enum smu_clk_ { int ret = 0, clk_id = 0; uint32_t param; + uint32_t min_freq, max_freq; clk_id = smu_clk_get_index(smu, clk_type); if (clk_id < 0) return clk_id; - if (max > 0) { + ret = smu_get_dpm_freq_range(smu, clk_type, &min_freq, &max_freq, true); + if (ret) + return ret; + + if (max > 0 && max <= max_freq) { param = (uint32_t)((clk_id << 16) | (max & 0xffff)); ret = smu_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxByFreq, param); @@ -1812,7 +1817,7 @@ int smu_v11_0_set_soft_freq_limited_range(struct smu_context *smu, enum smu_clk_ return ret; } - if (min > 0) { + if (min > 0 && min >= min_freq) { param = (uint32_t)((clk_id << 16) | (min & 0xffff)); ret = smu_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMinByFreq, param); -- 2.7.4 _______________________________________________ amd-gfx mailing list amd-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/amd-gfx