ec/lenovo/h8: Implement ACPI methods to set battery thresholds

There are two known reverse-engineered ways to manage battery
thresholds.
This patch implements them and adds a way to enable them for
different mainboards.

Tested on W530 with 4.18.3-gentoo kernel and X220 with 4.20.11.
Works fine with new Linux userspace API for controlling battery
thresholds, available since 4.17.
(/sys/class/power_supply/BAT0/charge_(start|stop)_threshold).

The new API is supported by TLP (you might need to set NATACPI_ENABLE=1
in /etc/tlp.conf).

tpacpi-bat works fine too.

Signed-off-by: Alexey Kharlamov <der@2-47.ru>
Signed-off-by: Evgeny Zinoviev <me@ch1p.com>

Change-Id: I2a90f9e9b32462b8a5e9bc8d3087ae0fea563ea5
Reviewed-on: https://review.coreboot.org/c/coreboot/+/23178
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Rudolph <siro@das-labor.org>
This commit is contained in:
Alexey Kharlamov 2018-01-09 00:50:06 +03:00 committed by Patrick Georgi
parent b697c90a4c
commit 93d6ba0889
29 changed files with 461 additions and 0 deletions

View File

@ -28,6 +28,10 @@ config H8_SUPPORT_BT_ON_WIFI
Disable BDC detection and assume bluetooth is installed. Required for Disable BDC detection and assume bluetooth is installed. Required for
bluetooth on wifi cards, as it's not possible to detect it in coreboot. bluetooth on wifi cards, as it's not possible to detect it in coreboot.
config H8_HAS_BAT_TRESHOLDS_IMPL
bool
default n
endif endif
config H8_DOCK_EARLY_INIT config H8_DOCK_EARLY_INIT

View File

@ -317,4 +317,8 @@ Device (HKEY)
Store (WWAN, \_SB.PCI0.LPCB.EC.WWEB) Store (WWAN, \_SB.PCI0.LPCB.EC.WWEB)
} }
} }
#if IS_ENABLED(CONFIG_H8_HAS_BAT_TRESHOLDS_IMPL)
#include "thinkpad_bat_thresholds.asl"
#endif
} }

View File

@ -0,0 +1,182 @@
/*
* This file is part of the coreboot project.
*
* Copyright (c) 2017 Arthur Heymans <arthur@aheymans.xyz>
* Copyright (c) 2018 Evgeny Zinoviev <me@ch1p.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; version 2 of
* the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
/*
* This defines the battery charging thresholds setting methods tpacpi-bat can
* use. This implements what the vendor defines but is rather ugly...
*/
/* SetBatteryCharge Start/Stop Capacity Threshold
* In Parameter:
* DWORD
* Bit 7-0: Charge stop capacity (Unit:%)
* =0: Use battery default setting
* =1-99: Threshold to stop charging battery (Relative capacity)
* Bit 9-8:BatteryID
* = 0: Any battery
* = 1: Primary battery
* = 2: Secondary battery
* = Others: Reserved (0)
* Bit 31-10: Reserved (0)
* Must be Zero
*
* Out Parameter:
* DWORD
* Bit 30-0: Reserved (0)
* Bit 31: Error status
* 0 ... Success
* 1 ... Fail
*/
#define START_THRESH_ARG 0
#define STOP_THRESH_ARG 1
// Set stop threshold
Method (BCSS, 1, NotSerialized)
{
Local0 = Arg0 & 0xff // Percentage
Local1 = (Arg0 >> 8) & 0x3 // Battery ID
// Any battery
If (Local1 == 0)
{
\_SB.PCI0.LPCB.EC.BAT0.SETT(STOP_THRESH_ARG, Local0)
\_SB.PCI0.LPCB.EC.BAT1.SETT(STOP_THRESH_ARG, Local0)
Local2 = Local0 != \_SB.PCI0.LPCB.EC.BAT0.GETT(STOP_THRESH_ARG)
Local3 = Local0 != \_SB.PCI0.LPCB.EC.BAT1.GETT(STOP_THRESH_ARG)
Return ((Local2 && Local3) << 31)
}
// Battery1
If (Local1 == 1)
{
\_SB.PCI0.LPCB.EC.BAT0.SETT(STOP_THRESH_ARG, Local0)
Return ((Local0 !=
\_SB.PCI0.LPCB.EC.BAT0.GETT(STOP_THRESH_ARG)) << 31)
}
// Battery2
If (Local1 == 2)
{
\_SB.PCI0.LPCB.EC.BAT1.SETT(STOP_THRESH_ARG, Local0)
Return ((Local0 !=
\_SB.PCI0.LPCB.EC.BAT1.GETT(STOP_THRESH_ARG)) << 31)
}
Return (1 << 31) /* Should not be reached */
}
// Set start threshold
Method (BCCS, 1, NotSerialized)
{
Local0 = Arg0 & 0xff // Percentage
Local1 = (Arg0 >> 8) & 0x3 // Battery ID
// Any battery
If (Local1 == 0)
{
\_SB.PCI0.LPCB.EC.BAT0.SETT(START_THRESH_ARG, Local0)
\_SB.PCI0.LPCB.EC.BAT1.SETT(START_THRESH_ARG, Local0)
Local2 = Local0 != \_SB.PCI0.LPCB.EC.BAT0.GETT(START_THRESH_ARG)
Local3 = Local0 != \_SB.PCI0.LPCB.EC.BAT1.GETT(START_THRESH_ARG)
Return ((Local2 && Local3) << 31)
}
// Battery1
If (Local1 == 1)
{
\_SB.PCI0.LPCB.EC.BAT0.SETT(START_THRESH_ARG, Local0)
Return ((Local0 !=
\_SB.PCI0.LPCB.EC.BAT0.GETT(START_THRESH_ARG)) << 31)
}
// Battery2
If (Local1 == 2)
{
\_SB.PCI0.LPCB.EC.BAT1.SETT(START_THRESH_ARG, Local0)
Return ((Local0 !=
\_SB.PCI0.LPCB.EC.BAT1.GETT(START_THRESH_ARG)) << 31)
}
Return (1 << 31) /* Should not be reached */
}
/*
* GetBatteryCharge Start/Stop Capacity Threshold
* In Parameter:
* DWORD
* Bit 7-0:BatteryID
* Bit 31-8: Reserved (0)
* Must be Zero
*
* Out Parameter:
* DWORD
* Bit 7-0: Charge stop capacity (Unit:%)
* =0: Use battery default setting
* =1-99: Threshold to stop charging battery (Relative capacity)
* =Others: Reserved (0)
* Bit 9-8: Capability of BatteryCharge Stop Capacity Threshold
* Bit 8:Batterycharge stop capacity threshold
* (0:Not support 1:Support)
* Bit 9: Specify every battery parameter
* (0:Not support(apply parameter for all battery)
* 1:Support(apply parameter for all battery))
* Bit 30-10: Reserved (0)
* Bit 31: Error status
* 0 ... Success
* 1 ... Fail
*/
// Get stop threshold
Method (BCSG, 1, NotSerialized)
{
// Battery1
If (Arg0 == 1)
{
Return (0x300 | \_SB.PCI0.LPCB.EC.BAT0.GETT(STOP_THRESH_ARG))
}
// Battery2
If (Arg0 == 2)
{
Return (0x300 | \_SB.PCI0.LPCB.EC.BAT1.GETT(STOP_THRESH_ARG))
}
Return (1 << 31)
}
// Get start threshold
Method (BCTG, 1, NotSerialized)
{
// Battery 1
If (Arg0 == 1)
{
Return (0x300 | \_SB.PCI0.LPCB.EC.BAT0.GETT(START_THRESH_ARG))
}
// Battery 2
If (Arg0 == 2)
{
Return (0x300 | \_SB.PCI0.LPCB.EC.BAT1.GETT(START_THRESH_ARG))
}
Return (1 << 31)
}

View File

@ -0,0 +1,117 @@
/*
* This file is part of the coreboot project.
*
* Copyright (c) 2017 Arthur Heymans <arthur@aheymans.xyz>
* Copyright (c) 2018 Evgeny Zinoviev <me@ch1p.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; version 2 of
* the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
Scope(\_SB.PCI0.LPCB.EC)
{
Field (ERAM, ByteAcc, NoLock, Preserve)
{
Offset (0x03),
, 2,
BSTP, 1, /* Battery start/stop threshold */
Offset (0x24),
TSH0, 8, /* Battery0 threshold */
Offset (0x25),
TSH1, 8, /* Battery1 threshold */
}
}
Scope(\_SB.PCI0.LPCB.EC.BAT0)
{
/*
* Set threshold on battery0,
*
* Arg0: 0: Start threshold
* 1: Stop threshold
* Arg1: Percentage
*/
Method (SETT, 2, NotSerialized)
{
if (Arg0 <= 1 && Arg1 <= 100)
{
BSTP = Arg0
#if defined(H8_BAT_THRESHOLDS_BIT7)
TSH0 = Arg1
#else
TSH0 = Arg1 | 0x80
#endif
}
}
/**
* Get threshold on battery0
*
* Arg0: 0: Start threshold
* 1: Stop threshold
*/
Method (GETT, 1, NotSerialized)
{
if (Arg0 <= 1)
{
BSTP = Arg0
#if defined(H8_BAT_THRESHOLDS_BIT7)
Return (TSH0)
#else
Return (TSH0 & ~0x80)
#endif
}
Return (0)
}
}
Scope(\_SB.PCI0.LPCB.EC.BAT1)
{
/*
* Set threshold on battery1
*
* Arg0: 0: Start threshold
* 1: Stop threshold
* Arg1: Percentage
*/
Method (SETT, 2, NotSerialized)
{
if (Arg0 <= 1 && Arg1 <= 100)
{
BSTP = Arg0
#if defined(H8_BAT_THRESHOLDS_BIT7)
TSH1 = Arg1
#else
TSH1 = Arg1 | 0x80
#endif
}
}
/**
* Get threshold on battery1
*
* Arg0: 0: Start threshold
* 1: Stop threshold
*/
Method (GETT, 1, NotSerialized)
{
if (Arg0 <= 1)
{
BSTP = Arg0
#if defined(H8_BAT_THRESHOLDS_BIT7)
Return (TSH1)
#else
Return (TSH1 & ~0x80)
#endif
}
Return (0)
}
}

View File

@ -0,0 +1,120 @@
/*
* This file is part of the coreboot project.
*
* Copyright (c) 2017 Arthur Heymans <arthur@aheymans.xyz>
* Copyright (c) 2018 Evgeny Zinoviev <me@ch1p.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; version 2 of
* the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
Scope(\_SB.PCI0.LPCB.EC)
{
Field (ERAM, ByteAcc, NoLock, Preserve)
{
Offset (0xb0),
TSL0, 8, /* Battery0 start threshold */
Offset (0xb1),
TSH0, 8, /* Battery0 stop threshold */
Offset (0xb2),
TSL1, 8, /* Battery1 start threshold */
Offset (0xb3),
TSH1, 8, /* Battery1 stop threshold */
}
}
Scope(\_SB.PCI0.LPCB.EC.BAT0)
{
/*
* Set threshold on battery0
*
* Arg0: 0: Start threshold
* 1: Stop threshold
* Arg1: Percentage
*/
Method (SETT, 2, NotSerialized)
{
if (Arg1 <= 100)
{
if (Arg0 == 0)
{
TSL0 = Arg1
}
if (Arg0 == 1)
{
TSH0 = Arg1
}
}
}
/**
* Get threshold on battery0
*
* Arg0: 0: Start threshold
* 1: Stop threshold
*/
Method (GETT, 1, NotSerialized)
{
if (Arg0 == 0)
{
Return (TSL0)
}
if (Arg0 == 1)
{
Return (TSH0)
}
Return (0)
}
}
Scope(\_SB.PCI0.LPCB.EC.BAT1)
{
/*
* Set threshold on battery1
*
* Arg0: 0: Start threshold
* 1: Stop threshold
* Arg1: Percentage
*/
Method (SETT, 2, NotSerialized)
{
if (Arg1 <= 100)
{
if (Arg0 == 0)
{
TSL1 = Arg1
}
if (Arg0 == 1)
{
TSH1 = Arg1
}
}
}
/**
* Get threshold on battery1
*
* Arg0: 0: Start threshold
* 1: Stop threshold
*/
Method (GETT, 1, NotSerialized)
{
if (Arg0 == 0)
{
Return (TSL1)
}
if (Arg0 == 1)
{
Return (TSH1 & ~0x80)
}
Return (0)
}
}

View File

@ -9,6 +9,7 @@ config BOARD_SPECIFIC_OPTIONS
select SOUTHBRIDGE_INTEL_I82801IX select SOUTHBRIDGE_INTEL_I82801IX
select EC_LENOVO_PMH7 select EC_LENOVO_PMH7
select EC_LENOVO_H8 select EC_LENOVO_H8
select H8_HAS_BAT_TRESHOLDS_IMPL
select H8_DOCK_EARLY_INIT select H8_DOCK_EARLY_INIT
select BOARD_ROMSIZE_KB_8192 select BOARD_ROMSIZE_KB_8192
select DRIVERS_GENERIC_IOAPIC select DRIVERS_GENERIC_IOAPIC

View File

@ -1 +1,2 @@
#include <ec/lenovo/h8/acpi/ec.asl> #include <ec/lenovo/h8/acpi/ec.asl>
#include <ec/lenovo/h8/acpi/thinkpad_bat_thresholds_24.asl>

View File

@ -8,6 +8,7 @@ config BOARD_SPECIFIC_OPTIONS
select SOUTHBRIDGE_INTEL_BD82X6X select SOUTHBRIDGE_INTEL_BD82X6X
select EC_LENOVO_PMH7 select EC_LENOVO_PMH7
select EC_LENOVO_H8 select EC_LENOVO_H8
select H8_HAS_BAT_TRESHOLDS_IMPL
select NO_UART_ON_SUPERIO select NO_UART_ON_SUPERIO
select BOARD_ROMSIZE_KB_8192 select BOARD_ROMSIZE_KB_8192
select HAVE_ACPI_TABLES select HAVE_ACPI_TABLES

View File

@ -19,3 +19,5 @@
Scope(\_SB.PCI0.LPCB.EC) Scope(\_SB.PCI0.LPCB.EC)
{ {
} }
#include <ec/lenovo/h8/acpi/thinkpad_bat_thresholds_b0.asl>

View File

@ -8,6 +8,7 @@ config BOARD_SPECIFIC_OPTIONS
select SOUTHBRIDGE_INTEL_BD82X6X select SOUTHBRIDGE_INTEL_BD82X6X
select EC_LENOVO_PMH7 select EC_LENOVO_PMH7
select EC_LENOVO_H8 select EC_LENOVO_H8
select H8_HAS_BAT_TRESHOLDS_IMPL
select NO_UART_ON_SUPERIO select NO_UART_ON_SUPERIO
select BOARD_ROMSIZE_KB_8192 select BOARD_ROMSIZE_KB_8192
select HAVE_ACPI_TABLES select HAVE_ACPI_TABLES

View File

@ -19,3 +19,5 @@
Scope(\_SB.PCI0.LPCB.EC) Scope(\_SB.PCI0.LPCB.EC)
{ {
} }
#include <ec/lenovo/h8/acpi/thinkpad_bat_thresholds_b0.asl>

View File

@ -5,6 +5,7 @@ config BOARD_SPECIFIC_OPTIONS
select BOARD_ROMSIZE_KB_12288 select BOARD_ROMSIZE_KB_12288
select DRIVERS_RICOH_RCE822 select DRIVERS_RICOH_RCE822
select EC_LENOVO_H8 select EC_LENOVO_H8
select H8_HAS_BAT_TRESHOLDS_IMPL
select EC_LENOVO_PMH7 select EC_LENOVO_PMH7
select NO_UART_ON_SUPERIO select NO_UART_ON_SUPERIO
select HAVE_ACPI_RESUME select HAVE_ACPI_RESUME

View File

@ -14,3 +14,4 @@
*/ */
#include <ec/lenovo/h8/acpi/ec.asl> #include <ec/lenovo/h8/acpi/ec.asl>
#include <ec/lenovo/h8/acpi/thinkpad_bat_thresholds_b0.asl>

View File

@ -8,6 +8,7 @@ config BOARD_SPECIFIC_OPTIONS
select SOUTHBRIDGE_INTEL_C216 select SOUTHBRIDGE_INTEL_C216
select EC_LENOVO_PMH7 select EC_LENOVO_PMH7
select EC_LENOVO_H8 select EC_LENOVO_H8
select H8_HAS_BAT_TRESHOLDS_IMPL
select NO_UART_ON_SUPERIO select NO_UART_ON_SUPERIO
select BOARD_ROMSIZE_KB_16384 select BOARD_ROMSIZE_KB_16384
select HAVE_ACPI_TABLES select HAVE_ACPI_TABLES

View File

@ -19,3 +19,5 @@
Scope(\_SB.PCI0.LPCB.EC) Scope(\_SB.PCI0.LPCB.EC)
{ {
} }
#include <ec/lenovo/h8/acpi/thinkpad_bat_thresholds_b0.asl>

View File

@ -6,6 +6,7 @@ config BOARD_LENOVO_BASEBOARD_T520
select SOUTHBRIDGE_INTEL_BD82X6X select SOUTHBRIDGE_INTEL_BD82X6X
select EC_LENOVO_PMH7 select EC_LENOVO_PMH7
select EC_LENOVO_H8 select EC_LENOVO_H8
select H8_HAS_BAT_TRESHOLDS_IMPL
select NO_UART_ON_SUPERIO select NO_UART_ON_SUPERIO
select BOARD_ROMSIZE_KB_8192 select BOARD_ROMSIZE_KB_8192
select HAVE_ACPI_TABLES select HAVE_ACPI_TABLES

View File

@ -19,3 +19,5 @@
Scope(\_SB.PCI0.LPCB.EC) Scope(\_SB.PCI0.LPCB.EC)
{ {
} }
#include <ec/lenovo/h8/acpi/thinkpad_bat_thresholds_b0.asl>

View File

@ -6,6 +6,7 @@ config BOARD_LENOVO_BASEBOARD_T530
select SOUTHBRIDGE_INTEL_C216 select SOUTHBRIDGE_INTEL_C216
select EC_LENOVO_PMH7 select EC_LENOVO_PMH7
select EC_LENOVO_H8 select EC_LENOVO_H8
select H8_HAS_BAT_TRESHOLDS_IMPL
select NO_UART_ON_SUPERIO select NO_UART_ON_SUPERIO
select BOARD_ROMSIZE_KB_12288 select BOARD_ROMSIZE_KB_12288
select HAVE_ACPI_TABLES select HAVE_ACPI_TABLES

View File

@ -19,3 +19,5 @@
Scope(\_SB.PCI0.LPCB.EC) Scope(\_SB.PCI0.LPCB.EC)
{ {
} }
#include <ec/lenovo/h8/acpi/thinkpad_bat_thresholds_b0.asl>

View File

@ -8,6 +8,7 @@ config BOARD_SPECIFIC_OPTIONS
select SOUTHBRIDGE_INTEL_C216 select SOUTHBRIDGE_INTEL_C216
select EC_LENOVO_PMH7 select EC_LENOVO_PMH7
select EC_LENOVO_H8 select EC_LENOVO_H8
select H8_HAS_BAT_TRESHOLDS_IMPL
select NO_UART_ON_SUPERIO select NO_UART_ON_SUPERIO
select BOARD_ROMSIZE_KB_12288 select BOARD_ROMSIZE_KB_12288
select HAVE_ACPI_TABLES select HAVE_ACPI_TABLES

View File

@ -19,3 +19,5 @@
Scope(\_SB.PCI0.LPCB.EC) Scope(\_SB.PCI0.LPCB.EC)
{ {
} }
#include <ec/lenovo/h8/acpi/thinkpad_bat_thresholds_b0.asl>

View File

@ -8,6 +8,7 @@ config BOARD_SPECIFIC_OPTIONS
select SOUTHBRIDGE_INTEL_I82801IX select SOUTHBRIDGE_INTEL_I82801IX
select EC_LENOVO_PMH7 select EC_LENOVO_PMH7
select EC_LENOVO_H8 select EC_LENOVO_H8
select H8_HAS_BAT_TRESHOLDS_IMPL
select NO_UART_ON_SUPERIO select NO_UART_ON_SUPERIO
select BOARD_ROMSIZE_KB_8192 select BOARD_ROMSIZE_KB_8192
select DRIVERS_GENERIC_IOAPIC select DRIVERS_GENERIC_IOAPIC

View File

@ -1 +1,2 @@
#include <ec/lenovo/h8/acpi/ec.asl> #include <ec/lenovo/h8/acpi/ec.asl>
#include <ec/lenovo/h8/acpi/thinkpad_bat_thresholds_24.asl>

View File

@ -21,6 +21,7 @@ config BOARD_SPECIFIC_OPTIONS
select MAINBOARD_HAS_TPM1 select MAINBOARD_HAS_TPM1
select INTEL_GMA_HAVE_VBT select INTEL_GMA_HAVE_VBT
select MAINBOARD_USES_IFD_GBE_REGION select MAINBOARD_USES_IFD_GBE_REGION
select H8_HAS_BAT_TRESHOLDS_IMPL
config MAINBOARD_DIR config MAINBOARD_DIR
string string

View File

@ -19,3 +19,6 @@
Scope(\_SB.PCI0.LPCB.EC) Scope(\_SB.PCI0.LPCB.EC)
{ {
} }
#define H8_BAT_THRESHOLDS_BIT7
#include <ec/lenovo/h8/acpi/thinkpad_bat_thresholds_24.asl>

View File

@ -7,6 +7,7 @@ config BOARD_SPECIFIC_OPTIONS
select SOUTHBRIDGE_INTEL_C216 select SOUTHBRIDGE_INTEL_C216
select EC_LENOVO_PMH7 select EC_LENOVO_PMH7
select EC_LENOVO_H8 select EC_LENOVO_H8
select H8_HAS_BAT_TRESHOLDS_IMPL
select NO_UART_ON_SUPERIO select NO_UART_ON_SUPERIO
select BOARD_ROMSIZE_KB_8192 select BOARD_ROMSIZE_KB_8192
select HAVE_ACPI_TABLES select HAVE_ACPI_TABLES

View File

@ -19,3 +19,5 @@
Scope(\_SB.PCI0.LPCB.EC) Scope(\_SB.PCI0.LPCB.EC)
{ {
} }
#include <ec/lenovo/h8/acpi/thinkpad_bat_thresholds_b0.asl>

View File

@ -8,6 +8,7 @@ config BOARD_SPECIFIC_OPTIONS
select SOUTHBRIDGE_INTEL_C216 select SOUTHBRIDGE_INTEL_C216
select EC_LENOVO_PMH7 select EC_LENOVO_PMH7
select EC_LENOVO_H8 select EC_LENOVO_H8
select H8_HAS_BAT_TRESHOLDS_IMPL
select NO_UART_ON_SUPERIO select NO_UART_ON_SUPERIO
select BOARD_ROMSIZE_KB_12288 select BOARD_ROMSIZE_KB_12288
select HAVE_ACPI_TABLES select HAVE_ACPI_TABLES

View File

@ -19,3 +19,5 @@
Scope(\_SB.PCI0.LPCB.EC) Scope(\_SB.PCI0.LPCB.EC)
{ {
} }
#include <ec/lenovo/h8/acpi/thinkpad_bat_thresholds_b0.asl>