nouveau_pm.c revision 35bb5089cc74e6d64cf0171b55c93e1bf8b8198d
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#include "drmP.h" 26 27#include "nouveau_drv.h" 28#include "nouveau_pm.h" 29 30#ifdef CONFIG_ACPI 31#include <linux/acpi.h> 32#endif 33#include <linux/power_supply.h> 34#include <linux/hwmon.h> 35#include <linux/hwmon-sysfs.h> 36 37static int 38nouveau_pwmfan_get(struct drm_device *dev) 39{ 40 struct drm_nouveau_private *dev_priv = dev->dev_private; 41 struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; 42 struct nouveau_pm_engine *pm = &dev_priv->engine.pm; 43 struct dcb_gpio_entry *gpio = NULL; 44 u32 divs, duty; 45 int ret; 46 47 if (!pm->pwm_get) 48 return -ENODEV; 49 50 gpio = nouveau_bios_gpio_entry(dev, DCB_GPIO_PWM_FAN); 51 if (gpio) { 52 ret = pm->pwm_get(dev, gpio, &divs, &duty); 53 if (ret == 0) { 54 divs = max(divs, duty); 55 if (dev_priv->card_type <= NV_40 || 56 (gpio->state[0] & 1)) 57 duty = divs - duty; 58 return (duty * 100) / divs; 59 } 60 61 return pgpio->get(dev, gpio->tag) * 100; 62 } 63 64 return -ENODEV; 65} 66 67static int 68nouveau_pwmfan_set(struct drm_device *dev, int percent) 69{ 70 struct drm_nouveau_private *dev_priv = dev->dev_private; 71 struct nouveau_pm_engine *pm = &dev_priv->engine.pm; 72 struct dcb_gpio_entry *gpio; 73 u32 divs, duty; 74 75 if (!pm->pwm_set) 76 return -ENODEV; 77 78 gpio = nouveau_bios_gpio_entry(dev, DCB_GPIO_PWM_FAN); 79 if (gpio) { 80 divs = pm->pwm_divisor; 81 if (pm->fan.pwm_freq) { 82 /*XXX: PNVIO clock more than likely... */ 83 divs = 135000 / pm->fan.pwm_freq; 84 if (dev_priv->chipset < 0xa3) 85 divs /= 4; 86 } 87 88 duty = ((divs * percent) + 99) / 100; 89 if (dev_priv->card_type <= NV_40 || 90 (gpio->state[0] & 1)) 91 duty = divs - duty; 92 93 return pm->pwm_set(dev, gpio, divs, duty); 94 } 95 96 return -ENODEV; 97} 98 99static int 100nouveau_pm_clock_set(struct drm_device *dev, struct nouveau_pm_level *perflvl, 101 u8 id, u32 khz) 102{ 103 struct drm_nouveau_private *dev_priv = dev->dev_private; 104 struct nouveau_pm_engine *pm = &dev_priv->engine.pm; 105 void *pre_state; 106 107 if (khz == 0) 108 return 0; 109 110 pre_state = pm->clock_pre(dev, perflvl, id, khz); 111 if (IS_ERR(pre_state)) 112 return PTR_ERR(pre_state); 113 114 if (pre_state) 115 pm->clock_set(dev, pre_state); 116 return 0; 117} 118 119static int 120nouveau_pm_perflvl_set(struct drm_device *dev, struct nouveau_pm_level *perflvl) 121{ 122 struct drm_nouveau_private *dev_priv = dev->dev_private; 123 struct nouveau_pm_engine *pm = &dev_priv->engine.pm; 124 int ret; 125 126 if (perflvl == pm->cur) 127 return 0; 128 129 /*XXX: not on all boards, we should control based on temperature 130 * on recent boards.. or maybe on some other factor we don't 131 * know about? 132 */ 133 if (perflvl->fanspeed) { 134 ret = nouveau_pwmfan_set(dev, perflvl->fanspeed); 135 if (ret && ret != -ENODEV) 136 NV_ERROR(dev, "set fanspeed failed: %d\n", ret); 137 } 138 139 if (pm->voltage.supported && pm->voltage_set && perflvl->volt_min) { 140 ret = pm->voltage_set(dev, perflvl->volt_min); 141 if (ret) { 142 NV_ERROR(dev, "voltage_set %d failed: %d\n", 143 perflvl->volt_min, ret); 144 } 145 } 146 147 if (pm->clocks_pre) { 148 void *state = pm->clocks_pre(dev, perflvl); 149 if (IS_ERR(state)) 150 return PTR_ERR(state); 151 pm->clocks_set(dev, state); 152 } else 153 if (pm->clock_set) { 154 nouveau_pm_clock_set(dev, perflvl, PLL_CORE, perflvl->core); 155 nouveau_pm_clock_set(dev, perflvl, PLL_SHADER, perflvl->shader); 156 nouveau_pm_clock_set(dev, perflvl, PLL_MEMORY, perflvl->memory); 157 nouveau_pm_clock_set(dev, perflvl, PLL_UNK05, perflvl->vdec); 158 } 159 160 pm->cur = perflvl; 161 return 0; 162} 163 164static int 165nouveau_pm_profile_set(struct drm_device *dev, const char *profile) 166{ 167 struct drm_nouveau_private *dev_priv = dev->dev_private; 168 struct nouveau_pm_engine *pm = &dev_priv->engine.pm; 169 struct nouveau_pm_level *perflvl = NULL; 170 171 /* safety precaution, for now */ 172 if (nouveau_perflvl_wr != 7777) 173 return -EPERM; 174 175 if (!strncmp(profile, "boot", 4)) 176 perflvl = &pm->boot; 177 else { 178 int pl = simple_strtol(profile, NULL, 10); 179 int i; 180 181 for (i = 0; i < pm->nr_perflvl; i++) { 182 if (pm->perflvl[i].id == pl) { 183 perflvl = &pm->perflvl[i]; 184 break; 185 } 186 } 187 188 if (!perflvl) 189 return -EINVAL; 190 } 191 192 NV_INFO(dev, "setting performance level: %s\n", profile); 193 return nouveau_pm_perflvl_set(dev, perflvl); 194} 195 196static int 197nouveau_pm_perflvl_get(struct drm_device *dev, struct nouveau_pm_level *perflvl) 198{ 199 struct drm_nouveau_private *dev_priv = dev->dev_private; 200 struct nouveau_pm_engine *pm = &dev_priv->engine.pm; 201 int ret; 202 203 memset(perflvl, 0, sizeof(*perflvl)); 204 205 if (pm->clocks_get) { 206 ret = pm->clocks_get(dev, perflvl); 207 if (ret) 208 return ret; 209 } else 210 if (pm->clock_get) { 211 ret = pm->clock_get(dev, PLL_CORE); 212 if (ret > 0) 213 perflvl->core = ret; 214 215 ret = pm->clock_get(dev, PLL_MEMORY); 216 if (ret > 0) 217 perflvl->memory = ret; 218 219 ret = pm->clock_get(dev, PLL_SHADER); 220 if (ret > 0) 221 perflvl->shader = ret; 222 223 ret = pm->clock_get(dev, PLL_UNK05); 224 if (ret > 0) 225 perflvl->vdec = ret; 226 } 227 228 if (pm->voltage.supported && pm->voltage_get) { 229 ret = pm->voltage_get(dev); 230 if (ret > 0) { 231 perflvl->volt_min = ret; 232 perflvl->volt_max = ret; 233 } 234 } 235 236 ret = nouveau_pwmfan_get(dev); 237 if (ret > 0) 238 perflvl->fanspeed = ret; 239 240 return 0; 241} 242 243static void 244nouveau_pm_perflvl_info(struct nouveau_pm_level *perflvl, char *ptr, int len) 245{ 246 char c[16], s[16], v[32], f[16], t[16], m[16]; 247 248 c[0] = '\0'; 249 if (perflvl->core) 250 snprintf(c, sizeof(c), " core %dMHz", perflvl->core / 1000); 251 252 s[0] = '\0'; 253 if (perflvl->shader) 254 snprintf(s, sizeof(s), " shader %dMHz", perflvl->shader / 1000); 255 256 m[0] = '\0'; 257 if (perflvl->memory) 258 snprintf(m, sizeof(m), " memory %dMHz", perflvl->memory / 1000); 259 260 v[0] = '\0'; 261 if (perflvl->volt_min && perflvl->volt_min != perflvl->volt_max) { 262 snprintf(v, sizeof(v), " voltage %dmV-%dmV", 263 perflvl->volt_min / 1000, perflvl->volt_max / 1000); 264 } else 265 if (perflvl->volt_min) { 266 snprintf(v, sizeof(v), " voltage %dmV", 267 perflvl->volt_min / 1000); 268 } 269 270 f[0] = '\0'; 271 if (perflvl->fanspeed) 272 snprintf(f, sizeof(f), " fanspeed %d%%", perflvl->fanspeed); 273 274 t[0] = '\0'; 275 if (perflvl->timing) 276 snprintf(t, sizeof(t), " timing %d", perflvl->timing->id); 277 278 snprintf(ptr, len, "%s%s%s%s%s%s\n", c, s, m, t, v, f); 279} 280 281static ssize_t 282nouveau_pm_get_perflvl_info(struct device *d, 283 struct device_attribute *a, char *buf) 284{ 285 struct nouveau_pm_level *perflvl = (struct nouveau_pm_level *)a; 286 char *ptr = buf; 287 int len = PAGE_SIZE; 288 289 snprintf(ptr, len, "%d:", perflvl->id); 290 ptr += strlen(buf); 291 len -= strlen(buf); 292 293 nouveau_pm_perflvl_info(perflvl, ptr, len); 294 return strlen(buf); 295} 296 297static ssize_t 298nouveau_pm_get_perflvl(struct device *d, struct device_attribute *a, char *buf) 299{ 300 struct drm_device *dev = pci_get_drvdata(to_pci_dev(d)); 301 struct drm_nouveau_private *dev_priv = dev->dev_private; 302 struct nouveau_pm_engine *pm = &dev_priv->engine.pm; 303 struct nouveau_pm_level cur; 304 int len = PAGE_SIZE, ret; 305 char *ptr = buf; 306 307 if (!pm->cur) 308 snprintf(ptr, len, "setting: boot\n"); 309 else if (pm->cur == &pm->boot) 310 snprintf(ptr, len, "setting: boot\nc:"); 311 else 312 snprintf(ptr, len, "setting: static %d\nc:", pm->cur->id); 313 ptr += strlen(buf); 314 len -= strlen(buf); 315 316 ret = nouveau_pm_perflvl_get(dev, &cur); 317 if (ret == 0) 318 nouveau_pm_perflvl_info(&cur, ptr, len); 319 return strlen(buf); 320} 321 322static ssize_t 323nouveau_pm_set_perflvl(struct device *d, struct device_attribute *a, 324 const char *buf, size_t count) 325{ 326 struct drm_device *dev = pci_get_drvdata(to_pci_dev(d)); 327 int ret; 328 329 ret = nouveau_pm_profile_set(dev, buf); 330 if (ret) 331 return ret; 332 return strlen(buf); 333} 334 335static DEVICE_ATTR(performance_level, S_IRUGO | S_IWUSR, 336 nouveau_pm_get_perflvl, nouveau_pm_set_perflvl); 337 338static int 339nouveau_sysfs_init(struct drm_device *dev) 340{ 341 struct drm_nouveau_private *dev_priv = dev->dev_private; 342 struct nouveau_pm_engine *pm = &dev_priv->engine.pm; 343 struct device *d = &dev->pdev->dev; 344 int ret, i; 345 346 ret = device_create_file(d, &dev_attr_performance_level); 347 if (ret) 348 return ret; 349 350 for (i = 0; i < pm->nr_perflvl; i++) { 351 struct nouveau_pm_level *perflvl = &pm->perflvl[i]; 352 353 perflvl->dev_attr.attr.name = perflvl->name; 354 perflvl->dev_attr.attr.mode = S_IRUGO; 355 perflvl->dev_attr.show = nouveau_pm_get_perflvl_info; 356 perflvl->dev_attr.store = NULL; 357 sysfs_attr_init(&perflvl->dev_attr.attr); 358 359 ret = device_create_file(d, &perflvl->dev_attr); 360 if (ret) { 361 NV_ERROR(dev, "failed pervlvl %d sysfs: %d\n", 362 perflvl->id, i); 363 perflvl->dev_attr.attr.name = NULL; 364 nouveau_pm_fini(dev); 365 return ret; 366 } 367 } 368 369 return 0; 370} 371 372static void 373nouveau_sysfs_fini(struct drm_device *dev) 374{ 375 struct drm_nouveau_private *dev_priv = dev->dev_private; 376 struct nouveau_pm_engine *pm = &dev_priv->engine.pm; 377 struct device *d = &dev->pdev->dev; 378 int i; 379 380 device_remove_file(d, &dev_attr_performance_level); 381 for (i = 0; i < pm->nr_perflvl; i++) { 382 struct nouveau_pm_level *pl = &pm->perflvl[i]; 383 384 if (!pl->dev_attr.attr.name) 385 break; 386 387 device_remove_file(d, &pl->dev_attr); 388 } 389} 390 391#if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE)) 392static ssize_t 393nouveau_hwmon_show_temp(struct device *d, struct device_attribute *a, char *buf) 394{ 395 struct drm_device *dev = dev_get_drvdata(d); 396 struct drm_nouveau_private *dev_priv = dev->dev_private; 397 struct nouveau_pm_engine *pm = &dev_priv->engine.pm; 398 399 return snprintf(buf, PAGE_SIZE, "%d\n", pm->temp_get(dev)*1000); 400} 401static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, nouveau_hwmon_show_temp, 402 NULL, 0); 403 404static ssize_t 405nouveau_hwmon_max_temp(struct device *d, struct device_attribute *a, char *buf) 406{ 407 struct drm_device *dev = dev_get_drvdata(d); 408 struct drm_nouveau_private *dev_priv = dev->dev_private; 409 struct nouveau_pm_engine *pm = &dev_priv->engine.pm; 410 struct nouveau_pm_threshold_temp *temp = &pm->threshold_temp; 411 412 return snprintf(buf, PAGE_SIZE, "%d\n", temp->down_clock*1000); 413} 414static ssize_t 415nouveau_hwmon_set_max_temp(struct device *d, struct device_attribute *a, 416 const char *buf, size_t count) 417{ 418 struct drm_device *dev = dev_get_drvdata(d); 419 struct drm_nouveau_private *dev_priv = dev->dev_private; 420 struct nouveau_pm_engine *pm = &dev_priv->engine.pm; 421 struct nouveau_pm_threshold_temp *temp = &pm->threshold_temp; 422 long value; 423 424 if (strict_strtol(buf, 10, &value) == -EINVAL) 425 return count; 426 427 temp->down_clock = value/1000; 428 429 nouveau_temp_safety_checks(dev); 430 431 return count; 432} 433static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, nouveau_hwmon_max_temp, 434 nouveau_hwmon_set_max_temp, 435 0); 436 437static ssize_t 438nouveau_hwmon_critical_temp(struct device *d, struct device_attribute *a, 439 char *buf) 440{ 441 struct drm_device *dev = dev_get_drvdata(d); 442 struct drm_nouveau_private *dev_priv = dev->dev_private; 443 struct nouveau_pm_engine *pm = &dev_priv->engine.pm; 444 struct nouveau_pm_threshold_temp *temp = &pm->threshold_temp; 445 446 return snprintf(buf, PAGE_SIZE, "%d\n", temp->critical*1000); 447} 448static ssize_t 449nouveau_hwmon_set_critical_temp(struct device *d, struct device_attribute *a, 450 const char *buf, 451 size_t count) 452{ 453 struct drm_device *dev = dev_get_drvdata(d); 454 struct drm_nouveau_private *dev_priv = dev->dev_private; 455 struct nouveau_pm_engine *pm = &dev_priv->engine.pm; 456 struct nouveau_pm_threshold_temp *temp = &pm->threshold_temp; 457 long value; 458 459 if (strict_strtol(buf, 10, &value) == -EINVAL) 460 return count; 461 462 temp->critical = value/1000; 463 464 nouveau_temp_safety_checks(dev); 465 466 return count; 467} 468static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO | S_IWUSR, 469 nouveau_hwmon_critical_temp, 470 nouveau_hwmon_set_critical_temp, 471 0); 472 473static ssize_t nouveau_hwmon_show_name(struct device *dev, 474 struct device_attribute *attr, 475 char *buf) 476{ 477 return sprintf(buf, "nouveau\n"); 478} 479static SENSOR_DEVICE_ATTR(name, S_IRUGO, nouveau_hwmon_show_name, NULL, 0); 480 481static ssize_t nouveau_hwmon_show_update_rate(struct device *dev, 482 struct device_attribute *attr, 483 char *buf) 484{ 485 return sprintf(buf, "1000\n"); 486} 487static SENSOR_DEVICE_ATTR(update_rate, S_IRUGO, 488 nouveau_hwmon_show_update_rate, 489 NULL, 0); 490 491static ssize_t 492nouveau_hwmon_show_fan0_input(struct device *d, struct device_attribute *attr, 493 char *buf) 494{ 495 struct drm_device *dev = dev_get_drvdata(d); 496 struct drm_nouveau_private *dev_priv = dev->dev_private; 497 struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; 498 struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; 499 struct dcb_gpio_entry *gpio; 500 u32 cycles, cur, prev; 501 u64 start; 502 503 gpio = nouveau_bios_gpio_entry(dev, DCB_GPIO_FAN_SENSE); 504 if (!gpio) 505 return -ENODEV; 506 507 /* Monitor the GPIO input 0x3b for 250ms. 508 * When the fan spins, it changes the value of GPIO FAN_SENSE. 509 * We get 4 changes (0 -> 1 -> 0 -> 1 -> [...]) per complete rotation. 510 */ 511 start = ptimer->read(dev); 512 prev = pgpio->get(dev, DCB_GPIO_FAN_SENSE); 513 cycles = 0; 514 do { 515 cur = pgpio->get(dev, DCB_GPIO_FAN_SENSE); 516 if (prev != cur) { 517 cycles++; 518 prev = cur; 519 } 520 521 usleep_range(500, 1000); /* supports 0 < rpm < 7500 */ 522 } while (ptimer->read(dev) - start < 250000000); 523 524 /* interpolate to get rpm */ 525 return sprintf(buf, "%i\n", cycles / 4 * 4 * 60); 526} 527static SENSOR_DEVICE_ATTR(fan0_input, S_IRUGO, nouveau_hwmon_show_fan0_input, 528 NULL, 0); 529 530static ssize_t 531nouveau_hwmon_get_pwm0(struct device *d, struct device_attribute *a, char *buf) 532{ 533 struct drm_device *dev = dev_get_drvdata(d); 534 int ret; 535 536 ret = nouveau_pwmfan_get(dev); 537 if (ret < 0) 538 return ret; 539 540 return sprintf(buf, "%i\n", ret); 541} 542 543static ssize_t 544nouveau_hwmon_set_pwm0(struct device *d, struct device_attribute *a, 545 const char *buf, size_t count) 546{ 547 struct drm_device *dev = dev_get_drvdata(d); 548 struct drm_nouveau_private *dev_priv = dev->dev_private; 549 struct nouveau_pm_engine *pm = &dev_priv->engine.pm; 550 int ret = -ENODEV; 551 long value; 552 553 if (nouveau_perflvl_wr != 7777) 554 return -EPERM; 555 556 if (strict_strtol(buf, 10, &value) == -EINVAL) 557 return -EINVAL; 558 559 if (value < pm->fan.min_duty) 560 value = pm->fan.min_duty; 561 if (value > pm->fan.max_duty) 562 value = pm->fan.max_duty; 563 564 ret = nouveau_pwmfan_set(dev, value); 565 if (ret) 566 return ret; 567 568 return count; 569} 570 571static SENSOR_DEVICE_ATTR(pwm0, S_IRUGO | S_IWUSR, 572 nouveau_hwmon_get_pwm0, 573 nouveau_hwmon_set_pwm0, 0); 574 575static ssize_t 576nouveau_hwmon_get_pwm0_min(struct device *d, 577 struct device_attribute *a, char *buf) 578{ 579 struct drm_device *dev = dev_get_drvdata(d); 580 struct drm_nouveau_private *dev_priv = dev->dev_private; 581 struct nouveau_pm_engine *pm = &dev_priv->engine.pm; 582 583 return sprintf(buf, "%i\n", pm->fan.min_duty); 584} 585 586static ssize_t 587nouveau_hwmon_set_pwm0_min(struct device *d, struct device_attribute *a, 588 const char *buf, size_t count) 589{ 590 struct drm_device *dev = dev_get_drvdata(d); 591 struct drm_nouveau_private *dev_priv = dev->dev_private; 592 struct nouveau_pm_engine *pm = &dev_priv->engine.pm; 593 long value; 594 595 if (strict_strtol(buf, 10, &value) == -EINVAL) 596 return -EINVAL; 597 598 if (value < 0) 599 value = 0; 600 601 if (pm->fan.max_duty - value < 10) 602 value = pm->fan.max_duty - 10; 603 604 if (value < 10) 605 pm->fan.min_duty = 10; 606 else 607 pm->fan.min_duty = value; 608 609 return count; 610} 611 612static SENSOR_DEVICE_ATTR(pwm0_min, S_IRUGO | S_IWUSR, 613 nouveau_hwmon_get_pwm0_min, 614 nouveau_hwmon_set_pwm0_min, 0); 615 616static ssize_t 617nouveau_hwmon_get_pwm0_max(struct device *d, 618 struct device_attribute *a, char *buf) 619{ 620 struct drm_device *dev = dev_get_drvdata(d); 621 struct drm_nouveau_private *dev_priv = dev->dev_private; 622 struct nouveau_pm_engine *pm = &dev_priv->engine.pm; 623 624 return sprintf(buf, "%i\n", pm->fan.max_duty); 625} 626 627static ssize_t 628nouveau_hwmon_set_pwm0_max(struct device *d, struct device_attribute *a, 629 const char *buf, size_t count) 630{ 631 struct drm_device *dev = dev_get_drvdata(d); 632 struct drm_nouveau_private *dev_priv = dev->dev_private; 633 struct nouveau_pm_engine *pm = &dev_priv->engine.pm; 634 long value; 635 636 if (strict_strtol(buf, 10, &value) == -EINVAL) 637 return -EINVAL; 638 639 if (value < 0) 640 value = 0; 641 642 if (value - pm->fan.min_duty < 10) 643 value = pm->fan.min_duty + 10; 644 645 if (value > 100) 646 pm->fan.max_duty = 100; 647 else 648 pm->fan.max_duty = value; 649 650 return count; 651} 652 653static SENSOR_DEVICE_ATTR(pwm0_max, S_IRUGO | S_IWUSR, 654 nouveau_hwmon_get_pwm0_max, 655 nouveau_hwmon_set_pwm0_max, 0); 656 657static struct attribute *hwmon_attributes[] = { 658 &sensor_dev_attr_temp1_input.dev_attr.attr, 659 &sensor_dev_attr_temp1_max.dev_attr.attr, 660 &sensor_dev_attr_temp1_crit.dev_attr.attr, 661 &sensor_dev_attr_name.dev_attr.attr, 662 &sensor_dev_attr_update_rate.dev_attr.attr, 663 NULL 664}; 665static struct attribute *hwmon_fan_rpm_attributes[] = { 666 &sensor_dev_attr_fan0_input.dev_attr.attr, 667 NULL 668}; 669static struct attribute *hwmon_pwm_fan_attributes[] = { 670 &sensor_dev_attr_pwm0.dev_attr.attr, 671 &sensor_dev_attr_pwm0_min.dev_attr.attr, 672 &sensor_dev_attr_pwm0_max.dev_attr.attr, 673 NULL 674}; 675 676static const struct attribute_group hwmon_attrgroup = { 677 .attrs = hwmon_attributes, 678}; 679static const struct attribute_group hwmon_fan_rpm_attrgroup = { 680 .attrs = hwmon_fan_rpm_attributes, 681}; 682static const struct attribute_group hwmon_pwm_fan_attrgroup = { 683 .attrs = hwmon_pwm_fan_attributes, 684}; 685#endif 686 687static int 688nouveau_hwmon_init(struct drm_device *dev) 689{ 690#if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE)) 691 struct drm_nouveau_private *dev_priv = dev->dev_private; 692 struct nouveau_pm_engine *pm = &dev_priv->engine.pm; 693 struct device *hwmon_dev; 694 int ret = 0; 695 696 if (!pm->temp_get) 697 return -ENODEV; 698 699 hwmon_dev = hwmon_device_register(&dev->pdev->dev); 700 if (IS_ERR(hwmon_dev)) { 701 ret = PTR_ERR(hwmon_dev); 702 NV_ERROR(dev, 703 "Unable to register hwmon device: %d\n", ret); 704 return ret; 705 } 706 dev_set_drvdata(hwmon_dev, dev); 707 708 /* default sysfs entries */ 709 ret = sysfs_create_group(&dev->pdev->dev.kobj, &hwmon_attrgroup); 710 if (ret) { 711 if (ret) 712 goto error; 713 } 714 715 /* if the card has a pwm fan */ 716 /*XXX: incorrect, need better detection for this, some boards have 717 * the gpio entries for pwm fan control even when there's no 718 * actual fan connected to it... therm table? */ 719 if (nouveau_pwmfan_get(dev) >= 0) { 720 ret = sysfs_create_group(&dev->pdev->dev.kobj, 721 &hwmon_pwm_fan_attrgroup); 722 if (ret) 723 goto error; 724 } 725 726 /* if the card can read the fan rpm */ 727 if (nouveau_bios_gpio_entry(dev, DCB_GPIO_FAN_SENSE)) { 728 ret = sysfs_create_group(&dev->pdev->dev.kobj, 729 &hwmon_fan_rpm_attrgroup); 730 if (ret) 731 goto error; 732 } 733 734 pm->hwmon = hwmon_dev; 735 736 return 0; 737 738error: 739 NV_ERROR(dev, "Unable to create some hwmon sysfs files: %d\n", ret); 740 hwmon_device_unregister(hwmon_dev); 741 pm->hwmon = NULL; 742 return ret; 743#else 744 pm->hwmon = NULL; 745 return 0; 746#endif 747} 748 749static void 750nouveau_hwmon_fini(struct drm_device *dev) 751{ 752#if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE)) 753 struct drm_nouveau_private *dev_priv = dev->dev_private; 754 struct nouveau_pm_engine *pm = &dev_priv->engine.pm; 755 756 if (pm->hwmon) { 757 sysfs_remove_group(&dev->pdev->dev.kobj, &hwmon_attrgroup); 758 sysfs_remove_group(&dev->pdev->dev.kobj, &hwmon_pwm_fan_attrgroup); 759 sysfs_remove_group(&dev->pdev->dev.kobj, &hwmon_fan_rpm_attrgroup); 760 761 hwmon_device_unregister(pm->hwmon); 762 } 763#endif 764} 765 766#if defined(CONFIG_ACPI) && defined(CONFIG_POWER_SUPPLY) 767static int 768nouveau_pm_acpi_event(struct notifier_block *nb, unsigned long val, void *data) 769{ 770 struct drm_nouveau_private *dev_priv = 771 container_of(nb, struct drm_nouveau_private, engine.pm.acpi_nb); 772 struct drm_device *dev = dev_priv->dev; 773 struct acpi_bus_event *entry = (struct acpi_bus_event *)data; 774 775 if (strcmp(entry->device_class, "ac_adapter") == 0) { 776 bool ac = power_supply_is_system_supplied(); 777 778 NV_DEBUG(dev, "power supply changed: %s\n", ac ? "AC" : "DC"); 779 } 780 781 return NOTIFY_OK; 782} 783#endif 784 785int 786nouveau_pm_init(struct drm_device *dev) 787{ 788 struct drm_nouveau_private *dev_priv = dev->dev_private; 789 struct nouveau_pm_engine *pm = &dev_priv->engine.pm; 790 char info[256]; 791 int ret, i; 792 793 nouveau_mem_timing_init(dev); 794 nouveau_volt_init(dev); 795 nouveau_perf_init(dev); 796 nouveau_temp_init(dev); 797 798 NV_INFO(dev, "%d available performance level(s)\n", pm->nr_perflvl); 799 for (i = 0; i < pm->nr_perflvl; i++) { 800 nouveau_pm_perflvl_info(&pm->perflvl[i], info, sizeof(info)); 801 NV_INFO(dev, "%d:%s", pm->perflvl[i].id, info); 802 } 803 804 /* determine current ("boot") performance level */ 805 ret = nouveau_pm_perflvl_get(dev, &pm->boot); 806 if (ret == 0) { 807 strncpy(pm->boot.name, "boot", 4); 808 pm->cur = &pm->boot; 809 810 nouveau_pm_perflvl_info(&pm->boot, info, sizeof(info)); 811 NV_INFO(dev, "c:%s", info); 812 } 813 814 /* switch performance levels now if requested */ 815 if (nouveau_perflvl != NULL) { 816 ret = nouveau_pm_profile_set(dev, nouveau_perflvl); 817 if (ret) { 818 NV_ERROR(dev, "error setting perflvl \"%s\": %d\n", 819 nouveau_perflvl, ret); 820 } 821 } 822 823 nouveau_sysfs_init(dev); 824 nouveau_hwmon_init(dev); 825#if defined(CONFIG_ACPI) && defined(CONFIG_POWER_SUPPLY) 826 pm->acpi_nb.notifier_call = nouveau_pm_acpi_event; 827 register_acpi_notifier(&pm->acpi_nb); 828#endif 829 830 return 0; 831} 832 833void 834nouveau_pm_fini(struct drm_device *dev) 835{ 836 struct drm_nouveau_private *dev_priv = dev->dev_private; 837 struct nouveau_pm_engine *pm = &dev_priv->engine.pm; 838 839 if (pm->cur != &pm->boot) 840 nouveau_pm_perflvl_set(dev, &pm->boot); 841 842 nouveau_temp_fini(dev); 843 nouveau_perf_fini(dev); 844 nouveau_volt_fini(dev); 845 nouveau_mem_timing_fini(dev); 846 847#if defined(CONFIG_ACPI) && defined(CONFIG_POWER_SUPPLY) 848 unregister_acpi_notifier(&pm->acpi_nb); 849#endif 850 nouveau_hwmon_fini(dev); 851 nouveau_sysfs_fini(dev); 852} 853 854void 855nouveau_pm_resume(struct drm_device *dev) 856{ 857 struct drm_nouveau_private *dev_priv = dev->dev_private; 858 struct nouveau_pm_engine *pm = &dev_priv->engine.pm; 859 struct nouveau_pm_level *perflvl; 860 861 if (!pm->cur || pm->cur == &pm->boot) 862 return; 863 864 perflvl = pm->cur; 865 pm->cur = &pm->boot; 866 nouveau_pm_perflvl_set(dev, perflvl); 867} 868