drm/amdgpu/pm: report gpu average power via hwmon API
authorAlex Deucher <alexander.deucher@amd.com>
Wed, 24 Jan 2018 23:34:26 +0000 (18:34 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 19 Feb 2018 19:18:50 +0000 (14:18 -0500)
Expose power via hwmon.

Acked-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Rex Zhu <Rex.Zhu@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c

index eaf91d0..17f9f3a 100644 (file)
@@ -1170,6 +1170,38 @@ static ssize_t amdgpu_hwmon_show_vddnb_label(struct device *dev,
        return snprintf(buf, PAGE_SIZE, "vddnb\n");
 }
 
+static ssize_t amdgpu_hwmon_show_power_avg(struct device *dev,
+                                          struct device_attribute *attr,
+                                          char *buf)
+{
+       struct amdgpu_device *adev = dev_get_drvdata(dev);
+       struct drm_device *ddev = adev->ddev;
+       struct pp_gpu_power query = {0};
+       int r, size = sizeof(query);
+       unsigned uw;
+
+       /* Can't get power 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 voltage */
+       r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_POWER,
+                                  (void *)&query, &size);
+       if (r)
+               return r;
+
+       /* convert to microwatts */
+       uw = (query.average_gpu_power >> 8) * 1000000;
+
+       return snprintf(buf, PAGE_SIZE, "%u\n", uw);
+}
+
 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, amdgpu_hwmon_show_temp, NULL, 0);
 static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, amdgpu_hwmon_show_temp_thresh, NULL, 0);
 static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO, amdgpu_hwmon_show_temp_thresh, NULL, 1);
@@ -1182,6 +1214,7 @@ static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, amdgpu_hwmon_show_vddgfx, NULL, 0)
 static SENSOR_DEVICE_ATTR(in0_label, S_IRUGO, amdgpu_hwmon_show_vddgfx_label, NULL, 0);
 static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, amdgpu_hwmon_show_vddnb, NULL, 0);
 static SENSOR_DEVICE_ATTR(in1_label, S_IRUGO, amdgpu_hwmon_show_vddnb_label, NULL, 0);
+static SENSOR_DEVICE_ATTR(power1_average, S_IRUGO, amdgpu_hwmon_show_power_avg, NULL, 0);
 
 static struct attribute *hwmon_attributes[] = {
        &sensor_dev_attr_temp1_input.dev_attr.attr,
@@ -1196,6 +1229,7 @@ static struct attribute *hwmon_attributes[] = {
        &sensor_dev_attr_in0_label.dev_attr.attr,
        &sensor_dev_attr_in1_input.dev_attr.attr,
        &sensor_dev_attr_in1_label.dev_attr.attr,
+       &sensor_dev_attr_power1_average.dev_attr.attr,
        NULL
 };