]> Pileus Git - ~andy/linux/blob - drivers/gpu/drm/nouveau/nouveau_pm.c
drm/nouveau/pm: fix a typo related to the move to the therm subdev
[~andy/linux] / drivers / gpu / drm / nouveau / nouveau_pm.c
1 /*
2  * Copyright 2010 Red Hat Inc.
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: Ben Skeggs
23  */
24
25 #ifdef CONFIG_ACPI
26 #include <linux/acpi.h>
27 #endif
28 #include <linux/power_supply.h>
29 #include <linux/hwmon.h>
30 #include <linux/hwmon-sysfs.h>
31
32 #include "drmP.h"
33
34 #include "nouveau_drm.h"
35 #include "nouveau_pm.h"
36
37 #include <subdev/gpio.h>
38 #include <subdev/timer.h>
39 #include <subdev/therm.h>
40
41 MODULE_PARM_DESC(perflvl, "Performance level (default: boot)");
42 static char *nouveau_perflvl;
43 module_param_named(perflvl, nouveau_perflvl, charp, 0400);
44
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);
48
49 static int
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)
52 {
53         struct nouveau_drm *drm = nouveau_drm(dev);
54         struct nouveau_pm *pm = nouveau_pm(dev);
55         struct nouveau_therm *therm = nouveau_therm(drm->device);
56         int ret;
57
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
60          *     know about?
61          */
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);
67                         return ret;
68                 }
69         }
70
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);
74                         if (ret) {
75                                 NV_ERROR(drm, "voltage set failed: %d\n", ret);
76                                 return ret;
77                         }
78                 }
79         }
80
81         return 0;
82 }
83
84 static int
85 nouveau_pm_perflvl_set(struct drm_device *dev, struct nouveau_pm_level *perflvl)
86 {
87         struct nouveau_pm *pm = nouveau_pm(dev);
88         void *state;
89         int ret;
90
91         if (perflvl == pm->cur)
92                 return 0;
93
94         ret = nouveau_pm_perflvl_aux(dev, perflvl, pm->cur, perflvl);
95         if (ret)
96                 return ret;
97
98         state = pm->clocks_pre(dev, perflvl);
99         if (IS_ERR(state)) {
100                 ret = PTR_ERR(state);
101                 goto error;
102         }
103         ret = pm->clocks_set(dev, state);
104         if (ret)
105                 goto error;
106
107         ret = nouveau_pm_perflvl_aux(dev, perflvl, perflvl, pm->cur);
108         if (ret)
109                 return ret;
110
111         pm->cur = perflvl;
112         return 0;
113
114 error:
115         /* restore the fan speed and voltage before leaving */
116         nouveau_pm_perflvl_aux(dev, perflvl, perflvl, pm->cur);
117         return ret;
118 }
119
120 void
121 nouveau_pm_trigger(struct drm_device *dev)
122 {
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;
128         int ret;
129
130         /* select power profile based on current power source */
131         if (power_supply_is_system_supplied())
132                 profile = pm->profile_ac;
133         else
134                 profile = pm->profile_dc;
135
136         if (profile != pm->profile) {
137                 pm->profile->func->fini(pm->profile);
138                 pm->profile = profile;
139                 pm->profile->func->init(pm->profile);
140         }
141
142         /* select performance level based on profile */
143         perflvl = profile->func->select(profile);
144
145         /* change perflvl, if necessary */
146         if (perflvl != pm->cur) {
147                 u64 time0 = ptimer->read(ptimer);
148
149                 NV_INFO(drm, "setting performance level: %d", perflvl->id);
150                 ret = nouveau_pm_perflvl_set(dev, perflvl);
151                 if (ret)
152                         NV_INFO(drm, "> reclocking failed: %d\n\n", ret);
153
154                 NV_INFO(drm, "> reclocking took %lluns\n\n",
155                              ptimer->read(ptimer) - time0);
156         }
157 }
158
159 static struct nouveau_pm_profile *
160 profile_find(struct drm_device *dev, const char *string)
161 {
162         struct nouveau_pm *pm = nouveau_pm(dev);
163         struct nouveau_pm_profile *profile;
164
165         list_for_each_entry(profile, &pm->profiles, head) {
166                 if (!strncmp(profile->name, string, sizeof(profile->name)))
167                         return profile;
168         }
169
170         return NULL;
171 }
172
173 static int
174 nouveau_pm_profile_set(struct drm_device *dev, const char *profile)
175 {
176         struct nouveau_pm *pm = nouveau_pm(dev);
177         struct nouveau_pm_profile *ac = NULL, *dc = NULL;
178         char string[16], *cur = string, *ptr;
179
180         /* safety precaution, for now */
181         if (nouveau_perflvl_wr != 7777)
182                 return -EPERM;
183
184         strncpy(string, profile, sizeof(string));
185         string[sizeof(string) - 1] = 0;
186         if ((ptr = strchr(string, '\n')))
187                 *ptr = '\0';
188
189         ptr = strsep(&cur, ",");
190         if (ptr)
191                 ac = profile_find(dev, ptr);
192
193         ptr = strsep(&cur, ",");
194         if (ptr)
195                 dc = profile_find(dev, ptr);
196         else
197                 dc = ac;
198
199         if (ac == NULL || dc == NULL)
200                 return -EINVAL;
201
202         pm->profile_ac = ac;
203         pm->profile_dc = dc;
204         nouveau_pm_trigger(dev);
205         return 0;
206 }
207
208 static void
209 nouveau_pm_static_dummy(struct nouveau_pm_profile *profile)
210 {
211 }
212
213 static struct nouveau_pm_level *
214 nouveau_pm_static_select(struct nouveau_pm_profile *profile)
215 {
216         return container_of(profile, struct nouveau_pm_level, profile);
217 }
218
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,
224 };
225
226 static int
227 nouveau_pm_perflvl_get(struct drm_device *dev, struct nouveau_pm_level *perflvl)
228 {
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);
232         int ret;
233
234         memset(perflvl, 0, sizeof(*perflvl));
235
236         if (pm->clocks_get) {
237                 ret = pm->clocks_get(dev, perflvl);
238                 if (ret)
239                         return ret;
240         }
241
242         if (pm->voltage.supported && pm->voltage_get) {
243                 ret = pm->voltage_get(dev);
244                 if (ret > 0) {
245                         perflvl->volt_min = ret;
246                         perflvl->volt_max = ret;
247                 }
248         }
249
250         if (therm && therm->fan_get) {
251                 ret = therm->fan_get(therm);
252                 if (ret >= 0)
253                         perflvl->fanspeed = ret;
254         }
255
256         nouveau_mem_timing_read(dev, &perflvl->timing);
257         return 0;
258 }
259
260 static void
261 nouveau_pm_perflvl_info(struct nouveau_pm_level *perflvl, char *ptr, int len)
262 {
263         char c[16], s[16], v[32], f[16], m[16];
264
265         c[0] = '\0';
266         if (perflvl->core)
267                 snprintf(c, sizeof(c), " core %dMHz", perflvl->core / 1000);
268
269         s[0] = '\0';
270         if (perflvl->shader)
271                 snprintf(s, sizeof(s), " shader %dMHz", perflvl->shader / 1000);
272
273         m[0] = '\0';
274         if (perflvl->memory)
275                 snprintf(m, sizeof(m), " memory %dMHz", perflvl->memory / 1000);
276
277         v[0] = '\0';
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);
281         } else
282         if (perflvl->volt_min) {
283                 snprintf(v, sizeof(v), " voltage %dmV",
284                          perflvl->volt_min / 1000);
285         }
286
287         f[0] = '\0';
288         if (perflvl->fanspeed)
289                 snprintf(f, sizeof(f), " fanspeed %d%%", perflvl->fanspeed);
290
291         snprintf(ptr, len, "%s%s%s%s%s\n", c, s, m, v, f);
292 }
293
294 static ssize_t
295 nouveau_pm_get_perflvl_info(struct device *d,
296                             struct device_attribute *a, char *buf)
297 {
298         struct nouveau_pm_level *perflvl =
299                 container_of(a, struct nouveau_pm_level, dev_attr);
300         char *ptr = buf;
301         int len = PAGE_SIZE;
302
303         snprintf(ptr, len, "%d:", perflvl->id);
304         ptr += strlen(buf);
305         len -= strlen(buf);
306
307         nouveau_pm_perflvl_info(perflvl, ptr, len);
308         return strlen(buf);
309 }
310
311 static ssize_t
312 nouveau_pm_get_perflvl(struct device *d, struct device_attribute *a, char *buf)
313 {
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;
318         char *ptr = buf;
319
320         snprintf(ptr, len, "profile: %s, %s\nc:",
321                  pm->profile_ac->name, pm->profile_dc->name);
322         ptr += strlen(buf);
323         len -= strlen(buf);
324
325         ret = nouveau_pm_perflvl_get(dev, &cur);
326         if (ret == 0)
327                 nouveau_pm_perflvl_info(&cur, ptr, len);
328         return strlen(buf);
329 }
330
331 static ssize_t
332 nouveau_pm_set_perflvl(struct device *d, struct device_attribute *a,
333                        const char *buf, size_t count)
334 {
335         struct drm_device *dev = pci_get_drvdata(to_pci_dev(d));
336         int ret;
337
338         ret = nouveau_pm_profile_set(dev, buf);
339         if (ret)
340                 return ret;
341         return strlen(buf);
342 }
343
344 static DEVICE_ATTR(performance_level, S_IRUGO | S_IWUSR,
345                    nouveau_pm_get_perflvl, nouveau_pm_set_perflvl);
346
347 static int
348 nouveau_sysfs_init(struct drm_device *dev)
349 {
350         struct nouveau_drm *drm = nouveau_drm(dev);
351         struct nouveau_pm *pm = nouveau_pm(dev);
352         struct device *d = &dev->pdev->dev;
353         int ret, i;
354
355         ret = device_create_file(d, &dev_attr_performance_level);
356         if (ret)
357                 return ret;
358
359         for (i = 0; i < pm->nr_perflvl; i++) {
360                 struct nouveau_pm_level *perflvl = &pm->perflvl[i];
361
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);
367
368                 ret = device_create_file(d, &perflvl->dev_attr);
369                 if (ret) {
370                         NV_ERROR(drm, "failed pervlvl %d sysfs: %d\n",
371                                  perflvl->id, i);
372                         perflvl->dev_attr.attr.name = NULL;
373                         nouveau_pm_fini(dev);
374                         return ret;
375                 }
376         }
377
378         return 0;
379 }
380
381 static void
382 nouveau_sysfs_fini(struct drm_device *dev)
383 {
384         struct nouveau_pm *pm = nouveau_pm(dev);
385         struct device *d = &dev->pdev->dev;
386         int i;
387
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];
391
392                 if (!pl->dev_attr.attr.name)
393                         break;
394
395                 device_remove_file(d, &pl->dev_attr);
396         }
397 }
398
399 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
400 static ssize_t
401 nouveau_hwmon_show_temp(struct device *d, struct device_attribute *a, char *buf)
402 {
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);
406
407         return snprintf(buf, PAGE_SIZE, "%d\n", therm->temp_get(therm) * 1000);
408 }
409 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, nouveau_hwmon_show_temp,
410                                                   NULL, 0);
411
412 static ssize_t
413 nouveau_hwmon_max_temp(struct device *d, struct device_attribute *a, char *buf)
414 {
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);
418
419         return snprintf(buf, PAGE_SIZE, "%d\n",
420                therm->attr_get(therm, NOUVEAU_THERM_ATTR_THRS_DOWN_CLK) * 1000);
421 }
422 static ssize_t
423 nouveau_hwmon_set_max_temp(struct device *d, struct device_attribute *a,
424                                                 const char *buf, size_t count)
425 {
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);
429         long value;
430
431         if (kstrtol(buf, 10, &value) == -EINVAL)
432                 return count;
433
434         therm->attr_set(therm, NOUVEAU_THERM_ATTR_THRS_DOWN_CLK, value / 1000);
435
436         return count;
437 }
438 static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, nouveau_hwmon_max_temp,
439                                                   nouveau_hwmon_set_max_temp,
440                                                   0);
441
442 static ssize_t
443 nouveau_hwmon_critical_temp(struct device *d, struct device_attribute *a,
444                                                         char *buf)
445 {
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);
449
450         return snprintf(buf, PAGE_SIZE, "%d\n",
451                therm->attr_get(therm, NOUVEAU_THERM_ATTR_THRS_CRITICAL) * 1000);
452 }
453 static ssize_t
454 nouveau_hwmon_set_critical_temp(struct device *d, struct device_attribute *a,
455                                                             const char *buf,
456                                                                 size_t count)
457 {
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);
461         long value;
462
463         if (kstrtol(buf, 10, &value) == -EINVAL)
464                 return count;
465
466         therm->attr_set(therm, NOUVEAU_THERM_ATTR_THRS_CRITICAL, value / 1000);
467
468         return count;
469 }
470 static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO | S_IWUSR,
471                                                 nouveau_hwmon_critical_temp,
472                                                 nouveau_hwmon_set_critical_temp,
473                                                 0);
474
475 static ssize_t nouveau_hwmon_show_name(struct device *dev,
476                                       struct device_attribute *attr,
477                                       char *buf)
478 {
479         return sprintf(buf, "nouveau\n");
480 }
481 static SENSOR_DEVICE_ATTR(name, S_IRUGO, nouveau_hwmon_show_name, NULL, 0);
482
483 static ssize_t nouveau_hwmon_show_update_rate(struct device *dev,
484                                       struct device_attribute *attr,
485                                       char *buf)
486 {
487         return sprintf(buf, "1000\n");
488 }
489 static SENSOR_DEVICE_ATTR(update_rate, S_IRUGO,
490                                                 nouveau_hwmon_show_update_rate,
491                                                 NULL, 0);
492
493 static ssize_t
494 nouveau_hwmon_show_fan0_input(struct device *d, struct device_attribute *attr,
495                               char *buf)
496 {
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);
500
501         return snprintf(buf, PAGE_SIZE, "%d\n", therm->fan_sense(therm));
502 }
503 static SENSOR_DEVICE_ATTR(fan0_input, S_IRUGO, nouveau_hwmon_show_fan0_input,
504                           NULL, 0);
505
506  static ssize_t
507 nouveau_hwmon_get_pwm1_enable(struct device *d,
508                            struct device_attribute *a, char *buf)
509 {
510         struct drm_device *dev = dev_get_drvdata(d);
511         struct nouveau_drm *drm = nouveau_drm(dev);
512         struct nouveau_therm *therm = nouveau_therm(drm->device);
513         int ret;
514
515         ret = therm->attr_get(therm, NOUVEAU_THERM_ATTR_FAN_MODE);
516         if (ret < 0)
517                 return ret;
518
519         return sprintf(buf, "%i\n", ret);
520 }
521
522 static ssize_t
523 nouveau_hwmon_set_pwm1_enable(struct device *d, struct device_attribute *a,
524                            const char *buf, size_t count)
525 {
526         struct drm_device *dev = dev_get_drvdata(d);
527         struct nouveau_drm *drm = nouveau_drm(dev);
528         struct nouveau_therm *therm = nouveau_therm(drm->device);
529         long value;
530         int ret;
531
532         if (strict_strtol(buf, 10, &value) == -EINVAL)
533                 return -EINVAL;
534
535         ret = therm->attr_set(therm, NOUVEAU_THERM_ATTR_FAN_MODE, value);
536         if (ret)
537                 return ret;
538         else
539                 return count;
540 }
541 static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
542                           nouveau_hwmon_get_pwm1_enable,
543                           nouveau_hwmon_set_pwm1_enable, 0);
544
545 static ssize_t
546 nouveau_hwmon_get_pwm1(struct device *d, struct device_attribute *a, char *buf)
547 {
548         struct drm_device *dev = dev_get_drvdata(d);
549         struct nouveau_drm *drm = nouveau_drm(dev);
550         struct nouveau_therm *therm = nouveau_therm(drm->device);
551         int ret;
552
553         ret = therm->fan_get(therm);
554         if (ret < 0)
555                 return ret;
556
557         return sprintf(buf, "%i\n", ret);
558 }
559
560 static ssize_t
561 nouveau_hwmon_set_pwm1(struct device *d, struct device_attribute *a,
562                        const char *buf, size_t count)
563 {
564         struct drm_device *dev = dev_get_drvdata(d);
565         struct nouveau_drm *drm = nouveau_drm(dev);
566         struct nouveau_therm *therm = nouveau_therm(drm->device);
567         int ret = -ENODEV;
568         long value;
569
570         if (nouveau_perflvl_wr != 7777)
571                 return -EPERM;
572
573         if (kstrtol(buf, 10, &value) == -EINVAL)
574                 return -EINVAL;
575
576         ret = therm->fan_set(therm, value);
577         if (ret)
578                 return ret;
579
580         return count;
581 }
582
583 static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR,
584                           nouveau_hwmon_get_pwm1,
585                           nouveau_hwmon_set_pwm1, 0);
586
587 static ssize_t
588 nouveau_hwmon_get_pwm1_min(struct device *d,
589                            struct device_attribute *a, char *buf)
590 {
591         struct drm_device *dev = dev_get_drvdata(d);
592         struct nouveau_drm *drm = nouveau_drm(dev);
593         struct nouveau_therm *therm = nouveau_therm(drm->device);
594         int ret;
595
596         ret = therm->attr_get(therm, NOUVEAU_THERM_ATTR_FAN_MIN_DUTY);
597         if (ret < 0)
598                 return ret;
599
600         return sprintf(buf, "%i\n", ret);
601 }
602
603 static ssize_t
604 nouveau_hwmon_set_pwm1_min(struct device *d, struct device_attribute *a,
605                            const char *buf, size_t count)
606 {
607         struct drm_device *dev = dev_get_drvdata(d);
608         struct nouveau_drm *drm = nouveau_drm(dev);
609         struct nouveau_therm *therm = nouveau_therm(drm->device);
610         long value;
611         int ret;
612
613         if (kstrtol(buf, 10, &value) == -EINVAL)
614                 return -EINVAL;
615
616         ret = therm->attr_set(therm, NOUVEAU_THERM_ATTR_FAN_MIN_DUTY, value);
617         if (ret < 0)
618                 return ret;
619
620         return count;
621 }
622
623 static SENSOR_DEVICE_ATTR(pwm1_min, S_IRUGO | S_IWUSR,
624                           nouveau_hwmon_get_pwm1_min,
625                           nouveau_hwmon_set_pwm1_min, 0);
626
627 static ssize_t
628 nouveau_hwmon_get_pwm1_max(struct device *d,
629                            struct device_attribute *a, char *buf)
630 {
631         struct drm_device *dev = dev_get_drvdata(d);
632         struct nouveau_drm *drm = nouveau_drm(dev);
633         struct nouveau_therm *therm = nouveau_therm(drm->device);
634         int ret;
635
636         ret = therm->attr_get(therm, NOUVEAU_THERM_ATTR_FAN_MAX_DUTY);
637         if (ret < 0)
638                 return ret;
639
640         return sprintf(buf, "%i\n", ret);
641 }
642
643 static ssize_t
644 nouveau_hwmon_set_pwm1_max(struct device *d, struct device_attribute *a,
645                            const char *buf, size_t count)
646 {
647         struct drm_device *dev = dev_get_drvdata(d);
648         struct nouveau_drm *drm = nouveau_drm(dev);
649         struct nouveau_therm *therm = nouveau_therm(drm->device);
650         long value;
651         int ret;
652
653         if (kstrtol(buf, 10, &value) == -EINVAL)
654                 return -EINVAL;
655
656         ret = therm->attr_set(therm, NOUVEAU_THERM_ATTR_FAN_MAX_DUTY, value);
657         if (ret < 0)
658                 return ret;
659
660         return count;
661 }
662
663 static SENSOR_DEVICE_ATTR(pwm1_max, S_IRUGO | S_IWUSR,
664                           nouveau_hwmon_get_pwm1_max,
665                           nouveau_hwmon_set_pwm1_max, 0);
666
667 static struct attribute *hwmon_attributes[] = {
668         &sensor_dev_attr_temp1_input.dev_attr.attr,
669         &sensor_dev_attr_temp1_max.dev_attr.attr,
670         &sensor_dev_attr_temp1_crit.dev_attr.attr,
671         &sensor_dev_attr_name.dev_attr.attr,
672         &sensor_dev_attr_update_rate.dev_attr.attr,
673         NULL
674 };
675 static struct attribute *hwmon_fan_rpm_attributes[] = {
676         &sensor_dev_attr_fan0_input.dev_attr.attr,
677         NULL
678 };
679 static struct attribute *hwmon_pwm_fan_attributes[] = {
680         &sensor_dev_attr_pwm1_enable.dev_attr.attr,
681         &sensor_dev_attr_pwm1.dev_attr.attr,
682         &sensor_dev_attr_pwm1_min.dev_attr.attr,
683         &sensor_dev_attr_pwm1_max.dev_attr.attr,
684         NULL
685 };
686
687 static const struct attribute_group hwmon_attrgroup = {
688         .attrs = hwmon_attributes,
689 };
690 static const struct attribute_group hwmon_fan_rpm_attrgroup = {
691         .attrs = hwmon_fan_rpm_attributes,
692 };
693 static const struct attribute_group hwmon_pwm_fan_attrgroup = {
694         .attrs = hwmon_pwm_fan_attributes,
695 };
696 #endif
697
698 static int
699 nouveau_hwmon_init(struct drm_device *dev)
700 {
701         struct nouveau_pm *pm = nouveau_pm(dev);
702         struct nouveau_drm *drm = nouveau_drm(dev);
703         struct nouveau_therm *therm = nouveau_therm(drm->device);
704
705 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
706         struct device *hwmon_dev;
707         int ret = 0;
708
709         if (!therm || !therm->temp_get || !therm->attr_get || !therm->attr_set)
710                 return -ENODEV;
711
712         hwmon_dev = hwmon_device_register(&dev->pdev->dev);
713         if (IS_ERR(hwmon_dev)) {
714                 ret = PTR_ERR(hwmon_dev);
715                 NV_ERROR(drm, "Unable to register hwmon device: %d\n", ret);
716                 return ret;
717         }
718         dev_set_drvdata(hwmon_dev, dev);
719
720         /* default sysfs entries */
721         ret = sysfs_create_group(&dev->pdev->dev.kobj, &hwmon_attrgroup);
722         if (ret) {
723                 if (ret)
724                         goto error;
725         }
726
727         /* if the card has a pwm fan */
728         /*XXX: incorrect, need better detection for this, some boards have
729          *     the gpio entries for pwm fan control even when there's no
730          *     actual fan connected to it... therm table? */
731         if (therm->fan_get && therm->fan_get(therm) >= 0) {
732                 ret = sysfs_create_group(&dev->pdev->dev.kobj,
733                                          &hwmon_pwm_fan_attrgroup);
734                 if (ret)
735                         goto error;
736         }
737
738         /* if the card can read the fan rpm */
739         if (therm->fan_sense(therm) >= 0) {
740                 ret = sysfs_create_group(&dev->pdev->dev.kobj,
741                                          &hwmon_fan_rpm_attrgroup);
742                 if (ret)
743                         goto error;
744         }
745
746         pm->hwmon = hwmon_dev;
747
748         return 0;
749
750 error:
751         NV_ERROR(drm, "Unable to create some hwmon sysfs files: %d\n", ret);
752         hwmon_device_unregister(hwmon_dev);
753         pm->hwmon = NULL;
754         return ret;
755 #else
756         pm->hwmon = NULL;
757         return 0;
758 #endif
759 }
760
761 static void
762 nouveau_hwmon_fini(struct drm_device *dev)
763 {
764 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
765         struct nouveau_pm *pm = nouveau_pm(dev);
766
767         if (pm->hwmon) {
768                 sysfs_remove_group(&dev->pdev->dev.kobj, &hwmon_attrgroup);
769                 sysfs_remove_group(&dev->pdev->dev.kobj,
770                                    &hwmon_pwm_fan_attrgroup);
771                 sysfs_remove_group(&dev->pdev->dev.kobj,
772                                    &hwmon_fan_rpm_attrgroup);
773
774                 hwmon_device_unregister(pm->hwmon);
775         }
776 #endif
777 }
778
779 #if defined(CONFIG_ACPI) && defined(CONFIG_POWER_SUPPLY)
780 static int
781 nouveau_pm_acpi_event(struct notifier_block *nb, unsigned long val, void *data)
782 {
783         struct nouveau_pm *pm = container_of(nb, struct nouveau_pm, acpi_nb);
784         struct nouveau_drm *drm = nouveau_drm(pm->dev);
785         struct acpi_bus_event *entry = (struct acpi_bus_event *)data;
786
787         if (strcmp(entry->device_class, "ac_adapter") == 0) {
788                 bool ac = power_supply_is_system_supplied();
789
790                 NV_DEBUG(drm, "power supply changed: %s\n", ac ? "AC" : "DC");
791                 nouveau_pm_trigger(pm->dev);
792         }
793
794         return NOTIFY_OK;
795 }
796 #endif
797
798 int
799 nouveau_pm_init(struct drm_device *dev)
800 {
801         struct nouveau_device *device = nouveau_dev(dev);
802         struct nouveau_drm *drm = nouveau_drm(dev);
803         struct nouveau_pm *pm;
804         char info[256];
805         int ret, i;
806
807         pm = drm->pm = kzalloc(sizeof(*pm), GFP_KERNEL);
808         if (!pm)
809                 return -ENOMEM;
810
811         pm->dev = dev;
812
813         if (device->card_type < NV_40) {
814                 pm->clocks_get = nv04_pm_clocks_get;
815                 pm->clocks_pre = nv04_pm_clocks_pre;
816                 pm->clocks_set = nv04_pm_clocks_set;
817                 if (nouveau_gpio(drm->device)) {
818                         pm->voltage_get = nouveau_voltage_gpio_get;
819                         pm->voltage_set = nouveau_voltage_gpio_set;
820                 }
821         } else
822         if (device->card_type < NV_50) {
823                 pm->clocks_get = nv40_pm_clocks_get;
824                 pm->clocks_pre = nv40_pm_clocks_pre;
825                 pm->clocks_set = nv40_pm_clocks_set;
826                 pm->voltage_get = nouveau_voltage_gpio_get;
827                 pm->voltage_set = nouveau_voltage_gpio_set;
828         } else
829         if (device->card_type < NV_C0) {
830                 if (device->chipset <  0xa3 ||
831                     device->chipset == 0xaa ||
832                     device->chipset == 0xac) {
833                         pm->clocks_get = nv50_pm_clocks_get;
834                         pm->clocks_pre = nv50_pm_clocks_pre;
835                         pm->clocks_set = nv50_pm_clocks_set;
836                 } else {
837                         pm->clocks_get = nva3_pm_clocks_get;
838                         pm->clocks_pre = nva3_pm_clocks_pre;
839                         pm->clocks_set = nva3_pm_clocks_set;
840                 }
841                 pm->voltage_get = nouveau_voltage_gpio_get;
842                 pm->voltage_set = nouveau_voltage_gpio_set;
843         } else
844         if (device->card_type < NV_E0) {
845                 pm->clocks_get = nvc0_pm_clocks_get;
846                 pm->clocks_pre = nvc0_pm_clocks_pre;
847                 pm->clocks_set = nvc0_pm_clocks_set;
848                 pm->voltage_get = nouveau_voltage_gpio_get;
849                 pm->voltage_set = nouveau_voltage_gpio_set;
850         }
851
852
853         /* parse aux tables from vbios */
854         nouveau_volt_init(dev);
855
856         INIT_LIST_HEAD(&pm->profiles);
857
858         /* determine current ("boot") performance level */
859         ret = nouveau_pm_perflvl_get(dev, &pm->boot);
860         if (ret) {
861                 NV_ERROR(drm, "failed to determine boot perflvl\n");
862                 return ret;
863         }
864
865         strncpy(pm->boot.name, "boot", 4);
866         strncpy(pm->boot.profile.name, "boot", 4);
867         pm->boot.profile.func = &nouveau_pm_static_profile_func;
868
869         list_add(&pm->boot.profile.head, &pm->profiles);
870
871         pm->profile_ac = &pm->boot.profile;
872         pm->profile_dc = &pm->boot.profile;
873         pm->profile = &pm->boot.profile;
874         pm->cur = &pm->boot;
875
876         /* add performance levels from vbios */
877         nouveau_perf_init(dev);
878
879         /* display available performance levels */
880         NV_INFO(drm, "%d available performance level(s)\n", pm->nr_perflvl);
881         for (i = 0; i < pm->nr_perflvl; i++) {
882                 nouveau_pm_perflvl_info(&pm->perflvl[i], info, sizeof(info));
883                 NV_INFO(drm, "%d:%s", pm->perflvl[i].id, info);
884         }
885
886         nouveau_pm_perflvl_info(&pm->boot, info, sizeof(info));
887         NV_INFO(drm, "c:%s", info);
888
889         /* switch performance levels now if requested */
890         if (nouveau_perflvl != NULL)
891                 nouveau_pm_profile_set(dev, nouveau_perflvl);
892
893         nouveau_sysfs_init(dev);
894         nouveau_hwmon_init(dev);
895 #if defined(CONFIG_ACPI) && defined(CONFIG_POWER_SUPPLY)
896         pm->acpi_nb.notifier_call = nouveau_pm_acpi_event;
897         register_acpi_notifier(&pm->acpi_nb);
898 #endif
899
900         return 0;
901 }
902
903 void
904 nouveau_pm_fini(struct drm_device *dev)
905 {
906         struct nouveau_pm *pm = nouveau_pm(dev);
907         struct nouveau_pm_profile *profile, *tmp;
908
909         list_for_each_entry_safe(profile, tmp, &pm->profiles, head) {
910                 list_del(&profile->head);
911                 profile->func->destroy(profile);
912         }
913
914         if (pm->cur != &pm->boot)
915                 nouveau_pm_perflvl_set(dev, &pm->boot);
916
917         nouveau_perf_fini(dev);
918         nouveau_volt_fini(dev);
919
920 #if defined(CONFIG_ACPI) && defined(CONFIG_POWER_SUPPLY)
921         unregister_acpi_notifier(&pm->acpi_nb);
922 #endif
923         nouveau_hwmon_fini(dev);
924         nouveau_sysfs_fini(dev);
925
926         nouveau_drm(dev)->pm = NULL;
927         kfree(pm);
928 }
929
930 void
931 nouveau_pm_resume(struct drm_device *dev)
932 {
933         struct nouveau_pm *pm = nouveau_pm(dev);
934         struct nouveau_pm_level *perflvl;
935
936         if (!pm->cur || pm->cur == &pm->boot)
937                 return;
938
939         perflvl = pm->cur;
940         pm->cur = &pm->boot;
941         nouveau_pm_perflvl_set(dev, perflvl);
942 }