Move power limit functions to common board code
Logic for changing power limit is the same for all boards with GPUs. It is still called from board_event() instead of in power_event() to maintain the current behavior of checking every main cycle. Signed-off-by: Tim Crawford <tcrawford@system76.com>
This commit is contained in:
parent
3f446e5c6e
commit
a8229d9e62
@ -7,7 +7,6 @@
|
||||
#include <board/gctrl.h>
|
||||
#include <board/gpio.h>
|
||||
#include <board/kbc.h>
|
||||
#include <board/peci.h>
|
||||
#include <board/power.h>
|
||||
#include <common/debug.h>
|
||||
|
||||
@ -32,44 +31,8 @@ void board_init(void) {
|
||||
gpio_set(&SWI_N, true);
|
||||
}
|
||||
|
||||
// Set PL4 using PECI
|
||||
static int set_power_limit(uint8_t watts) {
|
||||
return peci_wr_pkg_config(
|
||||
60, // index
|
||||
0, // param
|
||||
((uint32_t)watts) * 8
|
||||
);
|
||||
}
|
||||
|
||||
void board_on_ac(bool ac) {
|
||||
uint8_t power_limit = ac ? POWER_LIMIT_AC : POWER_LIMIT_DC;
|
||||
// Retry, timeout errors happen occasionally
|
||||
for (int i = 0; i < 16; i++) {
|
||||
int res = set_power_limit(power_limit);
|
||||
DEBUG("set_power_limit %d = %d\n", power_limit, res);
|
||||
if (res == 0x40) {
|
||||
break;
|
||||
} else if (res < 0) {
|
||||
ERROR("set_power_limit failed: 0x%02X\n", -res);
|
||||
} else {
|
||||
ERROR("set_power_limit unknown response: 0x%02X\n", res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void board_event(void) {
|
||||
bool ac = !gpio_get(&ACIN_N);
|
||||
|
||||
static bool last_power_limit_ac = true;
|
||||
// We don't use power_state because the latency needs to be low
|
||||
if (gpio_get(&BUF_PLT_RST_N)) {
|
||||
if (last_power_limit_ac != ac) {
|
||||
board_on_ac(ac);
|
||||
last_power_limit_ac = ac;
|
||||
}
|
||||
} else {
|
||||
last_power_limit_ac = true;
|
||||
}
|
||||
power_set_limit();
|
||||
|
||||
if (main_cycle == 0) {
|
||||
// Set keyboard LEDs
|
||||
|
@ -30,44 +30,8 @@ void board_init(void) {
|
||||
SPCTRL1 |= 0xC8;
|
||||
}
|
||||
|
||||
// Set PL4 using PECI
|
||||
static int set_power_limit(uint8_t watts) {
|
||||
return peci_wr_pkg_config(
|
||||
60, // index
|
||||
0, // param
|
||||
((uint32_t)watts) * 8
|
||||
);
|
||||
}
|
||||
|
||||
void board_on_ac(bool ac) {
|
||||
uint8_t power_limit = ac ? POWER_LIMIT_AC : POWER_LIMIT_DC;
|
||||
// Retry, timeout errors happen occasionally
|
||||
for (int i = 0; i < 16; i++) {
|
||||
int res = set_power_limit(power_limit);
|
||||
DEBUG("set_power_limit %d = %d\n", power_limit, res);
|
||||
if (res == 0x40) {
|
||||
break;
|
||||
} else if (res < 0) {
|
||||
ERROR("set_power_limit failed: 0x%02X\n", -res);
|
||||
} else {
|
||||
ERROR("set_power_limit unknown response: 0x%02X\n", res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void board_event(void) {
|
||||
bool ac = !gpio_get(&ACIN_N);
|
||||
|
||||
static bool last_power_limit_ac = true;
|
||||
// We don't use power_state because the latency needs to be low
|
||||
if (gpio_get(&BUF_PLT_RST_N)) {
|
||||
if (last_power_limit_ac != ac) {
|
||||
board_on_ac(ac);
|
||||
last_power_limit_ac = ac;
|
||||
}
|
||||
} else {
|
||||
last_power_limit_ac = true;
|
||||
}
|
||||
power_set_limit();
|
||||
|
||||
// Read POST codes
|
||||
while (P80H81HS & 1) {
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include <board/gctrl.h>
|
||||
#include <board/gpio.h>
|
||||
#include <board/kbc.h>
|
||||
#include <board/peci.h>
|
||||
#include <board/power.h>
|
||||
#include <common/debug.h>
|
||||
|
||||
@ -35,44 +34,8 @@ void board_init(void) {
|
||||
SPCTRL1 |= 0xC8;
|
||||
}
|
||||
|
||||
// Set PL4 using PECI
|
||||
static int set_power_limit(uint8_t watts) {
|
||||
return peci_wr_pkg_config(
|
||||
60, // index
|
||||
0, // param
|
||||
((uint32_t)watts) * 8
|
||||
);
|
||||
}
|
||||
|
||||
void board_on_ac(bool ac) {
|
||||
uint8_t power_limit = ac ? POWER_LIMIT_AC : POWER_LIMIT_DC;
|
||||
// Retry, timeout errors happen occasionally
|
||||
for (int i = 0; i < 16; i++) {
|
||||
int res = set_power_limit(power_limit);
|
||||
DEBUG("set_power_limit %d = %d\n", power_limit, res);
|
||||
if (res == 0x40) {
|
||||
break;
|
||||
} else if (res < 0) {
|
||||
ERROR("set_power_limit failed: 0x%02X\n", -res);
|
||||
} else {
|
||||
ERROR("set_power_limit unknown response: 0x%02X\n", res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void board_event(void) {
|
||||
bool ac = !gpio_get(&ACIN_N);
|
||||
|
||||
static bool last_power_limit_ac = true;
|
||||
// We don't use power_state because the latency needs to be low
|
||||
if (gpio_get(&BUF_PLT_RST_N)) {
|
||||
if (last_power_limit_ac != ac) {
|
||||
board_on_ac(ac);
|
||||
last_power_limit_ac = ac;
|
||||
}
|
||||
} else {
|
||||
last_power_limit_ac = true;
|
||||
}
|
||||
power_set_limit();
|
||||
|
||||
// Read POST codes
|
||||
while (P80H81HS & 1) {
|
||||
|
@ -7,6 +7,5 @@
|
||||
|
||||
void board_init(void);
|
||||
void board_event(void);
|
||||
void board_on_ac(bool ac);
|
||||
|
||||
#endif // _BOARD_BOARD_H
|
||||
|
@ -17,6 +17,7 @@ extern enum PowerState power_state;
|
||||
void power_on_ds5(void);
|
||||
void power_on_s5(void);
|
||||
void power_off_s5(void);
|
||||
void power_set_limit(void);
|
||||
void power_cpu_reset(void);
|
||||
|
||||
void power_event(void);
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <board/gpio.h>
|
||||
#include <board/kbled.h>
|
||||
#include <board/lid.h>
|
||||
#include <board/peci.h>
|
||||
#include <board/power.h>
|
||||
#include <board/pmc.h>
|
||||
#include <board/pnp.h>
|
||||
@ -350,6 +351,47 @@ void power_off_s5(void) {
|
||||
update_power_state();
|
||||
}
|
||||
|
||||
#ifdef HAVE_DGPU
|
||||
static void power_peci_limit(bool ac) {
|
||||
uint8_t watts = ac ? POWER_LIMIT_AC : POWER_LIMIT_DC;
|
||||
// Retry, timeout errors happen occasionally
|
||||
for (int i = 0; i < 16; i++) {
|
||||
// Set PL4 using PECI
|
||||
int res = peci_wr_pkg_config(60, 0, ((uint32_t)watts) * 8);
|
||||
DEBUG("power_peci_limit %d = %d\n", watts, res);
|
||||
if (res == 0x40) {
|
||||
break;
|
||||
} else if (res < 0) {
|
||||
ERROR("power_peci_limit failed: 0x%02X\n", -res);
|
||||
} else {
|
||||
ERROR("power_peci_limit unknown response: 0x%02X\n", res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set the power draw limit depending on if on AC or DC power
|
||||
void power_set_limit(void) {
|
||||
static bool last_power_limit_ac = true;
|
||||
// We don't use power_state because the latency needs to be low
|
||||
#if EC_ESPI
|
||||
if (gpio_get(&CPU_C10_GATE_N)) {
|
||||
#else
|
||||
if (gpio_get(&BUF_PLT_RST_N)) {
|
||||
#endif
|
||||
bool ac = !gpio_get(&ACIN_N);
|
||||
if (last_power_limit_ac != ac) {
|
||||
power_peci_limit(ac);
|
||||
last_power_limit_ac = ac;
|
||||
}
|
||||
} else {
|
||||
last_power_limit_ac = true;
|
||||
}
|
||||
}
|
||||
#else
|
||||
static void power_peci_limit(bool ac) { ac = ac; }
|
||||
void power_set_limit(void) {}
|
||||
#endif // HAVE_DGPU
|
||||
|
||||
// This function is run when the CPU is reset
|
||||
void power_cpu_reset(void) {
|
||||
// LPC was just reset, enable PNP devices
|
||||
@ -378,7 +420,7 @@ void power_event(void) {
|
||||
static bool ac_last = true;
|
||||
bool ac_new = gpio_get(&ACIN_N);
|
||||
if (ac_new != ac_last) {
|
||||
board_on_ac(!ac_new);
|
||||
power_peci_limit(!ac_new);
|
||||
|
||||
DEBUG("Power adapter ");
|
||||
if (ac_new) {
|
||||
|
@ -25,6 +25,4 @@ void board_init(void) {
|
||||
gpio_set(&SWI_N, true);
|
||||
}
|
||||
|
||||
void board_on_ac(bool ac) { /* Fix unused variable */ ac = ac; }
|
||||
|
||||
void board_event(void) {}
|
||||
|
@ -31,8 +31,6 @@ void board_init(void) {
|
||||
SPCTRL1 |= 0xC8;
|
||||
}
|
||||
|
||||
void board_on_ac(bool ac) { /* Fix unused variable */ ac = ac; }
|
||||
|
||||
void board_event(void) {
|
||||
espi_event();
|
||||
|
||||
|
@ -25,6 +25,4 @@ void board_init(void) {
|
||||
gpio_set(&SWI_N, true);
|
||||
}
|
||||
|
||||
void board_on_ac(bool ac) { /* Fix unused variable */ ac = ac; }
|
||||
|
||||
void board_event(void) {}
|
||||
|
@ -6,7 +6,6 @@
|
||||
#include <board/espi.h>
|
||||
#include <board/gctrl.h>
|
||||
#include <board/gpio.h>
|
||||
#include <board/peci.h>
|
||||
#include <board/power.h>
|
||||
#include <common/debug.h>
|
||||
|
||||
@ -38,48 +37,9 @@ void board_init(void) {
|
||||
SPCTRL1 |= 0xC8;
|
||||
}
|
||||
|
||||
#if HAVE_DGPU
|
||||
// Set PL4 using PECI
|
||||
static int set_power_limit(uint8_t watts) {
|
||||
return peci_wr_pkg_config(
|
||||
60, // index
|
||||
0, // param
|
||||
((uint32_t)watts) * 8
|
||||
);
|
||||
}
|
||||
|
||||
void board_on_ac(bool ac) {
|
||||
uint8_t power_limit = ac ? POWER_LIMIT_AC : POWER_LIMIT_DC;
|
||||
// Retry, timeout errors happen occasionally
|
||||
for (int i = 0; i < 16; i++) {
|
||||
int res = set_power_limit(power_limit);
|
||||
DEBUG("set_power_limit %d = %d\n", power_limit, res);
|
||||
if (res == 0x40) {
|
||||
break;
|
||||
} else if (res < 0) {
|
||||
ERROR("set_power_limit failed: 0x%02X\n", -res);
|
||||
} else {
|
||||
ERROR("set_power_limit unknown response: 0x%02X\n", res);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else // HAVE_DGPU
|
||||
void board_on_ac(bool ac) { /* Fix unused variable */ ac = ac; }
|
||||
#endif // HAVE_DGPU
|
||||
|
||||
void board_event(void) {
|
||||
#if HAVE_DGPU
|
||||
static bool last_power_limit_ac = true;
|
||||
// We don't use power_state because the latency needs to be low
|
||||
if (gpio_get(&CPU_C10_GATE_N)) {
|
||||
bool ac = !gpio_get(&ACIN_N);
|
||||
if (last_power_limit_ac != ac) {
|
||||
board_on_ac(ac);
|
||||
last_power_limit_ac = ac;
|
||||
}
|
||||
} else {
|
||||
last_power_limit_ac = true;
|
||||
}
|
||||
power_set_limit();
|
||||
#endif // HAVE_DGPU
|
||||
|
||||
espi_event();
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include <board/gctrl.h>
|
||||
#include <board/gpio.h>
|
||||
#include <board/kbc.h>
|
||||
#include <board/peci.h>
|
||||
#include <board/power.h>
|
||||
#include <common/debug.h>
|
||||
|
||||
@ -31,44 +30,8 @@ void board_init(void) {
|
||||
SPCTRL1 |= 0xC8;
|
||||
}
|
||||
|
||||
// Set PL4 using PECI
|
||||
static int set_power_limit(uint8_t watts) {
|
||||
return peci_wr_pkg_config(
|
||||
60, // index
|
||||
0, // param
|
||||
((uint32_t)watts) * 8
|
||||
);
|
||||
}
|
||||
|
||||
void board_on_ac(bool ac) {
|
||||
uint8_t power_limit = ac ? POWER_LIMIT_AC : POWER_LIMIT_DC;
|
||||
// Retry, timeout errors happen occasionally
|
||||
for (int i = 0; i < 16; i++) {
|
||||
int res = set_power_limit(power_limit);
|
||||
DEBUG("set_power_limit %d = %d\n", power_limit, res);
|
||||
if (res == 0x40) {
|
||||
break;
|
||||
} else if (res < 0) {
|
||||
ERROR("set_power_limit failed: 0x%02X\n", -res);
|
||||
} else {
|
||||
ERROR("set_power_limit unknown response: 0x%02X\n", res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void board_event(void) {
|
||||
bool ac = !gpio_get(&ACIN_N);
|
||||
|
||||
static bool last_power_limit_ac = true;
|
||||
// We don't use power_state because the latency needs to be low
|
||||
if (gpio_get(&BUF_PLT_RST_N)) {
|
||||
if (last_power_limit_ac != ac) {
|
||||
board_on_ac(ac);
|
||||
last_power_limit_ac = ac;
|
||||
}
|
||||
} else {
|
||||
last_power_limit_ac = true;
|
||||
}
|
||||
power_set_limit();
|
||||
|
||||
// Read POST codes
|
||||
while (P80H81HS & 1) {
|
||||
|
@ -33,8 +33,6 @@ void board_init(void) {
|
||||
SPCTRL1 |= 0xC8;
|
||||
}
|
||||
|
||||
void board_on_ac(bool ac) { /* Fix unused variable */ ac = ac; }
|
||||
|
||||
void board_event(void) {
|
||||
espi_event();
|
||||
|
||||
|
@ -25,8 +25,6 @@ void board_init(void) {
|
||||
gpio_set(&SWI_N, true);
|
||||
}
|
||||
|
||||
void board_on_ac(bool ac) { /* Fix unused variable */ ac = ac; }
|
||||
|
||||
void board_event(void) {
|
||||
if (main_cycle == 0) {
|
||||
if (power_state == POWER_STATE_S0 || power_state == POWER_STATE_S3 || power_state == POWER_STATE_DS3) {
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include <board/gctrl.h>
|
||||
#include <board/gpio.h>
|
||||
#include <board/kbc.h>
|
||||
#include <board/peci.h>
|
||||
#include <board/power.h>
|
||||
#include <common/debug.h>
|
||||
|
||||
@ -32,42 +31,6 @@ void board_init(void) {
|
||||
gpio_set(&SWI_N, true);
|
||||
}
|
||||
|
||||
// Set PL4 using PECI
|
||||
static int set_power_limit(uint8_t watts) {
|
||||
return peci_wr_pkg_config(
|
||||
60, // index
|
||||
0, // param
|
||||
((uint32_t)watts) * 8
|
||||
);
|
||||
}
|
||||
|
||||
void board_on_ac(bool ac) {
|
||||
uint8_t power_limit = ac ? POWER_LIMIT_AC : POWER_LIMIT_DC;
|
||||
// Retry, timeout errors happen occasionally
|
||||
for (int i = 0; i < 16; i++) {
|
||||
int res = set_power_limit(power_limit);
|
||||
DEBUG("set_power_limit %d = %d\n", power_limit, res);
|
||||
if (res == 0x40) {
|
||||
break;
|
||||
} else if (res < 0) {
|
||||
ERROR("set_power_limit failed: 0x%02X\n", -res);
|
||||
} else {
|
||||
ERROR("set_power_limit unknown response: 0x%02X\n", res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void board_event(void) {
|
||||
bool ac = !gpio_get(&ACIN_N);
|
||||
|
||||
static bool last_power_limit_ac = true;
|
||||
// We don't use power_state because the latency needs to be low
|
||||
if (gpio_get(&BUF_PLT_RST_N)) {
|
||||
if (last_power_limit_ac != ac) {
|
||||
board_on_ac(ac);
|
||||
last_power_limit_ac = ac;
|
||||
}
|
||||
} else {
|
||||
last_power_limit_ac = true;
|
||||
}
|
||||
power_set_limit();
|
||||
}
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include <board/gctrl.h>
|
||||
#include <board/gpio.h>
|
||||
#include <board/kbc.h>
|
||||
#include <board/peci.h>
|
||||
#include <board/power.h>
|
||||
#include <common/debug.h>
|
||||
|
||||
@ -35,44 +34,8 @@ void board_init(void) {
|
||||
SPCTRL1 |= 0xC8;
|
||||
}
|
||||
|
||||
// Set PL4 using PECI
|
||||
static int set_power_limit(uint8_t watts) {
|
||||
return peci_wr_pkg_config(
|
||||
60, // index
|
||||
0, // param
|
||||
((uint32_t)watts) * 8
|
||||
);
|
||||
}
|
||||
|
||||
void board_on_ac(bool ac) {
|
||||
uint8_t power_limit = ac ? POWER_LIMIT_AC : POWER_LIMIT_DC;
|
||||
// Retry, timeout errors happen occasionally
|
||||
for (int i = 0; i < 16; i++) {
|
||||
int res = set_power_limit(power_limit);
|
||||
DEBUG("set_power_limit %d = %d\n", power_limit, res);
|
||||
if (res == 0x40) {
|
||||
break;
|
||||
} else if (res < 0) {
|
||||
ERROR("set_power_limit failed: 0x%02X\n", -res);
|
||||
} else {
|
||||
ERROR("set_power_limit unknown response: 0x%02X\n", res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void board_event(void) {
|
||||
bool ac = !gpio_get(&ACIN_N);
|
||||
|
||||
static bool last_power_limit_ac = true;
|
||||
// We don't use power_state because the latency needs to be low
|
||||
if (gpio_get(&BUF_PLT_RST_N)) {
|
||||
if (last_power_limit_ac != ac) {
|
||||
board_on_ac(ac);
|
||||
last_power_limit_ac = ac;
|
||||
}
|
||||
} else {
|
||||
last_power_limit_ac = true;
|
||||
}
|
||||
power_set_limit();
|
||||
|
||||
// Read POST codes
|
||||
while (P80H81HS & 1) {
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include <board/gctrl.h>
|
||||
#include <board/gpio.h>
|
||||
#include <board/kbc.h>
|
||||
#include <board/peci.h>
|
||||
#include <board/power.h>
|
||||
#include <common/debug.h>
|
||||
|
||||
@ -34,44 +33,8 @@ void board_init(void) {
|
||||
SPCTRL1 |= 0xC8;
|
||||
}
|
||||
|
||||
// Set PL4 using PECI
|
||||
static int set_power_limit(uint8_t watts) {
|
||||
return peci_wr_pkg_config(
|
||||
60, // index
|
||||
0, // param
|
||||
((uint32_t)watts) * 8
|
||||
);
|
||||
}
|
||||
|
||||
void board_on_ac(bool ac) {
|
||||
uint8_t power_limit = ac ? POWER_LIMIT_AC : POWER_LIMIT_DC;
|
||||
// Retry, timeout errors happen occasionally
|
||||
for (int i = 0; i < 16; i++) {
|
||||
int res = set_power_limit(power_limit);
|
||||
DEBUG("set_power_limit %d = %d\n", power_limit, res);
|
||||
if (res == 0x40) {
|
||||
break;
|
||||
} else if (res < 0) {
|
||||
ERROR("set_power_limit failed: 0x%02X\n", -res);
|
||||
} else {
|
||||
ERROR("set_power_limit unknown response: 0x%02X\n", res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void board_event(void) {
|
||||
bool ac = !gpio_get(&ACIN_N);
|
||||
|
||||
static bool last_power_limit_ac = true;
|
||||
// We don't use power_state because the latency needs to be low
|
||||
if (gpio_get(&BUF_PLT_RST_N)) {
|
||||
if (last_power_limit_ac != ac) {
|
||||
board_on_ac(ac);
|
||||
last_power_limit_ac = ac;
|
||||
}
|
||||
} else {
|
||||
last_power_limit_ac = true;
|
||||
}
|
||||
power_set_limit();
|
||||
|
||||
// Read POST codes
|
||||
while (P80H81HS & 1) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user