[coreboot] New patch to review: 87c40a8 T60: handle EC events in SMM if ACPI is disabled

Sven Schnelle (svens@stackframe.org) gerrit at coreboot.org
Thu Jul 7 15:25:48 CEST 2011


Sven Schnelle (svens at stackframe.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/89

-gerrit

commit 87c40a816d41d4953c093decd8ac137235919226
Author: Sven Schnelle <svens at stackframe.org>
Date:   Thu Jun 23 19:12:25 2011 +0200

    T60: handle EC events in SMM if ACPI is disabled
    
    Change-Id: I6f9e90015cafef3da896453ef8e3588434ae3554
    Signed-off-by: Sven Schnelle <svens at stackframe.org>
---
 src/mainboard/lenovo/t60/acpi/video.asl  |    4 +
 src/mainboard/lenovo/t60/devicetree.cb   |    1 +
 src/mainboard/lenovo/t60/mainboard.c     |    3 +-
 src/mainboard/lenovo/t60/mainboard_smi.c |  119 +++++++++++++++++++++++++++++-
 src/mainboard/lenovo/t60/smi.h           |    2 +
 5 files changed, 126 insertions(+), 3 deletions(-)

diff --git a/src/mainboard/lenovo/t60/acpi/video.asl b/src/mainboard/lenovo/t60/acpi/video.asl
index c2f9dfb..9a458e9 100644
--- a/src/mainboard/lenovo/t60/acpi/video.asl
+++ b/src/mainboard/lenovo/t60/acpi/video.asl
@@ -19,6 +19,8 @@
  * MA 02110-1301 USA
  */
 
+#include "smi.h"
+
 Device (DSPC)
 {
 	Name (_ADR, 0x00020001)
@@ -31,6 +33,7 @@ Device (DSPC)
 
 	Method(BRTD, 0, NotSerialized)
 	{
+		Trap(SMI_BRIGHTNESS_DOWN)
 		Store(BRTC, Local0)
 		if (LGreater (Local0, 15))
 		{
@@ -41,6 +44,7 @@ Device (DSPC)
 
 	Method(BRTU, 0, NotSerialized)
 	{
+		Trap(SMI_BRIGHTNESS_UP)
 		Store (BRTC, Local0)
 		if (LLess(Local0, 0xff))
 		{
diff --git a/src/mainboard/lenovo/t60/devicetree.cb b/src/mainboard/lenovo/t60/devicetree.cb
index 9d7a414..3615e59 100644
--- a/src/mainboard/lenovo/t60/devicetree.cb
+++ b/src/mainboard/lenovo/t60/devicetree.cb
@@ -66,6 +66,7 @@ chip northbridge/intel/i945
 			register "sata_ahci" = "0x0"
 
 			register "gpe0_en" = "0x11000006"
+			register "alt_gp_smi_en" = "0x1000"
 
 			device pci 1b.0 on # Audio Cnotroller
 				subsystemid 0x17aa 0x2010
diff --git a/src/mainboard/lenovo/t60/mainboard.c b/src/mainboard/lenovo/t60/mainboard.c
index 371085b..2b8c5fe 100644
--- a/src/mainboard/lenovo/t60/mainboard.c
+++ b/src/mainboard/lenovo/t60/mainboard.c
@@ -61,7 +61,8 @@ static void mainboard_enable(device_t dev)
 	}
 
 	/* set dock status led */
-	ec_write(0x0c, inb(0x164c) & 8 ? 0x88 : 0x08);
+	ec_write(0x0c, 0x08);
+	ec_write(0x0c, inb(0x164c) & 8 ? 0x89 : 0x09);
 
 	if (get_option(&defaults_loaded, "cmos_defaults_loaded") < 0) {
 		printk(BIOS_INFO, "failed to get cmos_defaults_loaded");
diff --git a/src/mainboard/lenovo/t60/mainboard_smi.c b/src/mainboard/lenovo/t60/mainboard_smi.c
index 30c2420..4a0b506 100644
--- a/src/mainboard/lenovo/t60/mainboard_smi.c
+++ b/src/mainboard/lenovo/t60/mainboard_smi.c
@@ -24,10 +24,12 @@
 #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 LVTMA_BL_MOD_LEVEL 0x7af9 /* ATI Radeon backlight level */
 /* The southbridge SMI handler checks whether gnvs has a
  * valid pointer before calling the trap handler
  */
@@ -38,7 +40,28 @@ 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);
+}
+
+static void mainboard_smi_brightness_down(void)
+{
+	u8 *bar;
+	if ((bar = (u8 *)pci_read_config32(PCI_DEV(1, 0, 0), 0x18))) {
+		printk(BIOS_DEBUG, "bar: %08X, level %02X\n",  (unsigned int)bar, *(bar+LVTMA_BL_MOD_LEVEL));
+		*(bar+LVTMA_BL_MOD_LEVEL) &= 0xf0;
+		if (*(bar+LVTMA_BL_MOD_LEVEL) > 0x10)
+			*(bar+LVTMA_BL_MOD_LEVEL) -= 0x10;
+	}
+}
+
+static void mainboard_smi_brightness_up(void)
+{
+	u8 *bar;
+	if ((bar = (u8 *)pci_read_config32(PCI_DEV(1, 0, 0), 0x18))) {
+		printk(BIOS_DEBUG, "bar: %08X, level %02X\n",  (unsigned int )bar, *(bar+LVTMA_BL_MOD_LEVEL));
+		*(bar+LVTMA_BL_MOD_LEVEL) |= 0x0f;
+		if (*(bar+LVTMA_BL_MOD_LEVEL) < 0xf0)
+			*(bar+LVTMA_BL_MOD_LEVEL) += 0x10;
+	}
 }
 
 int mainboard_io_trap_handler(int smif)
@@ -55,18 +78,29 @@ int mainboard_io_trap_handler(int smif)
 		dlpc_init();
 		if (!dock_connect()) {
 			/* set dock LED to indicate status */
-			ec_write(0x0c, 0x88);
+			ec_write(0x0c, 0x08);
+			ec_write(0x0c, 0x89);
 		} else {
 			/* blink dock LED to indicate failure */
 			ec_write(0x0c, 0xc8);
+			ec_write(0x0c, 0x09);
 		}
 		break;
 
 	case SMI_DOCK_DISCONNECT:
 		dock_disconnect();
+		ec_write(0x0c, 0x09);
 		ec_write(0x0c, 0x08);
 		break;
 
+	case SMI_BRIGHTNESS_UP:
+		mainboard_smi_brightness_up();
+		break;
+
+	case SMI_BRIGHTNESS_DOWN:
+		mainboard_smi_brightness_down();
+		break;
+
 	default:
 		return 0;
 	}
@@ -76,3 +110,84 @@ int mainboard_io_trap_handler(int smif)
 	return 1;
 }
 
+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;
+		/* Fn-F9 Key */
+		case 0x18:
+		/* power loss */
+		case 0x27:
+		/* undock event */
+		case 0x50:
+			mainboard_io_trap_handler(SMI_DOCK_DISCONNECT);
+			break;
+		/* dock event */
+		case 0x37:
+			mainboard_io_trap_handler(SMI_DOCK_CONNECT);
+			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 APM_CNT_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 APM_CNT_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;
+}
+
diff --git a/src/mainboard/lenovo/t60/smi.h b/src/mainboard/lenovo/t60/smi.h
index f89b6bd..f8e8a7c 100644
--- a/src/mainboard/lenovo/t60/smi.h
+++ b/src/mainboard/lenovo/t60/smi.h
@@ -22,5 +22,7 @@
 
 #define SMI_DOCK_CONNECT 0x01
 #define SMI_DOCK_DISCONNECT 0x02
+#define SMI_BRIGHTNESS_UP 0x03
+#define SMI_BRIGHTNESS_DOWN 0x04
 
 #endif




More information about the coreboot mailing list