diff options
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/therm/base.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/therm/fan.c | 52 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/therm/priv.h | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_pm.c | 40 |
6 files changed, 105 insertions, 5 deletions
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/base.c b/drivers/gpu/drm/nouveau/core/subdev/therm/base.c index 6502dfb95dd6..1674c74a76c8 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/base.c | |||
@@ -40,6 +40,8 @@ nouveau_therm_attr_get(struct nouveau_therm *therm, | |||
40 | return priv->bios_fan.min_duty; | 40 | return priv->bios_fan.min_duty; |
41 | case NOUVEAU_THERM_ATTR_FAN_MAX_DUTY: | 41 | case NOUVEAU_THERM_ATTR_FAN_MAX_DUTY: |
42 | return priv->bios_fan.max_duty; | 42 | return priv->bios_fan.max_duty; |
43 | case NOUVEAU_THERM_ATTR_FAN_MODE: | ||
44 | return priv->fan.mode; | ||
43 | case NOUVEAU_THERM_ATTR_THRS_FAN_BOOST: | 45 | case NOUVEAU_THERM_ATTR_THRS_FAN_BOOST: |
44 | return priv->bios_sensor.thrs_fan_boost.temp; | 46 | return priv->bios_sensor.thrs_fan_boost.temp; |
45 | case NOUVEAU_THERM_ATTR_THRS_FAN_BOOST_HYST: | 47 | case NOUVEAU_THERM_ATTR_THRS_FAN_BOOST_HYST: |
@@ -82,6 +84,8 @@ nouveau_therm_attr_set(struct nouveau_therm *therm, | |||
82 | value = priv->bios_fan.min_duty; | 84 | value = priv->bios_fan.min_duty; |
83 | priv->bios_fan.max_duty = value; | 85 | priv->bios_fan.max_duty = value; |
84 | return 0; | 86 | return 0; |
87 | case NOUVEAU_THERM_ATTR_FAN_MODE: | ||
88 | return nouveau_therm_fan_set_mode(therm, value); | ||
85 | case NOUVEAU_THERM_ATTR_THRS_FAN_BOOST: | 89 | case NOUVEAU_THERM_ATTR_THRS_FAN_BOOST: |
86 | priv->bios_sensor.thrs_fan_boost.temp = value; | 90 | priv->bios_sensor.thrs_fan_boost.temp = value; |
87 | return 0; | 91 | return 0; |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c b/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c index 409b95d5b679..b29237970fa0 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c | |||
@@ -69,6 +69,9 @@ nouveau_therm_fan_set(struct nouveau_therm *therm, int percent) | |||
69 | u32 divs, duty; | 69 | u32 divs, duty; |
70 | int ret; | 70 | int ret; |
71 | 71 | ||
72 | if (priv->fan.mode == FAN_CONTROL_NONE) | ||
73 | return -EINVAL; | ||
74 | |||
72 | if (!priv->fan.pwm_set) | 75 | if (!priv->fan.pwm_set) |
73 | return -ENODEV; | 76 | return -ENODEV; |
74 | 77 | ||
@@ -138,7 +141,52 @@ nouveau_therm_fan_sense(struct nouveau_therm *therm) | |||
138 | return 0; | 141 | return 0; |
139 | } | 142 | } |
140 | 143 | ||
141 | static void | 144 | int |
145 | nouveau_therm_fan_set_mode(struct nouveau_therm *therm, | ||
146 | enum nouveau_therm_fan_mode mode) | ||
147 | { | ||
148 | struct nouveau_therm_priv *priv = (void *)therm; | ||
149 | |||
150 | if (priv->fan.mode == mode) | ||
151 | return 0; | ||
152 | |||
153 | if (mode < FAN_CONTROL_NONE || mode >= FAN_CONTROL_NR) | ||
154 | return -EINVAL; | ||
155 | |||
156 | switch (mode) | ||
157 | { | ||
158 | case FAN_CONTROL_NONE: | ||
159 | nv_info(therm, "switch fan to no-control mode\n"); | ||
160 | break; | ||
161 | case FAN_CONTROL_MANUAL: | ||
162 | nv_info(therm, "switch fan to manual mode\n"); | ||
163 | break; | ||
164 | case FAN_CONTROL_NR: | ||
165 | break; | ||
166 | } | ||
167 | |||
168 | priv->fan.mode = mode; | ||
169 | return 0; | ||
170 | } | ||
171 | |||
172 | int | ||
173 | nouveau_therm_fan_user_get(struct nouveau_therm *therm) | ||
174 | { | ||
175 | return nouveau_therm_fan_get(therm); | ||
176 | } | ||
177 | |||
178 | int | ||
179 | nouveau_therm_fan_user_set(struct nouveau_therm *therm, int percent) | ||
180 | { | ||
181 | struct nouveau_therm_priv *priv = (void *)therm; | ||
182 | |||
183 | if (priv->fan.mode != FAN_CONTROL_MANUAL) | ||
184 | return -EINVAL; | ||
185 | |||
186 | return nouveau_therm_fan_set(therm, percent); | ||
187 | } | ||
188 | |||
189 | void | ||
142 | nouveau_therm_fan_set_defaults(struct nouveau_therm *therm) | 190 | nouveau_therm_fan_set_defaults(struct nouveau_therm *therm) |
143 | { | 191 | { |
144 | struct nouveau_therm_priv *priv = (void *)therm; | 192 | struct nouveau_therm_priv *priv = (void *)therm; |
@@ -180,5 +228,7 @@ nouveau_therm_fan_ctor(struct nouveau_therm *therm) | |||
180 | nv_error(therm, "parsing the thermal table failed\n"); | 228 | nv_error(therm, "parsing the thermal table failed\n"); |
181 | nouveau_therm_fan_safety_checks(therm); | 229 | nouveau_therm_fan_safety_checks(therm); |
182 | 230 | ||
231 | nouveau_therm_fan_set_mode(therm, FAN_CONTROL_NONE); | ||
232 | |||
183 | return 0; | 233 | return 0; |
184 | } | 234 | } |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c index 9021b541da8d..fcf2cfe731d6 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c | |||
@@ -142,8 +142,8 @@ nv40_therm_ctor(struct nouveau_object *parent, | |||
142 | priv->fan.pwm_set = nv40_fan_pwm_set; | 142 | priv->fan.pwm_set = nv40_fan_pwm_set; |
143 | 143 | ||
144 | therm->temp_get = nv40_temp_get; | 144 | therm->temp_get = nv40_temp_get; |
145 | therm->fan_get = nouveau_therm_fan_get; | 145 | therm->fan_get = nouveau_therm_fan_user_get; |
146 | therm->fan_set = nouveau_therm_fan_set; | 146 | therm->fan_set = nouveau_therm_fan_user_set; |
147 | therm->fan_sense = nouveau_therm_fan_sense; | 147 | therm->fan_sense = nouveau_therm_fan_sense; |
148 | therm->attr_get = nouveau_therm_attr_get; | 148 | therm->attr_get = nouveau_therm_attr_get; |
149 | therm->attr_set = nouveau_therm_attr_set; | 149 | therm->attr_set = nouveau_therm_attr_set; |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c index de7dc20ed436..f87a7a3eb4e7 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c | |||
@@ -136,8 +136,8 @@ nv50_therm_ctor(struct nouveau_object *parent, | |||
136 | priv->fan.pwm_clock = nv50_fan_pwm_clock; | 136 | priv->fan.pwm_clock = nv50_fan_pwm_clock; |
137 | 137 | ||
138 | therm->temp_get = nv50_temp_get; | 138 | therm->temp_get = nv50_temp_get; |
139 | therm->fan_get = nouveau_therm_fan_get; | 139 | therm->fan_get = nouveau_therm_fan_user_get; |
140 | therm->fan_set = nouveau_therm_fan_set; | 140 | therm->fan_set = nouveau_therm_fan_user_set; |
141 | therm->fan_sense = nouveau_therm_fan_sense; | 141 | therm->fan_sense = nouveau_therm_fan_sense; |
142 | therm->attr_get = nouveau_therm_attr_get; | 142 | therm->attr_get = nouveau_therm_attr_get; |
143 | therm->attr_set = nouveau_therm_attr_set; | 143 | therm->attr_set = nouveau_therm_attr_set; |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h b/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h index c53eb5396972..1c3cd6abc36e 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h | |||
@@ -38,6 +38,7 @@ struct nouveau_therm_priv { | |||
38 | 38 | ||
39 | /* fan priv */ | 39 | /* fan priv */ |
40 | struct { | 40 | struct { |
41 | enum nouveau_therm_fan_mode mode; | ||
41 | int percent; | 42 | int percent; |
42 | 43 | ||
43 | int (*pwm_get)(struct nouveau_therm *, int line, u32*, u32*); | 44 | int (*pwm_get)(struct nouveau_therm *, int line, u32*, u32*); |
@@ -63,5 +64,10 @@ int nouveau_therm_sensor_ctor(struct nouveau_therm *therm); | |||
63 | int nouveau_therm_fan_ctor(struct nouveau_therm *therm); | 64 | int nouveau_therm_fan_ctor(struct nouveau_therm *therm); |
64 | int nouveau_therm_fan_get(struct nouveau_therm *therm); | 65 | int nouveau_therm_fan_get(struct nouveau_therm *therm); |
65 | int nouveau_therm_fan_set(struct nouveau_therm *therm, int percent); | 66 | int nouveau_therm_fan_set(struct nouveau_therm *therm, int percent); |
67 | int nouveau_therm_fan_user_get(struct nouveau_therm *therm); | ||
68 | int nouveau_therm_fan_user_set(struct nouveau_therm *therm, int percent); | ||
69 | int nouveau_therm_fan_set_mode(struct nouveau_therm *therm, | ||
70 | enum nouveau_therm_fan_mode mode); | ||
71 | |||
66 | 72 | ||
67 | int nouveau_therm_fan_sense(struct nouveau_therm *therm); | 73 | int nouveau_therm_fan_sense(struct nouveau_therm *therm); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c index 0dca191ee173..b9d5335df742 100644 --- a/drivers/gpu/drm/nouveau/nouveau_pm.c +++ b/drivers/gpu/drm/nouveau/nouveau_pm.c | |||
@@ -503,6 +503,45 @@ nouveau_hwmon_show_fan0_input(struct device *d, struct device_attribute *attr, | |||
503 | static SENSOR_DEVICE_ATTR(fan0_input, S_IRUGO, nouveau_hwmon_show_fan0_input, | 503 | static SENSOR_DEVICE_ATTR(fan0_input, S_IRUGO, nouveau_hwmon_show_fan0_input, |
504 | NULL, 0); | 504 | NULL, 0); |
505 | 505 | ||
506 | static ssize_t | ||
507 | nouveau_hwmon_get_pwm1_enable(struct device *d, | ||
508 | struct device_attribute *a, char *buf) | ||
509 | { | ||
510 | struct drm_device *dev = dev_get_drvdata(d); | ||
511 | struct nouveau_drm *drm = nouveau_drm(dev); | ||
512 | struct nouveau_therm *therm = nouveau_therm(drm->device); | ||
513 | int ret; | ||
514 | |||
515 | ret = therm->attr_get(therm, NOUVEAU_THERM_ATTR_FAN_MODE); | ||
516 | if (ret < 0) | ||
517 | return ret; | ||
518 | |||
519 | return sprintf(buf, "%i\n", ret); | ||
520 | } | ||
521 | |||
522 | static ssize_t | ||
523 | nouveau_hwmon_set_pwm1_enable(struct device *d, struct device_attribute *a, | ||
524 | const char *buf, size_t count) | ||
525 | { | ||
526 | struct drm_device *dev = dev_get_drvdata(d); | ||
527 | struct nouveau_drm *drm = nouveau_drm(dev); | ||
528 | struct nouveau_therm *therm = nouveau_therm(drm->device); | ||
529 | long value; | ||
530 | int ret; | ||
531 | |||
532 | if (strict_strtol(buf, 10, &value) == -EINVAL) | ||
533 | return -EINVAL; | ||
534 | |||
535 | ret = therm->attr_set(therm, NOUVEAU_THERM_ATTR_FAN_MODE, value); | ||
536 | if (ret) | ||
537 | return ret; | ||
538 | else | ||
539 | return count; | ||
540 | } | ||
541 | static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, | ||
542 | nouveau_hwmon_get_pwm1_enable, | ||
543 | nouveau_hwmon_set_pwm1_enable, 0); | ||
544 | |||
506 | static ssize_t | 545 | static ssize_t |
507 | nouveau_hwmon_get_pwm1(struct device *d, struct device_attribute *a, char *buf) | 546 | nouveau_hwmon_get_pwm1(struct device *d, struct device_attribute *a, char *buf) |
508 | { | 547 | { |
@@ -638,6 +677,7 @@ static struct attribute *hwmon_fan_rpm_attributes[] = { | |||
638 | NULL | 677 | NULL |
639 | }; | 678 | }; |
640 | static struct attribute *hwmon_pwm_fan_attributes[] = { | 679 | static struct attribute *hwmon_pwm_fan_attributes[] = { |
680 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, | ||
641 | &sensor_dev_attr_pwm1.dev_attr.attr, | 681 | &sensor_dev_attr_pwm1.dev_attr.attr, |
642 | &sensor_dev_attr_pwm1_min.dev_attr.attr, | 682 | &sensor_dev_attr_pwm1_min.dev_attr.attr, |
643 | &sensor_dev_attr_pwm1_max.dev_attr.attr, | 683 | &sensor_dev_attr_pwm1_max.dev_attr.attr, |