drm/amd/pm: add two new sysfs nodes for vangogh
authorXiaojian Du <Xiaojian.Du@amd.com>
Wed, 16 Dec 2020 06:44:10 +0000 (14:44 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 5 Jan 2021 16:30:00 +0000 (11:30 -0500)
This patch is to add two new sysfs nodes for vangogh:
pp_dpm_dclk and pp_dpm_vclk.
The two sysfs nodes are similar to pp_dpm_fclk/memclk/socclk.
pp_dpm_dclk represents the DPM frequency of dcn unit.
pp_dpm_vclk represents the DPM frequency of vcn unit.

Signed-off-by: Xiaojian Du <Xiaojian.Du@amd.com>
Acked-by: Evan Quan <evan.quan@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/pm/amdgpu_pm.c

index a68c8ba..97c669d 100644 (file)
@@ -1362,6 +1362,138 @@ static ssize_t amdgpu_set_pp_dpm_fclk(struct device *dev,
        return count;
 }
 
+static ssize_t amdgpu_get_pp_dpm_vclk(struct device *dev,
+               struct device_attribute *attr,
+               char *buf)
+{
+       struct drm_device *ddev = dev_get_drvdata(dev);
+       struct amdgpu_device *adev = drm_to_adev(ddev);
+       ssize_t size;
+       int ret;
+
+       if (amdgpu_in_reset(adev))
+               return -EPERM;
+
+       ret = pm_runtime_get_sync(ddev->dev);
+       if (ret < 0) {
+               pm_runtime_put_autosuspend(ddev->dev);
+               return ret;
+       }
+
+       if (is_support_sw_smu(adev))
+               size = smu_print_clk_levels(&adev->smu, SMU_VCLK, buf);
+       else
+               size = snprintf(buf, PAGE_SIZE, "\n");
+
+       pm_runtime_mark_last_busy(ddev->dev);
+       pm_runtime_put_autosuspend(ddev->dev);
+
+       return size;
+}
+
+static ssize_t amdgpu_set_pp_dpm_vclk(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 = drm_to_adev(ddev);
+       int ret;
+       uint32_t mask = 0;
+
+       if (amdgpu_in_reset(adev))
+               return -EPERM;
+
+       ret = amdgpu_read_mask(buf, count, &mask);
+       if (ret)
+               return ret;
+
+       ret = pm_runtime_get_sync(ddev->dev);
+       if (ret < 0) {
+               pm_runtime_put_autosuspend(ddev->dev);
+               return ret;
+       }
+
+       if (is_support_sw_smu(adev))
+               ret = smu_force_clk_levels(&adev->smu, SMU_VCLK, mask);
+       else
+               ret = 0;
+
+       pm_runtime_mark_last_busy(ddev->dev);
+       pm_runtime_put_autosuspend(ddev->dev);
+
+       if (ret)
+               return -EINVAL;
+
+       return count;
+}
+
+static ssize_t amdgpu_get_pp_dpm_dclk(struct device *dev,
+               struct device_attribute *attr,
+               char *buf)
+{
+       struct drm_device *ddev = dev_get_drvdata(dev);
+       struct amdgpu_device *adev = drm_to_adev(ddev);
+       ssize_t size;
+       int ret;
+
+       if (amdgpu_in_reset(adev))
+               return -EPERM;
+
+       ret = pm_runtime_get_sync(ddev->dev);
+       if (ret < 0) {
+               pm_runtime_put_autosuspend(ddev->dev);
+               return ret;
+       }
+
+       if (is_support_sw_smu(adev))
+               size = smu_print_clk_levels(&adev->smu, SMU_DCLK, buf);
+       else
+               size = snprintf(buf, PAGE_SIZE, "\n");
+
+       pm_runtime_mark_last_busy(ddev->dev);
+       pm_runtime_put_autosuspend(ddev->dev);
+
+       return size;
+}
+
+static ssize_t amdgpu_set_pp_dpm_dclk(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 = drm_to_adev(ddev);
+       int ret;
+       uint32_t mask = 0;
+
+       if (amdgpu_in_reset(adev))
+               return -EPERM;
+
+       ret = amdgpu_read_mask(buf, count, &mask);
+       if (ret)
+               return ret;
+
+       ret = pm_runtime_get_sync(ddev->dev);
+       if (ret < 0) {
+               pm_runtime_put_autosuspend(ddev->dev);
+               return ret;
+       }
+
+       if (is_support_sw_smu(adev))
+               ret = smu_force_clk_levels(&adev->smu, SMU_DCLK, mask);
+       else
+               ret = 0;
+
+       pm_runtime_mark_last_busy(ddev->dev);
+       pm_runtime_put_autosuspend(ddev->dev);
+
+       if (ret)
+               return -EINVAL;
+
+       return count;
+}
+
 static ssize_t amdgpu_get_pp_dpm_dcefclk(struct device *dev,
                struct device_attribute *attr,
                char *buf)
@@ -2041,6 +2173,8 @@ static struct amdgpu_device_attr amdgpu_device_attrs[] = {
        AMDGPU_DEVICE_ATTR_RW(pp_dpm_mclk,                              ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF),
        AMDGPU_DEVICE_ATTR_RW(pp_dpm_socclk,                            ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF),
        AMDGPU_DEVICE_ATTR_RW(pp_dpm_fclk,                              ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF),
+       AMDGPU_DEVICE_ATTR_RW(pp_dpm_vclk,                              ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF),
+       AMDGPU_DEVICE_ATTR_RW(pp_dpm_dclk,                              ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF),
        AMDGPU_DEVICE_ATTR_RW(pp_dpm_dcefclk,                           ATTR_FLAG_BASIC),
        AMDGPU_DEVICE_ATTR_RW(pp_dpm_pcie,                              ATTR_FLAG_BASIC),
        AMDGPU_DEVICE_ATTR_RW(pp_sclk_od,                               ATTR_FLAG_BASIC),
@@ -2103,6 +2237,12 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_
        } else if (DEVICE_ATTR_IS(gpu_metrics)) {
                if (asic_type < CHIP_VEGA12)
                        *states = ATTR_STATE_UNSUPPORTED;
+       } else if (DEVICE_ATTR_IS(pp_dpm_vclk)) {
+               if (!(asic_type == CHIP_VANGOGH))
+                       *states = ATTR_STATE_UNSUPPORTED;
+       } else if (DEVICE_ATTR_IS(pp_dpm_dclk)) {
+               if (!(asic_type == CHIP_VANGOGH))
+                       *states = ATTR_STATE_UNSUPPORTED;
        }
 
        if (asic_type == CHIP_ARCTURUS) {