amdgpu_pm.c revision 1.3.6.2 1 /* $NetBSD: amdgpu_pm.c,v 1.3.6.2 2019/06/10 22:07:58 christos Exp $ */
2
3 /*
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Rafa Miecki <zajec5 (at) gmail.com>
23 * Alex Deucher <alexdeucher (at) gmail.com>
24 */
25 #include <sys/cdefs.h>
26 __KERNEL_RCSID(0, "$NetBSD: amdgpu_pm.c,v 1.3.6.2 2019/06/10 22:07:58 christos Exp $");
27
28 #include <drm/drmP.h>
29 #include "amdgpu.h"
30 #include "amdgpu_drv.h"
31 #include "amdgpu_pm.h"
32 #include "amdgpu_dpm.h"
33 #include "atom.h"
34 #include <linux/power_supply.h>
35 #include <linux/hwmon.h>
36 #include <linux/hwmon-sysfs.h>
37
38 #ifndef __NetBSD__ /* XXX sysfs */
39 static int amdgpu_debugfs_pm_init(struct amdgpu_device *adev);
40 #endif
41
42 void amdgpu_pm_acpi_event_handler(struct amdgpu_device *adev)
43 {
44 if (adev->pm.dpm_enabled) {
45 mutex_lock(&adev->pm.mutex);
46 if (power_supply_is_system_supplied() > 0)
47 adev->pm.dpm.ac_power = true;
48 else
49 adev->pm.dpm.ac_power = false;
50 if (adev->pm.funcs->enable_bapm)
51 amdgpu_dpm_enable_bapm(adev, adev->pm.dpm.ac_power);
52 mutex_unlock(&adev->pm.mutex);
53 }
54 }
55
56 #ifndef __NetBSD__ /* XXX sysfs */
57
58 static ssize_t amdgpu_get_dpm_state(struct device *dev,
59 struct device_attribute *attr,
60 char *buf)
61 {
62 struct drm_device *ddev = dev_get_drvdata(dev);
63 struct amdgpu_device *adev = ddev->dev_private;
64 enum amdgpu_pm_state_type pm = adev->pm.dpm.user_state;
65
66 return snprintf(buf, PAGE_SIZE, "%s\n",
67 (pm == POWER_STATE_TYPE_BATTERY) ? "battery" :
68 (pm == POWER_STATE_TYPE_BALANCED) ? "balanced" : "performance");
69 }
70
71 static ssize_t amdgpu_set_dpm_state(struct device *dev,
72 struct device_attribute *attr,
73 const char *buf,
74 size_t count)
75 {
76 struct drm_device *ddev = dev_get_drvdata(dev);
77 struct amdgpu_device *adev = ddev->dev_private;
78
79 mutex_lock(&adev->pm.mutex);
80 if (strncmp("battery", buf, strlen("battery")) == 0)
81 adev->pm.dpm.user_state = POWER_STATE_TYPE_BATTERY;
82 else if (strncmp("balanced", buf, strlen("balanced")) == 0)
83 adev->pm.dpm.user_state = POWER_STATE_TYPE_BALANCED;
84 else if (strncmp("performance", buf, strlen("performance")) == 0)
85 adev->pm.dpm.user_state = POWER_STATE_TYPE_PERFORMANCE;
86 else {
87 mutex_unlock(&adev->pm.mutex);
88 count = -EINVAL;
89 goto fail;
90 }
91 mutex_unlock(&adev->pm.mutex);
92
93 /* Can't set dpm state when the card is off */
94 if (!(adev->flags & AMD_IS_PX) ||
95 (ddev->switch_power_state == DRM_SWITCH_POWER_ON))
96 amdgpu_pm_compute_clocks(adev);
97 fail:
98 return count;
99 }
100
101 static ssize_t amdgpu_get_dpm_forced_performance_level(struct device *dev,
102 struct device_attribute *attr,
103 char *buf)
104 {
105 struct drm_device *ddev = dev_get_drvdata(dev);
106 struct amdgpu_device *adev = ddev->dev_private;
107 enum amdgpu_dpm_forced_level level = adev->pm.dpm.forced_level;
108
109 return snprintf(buf, PAGE_SIZE, "%s\n",
110 (level == AMDGPU_DPM_FORCED_LEVEL_AUTO) ? "auto" :
111 (level == AMDGPU_DPM_FORCED_LEVEL_LOW) ? "low" : "high");
112 }
113
114 static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev,
115 struct device_attribute *attr,
116 const char *buf,
117 size_t count)
118 {
119 struct drm_device *ddev = dev_get_drvdata(dev);
120 struct amdgpu_device *adev = ddev->dev_private;
121 enum amdgpu_dpm_forced_level level;
122 int ret = 0;
123
124 mutex_lock(&adev->pm.mutex);
125 if (strncmp("low", buf, strlen("low")) == 0) {
126 level = AMDGPU_DPM_FORCED_LEVEL_LOW;
127 } else if (strncmp("high", buf, strlen("high")) == 0) {
128 level = AMDGPU_DPM_FORCED_LEVEL_HIGH;
129 } else if (strncmp("auto", buf, strlen("auto")) == 0) {
130 level = AMDGPU_DPM_FORCED_LEVEL_AUTO;
131 } else {
132 count = -EINVAL;
133 goto fail;
134 }
135 if (adev->pm.funcs->force_performance_level) {
136 if (adev->pm.dpm.thermal_active) {
137 count = -EINVAL;
138 goto fail;
139 }
140 ret = amdgpu_dpm_force_performance_level(adev, level);
141 if (ret)
142 count = -EINVAL;
143 }
144 fail:
145 mutex_unlock(&adev->pm.mutex);
146
147 return count;
148 }
149
150 static DEVICE_ATTR(power_dpm_state, S_IRUGO | S_IWUSR, amdgpu_get_dpm_state, amdgpu_set_dpm_state);
151 static DEVICE_ATTR(power_dpm_force_performance_level, S_IRUGO | S_IWUSR,
152 amdgpu_get_dpm_forced_performance_level,
153 amdgpu_set_dpm_forced_performance_level);
154
155 static ssize_t amdgpu_hwmon_show_temp(struct device *dev,
156 struct device_attribute *attr,
157 char *buf)
158 {
159 struct amdgpu_device *adev = dev_get_drvdata(dev);
160 int temp;
161
162 if (adev->pm.funcs->get_temperature)
163 temp = amdgpu_dpm_get_temperature(adev);
164 else
165 temp = 0;
166
167 return snprintf(buf, PAGE_SIZE, "%d\n", temp);
168 }
169
170 static ssize_t amdgpu_hwmon_show_temp_thresh(struct device *dev,
171 struct device_attribute *attr,
172 char *buf)
173 {
174 struct amdgpu_device *adev = dev_get_drvdata(dev);
175 int hyst = to_sensor_dev_attr(attr)->index;
176 int temp;
177
178 if (hyst)
179 temp = adev->pm.dpm.thermal.min_temp;
180 else
181 temp = adev->pm.dpm.thermal.max_temp;
182
183 return snprintf(buf, PAGE_SIZE, "%d\n", temp);
184 }
185
186 static ssize_t amdgpu_hwmon_get_pwm1_enable(struct device *dev,
187 struct device_attribute *attr,
188 char *buf)
189 {
190 struct amdgpu_device *adev = dev_get_drvdata(dev);
191 u32 pwm_mode = 0;
192
193 if (adev->pm.funcs->get_fan_control_mode)
194 pwm_mode = amdgpu_dpm_get_fan_control_mode(adev);
195
196 /* never 0 (full-speed), fuse or smc-controlled always */
197 return sprintf(buf, "%i\n", pwm_mode == FDO_PWM_MODE_STATIC ? 1 : 2);
198 }
199
200 static ssize_t amdgpu_hwmon_set_pwm1_enable(struct device *dev,
201 struct device_attribute *attr,
202 const char *buf,
203 size_t count)
204 {
205 struct amdgpu_device *adev = dev_get_drvdata(dev);
206 int err;
207 int value;
208
209 if(!adev->pm.funcs->set_fan_control_mode)
210 return -EINVAL;
211
212 err = kstrtoint(buf, 10, &value);
213 if (err)
214 return err;
215
216 switch (value) {
217 case 1: /* manual, percent-based */
218 amdgpu_dpm_set_fan_control_mode(adev, FDO_PWM_MODE_STATIC);
219 break;
220 default: /* disable */
221 amdgpu_dpm_set_fan_control_mode(adev, 0);
222 break;
223 }
224
225 return count;
226 }
227
228 static ssize_t amdgpu_hwmon_get_pwm1_min(struct device *dev,
229 struct device_attribute *attr,
230 char *buf)
231 {
232 return sprintf(buf, "%i\n", 0);
233 }
234
235 static ssize_t amdgpu_hwmon_get_pwm1_max(struct device *dev,
236 struct device_attribute *attr,
237 char *buf)
238 {
239 return sprintf(buf, "%i\n", 255);
240 }
241
242 static ssize_t amdgpu_hwmon_set_pwm1(struct device *dev,
243 struct device_attribute *attr,
244 const char *buf, size_t count)
245 {
246 struct amdgpu_device *adev = dev_get_drvdata(dev);
247 int err;
248 u32 value;
249
250 err = kstrtou32(buf, 10, &value);
251 if (err)
252 return err;
253
254 value = (value * 100) / 255;
255
256 err = amdgpu_dpm_set_fan_speed_percent(adev, value);
257 if (err)
258 return err;
259
260 return count;
261 }
262
263 static ssize_t amdgpu_hwmon_get_pwm1(struct device *dev,
264 struct device_attribute *attr,
265 char *buf)
266 {
267 struct amdgpu_device *adev = dev_get_drvdata(dev);
268 int err;
269 u32 speed;
270
271 err = amdgpu_dpm_get_fan_speed_percent(adev, &speed);
272 if (err)
273 return err;
274
275 speed = (speed * 255) / 100;
276
277 return sprintf(buf, "%i\n", speed);
278 }
279
280 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, amdgpu_hwmon_show_temp, NULL, 0);
281 static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, amdgpu_hwmon_show_temp_thresh, NULL, 0);
282 static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO, amdgpu_hwmon_show_temp_thresh, NULL, 1);
283 static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, amdgpu_hwmon_get_pwm1, amdgpu_hwmon_set_pwm1, 0);
284 static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, amdgpu_hwmon_get_pwm1_enable, amdgpu_hwmon_set_pwm1_enable, 0);
285 static SENSOR_DEVICE_ATTR(pwm1_min, S_IRUGO, amdgpu_hwmon_get_pwm1_min, NULL, 0);
286 static SENSOR_DEVICE_ATTR(pwm1_max, S_IRUGO, amdgpu_hwmon_get_pwm1_max, NULL, 0);
287
288 static struct attribute *hwmon_attributes[] = {
289 &sensor_dev_attr_temp1_input.dev_attr.attr,
290 &sensor_dev_attr_temp1_crit.dev_attr.attr,
291 &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr,
292 &sensor_dev_attr_pwm1.dev_attr.attr,
293 &sensor_dev_attr_pwm1_enable.dev_attr.attr,
294 &sensor_dev_attr_pwm1_min.dev_attr.attr,
295 &sensor_dev_attr_pwm1_max.dev_attr.attr,
296 NULL
297 };
298
299 static umode_t hwmon_attributes_visible(struct kobject *kobj,
300 struct attribute *attr, int index)
301 {
302 struct device *dev = container_of(kobj, struct device, kobj);
303 struct amdgpu_device *adev = dev_get_drvdata(dev);
304 umode_t effective_mode = attr->mode;
305
306 /* Skip attributes if DPM is not enabled */
307 if (!adev->pm.dpm_enabled &&
308 (attr == &sensor_dev_attr_temp1_crit.dev_attr.attr ||
309 attr == &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr ||
310 attr == &sensor_dev_attr_pwm1.dev_attr.attr ||
311 attr == &sensor_dev_attr_pwm1_enable.dev_attr.attr ||
312 attr == &sensor_dev_attr_pwm1_max.dev_attr.attr ||
313 attr == &sensor_dev_attr_pwm1_min.dev_attr.attr))
314 return 0;
315
316 /* Skip fan attributes if fan is not present */
317 if (adev->pm.no_fan &&
318 (attr == &sensor_dev_attr_pwm1.dev_attr.attr ||
319 attr == &sensor_dev_attr_pwm1_enable.dev_attr.attr ||
320 attr == &sensor_dev_attr_pwm1_max.dev_attr.attr ||
321 attr == &sensor_dev_attr_pwm1_min.dev_attr.attr))
322 return 0;
323
324 /* mask fan attributes if we have no bindings for this asic to expose */
325 if ((!adev->pm.funcs->get_fan_speed_percent &&
326 attr == &sensor_dev_attr_pwm1.dev_attr.attr) || /* can't query fan */
327 (!adev->pm.funcs->get_fan_control_mode &&
328 attr == &sensor_dev_attr_pwm1_enable.dev_attr.attr)) /* can't query state */
329 effective_mode &= ~S_IRUGO;
330
331 if ((!adev->pm.funcs->set_fan_speed_percent &&
332 attr == &sensor_dev_attr_pwm1.dev_attr.attr) || /* can't manage fan */
333 (!adev->pm.funcs->set_fan_control_mode &&
334 attr == &sensor_dev_attr_pwm1_enable.dev_attr.attr)) /* can't manage state */
335 effective_mode &= ~S_IWUSR;
336
337 /* hide max/min values if we can't both query and manage the fan */
338 if ((!adev->pm.funcs->set_fan_speed_percent &&
339 !adev->pm.funcs->get_fan_speed_percent) &&
340 (attr == &sensor_dev_attr_pwm1_max.dev_attr.attr ||
341 attr == &sensor_dev_attr_pwm1_min.dev_attr.attr))
342 return 0;
343
344 return effective_mode;
345 }
346
347 static const struct attribute_group hwmon_attrgroup = {
348 .attrs = hwmon_attributes,
349 .is_visible = hwmon_attributes_visible,
350 };
351
352 static const struct attribute_group *hwmon_groups[] = {
353 &hwmon_attrgroup,
354 NULL
355 };
356
357 #endif /* __NetBSD__ */
358
359 void amdgpu_dpm_thermal_work_handler(struct work_struct *work)
360 {
361 struct amdgpu_device *adev =
362 container_of(work, struct amdgpu_device,
363 pm.dpm.thermal.work);
364 /* switch to the thermal state */
365 enum amdgpu_pm_state_type dpm_state = POWER_STATE_TYPE_INTERNAL_THERMAL;
366
367 if (!adev->pm.dpm_enabled)
368 return;
369
370 if (adev->pm.funcs->get_temperature) {
371 int temp = amdgpu_dpm_get_temperature(adev);
372
373 if (temp < adev->pm.dpm.thermal.min_temp)
374 /* switch back the user state */
375 dpm_state = adev->pm.dpm.user_state;
376 } else {
377 if (adev->pm.dpm.thermal.high_to_low)
378 /* switch back the user state */
379 dpm_state = adev->pm.dpm.user_state;
380 }
381 mutex_lock(&adev->pm.mutex);
382 if (dpm_state == POWER_STATE_TYPE_INTERNAL_THERMAL)
383 adev->pm.dpm.thermal_active = true;
384 else
385 adev->pm.dpm.thermal_active = false;
386 adev->pm.dpm.state = dpm_state;
387 mutex_unlock(&adev->pm.mutex);
388
389 amdgpu_pm_compute_clocks(adev);
390 }
391
392 static struct amdgpu_ps *amdgpu_dpm_pick_power_state(struct amdgpu_device *adev,
393 enum amdgpu_pm_state_type dpm_state)
394 {
395 int i;
396 struct amdgpu_ps *ps;
397 u32 ui_class;
398 bool single_display = (adev->pm.dpm.new_active_crtc_count < 2) ?
399 true : false;
400
401 /* check if the vblank period is too short to adjust the mclk */
402 if (single_display && adev->pm.funcs->vblank_too_short) {
403 if (amdgpu_dpm_vblank_too_short(adev))
404 single_display = false;
405 }
406
407 /* certain older asics have a separare 3D performance state,
408 * so try that first if the user selected performance
409 */
410 if (dpm_state == POWER_STATE_TYPE_PERFORMANCE)
411 dpm_state = POWER_STATE_TYPE_INTERNAL_3DPERF;
412 /* balanced states don't exist at the moment */
413 if (dpm_state == POWER_STATE_TYPE_BALANCED)
414 dpm_state = POWER_STATE_TYPE_PERFORMANCE;
415
416 restart_search:
417 /* Pick the best power state based on current conditions */
418 for (i = 0; i < adev->pm.dpm.num_ps; i++) {
419 ps = &adev->pm.dpm.ps[i];
420 ui_class = ps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK;
421 switch (dpm_state) {
422 /* user states */
423 case POWER_STATE_TYPE_BATTERY:
424 if (ui_class == ATOM_PPLIB_CLASSIFICATION_UI_BATTERY) {
425 if (ps->caps & ATOM_PPLIB_SINGLE_DISPLAY_ONLY) {
426 if (single_display)
427 return ps;
428 } else
429 return ps;
430 }
431 break;
432 case POWER_STATE_TYPE_BALANCED:
433 if (ui_class == ATOM_PPLIB_CLASSIFICATION_UI_BALANCED) {
434 if (ps->caps & ATOM_PPLIB_SINGLE_DISPLAY_ONLY) {
435 if (single_display)
436 return ps;
437 } else
438 return ps;
439 }
440 break;
441 case POWER_STATE_TYPE_PERFORMANCE:
442 if (ui_class == ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE) {
443 if (ps->caps & ATOM_PPLIB_SINGLE_DISPLAY_ONLY) {
444 if (single_display)
445 return ps;
446 } else
447 return ps;
448 }
449 break;
450 /* internal states */
451 case POWER_STATE_TYPE_INTERNAL_UVD:
452 if (adev->pm.dpm.uvd_ps)
453 return adev->pm.dpm.uvd_ps;
454 else
455 break;
456 case POWER_STATE_TYPE_INTERNAL_UVD_SD:
457 if (ps->class & ATOM_PPLIB_CLASSIFICATION_SDSTATE)
458 return ps;
459 break;
460 case POWER_STATE_TYPE_INTERNAL_UVD_HD:
461 if (ps->class & ATOM_PPLIB_CLASSIFICATION_HDSTATE)
462 return ps;
463 break;
464 case POWER_STATE_TYPE_INTERNAL_UVD_HD2:
465 if (ps->class & ATOM_PPLIB_CLASSIFICATION_HD2STATE)
466 return ps;
467 break;
468 case POWER_STATE_TYPE_INTERNAL_UVD_MVC:
469 if (ps->class2 & ATOM_PPLIB_CLASSIFICATION2_MVC)
470 return ps;
471 break;
472 case POWER_STATE_TYPE_INTERNAL_BOOT:
473 return adev->pm.dpm.boot_ps;
474 case POWER_STATE_TYPE_INTERNAL_THERMAL:
475 if (ps->class & ATOM_PPLIB_CLASSIFICATION_THERMAL)
476 return ps;
477 break;
478 case POWER_STATE_TYPE_INTERNAL_ACPI:
479 if (ps->class & ATOM_PPLIB_CLASSIFICATION_ACPI)
480 return ps;
481 break;
482 case POWER_STATE_TYPE_INTERNAL_ULV:
483 if (ps->class2 & ATOM_PPLIB_CLASSIFICATION2_ULV)
484 return ps;
485 break;
486 case POWER_STATE_TYPE_INTERNAL_3DPERF:
487 if (ps->class & ATOM_PPLIB_CLASSIFICATION_3DPERFORMANCE)
488 return ps;
489 break;
490 default:
491 break;
492 }
493 }
494 /* use a fallback state if we didn't match */
495 switch (dpm_state) {
496 case POWER_STATE_TYPE_INTERNAL_UVD_SD:
497 dpm_state = POWER_STATE_TYPE_INTERNAL_UVD_HD;
498 goto restart_search;
499 case POWER_STATE_TYPE_INTERNAL_UVD_HD:
500 case POWER_STATE_TYPE_INTERNAL_UVD_HD2:
501 case POWER_STATE_TYPE_INTERNAL_UVD_MVC:
502 if (adev->pm.dpm.uvd_ps) {
503 return adev->pm.dpm.uvd_ps;
504 } else {
505 dpm_state = POWER_STATE_TYPE_PERFORMANCE;
506 goto restart_search;
507 }
508 case POWER_STATE_TYPE_INTERNAL_THERMAL:
509 dpm_state = POWER_STATE_TYPE_INTERNAL_ACPI;
510 goto restart_search;
511 case POWER_STATE_TYPE_INTERNAL_ACPI:
512 dpm_state = POWER_STATE_TYPE_BATTERY;
513 goto restart_search;
514 case POWER_STATE_TYPE_BATTERY:
515 case POWER_STATE_TYPE_BALANCED:
516 case POWER_STATE_TYPE_INTERNAL_3DPERF:
517 dpm_state = POWER_STATE_TYPE_PERFORMANCE;
518 goto restart_search;
519 default:
520 break;
521 }
522
523 return NULL;
524 }
525
526 static void amdgpu_dpm_change_power_state_locked(struct amdgpu_device *adev)
527 {
528 int i;
529 struct amdgpu_ps *ps;
530 enum amdgpu_pm_state_type dpm_state;
531 int ret;
532
533 /* if dpm init failed */
534 if (!adev->pm.dpm_enabled)
535 return;
536
537 if (adev->pm.dpm.user_state != adev->pm.dpm.state) {
538 /* add other state override checks here */
539 if ((!adev->pm.dpm.thermal_active) &&
540 (!adev->pm.dpm.uvd_active))
541 adev->pm.dpm.state = adev->pm.dpm.user_state;
542 }
543 dpm_state = adev->pm.dpm.state;
544
545 ps = amdgpu_dpm_pick_power_state(adev, dpm_state);
546 if (ps)
547 adev->pm.dpm.requested_ps = ps;
548 else
549 return;
550
551 /* no need to reprogram if nothing changed unless we are on BTC+ */
552 if (adev->pm.dpm.current_ps == adev->pm.dpm.requested_ps) {
553 /* vce just modifies an existing state so force a change */
554 if (ps->vce_active != adev->pm.dpm.vce_active)
555 goto force;
556 if (adev->flags & AMD_IS_APU) {
557 /* for APUs if the num crtcs changed but state is the same,
558 * all we need to do is update the display configuration.
559 */
560 if (adev->pm.dpm.new_active_crtcs != adev->pm.dpm.current_active_crtcs) {
561 /* update display watermarks based on new power state */
562 amdgpu_display_bandwidth_update(adev);
563 /* update displays */
564 amdgpu_dpm_display_configuration_changed(adev);
565 adev->pm.dpm.current_active_crtcs = adev->pm.dpm.new_active_crtcs;
566 adev->pm.dpm.current_active_crtc_count = adev->pm.dpm.new_active_crtc_count;
567 }
568 return;
569 } else {
570 /* for BTC+ if the num crtcs hasn't changed and state is the same,
571 * nothing to do, if the num crtcs is > 1 and state is the same,
572 * update display configuration.
573 */
574 if (adev->pm.dpm.new_active_crtcs ==
575 adev->pm.dpm.current_active_crtcs) {
576 return;
577 } else if ((adev->pm.dpm.current_active_crtc_count > 1) &&
578 (adev->pm.dpm.new_active_crtc_count > 1)) {
579 /* update display watermarks based on new power state */
580 amdgpu_display_bandwidth_update(adev);
581 /* update displays */
582 amdgpu_dpm_display_configuration_changed(adev);
583 adev->pm.dpm.current_active_crtcs = adev->pm.dpm.new_active_crtcs;
584 adev->pm.dpm.current_active_crtc_count = adev->pm.dpm.new_active_crtc_count;
585 return;
586 }
587 }
588 }
589
590 force:
591 if (amdgpu_dpm == 1) {
592 printk("switching from power state:\n");
593 amdgpu_dpm_print_power_state(adev, adev->pm.dpm.current_ps);
594 printk("switching to power state:\n");
595 amdgpu_dpm_print_power_state(adev, adev->pm.dpm.requested_ps);
596 }
597
598 mutex_lock(&adev->ring_lock);
599
600 /* update whether vce is active */
601 ps->vce_active = adev->pm.dpm.vce_active;
602
603 ret = amdgpu_dpm_pre_set_power_state(adev);
604 if (ret)
605 goto done;
606
607 /* update display watermarks based on new power state */
608 amdgpu_display_bandwidth_update(adev);
609
610 /* wait for the rings to drain */
611 for (i = 0; i < AMDGPU_MAX_RINGS; i++) {
612 struct amdgpu_ring *ring = adev->rings[i];
613 if (ring && ring->ready)
614 amdgpu_fence_wait_empty(ring);
615 }
616
617 /* program the new power state */
618 amdgpu_dpm_set_power_state(adev);
619
620 /* update current power state */
621 adev->pm.dpm.current_ps = adev->pm.dpm.requested_ps;
622
623 amdgpu_dpm_post_set_power_state(adev);
624
625 /* update displays */
626 amdgpu_dpm_display_configuration_changed(adev);
627
628 adev->pm.dpm.current_active_crtcs = adev->pm.dpm.new_active_crtcs;
629 adev->pm.dpm.current_active_crtc_count = adev->pm.dpm.new_active_crtc_count;
630
631 if (adev->pm.funcs->force_performance_level) {
632 if (adev->pm.dpm.thermal_active) {
633 enum amdgpu_dpm_forced_level level = adev->pm.dpm.forced_level;
634 /* force low perf level for thermal */
635 amdgpu_dpm_force_performance_level(adev, AMDGPU_DPM_FORCED_LEVEL_LOW);
636 /* save the user's level */
637 adev->pm.dpm.forced_level = level;
638 } else {
639 /* otherwise, user selected level */
640 amdgpu_dpm_force_performance_level(adev, adev->pm.dpm.forced_level);
641 }
642 }
643
644 done:
645 mutex_unlock(&adev->ring_lock);
646 }
647
648 void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable)
649 {
650 if (adev->pm.funcs->powergate_uvd) {
651 mutex_lock(&adev->pm.mutex);
652 /* enable/disable UVD */
653 amdgpu_dpm_powergate_uvd(adev, !enable);
654 mutex_unlock(&adev->pm.mutex);
655 } else {
656 if (enable) {
657 mutex_lock(&adev->pm.mutex);
658 adev->pm.dpm.uvd_active = true;
659 adev->pm.dpm.state = POWER_STATE_TYPE_INTERNAL_UVD;
660 mutex_unlock(&adev->pm.mutex);
661 } else {
662 mutex_lock(&adev->pm.mutex);
663 adev->pm.dpm.uvd_active = false;
664 mutex_unlock(&adev->pm.mutex);
665 }
666
667 amdgpu_pm_compute_clocks(adev);
668 }
669 }
670
671 void amdgpu_dpm_enable_vce(struct amdgpu_device *adev, bool enable)
672 {
673 if (adev->pm.funcs->powergate_vce) {
674 mutex_lock(&adev->pm.mutex);
675 /* enable/disable VCE */
676 amdgpu_dpm_powergate_vce(adev, !enable);
677
678 mutex_unlock(&adev->pm.mutex);
679 } else {
680 if (enable) {
681 mutex_lock(&adev->pm.mutex);
682 adev->pm.dpm.vce_active = true;
683 /* XXX select vce level based on ring/task */
684 adev->pm.dpm.vce_level = AMDGPU_VCE_LEVEL_AC_ALL;
685 mutex_unlock(&adev->pm.mutex);
686 } else {
687 mutex_lock(&adev->pm.mutex);
688 adev->pm.dpm.vce_active = false;
689 mutex_unlock(&adev->pm.mutex);
690 }
691
692 amdgpu_pm_compute_clocks(adev);
693 }
694 }
695
696 void amdgpu_pm_print_power_states(struct amdgpu_device *adev)
697 {
698 int i;
699
700 for (i = 0; i < adev->pm.dpm.num_ps; i++) {
701 printk("== power state %d ==\n", i);
702 amdgpu_dpm_print_power_state(adev, &adev->pm.dpm.ps[i]);
703 }
704 }
705
706 int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
707 {
708 #ifdef __NetBSD__ /* XXX sysfs */
709 return 0;
710 #else
711 int ret;
712
713 if (adev->pm.sysfs_initialized)
714 return 0;
715
716 if (adev->pm.funcs->get_temperature == NULL)
717 return 0;
718 adev->pm.int_hwmon_dev = hwmon_device_register_with_groups(adev->dev,
719 DRIVER_NAME, adev,
720 hwmon_groups);
721 if (IS_ERR(adev->pm.int_hwmon_dev)) {
722 ret = PTR_ERR(adev->pm.int_hwmon_dev);
723 dev_err(adev->dev,
724 "Unable to register hwmon device: %d\n", ret);
725 return ret;
726 }
727
728 ret = device_create_file(adev->dev, &dev_attr_power_dpm_state);
729 if (ret) {
730 DRM_ERROR("failed to create device file for dpm state\n");
731 return ret;
732 }
733 ret = device_create_file(adev->dev, &dev_attr_power_dpm_force_performance_level);
734 if (ret) {
735 DRM_ERROR("failed to create device file for dpm state\n");
736 return ret;
737 }
738 ret = amdgpu_debugfs_pm_init(adev);
739 if (ret) {
740 DRM_ERROR("Failed to register debugfs file for dpm!\n");
741 return ret;
742 }
743
744 adev->pm.sysfs_initialized = true;
745
746 return 0;
747 #endif
748 }
749
750 void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev)
751 {
752 #ifndef __NetBSD__
753 if (adev->pm.int_hwmon_dev)
754 hwmon_device_unregister(adev->pm.int_hwmon_dev);
755 device_remove_file(adev->dev, &dev_attr_power_dpm_state);
756 device_remove_file(adev->dev, &dev_attr_power_dpm_force_performance_level);
757 #endif
758 }
759
760 void amdgpu_pm_compute_clocks(struct amdgpu_device *adev)
761 {
762 struct drm_device *ddev = adev->ddev;
763 struct drm_crtc *crtc;
764 struct amdgpu_crtc *amdgpu_crtc;
765
766 if (!adev->pm.dpm_enabled)
767 return;
768
769 mutex_lock(&adev->pm.mutex);
770
771 /* update active crtc counts */
772 adev->pm.dpm.new_active_crtcs = 0;
773 adev->pm.dpm.new_active_crtc_count = 0;
774 if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
775 list_for_each_entry(crtc,
776 &ddev->mode_config.crtc_list, head) {
777 amdgpu_crtc = to_amdgpu_crtc(crtc);
778 if (crtc->enabled) {
779 adev->pm.dpm.new_active_crtcs |= (1 << amdgpu_crtc->crtc_id);
780 adev->pm.dpm.new_active_crtc_count++;
781 }
782 }
783 }
784
785 /* update battery/ac status */
786 if (power_supply_is_system_supplied() > 0)
787 adev->pm.dpm.ac_power = true;
788 else
789 adev->pm.dpm.ac_power = false;
790
791 amdgpu_dpm_change_power_state_locked(adev);
792
793 mutex_unlock(&adev->pm.mutex);
794
795 }
796
797 /*
798 * Debugfs info
799 */
800 #if defined(CONFIG_DEBUG_FS)
801
802 static int amdgpu_debugfs_pm_info(struct seq_file *m, void *data)
803 {
804 struct drm_info_node *node = (struct drm_info_node *) m->private;
805 struct drm_device *dev = node->minor->dev;
806 struct amdgpu_device *adev = dev->dev_private;
807
808 if (adev->pm.dpm_enabled) {
809 mutex_lock(&adev->pm.mutex);
810 if (adev->pm.funcs->debugfs_print_current_performance_level)
811 amdgpu_dpm_debugfs_print_current_performance_level(adev, m);
812 else
813 seq_printf(m, "Debugfs support not implemented for this asic\n");
814 mutex_unlock(&adev->pm.mutex);
815 }
816
817 return 0;
818 }
819
820 static struct drm_info_list amdgpu_pm_info_list[] = {
821 {"amdgpu_pm_info", amdgpu_debugfs_pm_info, 0, NULL},
822 };
823 #endif
824
825 #ifndef __NetBSD__ /* XXX sysfs */
826 static int amdgpu_debugfs_pm_init(struct amdgpu_device *adev)
827 {
828 #if defined(CONFIG_DEBUG_FS)
829 return amdgpu_debugfs_add_files(adev, amdgpu_pm_info_list, ARRAY_SIZE(amdgpu_pm_info_list));
830 #else
831 return 0;
832 #endif
833 }
834 #endif
835