diff options
author | Shawn Nematbakhsh <shawnn@chromium.org> | 2015-03-27 13:44:34 -0700 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2015-04-22 08:51:31 +0200 |
commit | 19ffcb3412d4fae370825c16b4bb0aaa0ed90ea9 (patch) | |
tree | f245a95c6b47631c34e6b394f095b08530de6d9c /src/ec | |
parent | 243c614134cd29b764425b18e85aca7c6ea21ab7 (diff) |
chromeec: Access ID + flags through ACPI I/O ports
If CONFIG_EC_GOOGLE_CHROMEEC_ACPI_MEMMAP is set, access to memmap data
should go through the ACPI CMD / DATA ports.
BUG=chrome-os-partner:38224
TEST=Manual on Samus. Define EC_GOOGLE_CHROMEEC_ACPI_MEMMAP. Verify
system boots cleanly.
BRANCH=None
Change-Id: I9d19704df259f5a25e04a9b07b23968e93fe6302
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: d0b59b040a7889d2d1bd6eeaf57dd960bd29927d
Original-Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org>
Original-Change-Id: I405e28828457a1fd83a7ece7192a7e7d0a37be95
Original-Reviewed-on: https://chromium-review.googlesource.com/262932
Original-Reviewed-by: Randall Spangler <rspangler@chromium.org>
Original-Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-on: http://review.coreboot.org/9893
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Diffstat (limited to 'src/ec')
-rw-r--r-- | src/ec/google/chromeec/ec_lpc.c | 83 |
1 files changed, 61 insertions, 22 deletions
diff --git a/src/ec/google/chromeec/ec_lpc.c b/src/ec/google/chromeec/ec_lpc.c index 061c1032c1..f5f5434548 100644 --- a/src/ec/google/chromeec/ec_lpc.c +++ b/src/ec/google/chromeec/ec_lpc.c @@ -29,13 +29,74 @@ #include "ec.h" #include "ec_commands.h" +static int google_chromeec_wait_ready(u16 port) +{ + u8 ec_status = inb(port); + u32 time_count = 0; + + /* + * One second is more than plenty for any EC operation to complete + * (and the bus accessing/code execution) overhead will make the + * timeout even longer. + */ +#define MAX_EC_TIMEOUT_US 1000000 + + while (ec_status & + (EC_LPC_CMDR_PENDING | EC_LPC_CMDR_BUSY)) { + udelay(1); + if (time_count++ == MAX_EC_TIMEOUT_US) + return -1; + ec_status = inb(port); + } + return 0; +} + +#if CONFIG_EC_GOOGLE_CHROMEEC_ACPI_MEMMAP +/* Read memmap data through ACPI port 66/62 */ +static int read_memmap(u8 *data, u8 offset) +{ + if (google_chromeec_wait_ready(EC_LPC_ADDR_ACPI_CMD)) { + printk(BIOS_ERR, "Timeout waiting for EC ready!\n"); + return -1; + } + + /* Issue the ACPI read command */ + outb(EC_CMD_ACPI_READ, EC_LPC_ADDR_ACPI_CMD); + + if (google_chromeec_wait_ready(EC_LPC_ADDR_ACPI_CMD)) { + printk(BIOS_ERR, "Timeout waiting for EC READ_EVENT!\n"); + return -1; + } + + /* Write data address */ + outb(offset + EC_ACPI_MEM_MAPPED_BEGIN, EC_LPC_ADDR_ACPI_DATA); + + if (google_chromeec_wait_ready(EC_LPC_ADDR_ACPI_CMD)) { + printk(BIOS_ERR, "Timeout waiting for EC DATA!\n"); + return -1; + } + + *data = inb(EC_LPC_ADDR_ACPI_DATA); + return 0; +} +#endif + static int google_chromeec_command_version(void) { u8 id1, id2, flags; +#if CONFIG_EC_GOOGLE_CHROMEEC_ACPI_MEMMAP + if (read_memmap(&id1, EC_MEMMAP_ID) || + read_memmap(&id2, EC_MEMMAP_ID + 1) || + read_memmap(&flags, EC_MEMMAP_HOST_CMD_FLAGS)) { + printk(BIOS_ERR, "Error reading memmap data.\n"); + return -1; + } +#else id1 = inb(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID); id2 = inb(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID + 1); flags = inb(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_HOST_CMD_FLAGS); +#endif if (id1 != 'E' || id2 != 'C') { printk(BIOS_ERR, "Missing Chromium EC memory map.\n"); @@ -53,28 +114,6 @@ static int google_chromeec_command_version(void) } } -static int google_chromeec_wait_ready(u16 port) -{ - u8 ec_status = inb(port); - u32 time_count = 0; - - /* - * One second is more than plenty for any EC operation to complete - * (and the bus accessing/code execution) overhead will make the - * timeout even longer. - */ -#define MAX_EC_TIMEOUT_US 1000000 - - while (ec_status & - (EC_LPC_CMDR_PENDING | EC_LPC_CMDR_BUSY)) { - udelay(1); - if (time_count++ == MAX_EC_TIMEOUT_US) - return -1; - ec_status = inb(port); - } - return 0; -} - static int google_chromeec_command_v3(struct chromeec_command *cec_command) { struct ec_host_request rq; |