2 * Copyright 2010 Red Hat Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
26 #include <linux/acpi.h>
28 #include <linux/power_supply.h>
29 #include <linux/hwmon.h>
30 #include <linux/hwmon-sysfs.h>
34 #include "nouveau_drm.h"
35 #include "nouveau_pm.h"
37 #include <subdev/gpio.h>
38 #include <subdev/timer.h>
39 #include <subdev/therm.h>
41 MODULE_PARM_DESC(perflvl
, "Performance level (default: boot)");
42 static char *nouveau_perflvl
;
43 module_param_named(perflvl
, nouveau_perflvl
, charp
, 0400);
45 MODULE_PARM_DESC(perflvl_wr
, "Allow perflvl changes (warning: dangerous!)");
46 static int nouveau_perflvl_wr
;
47 module_param_named(perflvl_wr
, nouveau_perflvl_wr
, int, 0400);
50 nouveau_pm_perflvl_aux(struct drm_device
*dev
, struct nouveau_pm_level
*perflvl
,
51 struct nouveau_pm_level
*a
, struct nouveau_pm_level
*b
)
53 struct nouveau_drm
*drm
= nouveau_drm(dev
);
54 struct nouveau_pm
*pm
= nouveau_pm(dev
);
55 struct nouveau_therm
*therm
= nouveau_therm(drm
);
58 /*XXX: not on all boards, we should control based on temperature
59 * on recent boards.. or maybe on some other factor we don't
62 if (therm
&& therm
->fan_set
&&
63 a
->fanspeed
&& b
->fanspeed
&& b
->fanspeed
> a
->fanspeed
) {
64 ret
= therm
->fan_set(therm
, perflvl
->fanspeed
);
65 if (ret
&& ret
!= -ENODEV
) {
66 NV_ERROR(drm
, "fanspeed set failed: %d\n", ret
);
71 if (pm
->voltage
.supported
&& pm
->voltage_set
) {
72 if (perflvl
->volt_min
&& b
->volt_min
> a
->volt_min
) {
73 ret
= pm
->voltage_set(dev
, perflvl
->volt_min
);
75 NV_ERROR(drm
, "voltage set failed: %d\n", ret
);
85 nouveau_pm_perflvl_set(struct drm_device
*dev
, struct nouveau_pm_level
*perflvl
)
87 struct nouveau_pm
*pm
= nouveau_pm(dev
);
91 if (perflvl
== pm
->cur
)
94 ret
= nouveau_pm_perflvl_aux(dev
, perflvl
, pm
->cur
, perflvl
);
98 state
= pm
->clocks_pre(dev
, perflvl
);
100 ret
= PTR_ERR(state
);
103 ret
= pm
->clocks_set(dev
, state
);
107 ret
= nouveau_pm_perflvl_aux(dev
, perflvl
, perflvl
, pm
->cur
);
115 /* restore the fan speed and voltage before leaving */
116 nouveau_pm_perflvl_aux(dev
, perflvl
, perflvl
, pm
->cur
);
121 nouveau_pm_trigger(struct drm_device
*dev
)
123 struct nouveau_drm
*drm
= nouveau_drm(dev
);
124 struct nouveau_timer
*ptimer
= nouveau_timer(drm
->device
);
125 struct nouveau_pm
*pm
= nouveau_pm(dev
);
126 struct nouveau_pm_profile
*profile
= NULL
;
127 struct nouveau_pm_level
*perflvl
= NULL
;
130 /* select power profile based on current power source */
131 if (power_supply_is_system_supplied())
132 profile
= pm
->profile_ac
;
134 profile
= pm
->profile_dc
;
136 if (profile
!= pm
->profile
) {
137 pm
->profile
->func
->fini(pm
->profile
);
138 pm
->profile
= profile
;
139 pm
->profile
->func
->init(pm
->profile
);
142 /* select performance level based on profile */
143 perflvl
= profile
->func
->select(profile
);
145 /* change perflvl, if necessary */
146 if (perflvl
!= pm
->cur
) {
147 u64 time0
= ptimer
->read(ptimer
);
149 NV_INFO(drm
, "setting performance level: %d", perflvl
->id
);
150 ret
= nouveau_pm_perflvl_set(dev
, perflvl
);
152 NV_INFO(drm
, "> reclocking failed: %d\n\n", ret
);
154 NV_INFO(drm
, "> reclocking took %lluns\n\n",
155 ptimer
->read(ptimer
) - time0
);
159 static struct nouveau_pm_profile
*
160 profile_find(struct drm_device
*dev
, const char *string
)
162 struct nouveau_pm
*pm
= nouveau_pm(dev
);
163 struct nouveau_pm_profile
*profile
;
165 list_for_each_entry(profile
, &pm
->profiles
, head
) {
166 if (!strncmp(profile
->name
, string
, sizeof(profile
->name
)))
174 nouveau_pm_profile_set(struct drm_device
*dev
, const char *profile
)
176 struct nouveau_pm
*pm
= nouveau_pm(dev
);
177 struct nouveau_pm_profile
*ac
= NULL
, *dc
= NULL
;
178 char string
[16], *cur
= string
, *ptr
;
180 /* safety precaution, for now */
181 if (nouveau_perflvl_wr
!= 7777)
184 strncpy(string
, profile
, sizeof(string
));
185 string
[sizeof(string
) - 1] = 0;
186 if ((ptr
= strchr(string
, '\n')))
189 ptr
= strsep(&cur
, ",");
191 ac
= profile_find(dev
, ptr
);
193 ptr
= strsep(&cur
, ",");
195 dc
= profile_find(dev
, ptr
);
199 if (ac
== NULL
|| dc
== NULL
)
204 nouveau_pm_trigger(dev
);
209 nouveau_pm_static_dummy(struct nouveau_pm_profile
*profile
)
213 static struct nouveau_pm_level
*
214 nouveau_pm_static_select(struct nouveau_pm_profile
*profile
)
216 return container_of(profile
, struct nouveau_pm_level
, profile
);
219 const struct nouveau_pm_profile_func nouveau_pm_static_profile_func
= {
220 .destroy
= nouveau_pm_static_dummy
,
221 .init
= nouveau_pm_static_dummy
,
222 .fini
= nouveau_pm_static_dummy
,
223 .select
= nouveau_pm_static_select
,
227 nouveau_pm_perflvl_get(struct drm_device
*dev
, struct nouveau_pm_level
*perflvl
)
229 struct nouveau_drm
*drm
= nouveau_drm(dev
);
230 struct nouveau_pm
*pm
= nouveau_pm(dev
);
231 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
234 memset(perflvl
, 0, sizeof(*perflvl
));
236 if (pm
->clocks_get
) {
237 ret
= pm
->clocks_get(dev
, perflvl
);
242 if (pm
->voltage
.supported
&& pm
->voltage_get
) {
243 ret
= pm
->voltage_get(dev
);
245 perflvl
->volt_min
= ret
;
246 perflvl
->volt_max
= ret
;
250 if (therm
&& therm
->fan_get
) {
251 ret
= therm
->fan_get(therm
);
253 perflvl
->fanspeed
= ret
;
256 nouveau_mem_timing_read(dev
, &perflvl
->timing
);
261 nouveau_pm_perflvl_info(struct nouveau_pm_level
*perflvl
, char *ptr
, int len
)
263 char c
[16], s
[16], v
[32], f
[16], m
[16];
267 snprintf(c
, sizeof(c
), " core %dMHz", perflvl
->core
/ 1000);
271 snprintf(s
, sizeof(s
), " shader %dMHz", perflvl
->shader
/ 1000);
275 snprintf(m
, sizeof(m
), " memory %dMHz", perflvl
->memory
/ 1000);
278 if (perflvl
->volt_min
&& perflvl
->volt_min
!= perflvl
->volt_max
) {
279 snprintf(v
, sizeof(v
), " voltage %dmV-%dmV",
280 perflvl
->volt_min
/ 1000, perflvl
->volt_max
/ 1000);
282 if (perflvl
->volt_min
) {
283 snprintf(v
, sizeof(v
), " voltage %dmV",
284 perflvl
->volt_min
/ 1000);
288 if (perflvl
->fanspeed
)
289 snprintf(f
, sizeof(f
), " fanspeed %d%%", perflvl
->fanspeed
);
291 snprintf(ptr
, len
, "%s%s%s%s%s\n", c
, s
, m
, v
, f
);
295 nouveau_pm_get_perflvl_info(struct device
*d
,
296 struct device_attribute
*a
, char *buf
)
298 struct nouveau_pm_level
*perflvl
=
299 container_of(a
, struct nouveau_pm_level
, dev_attr
);
303 snprintf(ptr
, len
, "%d:", perflvl
->id
);
307 nouveau_pm_perflvl_info(perflvl
, ptr
, len
);
312 nouveau_pm_get_perflvl(struct device
*d
, struct device_attribute
*a
, char *buf
)
314 struct drm_device
*dev
= pci_get_drvdata(to_pci_dev(d
));
315 struct nouveau_pm
*pm
= nouveau_pm(dev
);
316 struct nouveau_pm_level cur
;
317 int len
= PAGE_SIZE
, ret
;
320 snprintf(ptr
, len
, "profile: %s, %s\nc:",
321 pm
->profile_ac
->name
, pm
->profile_dc
->name
);
325 ret
= nouveau_pm_perflvl_get(dev
, &cur
);
327 nouveau_pm_perflvl_info(&cur
, ptr
, len
);
332 nouveau_pm_set_perflvl(struct device
*d
, struct device_attribute
*a
,
333 const char *buf
, size_t count
)
335 struct drm_device
*dev
= pci_get_drvdata(to_pci_dev(d
));
338 ret
= nouveau_pm_profile_set(dev
, buf
);
344 static DEVICE_ATTR(performance_level
, S_IRUGO
| S_IWUSR
,
345 nouveau_pm_get_perflvl
, nouveau_pm_set_perflvl
);
348 nouveau_sysfs_init(struct drm_device
*dev
)
350 struct nouveau_drm
*drm
= nouveau_drm(dev
);
351 struct nouveau_pm
*pm
= nouveau_pm(dev
);
352 struct device
*d
= &dev
->pdev
->dev
;
355 ret
= device_create_file(d
, &dev_attr_performance_level
);
359 for (i
= 0; i
< pm
->nr_perflvl
; i
++) {
360 struct nouveau_pm_level
*perflvl
= &pm
->perflvl
[i
];
362 perflvl
->dev_attr
.attr
.name
= perflvl
->name
;
363 perflvl
->dev_attr
.attr
.mode
= S_IRUGO
;
364 perflvl
->dev_attr
.show
= nouveau_pm_get_perflvl_info
;
365 perflvl
->dev_attr
.store
= NULL
;
366 sysfs_attr_init(&perflvl
->dev_attr
.attr
);
368 ret
= device_create_file(d
, &perflvl
->dev_attr
);
370 NV_ERROR(drm
, "failed pervlvl %d sysfs: %d\n",
372 perflvl
->dev_attr
.attr
.name
= NULL
;
373 nouveau_pm_fini(dev
);
382 nouveau_sysfs_fini(struct drm_device
*dev
)
384 struct nouveau_pm
*pm
= nouveau_pm(dev
);
385 struct device
*d
= &dev
->pdev
->dev
;
388 device_remove_file(d
, &dev_attr_performance_level
);
389 for (i
= 0; i
< pm
->nr_perflvl
; i
++) {
390 struct nouveau_pm_level
*pl
= &pm
->perflvl
[i
];
392 if (!pl
->dev_attr
.attr
.name
)
395 device_remove_file(d
, &pl
->dev_attr
);
399 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
401 nouveau_hwmon_show_temp(struct device
*d
, struct device_attribute
*a
, char *buf
)
403 struct drm_device
*dev
= dev_get_drvdata(d
);
404 struct nouveau_drm
*drm
= nouveau_drm(dev
);
405 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
407 return snprintf(buf
, PAGE_SIZE
, "%d\n", therm
->temp_get(therm
) * 1000);
409 static SENSOR_DEVICE_ATTR(temp1_input
, S_IRUGO
, nouveau_hwmon_show_temp
,
413 nouveau_hwmon_max_temp(struct device
*d
, struct device_attribute
*a
, char *buf
)
415 struct drm_device
*dev
= dev_get_drvdata(d
);
416 struct nouveau_drm
*drm
= nouveau_drm(dev
);
417 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
419 return snprintf(buf
, PAGE_SIZE
, "%d\n",
420 therm
->attr_get(therm
, NOUVEAU_THERM_ATTR_THRS_DOWN_CLK
) * 1000);
423 nouveau_hwmon_set_max_temp(struct device
*d
, struct device_attribute
*a
,
424 const char *buf
, size_t count
)
426 struct drm_device
*dev
= dev_get_drvdata(d
);
427 struct nouveau_drm
*drm
= nouveau_drm(dev
);
428 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
431 if (kstrtol(buf
, 10, &value
) == -EINVAL
)
434 therm
->attr_set(therm
, NOUVEAU_THERM_ATTR_THRS_DOWN_CLK
, value
/ 1000);
438 static SENSOR_DEVICE_ATTR(temp1_max
, S_IRUGO
| S_IWUSR
, nouveau_hwmon_max_temp
,
439 nouveau_hwmon_set_max_temp
,
443 nouveau_hwmon_critical_temp(struct device
*d
, struct device_attribute
*a
,
446 struct drm_device
*dev
= dev_get_drvdata(d
);
447 struct nouveau_drm
*drm
= nouveau_drm(dev
);
448 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
450 return snprintf(buf
, PAGE_SIZE
, "%d\n",
451 therm
->attr_get(therm
, NOUVEAU_THERM_ATTR_THRS_CRITICAL
) * 1000);
454 nouveau_hwmon_set_critical_temp(struct device
*d
, struct device_attribute
*a
,
458 struct drm_device
*dev
= dev_get_drvdata(d
);
459 struct nouveau_drm
*drm
= nouveau_drm(dev
);
460 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
463 if (kstrtol(buf
, 10, &value
) == -EINVAL
)
466 therm
->attr_set(therm
, NOUVEAU_THERM_ATTR_THRS_CRITICAL
, value
/ 1000);
470 static SENSOR_DEVICE_ATTR(temp1_crit
, S_IRUGO
| S_IWUSR
,
471 nouveau_hwmon_critical_temp
,
472 nouveau_hwmon_set_critical_temp
,
475 static ssize_t
nouveau_hwmon_show_name(struct device
*dev
,
476 struct device_attribute
*attr
,
479 return sprintf(buf
, "nouveau\n");
481 static SENSOR_DEVICE_ATTR(name
, S_IRUGO
, nouveau_hwmon_show_name
, NULL
, 0);
483 static ssize_t
nouveau_hwmon_show_update_rate(struct device
*dev
,
484 struct device_attribute
*attr
,
487 return sprintf(buf
, "1000\n");
489 static SENSOR_DEVICE_ATTR(update_rate
, S_IRUGO
,
490 nouveau_hwmon_show_update_rate
,
494 nouveau_hwmon_show_fan0_input(struct device
*d
, struct device_attribute
*attr
,
497 struct drm_device
*dev
= dev_get_drvdata(d
);
498 struct nouveau_drm
*drm
= nouveau_drm(dev
);
499 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
501 return snprintf(buf
, PAGE_SIZE
, "%d\n", therm
->fan_sense(therm
));
503 static SENSOR_DEVICE_ATTR(fan0_input
, S_IRUGO
, nouveau_hwmon_show_fan0_input
,
507 nouveau_hwmon_get_pwm0(struct device
*d
, struct device_attribute
*a
, char *buf
)
509 struct drm_device
*dev
= dev_get_drvdata(d
);
510 struct nouveau_drm
*drm
= nouveau_drm(dev
);
511 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
514 ret
= therm
->fan_get(therm
);
518 return sprintf(buf
, "%i\n", ret
);
522 nouveau_hwmon_set_pwm0(struct device
*d
, struct device_attribute
*a
,
523 const char *buf
, size_t count
)
525 struct drm_device
*dev
= dev_get_drvdata(d
);
526 struct nouveau_drm
*drm
= nouveau_drm(dev
);
527 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
531 if (nouveau_perflvl_wr
!= 7777)
534 if (kstrtol(buf
, 10, &value
) == -EINVAL
)
537 ret
= therm
->fan_set(therm
, value
);
544 static SENSOR_DEVICE_ATTR(pwm0
, S_IRUGO
| S_IWUSR
,
545 nouveau_hwmon_get_pwm0
,
546 nouveau_hwmon_set_pwm0
, 0);
549 nouveau_hwmon_get_pwm0_min(struct device
*d
,
550 struct device_attribute
*a
, char *buf
)
552 struct drm_device
*dev
= dev_get_drvdata(d
);
553 struct nouveau_drm
*drm
= nouveau_drm(dev
);
554 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
557 ret
= therm
->attr_get(therm
, NOUVEAU_THERM_ATTR_FAN_MIN_DUTY
);
561 return sprintf(buf
, "%i\n", ret
);
565 nouveau_hwmon_set_pwm0_min(struct device
*d
, struct device_attribute
*a
,
566 const char *buf
, size_t count
)
568 struct drm_device
*dev
= dev_get_drvdata(d
);
569 struct nouveau_drm
*drm
= nouveau_drm(dev
);
570 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
574 if (kstrtol(buf
, 10, &value
) == -EINVAL
)
577 ret
= therm
->attr_set(therm
, NOUVEAU_THERM_ATTR_FAN_MIN_DUTY
, value
);
584 static SENSOR_DEVICE_ATTR(pwm0_min
, S_IRUGO
| S_IWUSR
,
585 nouveau_hwmon_get_pwm0_min
,
586 nouveau_hwmon_set_pwm0_min
, 0);
589 nouveau_hwmon_get_pwm0_max(struct device
*d
,
590 struct device_attribute
*a
, char *buf
)
592 struct drm_device
*dev
= dev_get_drvdata(d
);
593 struct nouveau_drm
*drm
= nouveau_drm(dev
);
594 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
597 ret
= therm
->attr_get(therm
, NOUVEAU_THERM_ATTR_FAN_MAX_DUTY
);
601 return sprintf(buf
, "%i\n", ret
);
605 nouveau_hwmon_set_pwm0_max(struct device
*d
, struct device_attribute
*a
,
606 const char *buf
, size_t count
)
608 struct drm_device
*dev
= dev_get_drvdata(d
);
609 struct nouveau_drm
*drm
= nouveau_drm(dev
);
610 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
614 if (kstrtol(buf
, 10, &value
) == -EINVAL
)
617 ret
= therm
->attr_set(therm
, NOUVEAU_THERM_ATTR_FAN_MAX_DUTY
, value
);
624 static SENSOR_DEVICE_ATTR(pwm0_max
, S_IRUGO
| S_IWUSR
,
625 nouveau_hwmon_get_pwm0_max
,
626 nouveau_hwmon_set_pwm0_max
, 0);
628 static struct attribute
*hwmon_attributes
[] = {
629 &sensor_dev_attr_temp1_input
.dev_attr
.attr
,
630 &sensor_dev_attr_temp1_max
.dev_attr
.attr
,
631 &sensor_dev_attr_temp1_crit
.dev_attr
.attr
,
632 &sensor_dev_attr_name
.dev_attr
.attr
,
633 &sensor_dev_attr_update_rate
.dev_attr
.attr
,
636 static struct attribute
*hwmon_fan_rpm_attributes
[] = {
637 &sensor_dev_attr_fan0_input
.dev_attr
.attr
,
640 static struct attribute
*hwmon_pwm_fan_attributes
[] = {
641 &sensor_dev_attr_pwm0
.dev_attr
.attr
,
642 &sensor_dev_attr_pwm0_min
.dev_attr
.attr
,
643 &sensor_dev_attr_pwm0_max
.dev_attr
.attr
,
647 static const struct attribute_group hwmon_attrgroup
= {
648 .attrs
= hwmon_attributes
,
650 static const struct attribute_group hwmon_fan_rpm_attrgroup
= {
651 .attrs
= hwmon_fan_rpm_attributes
,
653 static const struct attribute_group hwmon_pwm_fan_attrgroup
= {
654 .attrs
= hwmon_pwm_fan_attributes
,
659 nouveau_hwmon_init(struct drm_device
*dev
)
661 struct nouveau_pm
*pm
= nouveau_pm(dev
);
662 struct nouveau_drm
*drm
= nouveau_drm(dev
);
663 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
665 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
666 struct device
*hwmon_dev
;
669 if (!therm
|| !therm
->temp_get
|| !therm
->attr_get
||
670 !therm
->attr_set
|| therm
->temp_get(therm
) < 0)
673 hwmon_dev
= hwmon_device_register(&dev
->pdev
->dev
);
674 if (IS_ERR(hwmon_dev
)) {
675 ret
= PTR_ERR(hwmon_dev
);
676 NV_ERROR(drm
, "Unable to register hwmon device: %d\n", ret
);
679 dev_set_drvdata(hwmon_dev
, dev
);
681 /* default sysfs entries */
682 ret
= sysfs_create_group(&dev
->pdev
->dev
.kobj
, &hwmon_attrgroup
);
688 /* if the card has a pwm fan */
689 /*XXX: incorrect, need better detection for this, some boards have
690 * the gpio entries for pwm fan control even when there's no
691 * actual fan connected to it... therm table? */
692 if (therm
->fan_get
&& therm
->fan_get(therm
) >= 0) {
693 ret
= sysfs_create_group(&dev
->pdev
->dev
.kobj
,
694 &hwmon_pwm_fan_attrgroup
);
699 /* if the card can read the fan rpm */
700 if (therm
->fan_sense(therm
) >= 0) {
701 ret
= sysfs_create_group(&dev
->pdev
->dev
.kobj
,
702 &hwmon_fan_rpm_attrgroup
);
707 pm
->hwmon
= hwmon_dev
;
712 NV_ERROR(drm
, "Unable to create some hwmon sysfs files: %d\n", ret
);
713 hwmon_device_unregister(hwmon_dev
);
723 nouveau_hwmon_fini(struct drm_device
*dev
)
725 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
726 struct nouveau_pm
*pm
= nouveau_pm(dev
);
729 sysfs_remove_group(&dev
->pdev
->dev
.kobj
, &hwmon_attrgroup
);
730 sysfs_remove_group(&dev
->pdev
->dev
.kobj
,
731 &hwmon_pwm_fan_attrgroup
);
732 sysfs_remove_group(&dev
->pdev
->dev
.kobj
,
733 &hwmon_fan_rpm_attrgroup
);
735 hwmon_device_unregister(pm
->hwmon
);
740 #if defined(CONFIG_ACPI) && defined(CONFIG_POWER_SUPPLY)
742 nouveau_pm_acpi_event(struct notifier_block
*nb
, unsigned long val
, void *data
)
744 struct nouveau_pm
*pm
= container_of(nb
, struct nouveau_pm
, acpi_nb
);
745 struct nouveau_drm
*drm
= nouveau_drm(pm
->dev
);
746 struct acpi_bus_event
*entry
= (struct acpi_bus_event
*)data
;
748 if (strcmp(entry
->device_class
, "ac_adapter") == 0) {
749 bool ac
= power_supply_is_system_supplied();
751 NV_DEBUG(drm
, "power supply changed: %s\n", ac
? "AC" : "DC");
752 nouveau_pm_trigger(pm
->dev
);
760 nouveau_pm_init(struct drm_device
*dev
)
762 struct nouveau_device
*device
= nouveau_dev(dev
);
763 struct nouveau_drm
*drm
= nouveau_drm(dev
);
764 struct nouveau_pm
*pm
;
768 pm
= drm
->pm
= kzalloc(sizeof(*pm
), GFP_KERNEL
);
774 if (device
->card_type
< NV_40
) {
775 pm
->clocks_get
= nv04_pm_clocks_get
;
776 pm
->clocks_pre
= nv04_pm_clocks_pre
;
777 pm
->clocks_set
= nv04_pm_clocks_set
;
778 if (nouveau_gpio(drm
->device
)) {
779 pm
->voltage_get
= nouveau_voltage_gpio_get
;
780 pm
->voltage_set
= nouveau_voltage_gpio_set
;
783 if (device
->card_type
< NV_50
) {
784 pm
->clocks_get
= nv40_pm_clocks_get
;
785 pm
->clocks_pre
= nv40_pm_clocks_pre
;
786 pm
->clocks_set
= nv40_pm_clocks_set
;
787 pm
->voltage_get
= nouveau_voltage_gpio_get
;
788 pm
->voltage_set
= nouveau_voltage_gpio_set
;
790 if (device
->card_type
< NV_C0
) {
791 if (device
->chipset
< 0xa3 ||
792 device
->chipset
== 0xaa ||
793 device
->chipset
== 0xac) {
794 pm
->clocks_get
= nv50_pm_clocks_get
;
795 pm
->clocks_pre
= nv50_pm_clocks_pre
;
796 pm
->clocks_set
= nv50_pm_clocks_set
;
798 pm
->clocks_get
= nva3_pm_clocks_get
;
799 pm
->clocks_pre
= nva3_pm_clocks_pre
;
800 pm
->clocks_set
= nva3_pm_clocks_set
;
802 pm
->voltage_get
= nouveau_voltage_gpio_get
;
803 pm
->voltage_set
= nouveau_voltage_gpio_set
;
805 if (device
->card_type
< NV_E0
) {
806 pm
->clocks_get
= nvc0_pm_clocks_get
;
807 pm
->clocks_pre
= nvc0_pm_clocks_pre
;
808 pm
->clocks_set
= nvc0_pm_clocks_set
;
809 pm
->voltage_get
= nouveau_voltage_gpio_get
;
810 pm
->voltage_set
= nouveau_voltage_gpio_set
;
814 /* parse aux tables from vbios */
815 nouveau_volt_init(dev
);
817 INIT_LIST_HEAD(&pm
->profiles
);
819 /* determine current ("boot") performance level */
820 ret
= nouveau_pm_perflvl_get(dev
, &pm
->boot
);
822 NV_ERROR(drm
, "failed to determine boot perflvl\n");
826 strncpy(pm
->boot
.name
, "boot", 4);
827 strncpy(pm
->boot
.profile
.name
, "boot", 4);
828 pm
->boot
.profile
.func
= &nouveau_pm_static_profile_func
;
830 list_add(&pm
->boot
.profile
.head
, &pm
->profiles
);
832 pm
->profile_ac
= &pm
->boot
.profile
;
833 pm
->profile_dc
= &pm
->boot
.profile
;
834 pm
->profile
= &pm
->boot
.profile
;
837 /* add performance levels from vbios */
838 nouveau_perf_init(dev
);
840 /* display available performance levels */
841 NV_INFO(drm
, "%d available performance level(s)\n", pm
->nr_perflvl
);
842 for (i
= 0; i
< pm
->nr_perflvl
; i
++) {
843 nouveau_pm_perflvl_info(&pm
->perflvl
[i
], info
, sizeof(info
));
844 NV_INFO(drm
, "%d:%s", pm
->perflvl
[i
].id
, info
);
847 nouveau_pm_perflvl_info(&pm
->boot
, info
, sizeof(info
));
848 NV_INFO(drm
, "c:%s", info
);
850 /* switch performance levels now if requested */
851 if (nouveau_perflvl
!= NULL
)
852 nouveau_pm_profile_set(dev
, nouveau_perflvl
);
854 nouveau_sysfs_init(dev
);
855 nouveau_hwmon_init(dev
);
856 #if defined(CONFIG_ACPI) && defined(CONFIG_POWER_SUPPLY)
857 pm
->acpi_nb
.notifier_call
= nouveau_pm_acpi_event
;
858 register_acpi_notifier(&pm
->acpi_nb
);
865 nouveau_pm_fini(struct drm_device
*dev
)
867 struct nouveau_pm
*pm
= nouveau_pm(dev
);
868 struct nouveau_pm_profile
*profile
, *tmp
;
870 list_for_each_entry_safe(profile
, tmp
, &pm
->profiles
, head
) {
871 list_del(&profile
->head
);
872 profile
->func
->destroy(profile
);
875 if (pm
->cur
!= &pm
->boot
)
876 nouveau_pm_perflvl_set(dev
, &pm
->boot
);
878 nouveau_perf_fini(dev
);
879 nouveau_volt_fini(dev
);
881 #if defined(CONFIG_ACPI) && defined(CONFIG_POWER_SUPPLY)
882 unregister_acpi_notifier(&pm
->acpi_nb
);
884 nouveau_hwmon_fini(dev
);
885 nouveau_sysfs_fini(dev
);
887 nouveau_drm(dev
)->pm
= NULL
;
892 nouveau_pm_resume(struct drm_device
*dev
)
894 struct nouveau_pm
*pm
= nouveau_pm(dev
);
895 struct nouveau_pm_level
*perflvl
;
897 if (!pm
->cur
|| pm
->cur
== &pm
->boot
)
902 nouveau_pm_perflvl_set(dev
, perflvl
);