linux/drivers/gpu/drm/nouveau/nouveau_pm.c
<<
>>
Prefs
   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
  41MODULE_PARM_DESC(perflvl, "Performance level (default: boot)");
  42static char *nouveau_perflvl;
  43module_param_named(perflvl, nouveau_perflvl, charp, 0400);
  44
  45MODULE_PARM_DESC(perflvl_wr, "Allow perflvl changes (warning: dangerous!)");
  46static int nouveau_perflvl_wr;
  47module_param_named(perflvl_wr, nouveau_perflvl_wr, int, 0400);
  48
  49static int
  50nouveau_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
  83static int
  84nouveau_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
 113error:
 114        /* restore the fan speed and voltage before leaving */
 115        nouveau_pm_perflvl_aux(dev, perflvl, perflvl, pm->cur);
 116        return ret;
 117}
 118
 119void
 120nouveau_pm_trigger(struct drm_device *dev)
 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 */
 130        if (power_supply_is_system_supplied())
 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
 158static struct nouveau_pm_profile *
 159profile_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
 172static int
 173nouveau_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
 207static void
 208nouveau_pm_static_dummy(struct nouveau_pm_profile *profile)
 209{
 210}
 211
 212static struct nouveau_pm_level *
 213nouveau_pm_static_select(struct nouveau_pm_profile *profile)
 214{
 215        return container_of(profile, struct nouveau_pm_level, profile);
 216}
 217
 218const struct nouveau_pm_profile_func nouveau_pm_static_profile_func = {
 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
 225static int
 226nouveau_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
 259static void
 260nouveau_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
 293static ssize_t
 294nouveau_pm_get_perflvl_info(struct device *d,
 295                            struct device_attribute *a, char *buf)
 296{
 297        struct nouveau_pm_level *perflvl =
 298                container_of(a, struct nouveau_pm_level, dev_attr);
 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
 310static ssize_t
 311nouveau_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
 330static ssize_t
 331nouveau_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
 343static DEVICE_ATTR(performance_level, S_IRUGO | S_IWUSR,
 344                   nouveau_pm_get_perflvl, nouveau_pm_set_perflvl);
 345
 346static int
 347nouveau_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
 380static void
 381nouveau_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))
 399static ssize_t
 400nouveau_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        int temp = therm->temp_get(therm);
 406
 407        if (temp < 0)
 408                return temp;
 409
 410        return snprintf(buf, PAGE_SIZE, "%d\n", temp * 1000);
 411}
 412static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, nouveau_hwmon_show_temp,
 413                                                  NULL, 0);
 414
 415static ssize_t
 416nouveau_hwmon_show_temp1_auto_point1_pwm(struct device *d,
 417                                         struct device_attribute *a, char *buf)
 418{
 419        return snprintf(buf, PAGE_SIZE, "%d\n", 100);
 420}
 421static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm, S_IRUGO,
 422                          nouveau_hwmon_show_temp1_auto_point1_pwm, NULL, 0);
 423
 424static ssize_t
 425nouveau_hwmon_temp1_auto_point1_temp(struct device *d,
 426                                     struct device_attribute *a, char *buf)
 427{
 428        struct drm_device *dev = dev_get_drvdata(d);
 429        struct nouveau_drm *drm = nouveau_drm(dev);
 430        struct nouveau_therm *therm = nouveau_therm(drm->device);
 431
 432        return snprintf(buf, PAGE_SIZE, "%d\n",
 433              therm->attr_get(therm, NOUVEAU_THERM_ATTR_THRS_FAN_BOOST) * 1000);
 434}
 435static ssize_t
 436nouveau_hwmon_set_temp1_auto_point1_temp(struct device *d,
 437                                         struct device_attribute *a,
 438                                         const char *buf, size_t count)
 439{
 440        struct drm_device *dev = dev_get_drvdata(d);
 441        struct nouveau_drm *drm = nouveau_drm(dev);
 442        struct nouveau_therm *therm = nouveau_therm(drm->device);
 443        long value;
 444
 445        if (kstrtol(buf, 10, &value) == -EINVAL)
 446                return count;
 447
 448        therm->attr_set(therm, NOUVEAU_THERM_ATTR_THRS_FAN_BOOST,
 449                        value / 1000);
 450
 451        return count;
 452}
 453static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, S_IRUGO | S_IWUSR,
 454                          nouveau_hwmon_temp1_auto_point1_temp,
 455                          nouveau_hwmon_set_temp1_auto_point1_temp, 0);
 456
 457static ssize_t
 458nouveau_hwmon_temp1_auto_point1_temp_hyst(struct device *d,
 459                                          struct device_attribute *a, char *buf)
 460{
 461        struct drm_device *dev = dev_get_drvdata(d);
 462        struct nouveau_drm *drm = nouveau_drm(dev);
 463        struct nouveau_therm *therm = nouveau_therm(drm->device);
 464
 465        return snprintf(buf, PAGE_SIZE, "%d\n",
 466         therm->attr_get(therm, NOUVEAU_THERM_ATTR_THRS_FAN_BOOST_HYST) * 1000);
 467}
 468static ssize_t
 469nouveau_hwmon_set_temp1_auto_point1_temp_hyst(struct device *d,
 470                                              struct device_attribute *a,
 471                                              const char *buf, size_t count)
 472{
 473        struct drm_device *dev = dev_get_drvdata(d);
 474        struct nouveau_drm *drm = nouveau_drm(dev);
 475        struct nouveau_therm *therm = nouveau_therm(drm->device);
 476        long value;
 477
 478        if (kstrtol(buf, 10, &value) == -EINVAL)
 479                return count;
 480
 481        therm->attr_set(therm, NOUVEAU_THERM_ATTR_THRS_FAN_BOOST_HYST,
 482                        value / 1000);
 483
 484        return count;
 485}
 486static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, S_IRUGO | S_IWUSR,
 487                          nouveau_hwmon_temp1_auto_point1_temp_hyst,
 488                          nouveau_hwmon_set_temp1_auto_point1_temp_hyst, 0);
 489
 490static ssize_t
 491nouveau_hwmon_max_temp(struct device *d, struct device_attribute *a, char *buf)
 492{
 493        struct drm_device *dev = dev_get_drvdata(d);
 494        struct nouveau_drm *drm = nouveau_drm(dev);
 495        struct nouveau_therm *therm = nouveau_therm(drm->device);
 496
 497        return snprintf(buf, PAGE_SIZE, "%d\n",
 498               therm->attr_get(therm, NOUVEAU_THERM_ATTR_THRS_DOWN_CLK) * 1000);
 499}
 500static ssize_t
 501nouveau_hwmon_set_max_temp(struct device *d, struct device_attribute *a,
 502                                                const char *buf, size_t count)
 503{
 504        struct drm_device *dev = dev_get_drvdata(d);
 505        struct nouveau_drm *drm = nouveau_drm(dev);
 506        struct nouveau_therm *therm = nouveau_therm(drm->device);
 507        long value;
 508
 509        if (kstrtol(buf, 10, &value) == -EINVAL)
 510                return count;
 511
 512        therm->attr_set(therm, NOUVEAU_THERM_ATTR_THRS_DOWN_CLK, value / 1000);
 513
 514        return count;
 515}
 516static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, nouveau_hwmon_max_temp,
 517                                                  nouveau_hwmon_set_max_temp,
 518                                                  0);
 519
 520static ssize_t
 521nouveau_hwmon_max_temp_hyst(struct device *d, struct device_attribute *a,
 522                            char *buf)
 523{
 524        struct drm_device *dev = dev_get_drvdata(d);
 525        struct nouveau_drm *drm = nouveau_drm(dev);
 526        struct nouveau_therm *therm = nouveau_therm(drm->device);
 527
 528        return snprintf(buf, PAGE_SIZE, "%d\n",
 529          therm->attr_get(therm, NOUVEAU_THERM_ATTR_THRS_DOWN_CLK_HYST) * 1000);
 530}
 531static ssize_t
 532nouveau_hwmon_set_max_temp_hyst(struct device *d, struct device_attribute *a,
 533                                                const char *buf, size_t count)
 534{
 535        struct drm_device *dev = dev_get_drvdata(d);
 536        struct nouveau_drm *drm = nouveau_drm(dev);
 537        struct nouveau_therm *therm = nouveau_therm(drm->device);
 538        long value;
 539
 540        if (kstrtol(buf, 10, &value) == -EINVAL)
 541                return count;
 542
 543        therm->attr_set(therm, NOUVEAU_THERM_ATTR_THRS_DOWN_CLK_HYST,
 544                        value / 1000);
 545
 546        return count;
 547}
 548static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR,
 549                          nouveau_hwmon_max_temp_hyst,
 550                          nouveau_hwmon_set_max_temp_hyst, 0);
 551
 552static ssize_t
 553nouveau_hwmon_critical_temp(struct device *d, struct device_attribute *a,
 554                                                        char *buf)
 555{
 556        struct drm_device *dev = dev_get_drvdata(d);
 557        struct nouveau_drm *drm = nouveau_drm(dev);
 558        struct nouveau_therm *therm = nouveau_therm(drm->device);
 559
 560        return snprintf(buf, PAGE_SIZE, "%d\n",
 561               therm->attr_get(therm, NOUVEAU_THERM_ATTR_THRS_CRITICAL) * 1000);
 562}
 563static ssize_t
 564nouveau_hwmon_set_critical_temp(struct device *d, struct device_attribute *a,
 565                                                            const char *buf,
 566                                                                size_t count)
 567{
 568        struct drm_device *dev = dev_get_drvdata(d);
 569        struct nouveau_drm *drm = nouveau_drm(dev);
 570        struct nouveau_therm *therm = nouveau_therm(drm->device);
 571        long value;
 572
 573        if (kstrtol(buf, 10, &value) == -EINVAL)
 574                return count;
 575
 576        therm->attr_set(therm, NOUVEAU_THERM_ATTR_THRS_CRITICAL, value / 1000);
 577
 578        return count;
 579}
 580static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO | S_IWUSR,
 581                                                nouveau_hwmon_critical_temp,
 582                                                nouveau_hwmon_set_critical_temp,
 583                                                0);
 584
 585static ssize_t
 586nouveau_hwmon_critical_temp_hyst(struct device *d, struct device_attribute *a,
 587                                                        char *buf)
 588{
 589        struct drm_device *dev = dev_get_drvdata(d);
 590        struct nouveau_drm *drm = nouveau_drm(dev);
 591        struct nouveau_therm *therm = nouveau_therm(drm->device);
 592
 593        return snprintf(buf, PAGE_SIZE, "%d\n",
 594          therm->attr_get(therm, NOUVEAU_THERM_ATTR_THRS_CRITICAL_HYST) * 1000);
 595}
 596static ssize_t
 597nouveau_hwmon_set_critical_temp_hyst(struct device *d,
 598                                     struct device_attribute *a,
 599                                     const char *buf,
 600                                     size_t count)
 601{
 602        struct drm_device *dev = dev_get_drvdata(d);
 603        struct nouveau_drm *drm = nouveau_drm(dev);
 604        struct nouveau_therm *therm = nouveau_therm(drm->device);
 605        long value;
 606
 607        if (kstrtol(buf, 10, &value) == -EINVAL)
 608                return count;
 609
 610        therm->attr_set(therm, NOUVEAU_THERM_ATTR_THRS_CRITICAL_HYST,
 611                        value / 1000);
 612
 613        return count;
 614}
 615static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO | S_IWUSR,
 616                          nouveau_hwmon_critical_temp_hyst,
 617                          nouveau_hwmon_set_critical_temp_hyst, 0);
 618static ssize_t
 619nouveau_hwmon_emergency_temp(struct device *d, struct device_attribute *a,
 620                                                        char *buf)
 621{
 622        struct drm_device *dev = dev_get_drvdata(d);
 623        struct nouveau_drm *drm = nouveau_drm(dev);
 624        struct nouveau_therm *therm = nouveau_therm(drm->device);
 625
 626        return snprintf(buf, PAGE_SIZE, "%d\n",
 627               therm->attr_get(therm, NOUVEAU_THERM_ATTR_THRS_SHUTDOWN) * 1000);
 628}
 629static ssize_t
 630nouveau_hwmon_set_emergency_temp(struct device *d, struct device_attribute *a,
 631                                                            const char *buf,
 632                                                                size_t count)
 633{
 634        struct drm_device *dev = dev_get_drvdata(d);
 635        struct nouveau_drm *drm = nouveau_drm(dev);
 636        struct nouveau_therm *therm = nouveau_therm(drm->device);
 637        long value;
 638
 639        if (kstrtol(buf, 10, &value) == -EINVAL)
 640                return count;
 641
 642        therm->attr_set(therm, NOUVEAU_THERM_ATTR_THRS_SHUTDOWN, value / 1000);
 643
 644        return count;
 645}
 646static SENSOR_DEVICE_ATTR(temp1_emergency, S_IRUGO | S_IWUSR,
 647                                        nouveau_hwmon_emergency_temp,
 648                                        nouveau_hwmon_set_emergency_temp,
 649                                        0);
 650
 651static ssize_t
 652nouveau_hwmon_emergency_temp_hyst(struct device *d, struct device_attribute *a,
 653                                                        char *buf)
 654{
 655        struct drm_device *dev = dev_get_drvdata(d);
 656        struct nouveau_drm *drm = nouveau_drm(dev);
 657        struct nouveau_therm *therm = nouveau_therm(drm->device);
 658
 659        return snprintf(buf, PAGE_SIZE, "%d\n",
 660          therm->attr_get(therm, NOUVEAU_THERM_ATTR_THRS_SHUTDOWN_HYST) * 1000);
 661}
 662static ssize_t
 663nouveau_hwmon_set_emergency_temp_hyst(struct device *d,
 664                                      struct device_attribute *a,
 665                                      const char *buf,
 666                                      size_t count)
 667{
 668        struct drm_device *dev = dev_get_drvdata(d);
 669        struct nouveau_drm *drm = nouveau_drm(dev);
 670        struct nouveau_therm *therm = nouveau_therm(drm->device);
 671        long value;
 672
 673        if (kstrtol(buf, 10, &value) == -EINVAL)
 674                return count;
 675
 676        therm->attr_set(therm, NOUVEAU_THERM_ATTR_THRS_SHUTDOWN_HYST,
 677                        value / 1000);
 678
 679        return count;
 680}
 681static SENSOR_DEVICE_ATTR(temp1_emergency_hyst, S_IRUGO | S_IWUSR,
 682                                        nouveau_hwmon_emergency_temp_hyst,
 683                                        nouveau_hwmon_set_emergency_temp_hyst,
 684                                        0);
 685
 686static ssize_t nouveau_hwmon_show_name(struct device *dev,
 687                                      struct device_attribute *attr,
 688                                      char *buf)
 689{
 690        return sprintf(buf, "nouveau\n");
 691}
 692static SENSOR_DEVICE_ATTR(name, S_IRUGO, nouveau_hwmon_show_name, NULL, 0);
 693
 694static ssize_t nouveau_hwmon_show_update_rate(struct device *dev,
 695                                      struct device_attribute *attr,
 696                                      char *buf)
 697{
 698        return sprintf(buf, "1000\n");
 699}
 700static SENSOR_DEVICE_ATTR(update_rate, S_IRUGO,
 701                                                nouveau_hwmon_show_update_rate,
 702                                                NULL, 0);
 703
 704static ssize_t
 705nouveau_hwmon_show_fan1_input(struct device *d, struct device_attribute *attr,
 706                              char *buf)
 707{
 708        struct drm_device *dev = dev_get_drvdata(d);
 709        struct nouveau_drm *drm = nouveau_drm(dev);
 710        struct nouveau_therm *therm = nouveau_therm(drm->device);
 711
 712        return snprintf(buf, PAGE_SIZE, "%d\n", therm->fan_sense(therm));
 713}
 714static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, nouveau_hwmon_show_fan1_input,
 715                          NULL, 0);
 716
 717 static ssize_t
 718nouveau_hwmon_get_pwm1_enable(struct device *d,
 719                           struct device_attribute *a, char *buf)
 720{
 721        struct drm_device *dev = dev_get_drvdata(d);
 722        struct nouveau_drm *drm = nouveau_drm(dev);
 723        struct nouveau_therm *therm = nouveau_therm(drm->device);
 724        int ret;
 725
 726        ret = therm->attr_get(therm, NOUVEAU_THERM_ATTR_FAN_MODE);
 727        if (ret < 0)
 728                return ret;
 729
 730        return sprintf(buf, "%i\n", ret);
 731}
 732
 733static ssize_t
 734nouveau_hwmon_set_pwm1_enable(struct device *d, struct device_attribute *a,
 735                           const char *buf, size_t count)
 736{
 737        struct drm_device *dev = dev_get_drvdata(d);
 738        struct nouveau_drm *drm = nouveau_drm(dev);
 739        struct nouveau_therm *therm = nouveau_therm(drm->device);
 740        long value;
 741        int ret;
 742
 743        if (strict_strtol(buf, 10, &value) == -EINVAL)
 744                return -EINVAL;
 745
 746        ret = therm->attr_set(therm, NOUVEAU_THERM_ATTR_FAN_MODE, value);
 747        if (ret)
 748                return ret;
 749        else
 750                return count;
 751}
 752static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
 753                          nouveau_hwmon_get_pwm1_enable,
 754                          nouveau_hwmon_set_pwm1_enable, 0);
 755
 756static ssize_t
 757nouveau_hwmon_get_pwm1(struct device *d, struct device_attribute *a, char *buf)
 758{
 759        struct drm_device *dev = dev_get_drvdata(d);
 760        struct nouveau_drm *drm = nouveau_drm(dev);
 761        struct nouveau_therm *therm = nouveau_therm(drm->device);
 762        int ret;
 763
 764        ret = therm->fan_get(therm);
 765        if (ret < 0)
 766                return ret;
 767
 768        return sprintf(buf, "%i\n", ret);
 769}
 770
 771static ssize_t
 772nouveau_hwmon_set_pwm1(struct device *d, struct device_attribute *a,
 773                       const char *buf, size_t count)
 774{
 775        struct drm_device *dev = dev_get_drvdata(d);
 776        struct nouveau_drm *drm = nouveau_drm(dev);
 777        struct nouveau_therm *therm = nouveau_therm(drm->device);
 778        int ret = -ENODEV;
 779        long value;
 780
 781        if (nouveau_perflvl_wr != 7777)
 782                return -EPERM;
 783
 784        if (kstrtol(buf, 10, &value) == -EINVAL)
 785                return -EINVAL;
 786
 787        ret = therm->fan_set(therm, value);
 788        if (ret)
 789                return ret;
 790
 791        return count;
 792}
 793
 794static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR,
 795                          nouveau_hwmon_get_pwm1,
 796                          nouveau_hwmon_set_pwm1, 0);
 797
 798static ssize_t
 799nouveau_hwmon_get_pwm1_min(struct device *d,
 800                           struct device_attribute *a, char *buf)
 801{
 802        struct drm_device *dev = dev_get_drvdata(d);
 803        struct nouveau_drm *drm = nouveau_drm(dev);
 804        struct nouveau_therm *therm = nouveau_therm(drm->device);
 805        int ret;
 806
 807        ret = therm->attr_get(therm, NOUVEAU_THERM_ATTR_FAN_MIN_DUTY);
 808        if (ret < 0)
 809                return ret;
 810
 811        return sprintf(buf, "%i\n", ret);
 812}
 813
 814static ssize_t
 815nouveau_hwmon_set_pwm1_min(struct device *d, struct device_attribute *a,
 816                           const char *buf, size_t count)
 817{
 818        struct drm_device *dev = dev_get_drvdata(d);
 819        struct nouveau_drm *drm = nouveau_drm(dev);
 820        struct nouveau_therm *therm = nouveau_therm(drm->device);
 821        long value;
 822        int ret;
 823
 824        if (kstrtol(buf, 10, &value) == -EINVAL)
 825                return -EINVAL;
 826
 827        ret = therm->attr_set(therm, NOUVEAU_THERM_ATTR_FAN_MIN_DUTY, value);
 828        if (ret < 0)
 829                return ret;
 830
 831        return count;
 832}
 833
 834static SENSOR_DEVICE_ATTR(pwm1_min, S_IRUGO | S_IWUSR,
 835                          nouveau_hwmon_get_pwm1_min,
 836                          nouveau_hwmon_set_pwm1_min, 0);
 837
 838static ssize_t
 839nouveau_hwmon_get_pwm1_max(struct device *d,
 840                           struct device_attribute *a, char *buf)
 841{
 842        struct drm_device *dev = dev_get_drvdata(d);
 843        struct nouveau_drm *drm = nouveau_drm(dev);
 844        struct nouveau_therm *therm = nouveau_therm(drm->device);
 845        int ret;
 846
 847        ret = therm->attr_get(therm, NOUVEAU_THERM_ATTR_FAN_MAX_DUTY);
 848        if (ret < 0)
 849                return ret;
 850
 851        return sprintf(buf, "%i\n", ret);
 852}
 853
 854static ssize_t
 855nouveau_hwmon_set_pwm1_max(struct device *d, struct device_attribute *a,
 856                           const char *buf, size_t count)
 857{
 858        struct drm_device *dev = dev_get_drvdata(d);
 859        struct nouveau_drm *drm = nouveau_drm(dev);
 860        struct nouveau_therm *therm = nouveau_therm(drm->device);
 861        long value;
 862        int ret;
 863
 864        if (kstrtol(buf, 10, &value) == -EINVAL)
 865                return -EINVAL;
 866
 867        ret = therm->attr_set(therm, NOUVEAU_THERM_ATTR_FAN_MAX_DUTY, value);
 868        if (ret < 0)
 869                return ret;
 870
 871        return count;
 872}
 873
 874static SENSOR_DEVICE_ATTR(pwm1_max, S_IRUGO | S_IWUSR,
 875                          nouveau_hwmon_get_pwm1_max,
 876                          nouveau_hwmon_set_pwm1_max, 0);
 877
 878static struct attribute *hwmon_default_attributes[] = {
 879        &sensor_dev_attr_name.dev_attr.attr,
 880        &sensor_dev_attr_update_rate.dev_attr.attr,
 881        NULL
 882};
 883static struct attribute *hwmon_temp_attributes[] = {
 884        &sensor_dev_attr_temp1_input.dev_attr.attr,
 885        &sensor_dev_attr_temp1_auto_point1_pwm.dev_attr.attr,
 886        &sensor_dev_attr_temp1_auto_point1_temp.dev_attr.attr,
 887        &sensor_dev_attr_temp1_auto_point1_temp_hyst.dev_attr.attr,
 888        &sensor_dev_attr_temp1_max.dev_attr.attr,
 889        &sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
 890        &sensor_dev_attr_temp1_crit.dev_attr.attr,
 891        &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr,
 892        &sensor_dev_attr_temp1_emergency.dev_attr.attr,
 893        &sensor_dev_attr_temp1_emergency_hyst.dev_attr.attr,
 894        NULL
 895};
 896static struct attribute *hwmon_fan_rpm_attributes[] = {
 897        &sensor_dev_attr_fan1_input.dev_attr.attr,
 898        NULL
 899};
 900static struct attribute *hwmon_pwm_fan_attributes[] = {
 901        &sensor_dev_attr_pwm1_enable.dev_attr.attr,
 902        &sensor_dev_attr_pwm1.dev_attr.attr,
 903        &sensor_dev_attr_pwm1_min.dev_attr.attr,
 904        &sensor_dev_attr_pwm1_max.dev_attr.attr,
 905        NULL
 906};
 907
 908static const struct attribute_group hwmon_default_attrgroup = {
 909        .attrs = hwmon_default_attributes,
 910};
 911static const struct attribute_group hwmon_temp_attrgroup = {
 912        .attrs = hwmon_temp_attributes,
 913};
 914static const struct attribute_group hwmon_fan_rpm_attrgroup = {
 915        .attrs = hwmon_fan_rpm_attributes,
 916};
 917static const struct attribute_group hwmon_pwm_fan_attrgroup = {
 918        .attrs = hwmon_pwm_fan_attributes,
 919};
 920#endif
 921
 922static int
 923nouveau_hwmon_init(struct drm_device *dev)
 924{
 925        struct nouveau_pm *pm = nouveau_pm(dev);
 926
 927#if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
 928        struct nouveau_drm *drm = nouveau_drm(dev);
 929        struct nouveau_therm *therm = nouveau_therm(drm->device);
 930        struct device *hwmon_dev;
 931        int ret = 0;
 932
 933        if (!therm || !therm->temp_get || !therm->attr_get || !therm->attr_set)
 934                return -ENODEV;
 935
 936        hwmon_dev = hwmon_device_register(&dev->pdev->dev);
 937        if (IS_ERR(hwmon_dev)) {
 938                ret = PTR_ERR(hwmon_dev);
 939                NV_ERROR(drm, "Unable to register hwmon device: %d\n", ret);
 940                return ret;
 941        }
 942        dev_set_drvdata(hwmon_dev, dev);
 943
 944        /* set the default attributes */
 945        ret = sysfs_create_group(&hwmon_dev->kobj, &hwmon_default_attrgroup);
 946        if (ret) {
 947                if (ret)
 948                        goto error;
 949        }
 950
 951        /* if the card has a working thermal sensor */
 952        if (therm->temp_get(therm) >= 0) {
 953                ret = sysfs_create_group(&hwmon_dev->kobj, &hwmon_temp_attrgroup);
 954                if (ret) {
 955                        if (ret)
 956                                goto error;
 957                }
 958        }
 959
 960        /* if the card has a pwm fan */
 961        /*XXX: incorrect, need better detection for this, some boards have
 962         *     the gpio entries for pwm fan control even when there's no
 963         *     actual fan connected to it... therm table? */
 964        if (therm->fan_get && therm->fan_get(therm) >= 0) {
 965                ret = sysfs_create_group(&hwmon_dev->kobj,
 966                                         &hwmon_pwm_fan_attrgroup);
 967                if (ret)
 968                        goto error;
 969        }
 970
 971        /* if the card can read the fan rpm */
 972        if (therm->fan_sense(therm) >= 0) {
 973                ret = sysfs_create_group(&hwmon_dev->kobj,
 974                                         &hwmon_fan_rpm_attrgroup);
 975                if (ret)
 976                        goto error;
 977        }
 978
 979        pm->hwmon = hwmon_dev;
 980
 981        return 0;
 982
 983error:
 984        NV_ERROR(drm, "Unable to create some hwmon sysfs files: %d\n", ret);
 985        hwmon_device_unregister(hwmon_dev);
 986        pm->hwmon = NULL;
 987        return ret;
 988#else
 989        pm->hwmon = NULL;
 990        return 0;
 991#endif
 992}
 993
 994static void
 995nouveau_hwmon_fini(struct drm_device *dev)
 996{
 997#if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
 998        struct nouveau_pm *pm = nouveau_pm(dev);
 999
1000        if (pm->hwmon) {
1001                sysfs_remove_group(&pm->hwmon->kobj, &hwmon_default_attrgroup);
1002                sysfs_remove_group(&pm->hwmon->kobj, &hwmon_temp_attrgroup);
1003                sysfs_remove_group(&pm->hwmon->kobj, &hwmon_pwm_fan_attrgroup);
1004                sysfs_remove_group(&pm->hwmon->kobj, &hwmon_fan_rpm_attrgroup);
1005
1006                hwmon_device_unregister(pm->hwmon);
1007        }
1008#endif
1009}
1010
1011#if defined(CONFIG_ACPI) && defined(CONFIG_POWER_SUPPLY)
1012static int
1013nouveau_pm_acpi_event(struct notifier_block *nb, unsigned long val, void *data)
1014{
1015        struct nouveau_pm *pm = container_of(nb, struct nouveau_pm, acpi_nb);
1016        struct nouveau_drm *drm = nouveau_drm(pm->dev);
1017        struct acpi_bus_event *entry = (struct acpi_bus_event *)data;
1018
1019        if (strcmp(entry->device_class, "ac_adapter") == 0) {
1020                bool ac = power_supply_is_system_supplied();
1021
1022                NV_DEBUG(drm, "power supply changed: %s\n", ac ? "AC" : "DC");
1023                nouveau_pm_trigger(pm->dev);
1024        }
1025
1026        return NOTIFY_OK;
1027}
1028#endif
1029
1030int
1031nouveau_pm_init(struct drm_device *dev)
1032{
1033        struct nouveau_device *device = nouveau_dev(dev);
1034        struct nouveau_drm *drm = nouveau_drm(dev);
1035        struct nouveau_pm *pm;
1036        char info[256];
1037        int ret, i;
1038
1039        pm = drm->pm = kzalloc(sizeof(*pm), GFP_KERNEL);
1040        if (!pm)
1041                return -ENOMEM;
1042
1043        pm->dev = dev;
1044
1045        if (device->card_type < NV_40) {
1046                pm->clocks_get = nv04_pm_clocks_get;
1047                pm->clocks_pre = nv04_pm_clocks_pre;
1048                pm->clocks_set = nv04_pm_clocks_set;
1049                if (nouveau_gpio(drm->device)) {
1050                        pm->voltage_get = nouveau_voltage_gpio_get;
1051                        pm->voltage_set = nouveau_voltage_gpio_set;
1052                }
1053        } else
1054        if (device->card_type < NV_50) {
1055                pm->clocks_get = nv40_pm_clocks_get;
1056                pm->clocks_pre = nv40_pm_clocks_pre;
1057                pm->clocks_set = nv40_pm_clocks_set;
1058                pm->voltage_get = nouveau_voltage_gpio_get;
1059                pm->voltage_set = nouveau_voltage_gpio_set;
1060        } else
1061        if (device->card_type < NV_C0) {
1062                if (device->chipset <  0xa3 ||
1063                    device->chipset == 0xaa ||
1064                    device->chipset == 0xac) {
1065                        pm->clocks_get = nv50_pm_clocks_get;
1066                        pm->clocks_pre = nv50_pm_clocks_pre;
1067                        pm->clocks_set = nv50_pm_clocks_set;
1068                } else {
1069                        pm->clocks_get = nva3_pm_clocks_get;
1070                        pm->clocks_pre = nva3_pm_clocks_pre;
1071                        pm->clocks_set = nva3_pm_clocks_set;
1072                }
1073                pm->voltage_get = nouveau_voltage_gpio_get;
1074                pm->voltage_set = nouveau_voltage_gpio_set;
1075        } else
1076        if (device->card_type < NV_E0) {
1077                pm->clocks_get = nvc0_pm_clocks_get;
1078                pm->clocks_pre = nvc0_pm_clocks_pre;
1079                pm->clocks_set = nvc0_pm_clocks_set;
1080                pm->voltage_get = nouveau_voltage_gpio_get;
1081                pm->voltage_set = nouveau_voltage_gpio_set;
1082        }
1083
1084
1085        /* parse aux tables from vbios */
1086        nouveau_volt_init(dev);
1087
1088        INIT_LIST_HEAD(&pm->profiles);
1089
1090        /* determine current ("boot") performance level */
1091        ret = nouveau_pm_perflvl_get(dev, &pm->boot);
1092        if (ret) {
1093                NV_ERROR(drm, "failed to determine boot perflvl\n");
1094                return ret;
1095        }
1096
1097        strncpy(pm->boot.name, "boot", 4);
1098        strncpy(pm->boot.profile.name, "boot", 4);
1099        pm->boot.profile.func = &nouveau_pm_static_profile_func;
1100
1101        list_add(&pm->boot.profile.head, &pm->profiles);
1102
1103        pm->profile_ac = &pm->boot.profile;
1104        pm->profile_dc = &pm->boot.profile;
1105        pm->profile = &pm->boot.profile;
1106        pm->cur = &pm->boot;
1107
1108        /* add performance levels from vbios */
1109        nouveau_perf_init(dev);
1110
1111        /* display available performance levels */
1112        NV_INFO(drm, "%d available performance level(s)\n", pm->nr_perflvl);
1113        for (i = 0; i < pm->nr_perflvl; i++) {
1114                nouveau_pm_perflvl_info(&pm->perflvl[i], info, sizeof(info));
1115                NV_INFO(drm, "%d:%s", pm->perflvl[i].id, info);
1116        }
1117
1118        nouveau_pm_perflvl_info(&pm->boot, info, sizeof(info));
1119        NV_INFO(drm, "c:%s", info);
1120
1121        /* switch performance levels now if requested */
1122        if (nouveau_perflvl != NULL)
1123                nouveau_pm_profile_set(dev, nouveau_perflvl);
1124
1125        nouveau_sysfs_init(dev);
1126        nouveau_hwmon_init(dev);
1127#if defined(CONFIG_ACPI) && defined(CONFIG_POWER_SUPPLY)
1128        pm->acpi_nb.notifier_call = nouveau_pm_acpi_event;
1129        register_acpi_notifier(&pm->acpi_nb);
1130#endif
1131
1132        return 0;
1133}
1134
1135void
1136nouveau_pm_fini(struct drm_device *dev)
1137{
1138        struct nouveau_pm *pm = nouveau_pm(dev);
1139        struct nouveau_pm_profile *profile, *tmp;
1140
1141        list_for_each_entry_safe(profile, tmp, &pm->profiles, head) {
1142                list_del(&profile->head);
1143                profile->func->destroy(profile);
1144        }
1145
1146        if (pm->cur != &pm->boot)
1147                nouveau_pm_perflvl_set(dev, &pm->boot);
1148
1149        nouveau_perf_fini(dev);
1150        nouveau_volt_fini(dev);
1151
1152#if defined(CONFIG_ACPI) && defined(CONFIG_POWER_SUPPLY)
1153        unregister_acpi_notifier(&pm->acpi_nb);
1154#endif
1155        nouveau_hwmon_fini(dev);
1156        nouveau_sysfs_fini(dev);
1157
1158        nouveau_drm(dev)->pm = NULL;
1159        kfree(pm);
1160}
1161
1162void
1163nouveau_pm_resume(struct drm_device *dev)
1164{
1165        struct nouveau_pm *pm = nouveau_pm(dev);
1166        struct nouveau_pm_level *perflvl;
1167
1168        if (!pm->cur || pm->cur == &pm->boot)
1169                return;
1170
1171        perflvl = pm->cur;
1172        pm->cur = &pm->boot;
1173        nouveau_pm_perflvl_set(dev, perflvl);
1174}
1175