diff options
author | Rex Zhu <Rex.Zhu@amd.com> | 2018-01-29 05:07:01 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2018-02-19 14:19:45 -0500 |
commit | 8d81bce71deed6354f2035b613abf6e3033f34fb (patch) | |
tree | 42983837a1fd554ef6519c098afe32eb741003e3 /drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | |
parent | 6ab8555e04ecd2278fdca54c33a7ddac7d4ba5d2 (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.c | 75 |
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 | ||
1210 | static 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 | |||
1217 | static 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 | |||
1232 | static 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 | |||
1248 | static 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 | |||
1210 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, amdgpu_hwmon_show_temp, NULL, 0); | 1273 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, amdgpu_hwmon_show_temp, NULL, 0); |
1211 | static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, amdgpu_hwmon_show_temp_thresh, NULL, 0); | 1274 | static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, amdgpu_hwmon_show_temp_thresh, NULL, 0); |
1212 | static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO, amdgpu_hwmon_show_temp_thresh, NULL, 1); | 1275 | static 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 | |||
1220 | static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, amdgpu_hwmon_show_vddnb, NULL, 0); | 1283 | static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, amdgpu_hwmon_show_vddnb, NULL, 0); |
1221 | static SENSOR_DEVICE_ATTR(in1_label, S_IRUGO, amdgpu_hwmon_show_vddnb_label, NULL, 0); | 1284 | static SENSOR_DEVICE_ATTR(in1_label, S_IRUGO, amdgpu_hwmon_show_vddnb_label, NULL, 0); |
1222 | static SENSOR_DEVICE_ATTR(power1_average, S_IRUGO, amdgpu_hwmon_show_power_avg, NULL, 0); | 1285 | static SENSOR_DEVICE_ATTR(power1_average, S_IRUGO, amdgpu_hwmon_show_power_avg, NULL, 0); |
1286 | static SENSOR_DEVICE_ATTR(power1_cap_max, S_IRUGO, amdgpu_hwmon_show_power_cap_max, NULL, 0); | ||
1287 | static SENSOR_DEVICE_ATTR(power1_cap_min, S_IRUGO, amdgpu_hwmon_show_power_cap_min, NULL, 0); | ||
1288 | static SENSOR_DEVICE_ATTR(power1_cap, S_IRUGO | S_IWUSR, amdgpu_hwmon_show_power_cap, amdgpu_hwmon_set_power_cap, 0); | ||
1223 | 1289 | ||
1224 | static struct attribute *hwmon_attributes[] = { | 1290 | static 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) && |