Move power handling to new power functions

This commit is contained in:
Jeremy Soller
2019-11-22 14:30:50 -07:00
parent c6588d8847
commit 38321e068b

View File

@ -10,6 +10,7 @@
#include <board/kbscan.h>
#include <board/peci.h>
#include <board/pmc.h>
#include <board/power.h>
#include <board/ps2.h>
#include <board/pwm.h>
#include <board/smbus.h>
@ -87,243 +88,6 @@ void ac_adapter() {
last = new;
}
volatile uint8_t __xdata __at(0x1200) IHIOA;
volatile uint8_t __xdata __at(0x1201) IHD;
volatile uint8_t __xdata __at(0x1204) IBMAE;
volatile uint8_t __xdata __at(0x1205) IBCTL;
void e2ci_write(uint8_t port, uint8_t data) {
while (IBCTL & ((1 << 2) | (1 << 1))) {}
IHIOA = port;
IHD = data;
IBMAE = 1;
IBCTL = 1;
while (IBCTL & (1 << 2)) {}
IBMAE = 0;
IBCTL = 0;
}
void pnp_write(uint8_t reg, uint8_t data) {
e2ci_write(0x2E, reg);
e2ci_write(0x2F, data);
}
void pnp_enable() {
DEBUG("Enable PNP devices\n");
// Enable PMC
pnp_write(0x07, 0x11);
pnp_write(0x30, 0x01);
// Enable KBC keyboard
pnp_write(0x07, 0x06);
pnp_write(0x30, 0x01);
// Enable KBC mouse
pnp_write(0x07, 0x05);
pnp_write(0x30, 0x01);
// Enable SWUC
pnp_write(0x07, 0x04);
pnp_write(0x30, 0x01);
}
void power_button() {
static struct Gpio __code PCH_DPWROK_EC = GPIO(A, 3);
static struct Gpio __code PCH_PWROK_EC = GPIO(A, 4);
static struct Gpio __code LED_PWR = GPIO(A, 7);
static struct Gpio __code ALL_SYS_PWRGD = GPIO(C, 0);
static struct Gpio __code PM_PWROK = GPIO(C, 6);
static struct Gpio __code PWR_SW_N = GPIO(D, 0);
static struct Gpio __code BUF_PLT_RST_N = GPIO(D, 2);
static struct Gpio __code PWR_BTN_N = GPIO(D, 5);
static struct Gpio __code SUSWARN_N = GPIO(D, 7);
static struct Gpio __code EC_EN = GPIO(E, 1);
static struct Gpio __code VA_EC_EN = GPIO(E, 3);
static struct Gpio __code DD_ON = GPIO(E, 4);
static struct Gpio __code EC_RSMRST_N = GPIO(E, 5);
static struct Gpio __code AC_PRESENT = GPIO(E, 7);
static struct Gpio __code SUSC_N_PCH = GPIO(H, 1);
static struct Gpio __code VR_ON = GPIO(H, 4);
static struct Gpio __code SUSB_N_PCH = GPIO(H, 6);
static struct Gpio __code SLP_SUS_N = GPIO(I, 2);
static struct Gpio __code SUS_PWR_ACK = GPIO(J, 0);
static bool power = false;
// Check if the power switch goes low
static bool last = true;
bool new = gpio_get(&PWR_SW_N);
if (!new && last) {
// Ensure press is not spurious
delay_ms(10);
if (gpio_get(&PWR_SW_N) != new) {
DEBUG("Spurious press\n");
return;
}
DEBUG("Power switch press\n");
power = !power;
if (power) {
DEBUG("Enabling S5 power\n");
// We assume that VCCRTC has already been stable, RTCRST# is
// already set, and VCCDSW_3P3 is stable
// Make sure VCCDSW is stable for at least 10 ms (tPCH02)
delay_ms(10 + 5);
// Assert DSW_PWROK
TRACE("PCH_DPWROK_EC: %d\n", power);
gpio_set(&PCH_DPWROK_EC, power);
// Wait for SLP_SUS# (tPCH32)
delay_ms(95);
for (;;) {
bool value = gpio_get(&SLP_SUS_N);
TRACE("SLP_SUS_N: %d\n", value);
if (value) break;
delay_ms(1);
}
// Enable VCCPRIM_* planes - must be enabled prior to USB power
// in order to avoid leakage
TRACE("VA_EC_EN: %d\n", power);
gpio_set(&VA_EC_EN, power);
// Make sure VCCPRIM_* is stable for at least 10 ms (tPCH03)
delay_ms(10 + 5);
// Enable VDD5
TRACE("DD_ON: %d\n", power);
gpio_set(&DD_ON, power);
// Assert RSMRST#
TRACE("EC_RSMRST_N: %d\n", power);
gpio_set(&EC_RSMRST_N, power);
// Allow processor to control SUSB# and SUSC#
TRACE("EC_EN: %d\n", power);
gpio_set(&EC_EN, power);
// Assert SUS_ACK#
TRACE("SUS_PWR_ACK: %d\n", power);
gpio_set(&SUS_PWR_ACK, power);
// DEBUG("VR_ON: %d\n", power);
// gpio_set(&VR_ON, power);
}
}
// Set PWR_BTN line!
gpio_set(&PWR_BTN_N, new);
if (!new && last) {
if (power) {
DEBUG("Enabling S0 power\n");
// Wait for ALL_SYS_PWRGD
for (;;) {
bool value = gpio_get(&ALL_SYS_PWRGD);
TRACE("ALL_SYS_PWRGD: %d\n", value);
if (value) break;
delay_ms(1);
}
// Assert VR_ON
TRACE("VR_ON: %d\n", power);
gpio_set(&VR_ON, power);
// Assert PM_PWEROK, PCH_PWROK will be asserted when H_VR_READY is
TRACE("PM_PWROK: %d\n", power);
gpio_set(&PM_PWROK, power);
// OEM defined delay from ALL_SYS_PWRGD to SYS_PWROK - TODO
delay_ms(10);
// Assert PCH_PWEROK_EC, SYS_PWEROK will be asserted
TRACE("PCH_PWROK_EC: %d\n", power);
gpio_set(&PCH_PWROK_EC, power);
// Wait for PLT_RST#
for (;;) {
bool value = gpio_get(&BUF_PLT_RST_N);
TRACE("BUF_PLT_RST_N: %d\n", value);
if (value) break;
delay_ms(1);
}
// enable pnp devices
pnp_enable();
} else {
DEBUG("Disabling power\n");
// De-assert SUS_ACK#
TRACE("SUS_PWR_ACK: %d\n", power);
gpio_set(&SUS_PWR_ACK, power);
// De-assert PCH_PWROK_EC, SYS_PWROK will be de-asserted
TRACE("PCH_PWROK_EC: %d\n", power);
gpio_set(&PCH_PWROK_EC, power);
// De-assert PM_PWROK, PCH_PWROK will be de-asserted
TRACE("PM_PWROK: %d\n", power);
gpio_set(&PM_PWROK, power);
// De-assert VR_ON
TRACE("VR_ON: %d\n", power);
gpio_set(&VR_ON, power);
// Block processor from controlling SUSB# and SUSC#
TRACE("EC_EN: %d\n", power);
gpio_set(&EC_EN, power);
// De-assert RSMRST#
TRACE("EC_RSMRST_N: %d\n", power);
gpio_set(&EC_RSMRST_N, power);
// Disable VDD5
TRACE("DD_ON: %d\n", power);
gpio_set(&DD_ON, power);
// Wait a minimum of 400 ns (tPCH12)
delay_ms(1);
// Disable VCCPRIM_* planes
TRACE("VA_EC_EN: %d\n", power);
gpio_set(&VA_EC_EN, power);
// De-assert DSW_PWROK
TRACE("PCH_DPWROK_EC: %d\n", power);
gpio_set(&PCH_DPWROK_EC, power);
// Wait a minimum of 400 ns (tPCH14)
delay_ms(1);
}
// Reset main loop cycle to force reading PECI and battery
main_cycle = 0;
TRACE("LED_PWR: %d\n", power);
gpio_set(&LED_PWR, power);
}
#if LEVEL >= LEVEL_DEBUG
else if (new && !last) {
DEBUG("Power switch release\n");
TRACE("SUSWARN_N: %d\n", gpio_get(&SUSWARN_N));
TRACE("SUSC_N_PCH: %d\n", gpio_get(&SUSC_N_PCH));
TRACE("SUSB_N_PCH: %d\n", gpio_get(&SUSB_N_PCH));
TRACE("ALL_SYS_PWRGD: %d\n", gpio_get(&ALL_SYS_PWRGD));
TRACE("BUF_PLT_RST_N: %d\n", gpio_get(&BUF_PLT_RST_N));
}
#endif
last = new;
}
void touchpad_event(struct Ps2 * ps2) {
if (kbc_second) {
*(ps2->control) = 0x07;
@ -387,8 +151,8 @@ void main(void) {
for(main_cycle = 0; ; main_cycle++) {
// Enables or disables battery charging based on AC adapter
ac_adapter();
// Checks for power button press
power_button();
// Handle power states
power_event();
// Scans keyboard and sends keyboard packets
kbscan_event();
// Passes through touchpad packets