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
bluetooth on wifi cards, as it's not possible to detect it in coreboot.
config H8_HAS_BAT_TRESHOLDS_IMPL
bool
default n
endif
config H8_DOCK_EARLY_INIT

View File

@ -317,4 +317,8 @@ Device (HKEY)
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 EC_LENOVO_PMH7
select EC_LENOVO_H8
select H8_HAS_BAT_TRESHOLDS_IMPL
select H8_DOCK_EARLY_INIT
select BOARD_ROMSIZE_KB_8192
select DRIVERS_GENERIC_IOAPIC

View File

@ -1 +1,2 @@
#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 EC_LENOVO_PMH7
select EC_LENOVO_H8
select H8_HAS_BAT_TRESHOLDS_IMPL
select NO_UART_ON_SUPERIO
select BOARD_ROMSIZE_KB_8192
select HAVE_ACPI_TABLES

View File

@ -19,3 +19,5 @@
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 EC_LENOVO_PMH7
select EC_LENOVO_H8
select H8_HAS_BAT_TRESHOLDS_IMPL
select NO_UART_ON_SUPERIO
select BOARD_ROMSIZE_KB_8192
select HAVE_ACPI_TABLES

View File

@ -19,3 +19,5 @@
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 DRIVERS_RICOH_RCE822
select EC_LENOVO_H8
select H8_HAS_BAT_TRESHOLDS_IMPL
select EC_LENOVO_PMH7
select NO_UART_ON_SUPERIO
select HAVE_ACPI_RESUME

View File

@ -14,3 +14,4 @@
*/
#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 EC_LENOVO_PMH7
select EC_LENOVO_H8
select H8_HAS_BAT_TRESHOLDS_IMPL
select NO_UART_ON_SUPERIO
select BOARD_ROMSIZE_KB_16384
select HAVE_ACPI_TABLES

View File

@ -19,3 +19,5 @@
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 EC_LENOVO_PMH7
select EC_LENOVO_H8
select H8_HAS_BAT_TRESHOLDS_IMPL
select NO_UART_ON_SUPERIO
select BOARD_ROMSIZE_KB_8192
select HAVE_ACPI_TABLES

View File

@ -19,3 +19,5 @@
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 EC_LENOVO_PMH7
select EC_LENOVO_H8
select H8_HAS_BAT_TRESHOLDS_IMPL
select NO_UART_ON_SUPERIO
select BOARD_ROMSIZE_KB_12288
select HAVE_ACPI_TABLES

View File

@ -19,3 +19,5 @@
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 EC_LENOVO_PMH7
select EC_LENOVO_H8
select H8_HAS_BAT_TRESHOLDS_IMPL
select NO_UART_ON_SUPERIO
select BOARD_ROMSIZE_KB_12288
select HAVE_ACPI_TABLES

View File

@ -19,3 +19,5 @@
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 EC_LENOVO_PMH7
select EC_LENOVO_H8
select H8_HAS_BAT_TRESHOLDS_IMPL
select NO_UART_ON_SUPERIO
select BOARD_ROMSIZE_KB_8192
select DRIVERS_GENERIC_IOAPIC

View File

@ -1 +1,2 @@
#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 INTEL_GMA_HAVE_VBT
select MAINBOARD_USES_IFD_GBE_REGION
select H8_HAS_BAT_TRESHOLDS_IMPL
config MAINBOARD_DIR
string

View File

@ -19,3 +19,6 @@
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 EC_LENOVO_PMH7
select EC_LENOVO_H8
select H8_HAS_BAT_TRESHOLDS_IMPL
select NO_UART_ON_SUPERIO
select BOARD_ROMSIZE_KB_8192
select HAVE_ACPI_TABLES

View File

@ -19,3 +19,5 @@
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 EC_LENOVO_PMH7
select EC_LENOVO_H8
select H8_HAS_BAT_TRESHOLDS_IMPL
select NO_UART_ON_SUPERIO
select BOARD_ROMSIZE_KB_12288
select HAVE_ACPI_TABLES

View File

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