[coreboot] [PATCH 2/2] X60: add support for handling EC events in SMM

Sven Schnelle svens at stackframe.org
Sat Jun 4 19:47:35 CEST 2011


could be used for various things if the OS doesn't provide
ACPI support, or has ACPI disabled. The current patch only
uses this to enable operation of the backlight hotkeys.

As the Thinkpad EC doesn't support EC_QUERY on ports 0x1600/0x1604
and there are no event queue registers in the EC register space,
we're using 0x62/0x66 as EC I/O ports as long as ACPI is disabled.

Signed-off-by: Sven Schnelle <svens at stackframe.org>
---
 src/mainboard/lenovo/x60/devicetree.cb   |    4 +-
 src/mainboard/lenovo/x60/mainboard_smi.c |   89 +++++++++++++++++++++++++++++-
 2 files changed, 90 insertions(+), 3 deletions(-)

diff --git a/src/mainboard/lenovo/x60/devicetree.cb b/src/mainboard/lenovo/x60/devicetree.cb
index b708dce..42a45d1 100644
--- a/src/mainboard/lenovo/x60/devicetree.cb
+++ b/src/mainboard/lenovo/x60/devicetree.cb
@@ -53,13 +53,13 @@ chip northbridge/intel/i945
 			#  1 SMI# (if corresponding ALT_GPI_SMI_EN bit is also set)
 			#  2 SCI (if corresponding GPIO_EN bit is also set)
 			register "gpi13_routing" = "2"
-			register "gpi12_routing" = "2"
+			register "gpi12_routing" = "1"
 			register "gpi8_routing" = "2"
 
 			register "sata_ahci" = "0x0"
 
 			register "gpe0_en" = "0x11000006"
-
+			register "alt_gp_smi_en" = "0x1000"
 			device pci 1b.0 on # Audio Cnotroller
 				subsystemid 0x17aa 0x2010
 			end
diff --git a/src/mainboard/lenovo/x60/mainboard_smi.c b/src/mainboard/lenovo/x60/mainboard_smi.c
index 5e0f6a9..e45c774 100644
--- a/src/mainboard/lenovo/x60/mainboard_smi.c
+++ b/src/mainboard/lenovo/x60/mainboard_smi.c
@@ -24,10 +24,14 @@
 #include <console/console.h>
 #include <cpu/x86/smm.h>
 #include "southbridge/intel/i82801gx/nvs.h"
+#include "southbridge/intel/i82801gx/i82801gx.h"
 #include <ec/acpi/ec.h>
 #include "dock.h"
 #include "smi.h"
 
+#define ACPI_ENABLE 0xe1
+#define ACPI_DISABLE 0x1e
+
 /* The southbridge SMI handler checks whether gnvs has a
  * valid pointer before calling the trap handler
  */
@@ -38,7 +42,6 @@ static void mainboard_smm_init(void)
 	printk(BIOS_DEBUG, "initializing SMI\n");
 	/* Enable 0x1600/0x1600 register pair */
 	ec_set_bit(0x00, 0x05);
-	ec_set_ports(0x1604, 0x1600);
 }
 
 int mainboard_io_trap_handler(int smif)
@@ -76,3 +79,87 @@ int mainboard_io_trap_handler(int smif)
 	return 0;
 }
 
+static void mainboard_smi_brightness_up(void)
+{
+	u8 value;
+
+	if ((value = pci_read_config8(PCI_DEV(0, 2, 1), 0xf4)) < 0xf0)
+		pci_write_config8(PCI_DEV(0, 2, 1), 0xf4, (value + 0x10) | 0xf);
+}
+
+static void mainboard_smi_brightness_down(void)
+{
+	u8 value;
+
+	if ((value = pci_read_config8(PCI_DEV(0, 2, 1), 0xf4)) > 0x10)
+		pci_write_config8(PCI_DEV(0, 2, 1), 0xf4, (value - 0x10) & 0xf0);
+}
+
+static void mainboard_smi_handle_ec_sci(void)
+{
+	u8 status = inb(EC_SC);
+	u8 event;
+
+	if (!(status & EC_SCI_EVT))
+		return;
+
+	event = ec_query();
+	printk(BIOS_DEBUG, "EC event %02x\n", event);
+
+	switch(event) {
+		/* brightness up */
+		case 0x14:
+			mainboard_smi_brightness_up();
+			break;
+		/* brightness down */
+		case 0x15:
+			mainboard_smi_brightness_down();
+			break;
+		default:
+			break;
+	}
+}
+
+void mainboard_smi_gpi(u16 gpi)
+{
+	if (gpi & (1 << 12))
+		mainboard_smi_handle_ec_sci();
+}
+
+int mainboard_apm_cnt(u8 data)
+{
+	u16 pmbase = pci_read_config16(PCI_DEV(0, 0x1f, 0), 0x40) & 0xfffc;
+	u8 tmp;
+
+	printk(BIOS_DEBUG, "%s: pmbase %04X, data %02X\n", __func__, pmbase, data);
+
+	if (!pmbase)
+		return 0;
+
+	switch(data) {
+		case ACPI_ENABLE:
+			/* use 0x1600/0x1604 to prevent races with userspace */
+			ec_set_ports(0x1604, 0x1600);
+			/* route H8SCI to SCI */
+			outw(inw(ALT_GP_SMI_EN) & ~0x1000, pmbase + ALT_GP_SMI_EN);
+			tmp = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xbb);
+			tmp &= ~0x03;
+			tmp |= 0x02;
+			pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xbb, tmp);
+			break;
+		case ACPI_DISABLE:
+			/* we have to use port 0x62/0x66, as 0x1600/0x1604 doesn't
+			   provide a EC query function */
+			ec_set_ports(0x66, 0x62);
+			/* route H8SCI# to SMI */
+			outw(inw(pmbase + ALT_GP_SMI_EN) | 0x1000, pmbase + ALT_GP_SMI_EN);
+			tmp = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xbb);
+			tmp &= ~0x03;
+			tmp |= 0x01;
+			pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xbb, tmp);
+			break;
+		default:
+			break;
+	}
+	return 0;
+}
-- 
1.7.5.3





More information about the coreboot mailing list