diff options
author | Martin Peres <martin.peres@labri.fr> | 2012-11-05 00:18:49 +0100 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2013-02-20 16:00:23 +1000 |
commit | 0083b91dac482c70eeb96745d9ef604f904da3e5 (patch) | |
tree | 657ddc161b7e1190fb1bbd6a48a5c9b2b1dfd482 /drivers/gpu/drm/nouveau/core/subdev/therm/priv.h | |
parent | 9d7175c808793b3e30db455da7529d3c05b00712 (diff) | |
download | op-kernel-dev-0083b91dac482c70eeb96745d9ef604f904da3e5.zip op-kernel-dev-0083b91dac482c70eeb96745d9ef604f904da3e5.tar.gz |
drm/nouveau/therm: implement support for temperature alarms
For now, we only boost the fan speed to the maximum and auto-mode
when hitting the FAN_BOOST threshold and halt the computer when it
reaches the shutdown temperature. The downclock and critical thresholds
do nothing.
On nv43:50 and nva3+, temperature is polled because of the limited hardware.
I'll improve the nva3+ situation by implementing alarm management in PDAEMON
whenever I can but polling once every second shouldn't be such a problem.
v2 (Ben Skeggs):
- rebased
v3: fixed false-detections and threshold reprogrammation handling on nv50:nvc0
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Signed-off-by: Martin Peres <martin.peres@labri.fr>
Diffstat (limited to 'drivers/gpu/drm/nouveau/core/subdev/therm/priv.h')
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/therm/priv.h | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h b/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h index 5c628b5..c2413e6 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h @@ -50,6 +50,24 @@ struct nouveau_fan { struct dcb_gpio_func tach; }; +enum nouveau_therm_thrs_direction { + NOUVEAU_THERM_THRS_FALLING = 0, + NOUVEAU_THERM_THRS_RISING = 1 +}; + +enum nouveau_therm_thrs_state { + NOUVEAU_THERM_THRS_LOWER = 0, + NOUVEAU_THERM_THRS_HIGHER = 1 +}; + +enum nouveau_therm_thrs { + NOUVEAU_THERM_THRS_FANBOOST = 0, + NOUVEAU_THERM_THRS_DOWNCLOCK = 1, + NOUVEAU_THERM_THRS_CRITICAL = 2, + NOUVEAU_THERM_THRS_SHUTDOWN = 3, + NOUVEAU_THERM_THRS_NR +}; + struct nouveau_therm_priv { struct nouveau_therm base; @@ -65,10 +83,25 @@ struct nouveau_therm_priv { /* fan priv */ struct nouveau_fan *fan; + /* alarms priv */ + struct { + spinlock_t alarm_program_lock; + struct nouveau_alarm therm_poll_alarm; + enum nouveau_therm_thrs_state alarm_state[NOUVEAU_THERM_THRS_NR]; + void (*program_alarms)(struct nouveau_therm *); + } sensor; + + /* what should be done if the card overheats */ + struct { + void (*downclock)(struct nouveau_therm *, bool active); + void (*pause)(struct nouveau_therm *, bool active); + } emergency; + /* ic */ struct i2c_client *ic; }; +int nouveau_therm_mode(struct nouveau_therm *therm, int mode); int nouveau_therm_attr_get(struct nouveau_therm *therm, enum nouveau_therm_attr_type type); int nouveau_therm_attr_set(struct nouveau_therm *therm, @@ -88,6 +121,17 @@ int nouveau_therm_fan_sense(struct nouveau_therm *therm); int nouveau_therm_preinit(struct nouveau_therm *); +void nouveau_therm_sensor_set_threshold_state(struct nouveau_therm *therm, + enum nouveau_therm_thrs thrs, + enum nouveau_therm_thrs_state st); +enum nouveau_therm_thrs_state +nouveau_therm_sensor_get_threshold_state(struct nouveau_therm *therm, + enum nouveau_therm_thrs thrs); +void nouveau_therm_sensor_event(struct nouveau_therm *therm, + enum nouveau_therm_thrs thrs, + enum nouveau_therm_thrs_direction dir); +void nouveau_therm_program_alarms_polling(struct nouveau_therm *therm); + int nv50_fan_pwm_ctrl(struct nouveau_therm *, int, bool); int nv50_fan_pwm_get(struct nouveau_therm *, int, u32 *, u32 *); int nv50_fan_pwm_set(struct nouveau_therm *, int, u32, u32); |