aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
diff options
context:
space:
mode:
authorRex Zhu <Rex.Zhu@amd.com>2018-01-29 05:07:01 -0500
committerAlex Deucher <alexander.deucher@amd.com>2018-02-19 14:19:45 -0500
commit8d81bce71deed6354f2035b613abf6e3033f34fb (patch)
tree42983837a1fd554ef6519c098afe32eb741003e3 /drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
parent6ab8555e04ecd2278fdca54c33a7ddac7d4ba5d2 (diff)
drm/amdgpu: Get/set dgpu power cap via hwmon API
v2: change power unit to microWatt Adust power limit through power1_cap Get min/max power limit through power1_cap_min/power1_cap_max Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Rex Zhu <Rex.Zhu@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
index 39ef93ac5467..9e73cbcfce44 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
@@ -1207,6 +1207,69 @@ static ssize_t amdgpu_hwmon_show_power_avg(struct device *dev,
1207 return snprintf(buf, PAGE_SIZE, "%u\n", uw); 1207 return snprintf(buf, PAGE_SIZE, "%u\n", uw);
1208} 1208}
1209 1209
1210static ssize_t amdgpu_hwmon_show_power_cap_min(struct device *dev,
1211 struct device_attribute *attr,
1212 char *buf)
1213{
1214 return sprintf(buf, "%i\n", 0);
1215}
1216
1217static ssize_t amdgpu_hwmon_show_power_cap_max(struct device *dev,
1218 struct device_attribute *attr,
1219 char *buf)
1220{
1221 struct amdgpu_device *adev = dev_get_drvdata(dev);
1222 uint32_t limit = 0;
1223
1224 if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_power_limit) {
1225 adev->powerplay.pp_funcs->get_power_limit(adev->powerplay.pp_handle, &limit, true);
1226 return snprintf(buf, PAGE_SIZE, "%u\n", limit * 1000000);
1227 } else {
1228 return snprintf(buf, PAGE_SIZE, "\n");
1229 }
1230}
1231
1232static ssize_t amdgpu_hwmon_show_power_cap(struct device *dev,
1233 struct device_attribute *attr,
1234 char *buf)
1235{
1236 struct amdgpu_device *adev = dev_get_drvdata(dev);
1237 uint32_t limit = 0;
1238
1239 if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_power_limit) {
1240 adev->powerplay.pp_funcs->get_power_limit(adev->powerplay.pp_handle, &limit, false);
1241 return snprintf(buf, PAGE_SIZE, "%u\n", limit * 1000000);
1242 } else {
1243 return snprintf(buf, PAGE_SIZE, "\n");
1244 }
1245}
1246
1247
1248static ssize_t amdgpu_hwmon_set_power_cap(struct device *dev,
1249 struct device_attribute *attr,
1250 const char *buf,
1251 size_t count)
1252{
1253 struct amdgpu_device *adev = dev_get_drvdata(dev);
1254 int err;
1255 u32 value;
1256
1257 err = kstrtou32(buf, 10, &value);
1258 if (err)
1259 return err;
1260
1261 value = value / 1000000; /* convert to Watt */
1262 if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->set_power_limit) {
1263 err = adev->powerplay.pp_funcs->set_power_limit(adev->powerplay.pp_handle, value);
1264 if (err)
1265 return err;
1266 } else {
1267 return -EINVAL;
1268 }
1269
1270 return count;
1271}
1272
1210static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, amdgpu_hwmon_show_temp, NULL, 0); 1273static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, amdgpu_hwmon_show_temp, NULL, 0);
1211static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, amdgpu_hwmon_show_temp_thresh, NULL, 0); 1274static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, amdgpu_hwmon_show_temp_thresh, NULL, 0);
1212static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO, amdgpu_hwmon_show_temp_thresh, NULL, 1); 1275static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO, amdgpu_hwmon_show_temp_thresh, NULL, 1);
@@ -1220,6 +1283,9 @@ static SENSOR_DEVICE_ATTR(in0_label, S_IRUGO, amdgpu_hwmon_show_vddgfx_label, NU
1220static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, amdgpu_hwmon_show_vddnb, NULL, 0); 1283static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, amdgpu_hwmon_show_vddnb, NULL, 0);
1221static SENSOR_DEVICE_ATTR(in1_label, S_IRUGO, amdgpu_hwmon_show_vddnb_label, NULL, 0); 1284static SENSOR_DEVICE_ATTR(in1_label, S_IRUGO, amdgpu_hwmon_show_vddnb_label, NULL, 0);
1222static SENSOR_DEVICE_ATTR(power1_average, S_IRUGO, amdgpu_hwmon_show_power_avg, NULL, 0); 1285static SENSOR_DEVICE_ATTR(power1_average, S_IRUGO, amdgpu_hwmon_show_power_avg, NULL, 0);
1286static SENSOR_DEVICE_ATTR(power1_cap_max, S_IRUGO, amdgpu_hwmon_show_power_cap_max, NULL, 0);
1287static SENSOR_DEVICE_ATTR(power1_cap_min, S_IRUGO, amdgpu_hwmon_show_power_cap_min, NULL, 0);
1288static SENSOR_DEVICE_ATTR(power1_cap, S_IRUGO | S_IWUSR, amdgpu_hwmon_show_power_cap, amdgpu_hwmon_set_power_cap, 0);
1223 1289
1224static struct attribute *hwmon_attributes[] = { 1290static struct attribute *hwmon_attributes[] = {
1225 &sensor_dev_attr_temp1_input.dev_attr.attr, 1291 &sensor_dev_attr_temp1_input.dev_attr.attr,
@@ -1235,6 +1301,9 @@ static struct attribute *hwmon_attributes[] = {
1235 &sensor_dev_attr_in1_input.dev_attr.attr, 1301 &sensor_dev_attr_in1_input.dev_attr.attr,
1236 &sensor_dev_attr_in1_label.dev_attr.attr, 1302 &sensor_dev_attr_in1_label.dev_attr.attr,
1237 &sensor_dev_attr_power1_average.dev_attr.attr, 1303 &sensor_dev_attr_power1_average.dev_attr.attr,
1304 &sensor_dev_attr_power1_cap_max.dev_attr.attr,
1305 &sensor_dev_attr_power1_cap_min.dev_attr.attr,
1306 &sensor_dev_attr_power1_cap.dev_attr.attr,
1238 NULL 1307 NULL
1239}; 1308};
1240 1309
@@ -1282,6 +1351,12 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj,
1282 attr == &sensor_dev_attr_pwm1_enable.dev_attr.attr)) /* can't manage state */ 1351 attr == &sensor_dev_attr_pwm1_enable.dev_attr.attr)) /* can't manage state */
1283 effective_mode &= ~S_IWUSR; 1352 effective_mode &= ~S_IWUSR;
1284 1353
1354 if ((adev->flags & AMD_IS_APU) &&
1355 (attr == &sensor_dev_attr_power1_cap_max.dev_attr.attr ||
1356 attr == &sensor_dev_attr_power1_cap_min.dev_attr.attr||
1357 attr == &sensor_dev_attr_power1_cap.dev_attr.attr))
1358 return 0;
1359
1285 /* hide max/min values if we can't both query and manage the fan */ 1360 /* hide max/min values if we can't both query and manage the fan */
1286 if ((!adev->powerplay.pp_funcs->set_fan_speed_percent && 1361 if ((!adev->powerplay.pp_funcs->set_fan_speed_percent &&
1287 !adev->powerplay.pp_funcs->get_fan_speed_percent) && 1362 !adev->powerplay.pp_funcs->get_fan_speed_percent) &&