Patchwork RFC: Make ec/acpi ports configurable

login
register
about
Submitter Sven Schnelle
Date 2011-03-08 15:53:48
Message ID <87vczt4nhv.fsf@begreifnix.stackframe.org>
Download mbox | patch
Permalink /patch/2755/
State New
Headers show

Comments

Sven Schnelle - 2011-03-08 15:53:48
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

Patch

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