summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nouveau/core/subdev
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau/core/subdev')
-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
5 files changed, 65 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,
return priv->bios_fan.min_duty;
case NOUVEAU_THERM_ATTR_FAN_MAX_DUTY:
return priv->bios_fan.max_duty;
+ case NOUVEAU_THERM_ATTR_FAN_MODE:
+ return priv->fan.mode;
case NOUVEAU_THERM_ATTR_THRS_FAN_BOOST:
return priv->bios_sensor.thrs_fan_boost.temp;
case NOUVEAU_THERM_ATTR_THRS_FAN_BOOST_HYST:
@@ -82,6 +84,8 @@ nouveau_therm_attr_set(struct nouveau_therm *therm,
value = priv->bios_fan.min_duty;
priv->bios_fan.max_duty = value;
return 0;
+ case NOUVEAU_THERM_ATTR_FAN_MODE:
+ return nouveau_therm_fan_set_mode(therm, value);
case NOUVEAU_THERM_ATTR_THRS_FAN_BOOST:
priv->bios_sensor.thrs_fan_boost.temp = value;
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)
u32 divs, duty;
int ret;
+ if (priv->fan.mode == FAN_CONTROL_NONE)
+ return -EINVAL;
+
if (!priv->fan.pwm_set)
return -ENODEV;
@@ -138,7 +141,52 @@ nouveau_therm_fan_sense(struct nouveau_therm *therm)
return 0;
}
-static void
+int
+nouveau_therm_fan_set_mode(struct nouveau_therm *therm,
+ enum nouveau_therm_fan_mode mode)
+{
+ struct nouveau_therm_priv *priv = (void *)therm;
+
+ if (priv->fan.mode == mode)
+ return 0;
+
+ if (mode < FAN_CONTROL_NONE || mode >= FAN_CONTROL_NR)
+ return -EINVAL;
+
+ switch (mode)
+ {
+ case FAN_CONTROL_NONE:
+ nv_info(therm, "switch fan to no-control mode\n");
+ break;
+ case FAN_CONTROL_MANUAL:
+ nv_info(therm, "switch fan to manual mode\n");
+ break;
+ case FAN_CONTROL_NR:
+ break;
+ }
+
+ priv->fan.mode = mode;
+ return 0;
+}
+
+int
+nouveau_therm_fan_user_get(struct nouveau_therm *therm)
+{
+ return nouveau_therm_fan_get(therm);
+}
+
+int
+nouveau_therm_fan_user_set(struct nouveau_therm *therm, int percent)
+{
+ struct nouveau_therm_priv *priv = (void *)therm;
+
+ if (priv->fan.mode != FAN_CONTROL_MANUAL)
+ return -EINVAL;
+
+ return nouveau_therm_fan_set(therm, percent);
+}
+
+void
nouveau_therm_fan_set_defaults(struct nouveau_therm *therm)
{
struct nouveau_therm_priv *priv = (void *)therm;
@@ -180,5 +228,7 @@ nouveau_therm_fan_ctor(struct nouveau_therm *therm)
nv_error(therm, "parsing the thermal table failed\n");
nouveau_therm_fan_safety_checks(therm);
+ nouveau_therm_fan_set_mode(therm, FAN_CONTROL_NONE);
+
return 0;
}
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,
priv->fan.pwm_set = nv40_fan_pwm_set;
therm->temp_get = nv40_temp_get;
- therm->fan_get = nouveau_therm_fan_get;
- therm->fan_set = nouveau_therm_fan_set;
+ therm->fan_get = nouveau_therm_fan_user_get;
+ therm->fan_set = nouveau_therm_fan_user_set;
therm->fan_sense = nouveau_therm_fan_sense;
therm->attr_get = nouveau_therm_attr_get;
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,
priv->fan.pwm_clock = nv50_fan_pwm_clock;
therm->temp_get = nv50_temp_get;
- therm->fan_get = nouveau_therm_fan_get;
- therm->fan_set = nouveau_therm_fan_set;
+ therm->fan_get = nouveau_therm_fan_user_get;
+ therm->fan_set = nouveau_therm_fan_user_set;
therm->fan_sense = nouveau_therm_fan_sense;
therm->attr_get = nouveau_therm_attr_get;
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 {
/* fan priv */
struct {
+ enum nouveau_therm_fan_mode mode;
int percent;
int (*pwm_get)(struct nouveau_therm *, int line, u32*, u32*);
@@ -63,5 +64,10 @@ int nouveau_therm_sensor_ctor(struct nouveau_therm *therm);
int nouveau_therm_fan_ctor(struct nouveau_therm *therm);
int nouveau_therm_fan_get(struct nouveau_therm *therm);
int nouveau_therm_fan_set(struct nouveau_therm *therm, int percent);
+int nouveau_therm_fan_user_get(struct nouveau_therm *therm);
+int nouveau_therm_fan_user_set(struct nouveau_therm *therm, int percent);
+int nouveau_therm_fan_set_mode(struct nouveau_therm *therm,
+ enum nouveau_therm_fan_mode mode);
+
int nouveau_therm_fan_sense(struct nouveau_therm *therm);