ec/lenovo/h8/acpi/thermal: Add ACPI fan control

Disengage the fan 10 degree below passive threshold as the automatic EC fan
control does not disengage the FAN even when CPU starts melting ...

* Add EC registers FAND and FANA.
* Add ACPI methods _AC0 and _AL0.
* Add fan device and PowerResource for fan control.

Tested on Lenovo T430:
* The fan disengages at 80°C and keeps running at full speed until temperature
  drops below 80°C.
* Fan can be disengaged using sysfs:
  /sys/devics/virtual/thermal/cooling_device0/cur_state
Tested on Lenovo T500:
* The fan disengages at 80°C and keeps running at full speed until temperature
  drops below 80°C.
* Fan cannot be disengaged using sysfs, but the current state can be read:
  /sys/devics/virtual/thermal/cooling_device0/cur_state

Change-Id: I075ff5c69676927db1c5e731294e18796884f97e
Signed-off-by: Patrick Rudolph <siro@das-labor.org>
Reviewed-on: https://review.coreboot.org/21227
Reviewed-by: Nico Huber <nico.h@gmx.de>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Patrick Rudolph 2017-08-27 17:46:52 +02:00 committed by Nico Huber
parent 3ab13a8691
commit 0709dc0468
2 changed files with 69 additions and 8 deletions

View File

@ -39,6 +39,10 @@ Device(EC)
DKR2, 1, /* Dock register 2 */
Offset (0x2a),
EVNT, 8, /* write will trigger EC event */
Offset (0x2f),
, 6,
FAND, 1, /* Fan disengage */
FANA, 1, /* Fan automatic mode enable */
Offset (0x30),
, 6,
ALMT, 1, /* Audio Mute + LED */

View File

@ -11,6 +11,8 @@
* GNU General Public License for more details.
*/
#include <arch/x86/acpi/statdef.asl>
Scope(\_TZ)
{
#if defined (EC_LENOVO_H8_ME_WORKAROUND)
@ -56,20 +58,30 @@ External (\PPKG, MethodObj)
Return (\PPKG ())
}
Method (_CRT, 0, NotSerialized) {
/* Get critical temperature in degree celsius */
Method (GCRT, 0, NotSerialized) {
Store (\TCRT, Local0)
if (LGreater (Local0, 0)) {
Return (C2K (Local0))
Return (Local0)
}
Return (C2K (127))
Return (127)
}
/* Get passive temperature in degree celsius */
Method (GPSV, 0, NotSerialized) {
Store (\TPSV, Local0)
if (LGreater (Local0, 0)) {
Return (Local0)
}
Return (95)
}
Method (_CRT, 0, NotSerialized) {
Return (C2K (GCRT ()))
}
Method (_PSV, 0, NotSerialized) {
Store (\TPSV, Local0)
if (LGreater (Local0, 0)) {
Return (C2K(Local0))
}
Return (C2K (95))
Return (C2K (GPSV ()))
}
Method(_TMP) {
@ -82,6 +94,51 @@ External (\PPKG, MethodObj)
#endif
Return (C2K(\_SB.PCI0.LPCB.EC.TMP0))
}
Method (_AC0) {
Store (GPSV (), Local0)
/* Active fan 10 degree below passive threshold */
Subtract (Local0, 10, Local0)
If (LEqual (\_SB.PCI0.LPCB.EC.FAND, 1)) {
/* Turn of 5 degree below trip point */
Subtract (Local0, 5, Local0)
}
Return (C2K (Local0))
}
Name (_AL0, Package () { FAN })
PowerResource (FPwR, 0, 0)
{
Method (_STA) {
If (LEqual (\_SB.PCI0.LPCB.EC.FAND, 0)) {
Return (Zero)
} Else {
Return (One)
}
}
Method (_ON) {
Store (One, \_SB.PCI0.LPCB.EC.FAND)
Store (Zero, \_SB.PCI0.LPCB.EC.FANA)
Notify (\_TZ.THM0, NOTIFY_TZ_TRIPPTCHG)
}
Method (_OFF) {
Store (Zero, \_SB.PCI0.LPCB.EC.FAND)
Store (One, \_SB.PCI0.LPCB.EC.FANA)
Notify (\_TZ.THM0, NOTIFY_TZ_TRIPPTCHG)
}
}
Device (FAN)
{
Name (_HID, EISAID ("PNP0C0B"))
Name (_PR0, Package () { FPwR })
}
}
ThermalZone(THM1)