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