Hi List,
the Lenovo Embedded Controller contains 2 register pairs for ACPI: the default 0x62/0x66 pair, and a 0x1600/0x1604 pair, which is intended to be used by SMM code.
While the current code works with the 0x62/0x66 pair (which is fine because there are no SMM users right now), we might switch to 0x1600/0x1604 for later versions where the SMM code actually uses the EC.
So i thought about using the sconfig 'register' keyword for specifying the Register pair. If it is not given in devicetree.cb, the default ACPI addresses will be used.
I've attached a short patch as an example to this mail (i have not tried if it works - it is just for discussion).
One question is if we should use global static variables for the register addresses, or pass struct ec_acpi_config * to all functions?
And we may think about renaming the 'register' keyword to something like 'config', as this describes better what it does.
Regards,
Sven.
From 9a3d656d19849bf842b0f2e1e3a86ee6b0d5a77a Mon Sep 17 00:00:00 2001
From: Sven Schnelle svens@stackframe.org Date: Tue, 8 Mar 2011 16:43:28 +0100 Subject: [PATCH] ec/acpi: make ACPI register pair configurable To: coreboot@coreboot.org Cc: svens@stackframe.org, svens@stackframe.org
Signed-off-by: Sven Schnelle svens@stackframe.org --- src/ec/acpi/chip.h | 31 +++++++++++++++++++++++++++++++ src/ec/acpi/ec.c | 30 +++++++++++++++++++++++------- src/mainboard/lenovo/x60/devicetree.cb | 2 ++ 3 files changed, 56 insertions(+), 7 deletions(-) create mode 100644 src/ec/acpi/chip.h
diff --git a/src/ec/acpi/chip.h b/src/ec/acpi/chip.h new file mode 100644 index 0000000..b0d1121 --- /dev/null +++ b/src/ec/acpi/chip.h @@ -0,0 +1,31 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2011 Sven Schnelle svens@stackframe.org + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef EC_ACPI_CHIP_H +#define EC_ACPI_CHIP_H + +extern struct chip_operations ec_acpi_ops; + +struct ec_acpi_config { + int cmd_reg; + int data_reg; +}; + +#endif diff --git a/src/ec/acpi/ec.c b/src/ec/acpi/ec.c index 7a01b7e..80d5056 100644 --- a/src/ec/acpi/ec.c +++ b/src/ec/acpi/ec.c @@ -24,13 +24,17 @@ #include <arch/io.h> #include <delay.h> #include "ec.h" +#include "chip.h" + +static int ec_cmd_reg = EC_SC; +static int ec_data_reg = EC_DATA;
int send_ec_command(u8 command) { int timeout;
timeout = 0x7ff; - while ((inb(EC_SC) & EC_IBF) && --timeout) { + while ((inb(ec_cmd_reg) & EC_IBF) && --timeout) { udelay(10); if ((timeout & 0xff) == 0) printk(BIOS_SPEW, "."); @@ -41,7 +45,7 @@ int send_ec_command(u8 command) // return -1; }
- outb(command, EC_SC); + outb(command, ec_cmd_reg); return 0; }
@@ -50,7 +54,7 @@ int send_ec_data(u8 data) int timeout;
timeout = 0x7ff; - while ((inb(EC_SC) & EC_IBF) && --timeout) { // wait for IBF = 0 + while ((inb(ec_cmd_reg) & EC_IBF) && --timeout) { // wait for IBF = 0 udelay(10); if ((timeout & 0xff) == 0) printk(BIOS_SPEW, "."); @@ -61,14 +65,14 @@ int send_ec_data(u8 data) // return -1; }
- outb(data, EC_DATA); + outb(data, ec_data_reg);
return 0; }
int send_ec_data_nowait(u8 data) { - outb(data, EC_DATA); + outb(data, ec_data_reg);
return 0; } @@ -80,7 +84,7 @@ u8 recv_ec_data(void)
timeout = 0x7fff; while (--timeout) { // Wait for OBF = 1 - if (inb(EC_SC) & EC_OBF) { + if (inb(ec_cmd_reg) & EC_OBF) { break; } udelay(10); @@ -92,7 +96,7 @@ u8 recv_ec_data(void) // return -1; }
- data = inb(EC_DATA); + data = inb(ec_data_reg); printk(BIOS_DEBUG, "recv_ec_data: 0x%02x\n", data);
return data; @@ -113,6 +117,18 @@ int ec_write(u8 addr, u8 data) return send_ec_data(data); }
+static void ec_acpi_init(device_t dev) +{ + struct ec_acpi_config *cfg = dev->chip_info; + + if (cfg->cmd_reg) + ec_cmd_reg = cfg->cmd_reg; + + if (cfg->data_reg) + ec_data_reg = cfg->data_reg; +} + struct chip_operations ec_acpi_ops = { CHIP_NAME("ACPI Embedded Controller") + .enable_dev = ec_acpi_init }; diff --git a/src/mainboard/lenovo/x60/devicetree.cb b/src/mainboard/lenovo/x60/devicetree.cb index 2817255..eaad967 100644 --- a/src/mainboard/lenovo/x60/devicetree.cb +++ b/src/mainboard/lenovo/x60/devicetree.cb @@ -87,6 +87,8 @@ chip northbridge/intel/i945 end end chip ec/acpi + register "cmd_reg" = "0x1604" + register "data_reg" = "0x1600" device pnp ff.2 on # dummy io 0x60 = 0x62 io 0x62 = 0x66