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(a)stackframe.org>
Date: Tue, 8 Mar 2011 16:43:28 +0100
Subject: [PATCH] ec/acpi: make ACPI register pair configurable
To: coreboot(a)coreboot.org
Cc: svens(a)stackframe.org,
svens(a)stackframe.org
Signed-off-by: Sven Schnelle <svens(a)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(a)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
--
1.7.4.1