diff options
| -rw-r--r-- | Documentation/gpu/amdgpu.rst | 5 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 40 |
2 files changed, 45 insertions, 0 deletions
diff --git a/Documentation/gpu/amdgpu.rst b/Documentation/gpu/amdgpu.rst index e52d0ce186fe..765c2a32938f 100644 --- a/Documentation/gpu/amdgpu.rst +++ b/Documentation/gpu/amdgpu.rst | |||
| @@ -115,3 +115,8 @@ pp_power_profile_mode | |||
| 115 | .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 115 | .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c |
| 116 | :doc: pp_power_profile_mode | 116 | :doc: pp_power_profile_mode |
| 117 | 117 | ||
| 118 | busy_percent | ||
| 119 | ~~~~~~~~~~~~ | ||
| 120 | |||
| 121 | .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | ||
| 122 | :doc: busy_percent | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 113edffb5960..fdb399821915 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | |||
| @@ -918,6 +918,36 @@ fail: | |||
| 918 | return -EINVAL; | 918 | return -EINVAL; |
| 919 | } | 919 | } |
| 920 | 920 | ||
| 921 | /** | ||
| 922 | * DOC: busy_percent | ||
| 923 | * | ||
| 924 | * The amdgpu driver provides a sysfs API for reading how busy the GPU | ||
| 925 | * is as a percentage. The file gpu_busy_percent is used for this. | ||
| 926 | * The SMU firmware computes a percentage of load based on the | ||
| 927 | * aggregate activity level in the IP cores. | ||
| 928 | */ | ||
| 929 | static ssize_t amdgpu_get_busy_percent(struct device *dev, | ||
| 930 | struct device_attribute *attr, | ||
| 931 | char *buf) | ||
| 932 | { | ||
| 933 | struct drm_device *ddev = dev_get_drvdata(dev); | ||
| 934 | struct amdgpu_device *adev = ddev->dev_private; | ||
| 935 | int r, value, size = sizeof(value); | ||
| 936 | |||
| 937 | /* sanity check PP is enabled */ | ||
| 938 | if (!(adev->powerplay.pp_funcs && | ||
| 939 | adev->powerplay.pp_funcs->read_sensor)) | ||
| 940 | return -EINVAL; | ||
| 941 | |||
| 942 | /* read the IP busy sensor */ | ||
| 943 | r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_LOAD, | ||
| 944 | (void *)&value, &size); | ||
| 945 | if (r) | ||
| 946 | return r; | ||
| 947 | |||
| 948 | return snprintf(buf, PAGE_SIZE, "%d\n", value); | ||
| 949 | } | ||
| 950 | |||
| 921 | static DEVICE_ATTR(power_dpm_state, S_IRUGO | S_IWUSR, amdgpu_get_dpm_state, amdgpu_set_dpm_state); | 951 | static DEVICE_ATTR(power_dpm_state, S_IRUGO | S_IWUSR, amdgpu_get_dpm_state, amdgpu_set_dpm_state); |
| 922 | static DEVICE_ATTR(power_dpm_force_performance_level, S_IRUGO | S_IWUSR, | 952 | static DEVICE_ATTR(power_dpm_force_performance_level, S_IRUGO | S_IWUSR, |
| 923 | amdgpu_get_dpm_forced_performance_level, | 953 | amdgpu_get_dpm_forced_performance_level, |
| @@ -951,6 +981,8 @@ static DEVICE_ATTR(pp_power_profile_mode, S_IRUGO | S_IWUSR, | |||
| 951 | static DEVICE_ATTR(pp_od_clk_voltage, S_IRUGO | S_IWUSR, | 981 | static DEVICE_ATTR(pp_od_clk_voltage, S_IRUGO | S_IWUSR, |
| 952 | amdgpu_get_pp_od_clk_voltage, | 982 | amdgpu_get_pp_od_clk_voltage, |
| 953 | amdgpu_set_pp_od_clk_voltage); | 983 | amdgpu_set_pp_od_clk_voltage); |
| 984 | static DEVICE_ATTR(gpu_busy_percent, S_IRUGO, | ||
| 985 | amdgpu_get_busy_percent, NULL); | ||
| 954 | 986 | ||
| 955 | static ssize_t amdgpu_hwmon_show_temp(struct device *dev, | 987 | static ssize_t amdgpu_hwmon_show_temp(struct device *dev, |
| 956 | struct device_attribute *attr, | 988 | struct device_attribute *attr, |
| @@ -1854,6 +1886,13 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev) | |||
| 1854 | "pp_od_clk_voltage\n"); | 1886 | "pp_od_clk_voltage\n"); |
| 1855 | return ret; | 1887 | return ret; |
| 1856 | } | 1888 | } |
| 1889 | ret = device_create_file(adev->dev, | ||
| 1890 | &dev_attr_gpu_busy_percent); | ||
| 1891 | if (ret) { | ||
| 1892 | DRM_ERROR("failed to create device file " | ||
| 1893 | "gpu_busy_level\n"); | ||
| 1894 | return ret; | ||
| 1895 | } | ||
| 1857 | ret = amdgpu_debugfs_pm_init(adev); | 1896 | ret = amdgpu_debugfs_pm_init(adev); |
| 1858 | if (ret) { | 1897 | if (ret) { |
| 1859 | DRM_ERROR("Failed to register debugfs file for dpm!\n"); | 1898 | DRM_ERROR("Failed to register debugfs file for dpm!\n"); |
| @@ -1889,6 +1928,7 @@ void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev) | |||
| 1889 | &dev_attr_pp_power_profile_mode); | 1928 | &dev_attr_pp_power_profile_mode); |
| 1890 | device_remove_file(adev->dev, | 1929 | device_remove_file(adev->dev, |
| 1891 | &dev_attr_pp_od_clk_voltage); | 1930 | &dev_attr_pp_od_clk_voltage); |
| 1931 | device_remove_file(adev->dev, &dev_attr_gpu_busy_percent); | ||
| 1892 | } | 1932 | } |
| 1893 | 1933 | ||
| 1894 | void amdgpu_pm_compute_clocks(struct amdgpu_device *adev) | 1934 | void amdgpu_pm_compute_clocks(struct amdgpu_device *adev) |
