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_drv.h"
35 #include "nouveau_hwmon.h"
37 #include <nvkm/subdev/iccsense.h>
38 #include <nvkm/subdev/volt.h>
40 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
43 nouveau_hwmon_show_temp1_auto_point1_pwm(struct device
*d
,
44 struct device_attribute
*a
, char *buf
)
46 return snprintf(buf
, PAGE_SIZE
, "%d\n", 100);
48 static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm
, 0444,
49 nouveau_hwmon_show_temp1_auto_point1_pwm
, NULL
, 0);
52 nouveau_hwmon_temp1_auto_point1_temp(struct device
*d
,
53 struct device_attribute
*a
, char *buf
)
55 struct drm_device
*dev
= dev_get_drvdata(d
);
56 struct nouveau_drm
*drm
= nouveau_drm(dev
);
57 struct nvkm_therm
*therm
= nvxx_therm(&drm
->client
.device
);
59 return snprintf(buf
, PAGE_SIZE
, "%d\n",
60 therm
->attr_get(therm
, NVKM_THERM_ATTR_THRS_FAN_BOOST
) * 1000);
63 nouveau_hwmon_set_temp1_auto_point1_temp(struct device
*d
,
64 struct device_attribute
*a
,
65 const char *buf
, size_t count
)
67 struct drm_device
*dev
= dev_get_drvdata(d
);
68 struct nouveau_drm
*drm
= nouveau_drm(dev
);
69 struct nvkm_therm
*therm
= nvxx_therm(&drm
->client
.device
);
72 if (kstrtol(buf
, 10, &value
))
75 therm
->attr_set(therm
, NVKM_THERM_ATTR_THRS_FAN_BOOST
,
80 static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp
, 0644,
81 nouveau_hwmon_temp1_auto_point1_temp
,
82 nouveau_hwmon_set_temp1_auto_point1_temp
, 0);
85 nouveau_hwmon_temp1_auto_point1_temp_hyst(struct device
*d
,
86 struct device_attribute
*a
, char *buf
)
88 struct drm_device
*dev
= dev_get_drvdata(d
);
89 struct nouveau_drm
*drm
= nouveau_drm(dev
);
90 struct nvkm_therm
*therm
= nvxx_therm(&drm
->client
.device
);
92 return snprintf(buf
, PAGE_SIZE
, "%d\n",
93 therm
->attr_get(therm
, NVKM_THERM_ATTR_THRS_FAN_BOOST_HYST
) * 1000);
96 nouveau_hwmon_set_temp1_auto_point1_temp_hyst(struct device
*d
,
97 struct device_attribute
*a
,
98 const char *buf
, size_t count
)
100 struct drm_device
*dev
= dev_get_drvdata(d
);
101 struct nouveau_drm
*drm
= nouveau_drm(dev
);
102 struct nvkm_therm
*therm
= nvxx_therm(&drm
->client
.device
);
105 if (kstrtol(buf
, 10, &value
))
108 therm
->attr_set(therm
, NVKM_THERM_ATTR_THRS_FAN_BOOST_HYST
,
113 static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst
, 0644,
114 nouveau_hwmon_temp1_auto_point1_temp_hyst
,
115 nouveau_hwmon_set_temp1_auto_point1_temp_hyst
, 0);
118 nouveau_hwmon_get_pwm1_max(struct device
*d
,
119 struct device_attribute
*a
, char *buf
)
121 struct drm_device
*dev
= dev_get_drvdata(d
);
122 struct nouveau_drm
*drm
= nouveau_drm(dev
);
123 struct nvkm_therm
*therm
= nvxx_therm(&drm
->client
.device
);
126 ret
= therm
->attr_get(therm
, NVKM_THERM_ATTR_FAN_MAX_DUTY
);
130 return sprintf(buf
, "%i\n", ret
);
134 nouveau_hwmon_get_pwm1_min(struct device
*d
,
135 struct device_attribute
*a
, char *buf
)
137 struct drm_device
*dev
= dev_get_drvdata(d
);
138 struct nouveau_drm
*drm
= nouveau_drm(dev
);
139 struct nvkm_therm
*therm
= nvxx_therm(&drm
->client
.device
);
142 ret
= therm
->attr_get(therm
, NVKM_THERM_ATTR_FAN_MIN_DUTY
);
146 return sprintf(buf
, "%i\n", ret
);
150 nouveau_hwmon_set_pwm1_min(struct device
*d
, struct device_attribute
*a
,
151 const char *buf
, size_t count
)
153 struct drm_device
*dev
= dev_get_drvdata(d
);
154 struct nouveau_drm
*drm
= nouveau_drm(dev
);
155 struct nvkm_therm
*therm
= nvxx_therm(&drm
->client
.device
);
159 if (kstrtol(buf
, 10, &value
))
162 ret
= therm
->attr_set(therm
, NVKM_THERM_ATTR_FAN_MIN_DUTY
, value
);
168 static SENSOR_DEVICE_ATTR(pwm1_min
, 0644,
169 nouveau_hwmon_get_pwm1_min
,
170 nouveau_hwmon_set_pwm1_min
, 0);
173 nouveau_hwmon_set_pwm1_max(struct device
*d
, struct device_attribute
*a
,
174 const char *buf
, size_t count
)
176 struct drm_device
*dev
= dev_get_drvdata(d
);
177 struct nouveau_drm
*drm
= nouveau_drm(dev
);
178 struct nvkm_therm
*therm
= nvxx_therm(&drm
->client
.device
);
182 if (kstrtol(buf
, 10, &value
))
185 ret
= therm
->attr_set(therm
, NVKM_THERM_ATTR_FAN_MAX_DUTY
, value
);
191 static SENSOR_DEVICE_ATTR(pwm1_max
, 0644,
192 nouveau_hwmon_get_pwm1_max
,
193 nouveau_hwmon_set_pwm1_max
, 0);
195 static struct attribute
*pwm_fan_sensor_attrs
[] = {
196 &sensor_dev_attr_pwm1_min
.dev_attr
.attr
,
197 &sensor_dev_attr_pwm1_max
.dev_attr
.attr
,
200 static const struct attribute_group pwm_fan_sensor_group
= {
201 .attrs
= pwm_fan_sensor_attrs
,
204 static struct attribute
*temp1_auto_point_sensor_attrs
[] = {
205 &sensor_dev_attr_temp1_auto_point1_pwm
.dev_attr
.attr
,
206 &sensor_dev_attr_temp1_auto_point1_temp
.dev_attr
.attr
,
207 &sensor_dev_attr_temp1_auto_point1_temp_hyst
.dev_attr
.attr
,
210 static const struct attribute_group temp1_auto_point_sensor_group
= {
211 .attrs
= temp1_auto_point_sensor_attrs
,
214 #define N_ATTR_GROUPS 3
216 static const u32 nouveau_config_chip
[] = {
217 HWMON_C_UPDATE_INTERVAL
,
221 static const u32 nouveau_config_in
[] = {
222 HWMON_I_INPUT
| HWMON_I_MIN
| HWMON_I_MAX
| HWMON_I_LABEL
,
226 static const u32 nouveau_config_temp
[] = {
227 HWMON_T_INPUT
| HWMON_T_MAX
| HWMON_T_MAX_HYST
|
228 HWMON_T_CRIT
| HWMON_T_CRIT_HYST
| HWMON_T_EMERGENCY
|
229 HWMON_T_EMERGENCY_HYST
,
233 static const u32 nouveau_config_fan
[] = {
238 static const u32 nouveau_config_pwm
[] = {
239 HWMON_PWM_INPUT
| HWMON_PWM_ENABLE
,
243 static const u32 nouveau_config_power
[] = {
244 HWMON_P_INPUT
| HWMON_P_CAP_MAX
| HWMON_P_CRIT
,
248 static const struct hwmon_channel_info nouveau_chip
= {
250 .config
= nouveau_config_chip
,
253 static const struct hwmon_channel_info nouveau_temp
= {
255 .config
= nouveau_config_temp
,
258 static const struct hwmon_channel_info nouveau_fan
= {
260 .config
= nouveau_config_fan
,
263 static const struct hwmon_channel_info nouveau_in
= {
265 .config
= nouveau_config_in
,
268 static const struct hwmon_channel_info nouveau_pwm
= {
270 .config
= nouveau_config_pwm
,
273 static const struct hwmon_channel_info nouveau_power
= {
275 .config
= nouveau_config_power
,
278 static const struct hwmon_channel_info
*nouveau_info
[] = {
289 nouveau_chip_is_visible(const void *data
, u32 attr
, int channel
)
292 case hwmon_chip_update_interval
:
300 nouveau_power_is_visible(const void *data
, u32 attr
, int channel
)
302 struct nouveau_drm
*drm
= nouveau_drm((struct drm_device
*)data
);
303 struct nvkm_iccsense
*iccsense
= nvxx_iccsense(&drm
->client
.device
);
305 if (!iccsense
|| !iccsense
->data_valid
|| list_empty(&iccsense
->rails
))
309 case hwmon_power_input
:
311 case hwmon_power_max
:
312 if (iccsense
->power_w_max
)
315 case hwmon_power_crit
:
316 if (iccsense
->power_w_crit
)
325 nouveau_temp_is_visible(const void *data
, u32 attr
, int channel
)
327 struct nouveau_drm
*drm
= nouveau_drm((struct drm_device
*)data
);
328 struct nvkm_therm
*therm
= nvxx_therm(&drm
->client
.device
);
330 if (!therm
|| !therm
->attr_get
|| nvkm_therm_temp_get(therm
) < 0)
334 case hwmon_temp_input
:
337 case hwmon_temp_max_hyst
:
338 case hwmon_temp_crit
:
339 case hwmon_temp_crit_hyst
:
340 case hwmon_temp_emergency
:
341 case hwmon_temp_emergency_hyst
:
349 nouveau_pwm_is_visible(const void *data
, u32 attr
, int channel
)
351 struct nouveau_drm
*drm
= nouveau_drm((struct drm_device
*)data
);
352 struct nvkm_therm
*therm
= nvxx_therm(&drm
->client
.device
);
354 if (!therm
|| !therm
->attr_get
|| !therm
->fan_get
||
355 therm
->fan_get(therm
) < 0)
359 case hwmon_pwm_enable
:
360 case hwmon_pwm_input
:
368 nouveau_input_is_visible(const void *data
, u32 attr
, int channel
)
370 struct nouveau_drm
*drm
= nouveau_drm((struct drm_device
*)data
);
371 struct nvkm_volt
*volt
= nvxx_volt(&drm
->client
.device
);
373 if (!volt
|| nvkm_volt_get(volt
) < 0)
388 nouveau_fan_is_visible(const void *data
, u32 attr
, int channel
)
390 struct nouveau_drm
*drm
= nouveau_drm((struct drm_device
*)data
);
391 struct nvkm_therm
*therm
= nvxx_therm(&drm
->client
.device
);
393 if (!therm
|| !therm
->attr_get
|| nvkm_therm_fan_sense(therm
) < 0)
397 case hwmon_fan_input
:
405 nouveau_chip_read(struct device
*dev
, u32 attr
, int channel
, long *val
)
408 case hwmon_chip_update_interval
:
419 nouveau_temp_read(struct device
*dev
, u32 attr
, int channel
, long *val
)
421 struct drm_device
*drm_dev
= dev_get_drvdata(dev
);
422 struct nouveau_drm
*drm
= nouveau_drm(drm_dev
);
423 struct nvkm_therm
*therm
= nvxx_therm(&drm
->client
.device
);
426 if (!therm
|| !therm
->attr_get
)
430 case hwmon_temp_input
:
431 ret
= nvkm_therm_temp_get(therm
);
432 *val
= ret
< 0 ? ret
: (ret
* 1000);
435 *val
= therm
->attr_get(therm
, NVKM_THERM_ATTR_THRS_DOWN_CLK
)
438 case hwmon_temp_max_hyst
:
439 *val
= therm
->attr_get(therm
, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST
)
442 case hwmon_temp_crit
:
443 *val
= therm
->attr_get(therm
, NVKM_THERM_ATTR_THRS_CRITICAL
)
446 case hwmon_temp_crit_hyst
:
447 *val
= therm
->attr_get(therm
, NVKM_THERM_ATTR_THRS_CRITICAL_HYST
)
450 case hwmon_temp_emergency
:
451 *val
= therm
->attr_get(therm
, NVKM_THERM_ATTR_THRS_SHUTDOWN
)
454 case hwmon_temp_emergency_hyst
:
455 *val
= therm
->attr_get(therm
, NVKM_THERM_ATTR_THRS_SHUTDOWN_HYST
)
466 nouveau_fan_read(struct device
*dev
, u32 attr
, int channel
, long *val
)
468 struct drm_device
*drm_dev
= dev_get_drvdata(dev
);
469 struct nouveau_drm
*drm
= nouveau_drm(drm_dev
);
470 struct nvkm_therm
*therm
= nvxx_therm(&drm
->client
.device
);
476 case hwmon_fan_input
:
477 *val
= nvkm_therm_fan_sense(therm
);
487 nouveau_in_read(struct device
*dev
, u32 attr
, int channel
, long *val
)
489 struct drm_device
*drm_dev
= dev_get_drvdata(dev
);
490 struct nouveau_drm
*drm
= nouveau_drm(drm_dev
);
491 struct nvkm_volt
*volt
= nvxx_volt(&drm
->client
.device
);
499 ret
= nvkm_volt_get(volt
);
500 *val
= ret
< 0 ? ret
: (ret
/ 1000);
503 *val
= volt
->min_uv
> 0 ? (volt
->min_uv
/ 1000) : -ENODEV
;
506 *val
= volt
->max_uv
> 0 ? (volt
->max_uv
/ 1000) : -ENODEV
;
516 nouveau_pwm_read(struct device
*dev
, u32 attr
, int channel
, long *val
)
518 struct drm_device
*drm_dev
= dev_get_drvdata(dev
);
519 struct nouveau_drm
*drm
= nouveau_drm(drm_dev
);
520 struct nvkm_therm
*therm
= nvxx_therm(&drm
->client
.device
);
522 if (!therm
|| !therm
->attr_get
|| !therm
->fan_get
)
526 case hwmon_pwm_enable
:
527 *val
= therm
->attr_get(therm
, NVKM_THERM_ATTR_FAN_MODE
);
529 case hwmon_pwm_input
:
530 *val
= therm
->fan_get(therm
);
540 nouveau_power_read(struct device
*dev
, u32 attr
, int channel
, long *val
)
542 struct drm_device
*drm_dev
= dev_get_drvdata(dev
);
543 struct nouveau_drm
*drm
= nouveau_drm(drm_dev
);
544 struct nvkm_iccsense
*iccsense
= nvxx_iccsense(&drm
->client
.device
);
550 case hwmon_power_input
:
551 *val
= nvkm_iccsense_read_all(iccsense
);
553 case hwmon_power_max
:
554 *val
= iccsense
->power_w_max
;
556 case hwmon_power_crit
:
557 *val
= iccsense
->power_w_crit
;
567 nouveau_temp_write(struct device
*dev
, u32 attr
, int channel
, long val
)
569 struct drm_device
*drm_dev
= dev_get_drvdata(dev
);
570 struct nouveau_drm
*drm
= nouveau_drm(drm_dev
);
571 struct nvkm_therm
*therm
= nvxx_therm(&drm
->client
.device
);
573 if (!therm
|| !therm
->attr_set
)
578 return therm
->attr_set(therm
, NVKM_THERM_ATTR_THRS_DOWN_CLK
,
580 case hwmon_temp_max_hyst
:
581 return therm
->attr_set(therm
, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST
,
583 case hwmon_temp_crit
:
584 return therm
->attr_set(therm
, NVKM_THERM_ATTR_THRS_CRITICAL
,
586 case hwmon_temp_crit_hyst
:
587 return therm
->attr_set(therm
, NVKM_THERM_ATTR_THRS_CRITICAL_HYST
,
589 case hwmon_temp_emergency
:
590 return therm
->attr_set(therm
, NVKM_THERM_ATTR_THRS_SHUTDOWN
,
592 case hwmon_temp_emergency_hyst
:
593 return therm
->attr_set(therm
, NVKM_THERM_ATTR_THRS_SHUTDOWN_HYST
,
601 nouveau_pwm_write(struct device
*dev
, u32 attr
, int channel
, long val
)
603 struct drm_device
*drm_dev
= dev_get_drvdata(dev
);
604 struct nouveau_drm
*drm
= nouveau_drm(drm_dev
);
605 struct nvkm_therm
*therm
= nvxx_therm(&drm
->client
.device
);
607 if (!therm
|| !therm
->attr_set
)
611 case hwmon_pwm_input
:
612 return therm
->fan_set(therm
, val
);
613 case hwmon_pwm_enable
:
614 return therm
->attr_set(therm
, NVKM_THERM_ATTR_FAN_MODE
, val
);
621 nouveau_is_visible(const void *data
, enum hwmon_sensor_types type
, u32 attr
,
626 return nouveau_chip_is_visible(data
, attr
, channel
);
628 return nouveau_temp_is_visible(data
, attr
, channel
);
630 return nouveau_fan_is_visible(data
, attr
, channel
);
632 return nouveau_input_is_visible(data
, attr
, channel
);
634 return nouveau_pwm_is_visible(data
, attr
, channel
);
636 return nouveau_power_is_visible(data
, attr
, channel
);
642 static const char input_label
[] = "GPU core";
645 nouveau_read_string(struct device
*dev
, enum hwmon_sensor_types type
, u32 attr
,
646 int channel
, const char **buf
)
648 if (type
== hwmon_in
&& attr
== hwmon_in_label
) {
657 nouveau_read(struct device
*dev
, enum hwmon_sensor_types type
, u32 attr
,
658 int channel
, long *val
)
662 return nouveau_chip_read(dev
, attr
, channel
, val
);
664 return nouveau_temp_read(dev
, attr
, channel
, val
);
666 return nouveau_fan_read(dev
, attr
, channel
, val
);
668 return nouveau_in_read(dev
, attr
, channel
, val
);
670 return nouveau_pwm_read(dev
, attr
, channel
, val
);
672 return nouveau_power_read(dev
, attr
, channel
, val
);
679 nouveau_write(struct device
*dev
, enum hwmon_sensor_types type
, u32 attr
,
680 int channel
, long val
)
684 return nouveau_temp_write(dev
, attr
, channel
, val
);
686 return nouveau_pwm_write(dev
, attr
, channel
, val
);
692 static const struct hwmon_ops nouveau_hwmon_ops
= {
693 .is_visible
= nouveau_is_visible
,
694 .read
= nouveau_read
,
695 .read_string
= nouveau_read_string
,
696 .write
= nouveau_write
,
699 static const struct hwmon_chip_info nouveau_chip_info
= {
700 .ops
= &nouveau_hwmon_ops
,
701 .info
= nouveau_info
,
706 nouveau_hwmon_init(struct drm_device
*dev
)
708 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
709 struct nouveau_drm
*drm
= nouveau_drm(dev
);
710 struct nvkm_iccsense
*iccsense
= nvxx_iccsense(&drm
->client
.device
);
711 struct nvkm_therm
*therm
= nvxx_therm(&drm
->client
.device
);
712 struct nvkm_volt
*volt
= nvxx_volt(&drm
->client
.device
);
713 const struct attribute_group
*special_groups
[N_ATTR_GROUPS
];
714 struct nouveau_hwmon
*hwmon
;
715 struct device
*hwmon_dev
;
719 if (!iccsense
&& !therm
&& !volt
) {
720 NV_DEBUG(drm
, "Skipping hwmon registration\n");
724 hwmon
= drm
->hwmon
= kzalloc(sizeof(*hwmon
), GFP_KERNEL
);
729 if (therm
&& therm
->attr_get
&& therm
->attr_set
) {
730 if (nvkm_therm_temp_get(therm
) >= 0)
731 special_groups
[i
++] = &temp1_auto_point_sensor_group
;
732 if (therm
->fan_get
&& therm
->fan_get(therm
) >= 0)
733 special_groups
[i
++] = &pwm_fan_sensor_group
;
736 special_groups
[i
] = 0;
737 hwmon_dev
= hwmon_device_register_with_info(dev
->dev
, "nouveau", dev
,
740 if (IS_ERR(hwmon_dev
)) {
741 ret
= PTR_ERR(hwmon_dev
);
742 NV_ERROR(drm
, "Unable to register hwmon device: %d\n", ret
);
746 hwmon
->hwmon
= hwmon_dev
;
754 nouveau_hwmon_fini(struct drm_device
*dev
)
756 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
757 struct nouveau_hwmon
*hwmon
= nouveau_hwmon(dev
);
763 hwmon_device_unregister(hwmon
->hwmon
);
765 nouveau_drm(dev
)->hwmon
= NULL
;