aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.19.8/1053-drm-amdgpu-expose-sclk-and-mclk-via-hwmon.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/1053-drm-amdgpu-expose-sclk-and-mclk-via-hwmon.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.19.8/1053-drm-amdgpu-expose-sclk-and-mclk-via-hwmon.patch162
1 files changed, 162 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/1053-drm-amdgpu-expose-sclk-and-mclk-via-hwmon.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/1053-drm-amdgpu-expose-sclk-and-mclk-via-hwmon.patch
new file mode 100644
index 00000000..49ec3e85
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/1053-drm-amdgpu-expose-sclk-and-mclk-via-hwmon.patch
@@ -0,0 +1,162 @@
+From 06ca134cca5414ab41d4dfc47226a755c46a64e4 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Mon, 10 Dec 2018 16:04:15 -0500
+Subject: [PATCH 1053/2940] drm/amdgpu: expose sclk and mclk via hwmon
+
+Expose sclk (gfx clock) and mclk (memory clock) via
+hwmon compatible interface. hwmon does not actually
+formally specify a frequency type attribute, but these
+are compatible with the format of the other attributes
+exposed via hwmon. Units are hertz.
+
+freq1_input - GPU gfx/compute clock in hertz
+freq2_input - GPU memory clock in hertz (dGPU only)
+
+Reviewed-by: Evan Quan <evan.quan@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 93 ++++++++++++++++++++++++++
+ 1 file changed, 93 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
+index b38c06f0196e..51eb2cf42b81 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
+@@ -1542,6 +1542,75 @@ static ssize_t amdgpu_hwmon_set_power_cap(struct device *dev,
+ return count;
+ }
+
++static ssize_t amdgpu_hwmon_show_sclk(struct device *dev,
++ struct device_attribute *attr,
++ char *buf)
++{
++ struct amdgpu_device *adev = dev_get_drvdata(dev);
++ struct drm_device *ddev = adev->ddev;
++ uint32_t sclk;
++ int r, size = sizeof(sclk);
++
++ /* Can't get voltage when the card is off */
++ if ((adev->flags & AMD_IS_PX) &&
++ (ddev->switch_power_state != DRM_SWITCH_POWER_ON))
++ return -EINVAL;
++
++ /* sanity check PP is enabled */
++ if (!(adev->powerplay.pp_funcs &&
++ adev->powerplay.pp_funcs->read_sensor))
++ return -EINVAL;
++
++ /* get the sclk */
++ r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GFX_SCLK,
++ (void *)&sclk, &size);
++ if (r)
++ return r;
++
++ return snprintf(buf, PAGE_SIZE, "%d\n", sclk * 10 * 1000);
++}
++
++static ssize_t amdgpu_hwmon_show_sclk_label(struct device *dev,
++ struct device_attribute *attr,
++ char *buf)
++{
++ return snprintf(buf, PAGE_SIZE, "sclk\n");
++}
++
++static ssize_t amdgpu_hwmon_show_mclk(struct device *dev,
++ struct device_attribute *attr,
++ char *buf)
++{
++ struct amdgpu_device *adev = dev_get_drvdata(dev);
++ struct drm_device *ddev = adev->ddev;
++ uint32_t mclk;
++ int r, size = sizeof(mclk);
++
++ /* Can't get voltage when the card is off */
++ if ((adev->flags & AMD_IS_PX) &&
++ (ddev->switch_power_state != DRM_SWITCH_POWER_ON))
++ return -EINVAL;
++
++ /* sanity check PP is enabled */
++ if (!(adev->powerplay.pp_funcs &&
++ adev->powerplay.pp_funcs->read_sensor))
++ return -EINVAL;
++
++ /* get the sclk */
++ r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GFX_MCLK,
++ (void *)&mclk, &size);
++ if (r)
++ return r;
++
++ return snprintf(buf, PAGE_SIZE, "%d\n", mclk * 10 * 1000);
++}
++
++static ssize_t amdgpu_hwmon_show_mclk_label(struct device *dev,
++ struct device_attribute *attr,
++ char *buf)
++{
++ return snprintf(buf, PAGE_SIZE, "mclk\n");
++}
+
+ /**
+ * DOC: hwmon
+@@ -1558,6 +1627,10 @@ static ssize_t amdgpu_hwmon_set_power_cap(struct device *dev,
+ *
+ * - GPU fan
+ *
++ * - GPU gfx/compute engine clock
++ *
++ * - GPU memory clock (dGPU only)
++ *
+ * hwmon interfaces for GPU temperature:
+ *
+ * - temp1_input: the on die GPU temperature in millidegrees Celsius
+@@ -1602,6 +1675,12 @@ static ssize_t amdgpu_hwmon_set_power_cap(struct device *dev,
+ *
+ * - fan[1-*]_enable: Enable or disable the sensors.1: Enable 0: Disable
+ *
++ * hwmon interfaces for GPU clocks:
++ *
++ * - freq1_input: the gfx/compute clock in hertz
++ *
++ * - freq2_input: the memory clock in hertz
++ *
+ * You can use hwmon tools like sensors to view this information on your system.
+ *
+ */
+@@ -1626,6 +1705,10 @@ static SENSOR_DEVICE_ATTR(power1_average, S_IRUGO, amdgpu_hwmon_show_power_avg,
+ static SENSOR_DEVICE_ATTR(power1_cap_max, S_IRUGO, amdgpu_hwmon_show_power_cap_max, NULL, 0);
+ static SENSOR_DEVICE_ATTR(power1_cap_min, S_IRUGO, amdgpu_hwmon_show_power_cap_min, NULL, 0);
+ static SENSOR_DEVICE_ATTR(power1_cap, S_IRUGO | S_IWUSR, amdgpu_hwmon_show_power_cap, amdgpu_hwmon_set_power_cap, 0);
++static SENSOR_DEVICE_ATTR(freq1_input, S_IRUGO, amdgpu_hwmon_show_sclk, NULL, 0);
++static SENSOR_DEVICE_ATTR(freq1_label, S_IRUGO, amdgpu_hwmon_show_sclk_label, NULL, 0);
++static SENSOR_DEVICE_ATTR(freq2_input, S_IRUGO, amdgpu_hwmon_show_mclk, NULL, 0);
++static SENSOR_DEVICE_ATTR(freq2_label, S_IRUGO, amdgpu_hwmon_show_mclk_label, NULL, 0);
+
+ static struct attribute *hwmon_attributes[] = {
+ &sensor_dev_attr_temp1_input.dev_attr.attr,
+@@ -1648,6 +1731,10 @@ static struct attribute *hwmon_attributes[] = {
+ &sensor_dev_attr_power1_cap_max.dev_attr.attr,
+ &sensor_dev_attr_power1_cap_min.dev_attr.attr,
+ &sensor_dev_attr_power1_cap.dev_attr.attr,
++ &sensor_dev_attr_freq1_input.dev_attr.attr,
++ &sensor_dev_attr_freq1_label.dev_attr.attr,
++ &sensor_dev_attr_freq2_input.dev_attr.attr,
++ &sensor_dev_attr_freq2_label.dev_attr.attr,
+ NULL
+ };
+
+@@ -1738,6 +1825,12 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj,
+ attr == &sensor_dev_attr_in1_label.dev_attr.attr))
+ return 0;
+
++ /* no mclk on APUs */
++ if ((adev->flags & AMD_IS_APU) &&
++ (attr == &sensor_dev_attr_freq2_input.dev_attr.attr ||
++ attr == &sensor_dev_attr_freq2_label.dev_attr.attr))
++ return 0;
++
+ return effective_mode;
+ }
+
+--
+2.17.1
+