aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/base.c4
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/fan.c52
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c4
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c4
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/priv.h6
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_pm.c40
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
141static void 144int
145nouveau_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
172int
173nouveau_therm_fan_user_get(struct nouveau_therm *therm)
174{
175 return nouveau_therm_fan_get(therm);
176}
177
178int
179nouveau_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
189void
142nouveau_therm_fan_set_defaults(struct nouveau_therm *therm) 190nouveau_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);
63int nouveau_therm_fan_ctor(struct nouveau_therm *therm); 64int nouveau_therm_fan_ctor(struct nouveau_therm *therm);
64int nouveau_therm_fan_get(struct nouveau_therm *therm); 65int nouveau_therm_fan_get(struct nouveau_therm *therm);
65int nouveau_therm_fan_set(struct nouveau_therm *therm, int percent); 66int nouveau_therm_fan_set(struct nouveau_therm *therm, int percent);
67int nouveau_therm_fan_user_get(struct nouveau_therm *therm);
68int nouveau_therm_fan_user_set(struct nouveau_therm *therm, int percent);
69int nouveau_therm_fan_set_mode(struct nouveau_therm *therm,
70 enum nouveau_therm_fan_mode mode);
71
66 72
67int nouveau_therm_fan_sense(struct nouveau_therm *therm); 73int 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,
503static SENSOR_DEVICE_ATTR(fan0_input, S_IRUGO, nouveau_hwmon_show_fan0_input, 503static SENSOR_DEVICE_ATTR(fan0_input, S_IRUGO, nouveau_hwmon_show_fan0_input,
504 NULL, 0); 504 NULL, 0);
505 505
506 static ssize_t
507nouveau_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
522static ssize_t
523nouveau_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}
541static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
542 nouveau_hwmon_get_pwm1_enable,
543 nouveau_hwmon_set_pwm1_enable, 0);
544
506static ssize_t 545static ssize_t
507nouveau_hwmon_get_pwm1(struct device *d, struct device_attribute *a, char *buf) 546nouveau_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};
640static struct attribute *hwmon_pwm_fan_attributes[] = { 679static 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,