Duncan Laurie has uploaded this change for review. ( https://review.coreboot.org/29116
Change subject: ec/google/wilco: Add power related mailbox commands ......................................................................
ec/google/wilco: Add power related mailbox commands
Add EC mailbox commands that are related to the power and state of the system. These commands include:
- read the power status registers from the EC - read & clear the power status registers - helper function to read the current lid state - tell the EC why the host is about to power off - tell the EC that the host is about to enter a sleep state
Change-Id: Iaa7051b4006e3c1687933e0384d962516220621f Signed-off-by: Duncan Laurie dlaurie@google.com --- M src/ec/google/wilco/commands.c M src/ec/google/wilco/commands.h 2 files changed, 169 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/16/29116/1
diff --git a/src/ec/google/wilco/commands.c b/src/ec/google/wilco/commands.c index 4cec58b..ccf9f73 100644 --- a/src/ec/google/wilco/commands.c +++ b/src/ec/google/wilco/commands.c @@ -50,3 +50,72 @@ if (!wilco_ec_get_info(GET_EC_BUILD_DATE, info)) printk(BIOS_INFO, "EC Build Date : %s\n", info); } + +int wilco_ec_power_smi(struct ec_pm_event_state *pm) +{ + struct ec_response_power_smi rsp; + + if (!pm) + return -1; + if (wilco_ec_sendrecv_noargs(KB_POWER_SMI, &rsp, sizeof(rsp)) < 0) + return -1; + + pm->event[0] = rsp.pm_event_1; + pm->event[1] = rsp.pm_event_2; + pm->state[0] = rsp.pm_state_1; + pm->state[1] = rsp.pm_state_2; + pm->state[2] = rsp.pm_state_3; + pm->state[3] = rsp.pm_state_4; + pm->state[4] = rsp.pm_state_5; + pm->state[5] = rsp.pm_state_6; + pm->hotkey = rsp.hotkey; + + return 0; +} + +int wilco_ec_power_status(struct ec_pm_event_state *pm) +{ + struct ec_response_power_status rsp; + + if (!pm) + return -1; + if (wilco_ec_sendrecv_noargs(KB_POWER_STATUS, &rsp, sizeof(rsp)) < 0) + return -1; + + pm->hotkey = 0; + pm->event[0] = 0; + pm->event[1] = rsp.pm_event_2; + pm->state[0] = rsp.pm_state_1; + pm->state[1] = rsp.pm_state_2; + pm->state[2] = rsp.pm_state_3; + pm->state[3] = rsp.pm_state_4; + pm->state[4] = rsp.pm_state_5; + pm->state[5] = rsp.pm_state_6; + pm->ac_type = rsp.ac_type_msb << 8 | rsp.ac_type_lsb; + + return 0; +} + +int wilco_ec_get_lid_state(void) +{ + struct ec_pm_event_state pm; + + if (wilco_ec_power_status(&pm) < 0) + return -1; + + return !!(pm.state[0] & EC_PM1_LID_OPEN); +} + +void wilco_ec_slp_en(void) +{ + /* EC does not respond to this command */ + wilco_ec_mailbox(WILCO_EC_MSG_NO_RESPONSE, + KB_SLP_EN, NULL, 0, NULL, 0); +} + +void wilco_ec_power_off(enum ec_power_off_reason reason) +{ + /* EC does not respond to this command */ + wilco_ec_mailbox(WILCO_EC_MSG_NO_RESPONSE, + KB_POWER_OFF, &reason, 1, NULL, 0); +} diff --git a/src/ec/google/wilco/commands.h b/src/ec/google/wilco/commands.h index 76949d0..c277d83 100644 --- a/src/ec/google/wilco/commands.h +++ b/src/ec/google/wilco/commands.h @@ -19,12 +19,20 @@ #include <stdint.h>
enum { + /* Read and clear power state information */ + KB_POWER_SMI = 0x04, + /* Read but do not clear power state information */ + KB_POWER_STATUS = 0x05, + /* Inform the EC aboout the reason host is turning off */ + KB_POWER_OFF = 0x08, /* Retrieve information about the EC */ KB_EC_INFO = 0x38, /* Set ACPI mode on or off */ KB_ACPI = 0x3a, /* Manage the EC power button passthru to the host */ KB_POWER_BUTTON_TO_HOST = 0x3e, + /* Inform the EC that the host is about to enter S3 */ + KB_SLP_EN = 0x64, };
enum set_acpi_mode_cmd { @@ -51,4 +59,96 @@ int wilco_ec_get_info(enum get_ec_info_cmd cmd, char *info); void wilco_ec_print_info(void);
+/* + * EC Power State + */ + +enum ec_power_off_reason { + EC_PWROFF_FLASH = 0x11, + EC_PWROFF_AC_REMOVED = 0x12, + EC_PWROFF_BAT_REMOVED = 0x13, + EC_PWROFF_LOBAT = 0x15, + EC_PWROFF_PWRB_IN_POST = 0x16, + EC_PWROFF_FORCE_IMMEDIATE = 0x18, + EC_PWROFF_WDT = 0x1b, + EC_PWROFF_FORCE_THERMAL = 0x22, + EC_PWROFF_ERR_CODE = 0x23, + EC_PWROFF_PAID_PWRGD = 0x27, + EC_PWROFF_PAID_CPU = 0x28, + EC_PWROFF_PAID_GFX = 0x29, + EC_PWROFF_PAID_CLK = 0x2a, + EC_PWROFF_PAID_NOMEMORY = 0x2b, + EC_PWROFF_PAID_MEMORY_ERR = 0x2c, + EC_PWROFF_PAID_MEMORY_SPD = 0x2d, + EC_SWOFF_ACPI = 0x31, + EC_SWOFF_BOOT_PASSWORD = 0x33, + EC_SWOFF_DISK_PASSWORD = 0x34, + EC_SWOFF_POWER_CYCLE = 0x37, + EC_SWOFF_HARD_RESET = 0x3b, + EC_SWOFF_FSMI = 0x3f, + EC_PWRLOG_THERMTRIP = 0x41, + EC_PWRLOG_NO_S5 = 0x42, + EC_PWROFF_4S_PWRB = 0x44, + EC_PWROFF_ASF2_FORCEOFF = 0x45, + EC_PWROFF_PWRB_THERMAL = 0x48, + EC_PWROFF_AOAC_TIMER = 0x4b, +}; + +/* Tell the EC why the host is about to power off */ +void wilco_ec_power_off(enum ec_power_off_reason reason); + +enum ec_pm1_state { + EC_PM1_AC_AVAIL = 0x01, + EC_PM1_BAT_AVAIL = 0x02, + EC_PM1_LO_BAT1 = 0x03, + EC_PM1_LO_BAT2 = 0x04, + EC_PM1_LID_OPEN = 0x10, + EC_PM1_LCD_POWER = 0x20, + EC_PM1_OVER_TEMP = 0x40, + EC_PM1_DOCKED = 0x80 +}; + +struct ec_pm_event_state { + uint8_t event[2]; + uint8_t state[6]; + uint8_t hotkey; + uint16_t ac_type; +}; + +struct ec_response_power_status { + uint8_t pm_state_1; + uint8_t pm_state_2; + uint8_t pm_state_3; + uint8_t pm_state_4; + uint8_t pm_state_5; + uint8_t ac_type_lsb; + uint8_t pm_state_6; + uint8_t pm_event_2; + uint8_t ac_type_msb; +} __packed; + +/* Retrieve the power state information */ +int wilco_ec_power_status(struct ec_pm_event_state *pm); + +/* Read but do not clear lid state */ +int wilco_ec_get_lid_state(void); + +struct ec_response_power_smi { + uint8_t pm_event_1; + uint8_t pm_state_1; + uint8_t hotkey; + uint8_t pm_state_2; + uint8_t pm_state_3; + uint8_t pm_state_4; + uint8_t pm_state_5; + uint8_t pm_event_2; + uint8_t pm_state_6; +} __packed; + +/* Retrieve *and clears* the power state information */ +int wilco_ec_power_smi(struct ec_pm_event_state *pm); + +/* Tell the EC that the host is entering a sleep state */ +void wilco_ec_slp_en(void); + #endif /* EC_GOOGLE_WILCO_COMMANDS_H */