igd.asl rewrite

Old igd.asl had inconsistent addresses (between _DOD and actual device)
and ghost devices. Any of those is enough to make brightness on windows
fail and make igd.asl out-of-ACPI-spec. Also old code favoured ridiculous
copying of the same thing 6 times per chipset. Leave only hooking up and
chipset-specific part in chipset directory. Move NVS handling and ACPI-spec
parts to a common file.

Change-Id: I556769e5e28b83e7465e3db689e26c8c0ab44757
Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com>
Reviewed-on: http://review.coreboot.org/7472
Tested-by: build bot (Jenkins)
Reviewed-by: Edward O'Callaghan <edward.ocallaghan@koparo.com>
Reviewed-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
diff --git a/src/northbridge/intel/fsp_sandybridge/Kconfig b/src/northbridge/intel/fsp_sandybridge/Kconfig
index dae2780..21d3f65 100644
--- a/src/northbridge/intel/fsp_sandybridge/Kconfig
+++ b/src/northbridge/intel/fsp_sandybridge/Kconfig
@@ -21,10 +21,12 @@
 config NORTHBRIDGE_INTEL_FSP_SANDYBRIDGE
 	bool
 	select CPU_INTEL_FSP_MODEL_206AX
+	select INTEL_GMA_ACPI
 
 config NORTHBRIDGE_INTEL_FSP_IVYBRIDGE
 	bool
 	select CPU_INTEL_FSP_MODEL_306AX
+	select INTEL_GMA_ACPI
 
 if NORTHBRIDGE_INTEL_FSP_IVYBRIDGE || NORTHBRIDGE_INTEL_FSP_SANDYBRIDGE
 
diff --git a/src/northbridge/intel/fsp_sandybridge/acpi/igd.asl b/src/northbridge/intel/fsp_sandybridge/acpi/igd.asl
index 8ad70d7..df8a389 100644
--- a/src/northbridge/intel/fsp_sandybridge/acpi/igd.asl
+++ b/src/northbridge/intel/fsp_sandybridge/acpi/igd.asl
@@ -22,301 +22,57 @@
 {
 	Name (_ADR, 0x00020000)
 
-	/* Display Output Switching */
-	Method (_DOS, 1)
+	OperationRegion (GFXC, PCI_Config, 0x00, 0x0100)
+	Field (GFXC, DWordAcc, NoLock, Preserve)
 	{
-		/* Windows 2000 and Windows XP call _DOS to enable/disable
-		 * Display Output Switching during init and while a switch
-		 * is already active
-		 */
-		Store (And(Arg0, 7), DSEN)
+		Offset (0x10),
+		BAR0, 64
 	}
 
-	/* We try to support as many i945 systems as possible,
-	 * so keep the number of DIDs flexible.
-	 */
-	Method (_DOD, 0)
+	OperationRegion (GFRG, SystemMemory, And(BAR0, 0xfffffffffffffff0), 0x400000)
+	Field (GFRG, DWordAcc, NoLock, Preserve)
 	{
-		If (LEqual(NDID, 1)) {
-			Name(DOD1, Package() {
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID1), Index(DOD1, 0))
-			Return(DOD1)
-		}
-
-		If (LEqual(NDID, 2)) {
-			Name(DOD2, Package() {
-				0xffffffff,
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID2), Index(DOD2, 0))
-			Store (Or(0x00010000, DID2), Index(DOD2, 1))
-			Return(DOD2)
-		}
-
-		If (LEqual(NDID, 3)) {
-			Name(DOD3, Package() {
-				0xffffffff,
-				0xffffffff,
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID3), Index(DOD3, 0))
-			Store (Or(0x00010000, DID3), Index(DOD3, 1))
-			Store (Or(0x00010000, DID3), Index(DOD3, 2))
-			Return(DOD3)
-		}
-
-		If (LEqual(NDID, 4)) {
-			Name(DOD4, Package() {
-				0xffffffff,
-				0xffffffff,
-				0xffffffff,
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID4), Index(DOD4, 0))
-			Store (Or(0x00010000, DID4), Index(DOD4, 1))
-			Store (Or(0x00010000, DID4), Index(DOD4, 2))
-			Store (Or(0x00010000, DID4), Index(DOD4, 3))
-			Return(DOD4)
-		}
-
-		If (LGreater(NDID, 4)) {
-			Name(DOD5, Package() {
-				0xffffffff,
-				0xffffffff,
-				0xffffffff,
-				0xffffffff,
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID5), Index(DOD5, 0))
-			Store (Or(0x00010000, DID5), Index(DOD5, 1))
-			Store (Or(0x00010000, DID5), Index(DOD5, 2))
-			Store (Or(0x00010000, DID5), Index(DOD5, 3))
-			Store (Or(0x00010000, DID5), Index(DOD5, 4))
-			Return(DOD5)
-		}
-
-		/* Some error happened, but we have to return something */
-		Return (Package() {0x00000400})
+		Offset (0x48254),
+			BCLV, 16,
+		Offset (0xc8250),
+			CR1, 32,
+			CR2, 32
 	}
 
-	Device(DD01)
+	Name (BRIG, Package (0x12)
 	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID1, 0)) {
-				Return (1)
-			} Else {
-				Return (And(0xffff, DID1))
-			}
-		}
+		0x61,
+		0x61,
+		0x2,
+		0x4,
+		0x5,
+		0x7,
+		0x9,
+		0xb,
+		0xd,
+		0x11,
+		0x14,
+		0x17,
+		0x1c,
+		0x20,
+		0x27,
+		0x31,
+		0x41,
+		0x61,
+	})
 
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 1)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 1)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
+	Method (XBCM, 1, NotSerialized)
+	{
+		Store (ShiftLeft (Arg0, 4), BCLV)
+		Store (0x80000000, CR1)
+		Store (0x061a061a, CR2)
 	}
 
-	Device(DD02)
+	Method (XBQC, 0, NotSerialized)
 	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID2, 0)) {
-				Return (2)
-			} Else {
-				Return (And(0xffff, DID2))
-			}
-		}
-
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 2)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 2)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
+		Store (BCLV, Local0)
+		ShiftRight (Local0, 4, Local0)
+		Return (Local0)
 	}
-
-
-	Device(DD03)
-	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID3, 0)) {
-				Return (3)
-			} Else {
-				Return (And(0xffff, DID3))
-			}
-		}
-
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 4)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 4)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
-	}
-
-
-	Device(DD04)
-	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID4, 0)) {
-				Return (4)
-			} Else {
-				Return (And(0xffff, DID4))
-			}
-		}
-
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 8)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 4)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
-	}
-
-
-	Device(DD05)
-	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID5, 0)) {
-				Return (5)
-			} Else {
-				Return (And(0xffff, DID5))
-			}
-		}
-
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 16)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 4)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
-	}
-
+#include <drivers/intel/gma/igd.asl>
 }
diff --git a/src/northbridge/intel/fsp_sandybridge/chip.h b/src/northbridge/intel/fsp_sandybridge/chip.h
index 75d967e..6e823dc 100644
--- a/src/northbridge/intel/fsp_sandybridge/chip.h
+++ b/src/northbridge/intel/fsp_sandybridge/chip.h
@@ -17,6 +17,8 @@
  * Foundation, Inc.
  */
 
+#include <drivers/intel/gma/i915.h>
+
 /*
  * Digital Port Hotplug Enable:
  *  0x04 = Enabled, 2ms short pulse
@@ -38,4 +40,6 @@
 
 	u32 gpu_cpu_backlight;	/* CPU Backlight PWM value */
 	u32 gpu_pch_backlight;	/* PCH Backlight PWM value */
+
+	struct i915_gpu_controller_info gfx;
 };
diff --git a/src/northbridge/intel/fsp_sandybridge/gma.c b/src/northbridge/intel/fsp_sandybridge/gma.c
index e86c478..26f1ae6 100644
--- a/src/northbridge/intel/fsp_sandybridge/gma.c
+++ b/src/northbridge/intel/fsp_sandybridge/gma.c
@@ -63,6 +63,27 @@
 	}
 }
 
+const struct i915_gpu_controller_info *
+intel_gma_get_controller_info(void)
+{
+	device_t dev = dev_find_slot(0, PCI_DEVFN(0x2,0));
+	if (!dev) {
+		return NULL;
+	}
+	struct northbridge_intel_fsp_sandybridge_config *chip = dev->chip_info;
+	return &chip->gfx;
+}
+
+static void gma_ssdt(void)
+{
+	const struct i915_gpu_controller_info *gfx = intel_gma_get_controller_info();
+	if (!gfx) {
+		return;
+	}
+
+	drivers_intel_gma_displays_ssdt_generate(gfx);
+}
+
 static struct pci_operations gma_pci_ops = {
 	.set_subsystem    = gma_set_subsystem,
 };
@@ -71,6 +92,7 @@
 	.read_resources		= pci_dev_read_resources,
 	.set_resources		= pci_dev_set_resources,
 	.enable_resources	= pci_dev_enable_resources,
+	.acpi_fill_ssdt_generator = gma_ssdt,
 	.init			= pci_dev_init,
 	.scan_bus		= 0,
 	.enable			= 0,
diff --git a/src/northbridge/intel/gm45/Kconfig b/src/northbridge/intel/gm45/Kconfig
index add8c4a..9564ea6 100644
--- a/src/northbridge/intel/gm45/Kconfig
+++ b/src/northbridge/intel/gm45/Kconfig
@@ -30,6 +30,7 @@
 	select IOMMU
 	select VGA
 	select INTEL_EDID
+	select INTEL_GMA_ACPI
 
 config BOOTBLOCK_NORTHBRIDGE_INIT
 	string
diff --git a/src/northbridge/intel/gm45/acpi/igd.asl b/src/northbridge/intel/gm45/acpi/igd.asl
index cb99694..696cc2b 100644
--- a/src/northbridge/intel/gm45/acpi/igd.asl
+++ b/src/northbridge/intel/gm45/acpi/igd.asl
@@ -26,10 +26,10 @@
 	Field (GFXC, DWordAcc, NoLock, Preserve)
 	{
 		Offset (0x10),
-			BAR0, 64
+		BAR0, 64
 	}
 
-	OperationRegion (GFRG, SystemMemory, And (BAR0, 0xfffffffffffffff0), 0x400000)
+	OperationRegion (GFRG, SystemMemory, And(BAR0, 0xfffffffffffffff0), 0x400000)
 	Field (GFRG, DWordAcc, NoLock, Preserve)
 	{
 		Offset (0x61250),
@@ -38,399 +38,40 @@
 			BCLM, 16,
 	}
 
-	/* Display Output Switching */
-	Method (_DOS, 1)
+	Name (BRIG, Package (0x12)
 	{
-		/* Windows 2000 and Windows XP call _DOS to enable/disable
-		 * Display Output Switching during init and while a switch
-		 * is already active
-		 */
-		Store (And(Arg0, 7), DSEN)
+		0x61,
+		0x61,
+		0x2,
+		0x4,
+		0x5,
+		0x7,
+		0x9,
+		0xb,
+		0xd,
+		0x11,
+		0x14,
+		0x17,
+		0x1c,
+		0x20,
+		0x27,
+		0x31,
+		0x41,
+		0x61,
+	})
+
+	Method (XBCM, 1, NotSerialized)
+	{
+		Store (ShiftLeft (Arg0, 4), BCLV)
+		Store (0x80000000, CR1)
+		Store (0x0610, BCLM)
 	}
 
-	/* We try to support as many GM45 systems as possible,
-	 * so keep the number of DIDs flexible.
-	 */
-	Method (_DOD, 0)
+	Method (XBQC, 0, NotSerialized)
 	{
-		If (LEqual(NDID, 1)) {
-			Name(DOD1, Package() {
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID1), Index(DOD1, 0))
-			Return(DOD1)
-		}
-
-		If (LEqual(NDID, 2)) {
-			Name(DOD2, Package() {
-				0xffffffff,
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID1), Index(DOD2, 0))
-			Store (Or(0x00010000, DID2), Index(DOD2, 1))
-			Return(DOD2)
-		}
-
-		If (LEqual(NDID, 3)) {
-			Name(DOD3, Package() {
-				0xffffffff,
-				0xffffffff,
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID1), Index(DOD3, 0))
-			Store (Or(0x00010000, DID2), Index(DOD3, 1))
-			Store (Or(0x00010000, DID3), Index(DOD3, 2))
-			Return(DOD3)
-		}
-
-		If (LEqual(NDID, 4)) {
-			Name(DOD4, Package() {
-				0xffffffff,
-				0xffffffff,
-				0xffffffff,
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID1), Index(DOD4, 0))
-			Store (Or(0x00010000, DID2), Index(DOD4, 1))
-			Store (Or(0x00010000, DID3), Index(DOD4, 2))
-			Store (Or(0x00010000, DID4), Index(DOD4, 3))
-			Return(DOD4)
-		}
-
-		If (LGreater(NDID, 4)) {
-			Name(DOD5, Package() {
-				0xffffffff,
-				0xffffffff,
-				0xffffffff,
-				0xffffffff,
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID1), Index(DOD5, 0))
-			Store (Or(0x00010000, DID2), Index(DOD5, 1))
-			Store (Or(0x00010000, DID3), Index(DOD5, 2))
-			Store (Or(0x00010000, DID4), Index(DOD5, 3))
-			Store (Or(0x00010000, DID5), Index(DOD5, 4))
-			Return(DOD5)
-		}
-
-		/* Some error happened, but we have to return something */
-		Return (Package() {0x00000400})
+		Store (BCLV, Local0)
+		ShiftRight (Local0, 4, Local0)
+		Return (Local0)
 	}
-
-	Device(DD01)
-	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID1, 0)) {
-				Return (1)
-			} Else {
-				Return (And(0xffff, DID1))
-			}
-		}
-
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 1)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 1)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
-	}
-
-#ifdef DISPLAY_DEVICE_2_IS_LCD_SCREEN
-	Device (LCD0)
-	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID2, 0)) {
-				Return (2)
-			} Else {
-				Return (And(0xffff, DID2))
-			}
-		}
-
-		Name (BRCT, 0)
-
-		Name (BRIG, Package (0x12)
-		{
-			0x61,
-			0x61,
-			0x2,
-			0x4,
-			0x5,
-			0x7,
-			0x9,
-			0xb,
-			0xd,
-			0x11,
-			0x14,
-			0x17,
-			0x1c,
-			0x20,
-			0x27,
-			0x31,
-			0x41,
-			0x61,
-		})
-
-		Method (_BCL, 0, NotSerialized)
-		{
-			Store (1, BRCT)
-			Return (BRIG)
-		}
-
-		Method (_BCM, 1, NotSerialized)
-		{
-			Store (ShiftLeft (Arg0, 4), ^^BCLV)
-			Store (0x80000000, ^^CR1)
-			Store (0x0610, ^^BCLM)
-		}
-		Method (_BQC, 0, NotSerialized)
-		{
-			Store (^^BCLV, Local0)
-			ShiftRight (Local0, 4, Local0)
-			Return (Local0)
-		}
-
-		Method(BRID, 1, NotSerialized)
-		{
-			Store (Match (BRIG, MEQ, Arg0, MTR, Zero, 2), Local0)
-			If (LEqual (Local0, Ones))
-			{
-				Return (0x11)
-			}
-			Return (Local0)
-		}
-
-		/* Using Notify is the right way. But Windows doesn't handle
-		   it well. So use both method in a way to avoid double action.
-		 */
-		Method (DECB, 0, NotSerialized)
-		{
-			If (BRCT)
-			{
-				Notify (LCD0, 0x87)
-			} Else {
-				Store (BRID (_BQC ()), Local0)
-				If (LNotEqual (Local0, 2))
-				{
-					Decrement (Local0)
-				}
-				_BCM (DerefOf (Index (BRIG, Local0)))
-			}
-		}
-		Method (INCB, 0, NotSerialized)
-		{
-			If (BRCT)
-			{
-				Notify (LCD0, 0x86)
-			} Else {
-				Store (BRID (_BQC ()), Local0)
-				If (LNotEqual (Local0, 0x11))
-				{
-					Increment (Local0)
-				}
-				_BCM (DerefOf (Index (BRIG, Local0)))
-			}
-		}
-	}
-#else
-	Device(DD02)
-	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID2, 0)) {
-				Return (2)
-			} Else {
-				Return (And(0xffff, DID2))
-			}
-		}
-
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 2)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 2)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
-	}
-#endif
-
-	Device(DD03)
-	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID3, 0)) {
-				Return (3)
-			} Else {
-				Return (And(0xffff, DID3))
-			}
-		}
-
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 4)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 4)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
-	}
-
-
-	Device(DD04)
-	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID4, 0)) {
-				Return (4)
-			} Else {
-				Return (And(0xffff, DID4))
-			}
-		}
-
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 8)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 4)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
-	}
-
-
-	Device(DD05)
-	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID5, 0)) {
-				Return (5)
-			} Else {
-				Return (And(0xffff, DID5))
-			}
-		}
-
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 16)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 4)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
-	}
+#include <drivers/intel/gma/igd.asl>
 }
diff --git a/src/northbridge/intel/gm45/gma.c b/src/northbridge/intel/gm45/gma.c
index fab7787..7cc59c8 100644
--- a/src/northbridge/intel/gm45/gma.c
+++ b/src/northbridge/intel/gm45/gma.c
@@ -491,6 +491,27 @@
 	}
 }
 
+const struct i915_gpu_controller_info *
+intel_gma_get_controller_info(void)
+{
+	device_t dev = dev_find_slot(0, PCI_DEVFN(0x2,0));
+	if (!dev) {
+		return NULL;
+	}
+	struct northbridge_intel_gm45_config *chip = dev->chip_info;
+	return &chip->gfx;
+}
+
+static void gma_ssdt(void)
+{
+	const struct i915_gpu_controller_info *gfx = intel_gma_get_controller_info();
+	if (!gfx) {
+		return;
+	}
+
+	drivers_intel_gma_displays_ssdt_generate(gfx);
+}
+
 static struct pci_operations gma_pci_ops = {
 	.set_subsystem = gma_set_subsystem,
 };
@@ -499,6 +520,7 @@
 	.read_resources = pci_dev_read_resources,
 	.set_resources = pci_dev_set_resources,
 	.enable_resources = pci_dev_enable_resources,
+	.acpi_fill_ssdt_generator = gma_ssdt,
 	.init = gma_func0_init,
 	.scan_bus = 0,
 	.enable = 0,
diff --git a/src/northbridge/intel/haswell/Kconfig b/src/northbridge/intel/haswell/Kconfig
index f04b5c3..e51ac3c 100644
--- a/src/northbridge/intel/haswell/Kconfig
+++ b/src/northbridge/intel/haswell/Kconfig
@@ -26,6 +26,7 @@
 	select MMCONF_SUPPORT_DEFAULT
 	select INTEL_DDI
 	select INTEL_DP
+	select INTEL_GMA_ACPI
 
 if NORTHBRIDGE_INTEL_HASWELL
 
diff --git a/src/northbridge/intel/haswell/acpi/igd.asl b/src/northbridge/intel/haswell/acpi/igd.asl
index 8ad70d7..df8a389 100644
--- a/src/northbridge/intel/haswell/acpi/igd.asl
+++ b/src/northbridge/intel/haswell/acpi/igd.asl
@@ -22,301 +22,57 @@
 {
 	Name (_ADR, 0x00020000)
 
-	/* Display Output Switching */
-	Method (_DOS, 1)
+	OperationRegion (GFXC, PCI_Config, 0x00, 0x0100)
+	Field (GFXC, DWordAcc, NoLock, Preserve)
 	{
-		/* Windows 2000 and Windows XP call _DOS to enable/disable
-		 * Display Output Switching during init and while a switch
-		 * is already active
-		 */
-		Store (And(Arg0, 7), DSEN)
+		Offset (0x10),
+		BAR0, 64
 	}
 
-	/* We try to support as many i945 systems as possible,
-	 * so keep the number of DIDs flexible.
-	 */
-	Method (_DOD, 0)
+	OperationRegion (GFRG, SystemMemory, And(BAR0, 0xfffffffffffffff0), 0x400000)
+	Field (GFRG, DWordAcc, NoLock, Preserve)
 	{
-		If (LEqual(NDID, 1)) {
-			Name(DOD1, Package() {
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID1), Index(DOD1, 0))
-			Return(DOD1)
-		}
-
-		If (LEqual(NDID, 2)) {
-			Name(DOD2, Package() {
-				0xffffffff,
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID2), Index(DOD2, 0))
-			Store (Or(0x00010000, DID2), Index(DOD2, 1))
-			Return(DOD2)
-		}
-
-		If (LEqual(NDID, 3)) {
-			Name(DOD3, Package() {
-				0xffffffff,
-				0xffffffff,
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID3), Index(DOD3, 0))
-			Store (Or(0x00010000, DID3), Index(DOD3, 1))
-			Store (Or(0x00010000, DID3), Index(DOD3, 2))
-			Return(DOD3)
-		}
-
-		If (LEqual(NDID, 4)) {
-			Name(DOD4, Package() {
-				0xffffffff,
-				0xffffffff,
-				0xffffffff,
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID4), Index(DOD4, 0))
-			Store (Or(0x00010000, DID4), Index(DOD4, 1))
-			Store (Or(0x00010000, DID4), Index(DOD4, 2))
-			Store (Or(0x00010000, DID4), Index(DOD4, 3))
-			Return(DOD4)
-		}
-
-		If (LGreater(NDID, 4)) {
-			Name(DOD5, Package() {
-				0xffffffff,
-				0xffffffff,
-				0xffffffff,
-				0xffffffff,
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID5), Index(DOD5, 0))
-			Store (Or(0x00010000, DID5), Index(DOD5, 1))
-			Store (Or(0x00010000, DID5), Index(DOD5, 2))
-			Store (Or(0x00010000, DID5), Index(DOD5, 3))
-			Store (Or(0x00010000, DID5), Index(DOD5, 4))
-			Return(DOD5)
-		}
-
-		/* Some error happened, but we have to return something */
-		Return (Package() {0x00000400})
+		Offset (0x48254),
+			BCLV, 16,
+		Offset (0xc8250),
+			CR1, 32,
+			CR2, 32
 	}
 
-	Device(DD01)
+	Name (BRIG, Package (0x12)
 	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID1, 0)) {
-				Return (1)
-			} Else {
-				Return (And(0xffff, DID1))
-			}
-		}
+		0x61,
+		0x61,
+		0x2,
+		0x4,
+		0x5,
+		0x7,
+		0x9,
+		0xb,
+		0xd,
+		0x11,
+		0x14,
+		0x17,
+		0x1c,
+		0x20,
+		0x27,
+		0x31,
+		0x41,
+		0x61,
+	})
 
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 1)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 1)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
+	Method (XBCM, 1, NotSerialized)
+	{
+		Store (ShiftLeft (Arg0, 4), BCLV)
+		Store (0x80000000, CR1)
+		Store (0x061a061a, CR2)
 	}
 
-	Device(DD02)
+	Method (XBQC, 0, NotSerialized)
 	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID2, 0)) {
-				Return (2)
-			} Else {
-				Return (And(0xffff, DID2))
-			}
-		}
-
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 2)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 2)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
+		Store (BCLV, Local0)
+		ShiftRight (Local0, 4, Local0)
+		Return (Local0)
 	}
-
-
-	Device(DD03)
-	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID3, 0)) {
-				Return (3)
-			} Else {
-				Return (And(0xffff, DID3))
-			}
-		}
-
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 4)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 4)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
-	}
-
-
-	Device(DD04)
-	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID4, 0)) {
-				Return (4)
-			} Else {
-				Return (And(0xffff, DID4))
-			}
-		}
-
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 8)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 4)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
-	}
-
-
-	Device(DD05)
-	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID5, 0)) {
-				Return (5)
-			} Else {
-				Return (And(0xffff, DID5))
-			}
-		}
-
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 16)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 4)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
-	}
-
+#include <drivers/intel/gma/igd.asl>
 }
diff --git a/src/northbridge/intel/haswell/chip.h b/src/northbridge/intel/haswell/chip.h
index 801e062..6ae3483 100644
--- a/src/northbridge/intel/haswell/chip.h
+++ b/src/northbridge/intel/haswell/chip.h
@@ -17,6 +17,8 @@
  * Foundation, Inc.
  */
 
+#include <drivers/intel/gma/i915.h>
+
 /*
  * Digital Port Hotplug Enable:
  *  0x04 = Enabled, 2ms short pulse
@@ -38,6 +40,8 @@
 
 	u32 gpu_cpu_backlight;	/* CPU Backlight PWM value */
 	u32 gpu_pch_backlight;	/* PCH Backlight PWM value */
+
+	struct i915_gpu_controller_info gfx;
 };
 
 extern struct chip_operations northbridge_intel_haswell_ops;
diff --git a/src/northbridge/intel/haswell/gma.c b/src/northbridge/intel/haswell/gma.c
index 6faae25..f120670 100644
--- a/src/northbridge/intel/haswell/gma.c
+++ b/src/northbridge/intel/haswell/gma.c
@@ -487,6 +487,27 @@
 	}
 }
 
+const struct i915_gpu_controller_info *
+intel_gma_get_controller_info(void)
+{
+	device_t dev = dev_find_slot(0, PCI_DEVFN(0x2,0));
+	if (!dev) {
+		return NULL;
+	}
+	struct northbridge_intel_haswell_config *chip = dev->chip_info;
+	return &chip->gfx;
+}
+
+static void gma_ssdt(void)
+{
+	const struct i915_gpu_controller_info *gfx = intel_gma_get_controller_info();
+	if (!gfx) {
+		return;
+	}
+
+	drivers_intel_gma_displays_ssdt_generate(gfx);
+}
+
 static struct pci_operations gma_pci_ops = {
 	.set_subsystem    = gma_set_subsystem,
 };
@@ -496,6 +517,7 @@
 	.set_resources		= pci_dev_set_resources,
 	.enable_resources	= pci_dev_enable_resources,
 	.init			= gma_func0_init,
+	.acpi_fill_ssdt_generator = gma_ssdt,
 	.scan_bus		= 0,
 	.enable			= 0,
 	.ops_pci		= &gma_pci_ops,
diff --git a/src/northbridge/intel/i945/Kconfig b/src/northbridge/intel/i945/Kconfig
index a592666..b17dda6 100644
--- a/src/northbridge/intel/i945/Kconfig
+++ b/src/northbridge/intel/i945/Kconfig
@@ -29,6 +29,7 @@
 	select HAVE_DEBUG_RAM_SETUP
 	select LAPIC_MONOTONIC_TIMER
 	select VGA
+	select INTEL_GMA_ACPI
 
 config NORTHBRIDGE_INTEL_SUBTYPE_I945GC
 	def_bool n
diff --git a/src/northbridge/intel/i945/acpi/i945.asl b/src/northbridge/intel/i945/acpi/i945.asl
index 74302c9..2a4eb9f 100644
--- a/src/northbridge/intel/i945/acpi/i945.asl
+++ b/src/northbridge/intel/i945/acpi/i945.asl
@@ -99,9 +99,3 @@
 
 // Integrated graphics 0:2.0
 #include "igd.asl"
-
-Scope (\)
-{
-	// backlight control, display switching, lid
-	#include "acpi/video.asl"
-}
diff --git a/src/northbridge/intel/i945/acpi/igd.asl b/src/northbridge/intel/i945/acpi/igd.asl
index 8ad70d7..fb89e55 100644
--- a/src/northbridge/intel/i945/acpi/igd.asl
+++ b/src/northbridge/intel/i945/acpi/igd.asl
@@ -22,301 +22,52 @@
 {
 	Name (_ADR, 0x00020000)
 
-	/* Display Output Switching */
-	Method (_DOS, 1)
+	Name (BRIG, Package (0x12)
 	{
-		/* Windows 2000 and Windows XP call _DOS to enable/disable
-		 * Display Output Switching during init and while a switch
-		 * is already active
-		 */
-		Store (And(Arg0, 7), DSEN)
+		0xf,
+		0xf,
+		0x0,
+		0x1,
+		0x2,
+		0x3,
+		0x4,
+		0x5,
+		0x6,
+		0x7,
+		0x8,
+		0x9,
+		0xa,
+		0xb,
+		0xc,
+		0xd,
+		0xe,
+		0xf,
+	})
+
+	Method (XBCM, 1, NotSerialized)
+	{
+		Store (Or(ShiftLeft (Arg0, 4), 0xf), ^^DSPC.BRTC)
+#ifdef SMI_SAVE_CMOS
+		Trap(SMI_SAVE_CMOS)
+#endif
 	}
 
-	/* We try to support as many i945 systems as possible,
-	 * so keep the number of DIDs flexible.
-	 */
-	Method (_DOD, 0)
+	Method (XBQC, 0, NotSerialized)
 	{
-		If (LEqual(NDID, 1)) {
-			Name(DOD1, Package() {
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID1), Index(DOD1, 0))
-			Return(DOD1)
-		}
-
-		If (LEqual(NDID, 2)) {
-			Name(DOD2, Package() {
-				0xffffffff,
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID2), Index(DOD2, 0))
-			Store (Or(0x00010000, DID2), Index(DOD2, 1))
-			Return(DOD2)
-		}
-
-		If (LEqual(NDID, 3)) {
-			Name(DOD3, Package() {
-				0xffffffff,
-				0xffffffff,
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID3), Index(DOD3, 0))
-			Store (Or(0x00010000, DID3), Index(DOD3, 1))
-			Store (Or(0x00010000, DID3), Index(DOD3, 2))
-			Return(DOD3)
-		}
-
-		If (LEqual(NDID, 4)) {
-			Name(DOD4, Package() {
-				0xffffffff,
-				0xffffffff,
-				0xffffffff,
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID4), Index(DOD4, 0))
-			Store (Or(0x00010000, DID4), Index(DOD4, 1))
-			Store (Or(0x00010000, DID4), Index(DOD4, 2))
-			Store (Or(0x00010000, DID4), Index(DOD4, 3))
-			Return(DOD4)
-		}
-
-		If (LGreater(NDID, 4)) {
-			Name(DOD5, Package() {
-				0xffffffff,
-				0xffffffff,
-				0xffffffff,
-				0xffffffff,
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID5), Index(DOD5, 0))
-			Store (Or(0x00010000, DID5), Index(DOD5, 1))
-			Store (Or(0x00010000, DID5), Index(DOD5, 2))
-			Store (Or(0x00010000, DID5), Index(DOD5, 3))
-			Store (Or(0x00010000, DID5), Index(DOD5, 4))
-			Return(DOD5)
-		}
-
-		/* Some error happened, but we have to return something */
-		Return (Package() {0x00000400})
+		Store (^^DSPC.BRTC, Local0)
+		ShiftRight (Local0, 4, Local0)
+		Return (Local0)
 	}
-
-	Device(DD01)
-	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID1, 0)) {
-				Return (1)
-			} Else {
-				Return (And(0xffff, DID1))
-			}
-		}
-
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 1)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 1)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
-	}
-
-	Device(DD02)
-	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID2, 0)) {
-				Return (2)
-			} Else {
-				Return (And(0xffff, DID2))
-			}
-		}
-
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 2)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 2)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
-	}
-
-
-	Device(DD03)
-	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID3, 0)) {
-				Return (3)
-			} Else {
-				Return (And(0xffff, DID3))
-			}
-		}
-
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 4)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 4)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
-	}
-
-
-	Device(DD04)
-	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID4, 0)) {
-				Return (4)
-			} Else {
-				Return (And(0xffff, DID4))
-			}
-		}
-
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 8)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 4)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
-	}
-
-
-	Device(DD05)
-	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID5, 0)) {
-				Return (5)
-			} Else {
-				Return (And(0xffff, DID5))
-			}
-		}
-
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 16)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 4)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
-	}
-
+#include <drivers/intel/gma/igd.asl>
 }
+
+Device (DSPC)
+{
+	Name (_ADR, 0x00020001)
+	OperationRegion (DSPC, PCI_Config, 0x00, 0x100)
+	Field (DSPC, ByteAcc, NoLock, Preserve)
+	{
+		Offset (0xf4),
+		       BRTC, 8
+	}
+}
\ No newline at end of file
diff --git a/src/northbridge/intel/i945/chip.h b/src/northbridge/intel/i945/chip.h
index 9e25ecc..5706086 100644
--- a/src/northbridge/intel/i945/chip.h
+++ b/src/northbridge/intel/i945/chip.h
@@ -1,6 +1,9 @@
+#include <drivers/intel/gma/i915.h>
+
 struct northbridge_intel_i945_config {
 	u32 gpu_hotplug;
 	u32 gpu_backlight;
 	int gpu_lvds_use_spread_spectrum_clock;
 	int gpu_lvds_is_dual_channel;
+	struct i915_gpu_controller_info gfx;
 };
diff --git a/src/northbridge/intel/i945/gma.c b/src/northbridge/intel/i945/gma.c
index ebc2f1c..28f611f 100644
--- a/src/northbridge/intel/i945/gma.c
+++ b/src/northbridge/intel/i945/gma.c
@@ -488,6 +488,27 @@
 	}
 }
 
+const struct i915_gpu_controller_info *
+intel_gma_get_controller_info(void)
+{
+	device_t dev = dev_find_slot(0, PCI_DEVFN(0x2,0));
+	if (!dev) {
+		return NULL;
+	}
+	struct northbridge_intel_i945_config *chip = dev->chip_info;
+	return &chip->gfx;
+}
+
+static void gma_ssdt(void)
+{
+	const struct i915_gpu_controller_info *gfx = intel_gma_get_controller_info();
+	if (!gfx) {
+		return;
+	}
+
+	drivers_intel_gma_displays_ssdt_generate(gfx);
+}
+
 static struct pci_operations gma_pci_ops = {
 	.set_subsystem    = gma_set_subsystem,
 };
@@ -497,6 +518,7 @@
 	.set_resources		= pci_dev_set_resources,
 	.enable_resources	= pci_dev_enable_resources,
 	.init			= gma_func0_init,
+	.acpi_fill_ssdt_generator = gma_ssdt,
 	.scan_bus		= 0,
 	.enable			= 0,
 	.disable		= gma_func0_disable,
diff --git a/src/northbridge/intel/nehalem/Kconfig b/src/northbridge/intel/nehalem/Kconfig
index 6646bb1..17c94b6 100644
--- a/src/northbridge/intel/nehalem/Kconfig
+++ b/src/northbridge/intel/nehalem/Kconfig
@@ -25,6 +25,7 @@
 	select VGA
 	select INTEL_EDID
 	select TSC_MONOTONIC_TIMER
+	select INTEL_GMA_ACPI
 
 if NORTHBRIDGE_INTEL_NEHALEM
 
diff --git a/src/northbridge/intel/nehalem/acpi/igd.asl b/src/northbridge/intel/nehalem/acpi/igd.asl
index 6c9959d..df8a389 100644
--- a/src/northbridge/intel/nehalem/acpi/igd.asl
+++ b/src/northbridge/intel/nehalem/acpi/igd.asl
@@ -26,10 +26,10 @@
 	Field (GFXC, DWordAcc, NoLock, Preserve)
 	{
 		Offset (0x10),
-			BAR0, 64
+		BAR0, 64
 	}
 
-	OperationRegion (GFRG, SystemMemory, And (BAR0, 0xfffffffffffffff0), 0x400000)
+	OperationRegion (GFRG, SystemMemory, And(BAR0, 0xfffffffffffffff0), 0x400000)
 	Field (GFRG, DWordAcc, NoLock, Preserve)
 	{
 		Offset (0x48254),
@@ -39,391 +39,40 @@
 			CR2, 32
 	}
 
-	/* Display Output Switching */
-	Method (_DOS, 1)
+	Name (BRIG, Package (0x12)
 	{
-		/* Windows 2000 and Windows XP call _DOS to enable/disable
-		 * Display Output Switching during init and while a switch
-		 * is already active
-		 */
-		Store (And(Arg0, 7), DSEN)
+		0x61,
+		0x61,
+		0x2,
+		0x4,
+		0x5,
+		0x7,
+		0x9,
+		0xb,
+		0xd,
+		0x11,
+		0x14,
+		0x17,
+		0x1c,
+		0x20,
+		0x27,
+		0x31,
+		0x41,
+		0x61,
+	})
+
+	Method (XBCM, 1, NotSerialized)
+	{
+		Store (ShiftLeft (Arg0, 4), BCLV)
+		Store (0x80000000, CR1)
+		Store (0x061a061a, CR2)
 	}
 
-	/* We try to support as many i945 systems as possible,
-	 * so keep the number of DIDs flexible.
-	 */
-	Method (_DOD, 0)
+	Method (XBQC, 0, NotSerialized)
 	{
-		If (LEqual(NDID, 1)) {
-			Name(DOD1, Package() {
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID1), Index(DOD1, 0))
-			Return(DOD1)
-		}
-
-		If (LEqual(NDID, 2)) {
-			Name(DOD2, Package() {
-				0xffffffff,
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID2), Index(DOD2, 0))
-			Store (Or(0x00010000, DID2), Index(DOD2, 1))
-			Return(DOD2)
-		}
-
-		If (LEqual(NDID, 3)) {
-			Name(DOD3, Package() {
-				0xffffffff,
-				0xffffffff,
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID3), Index(DOD3, 0))
-			Store (Or(0x00010000, DID3), Index(DOD3, 1))
-			Store (Or(0x00010000, DID3), Index(DOD3, 2))
-			Return(DOD3)
-		}
-
-		If (LEqual(NDID, 4)) {
-			Name(DOD4, Package() {
-				0xffffffff,
-				0xffffffff,
-				0xffffffff,
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID4), Index(DOD4, 0))
-			Store (Or(0x00010000, DID4), Index(DOD4, 1))
-			Store (Or(0x00010000, DID4), Index(DOD4, 2))
-			Store (Or(0x00010000, DID4), Index(DOD4, 3))
-			Return(DOD4)
-		}
-
-		If (LGreater(NDID, 4)) {
-			Name(DOD5, Package() {
-				0xffffffff,
-				0xffffffff,
-				0xffffffff,
-				0xffffffff,
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID5), Index(DOD5, 0))
-			Store (Or(0x00010000, DID5), Index(DOD5, 1))
-			Store (Or(0x00010000, DID5), Index(DOD5, 2))
-			Store (Or(0x00010000, DID5), Index(DOD5, 3))
-			Store (Or(0x00010000, DID5), Index(DOD5, 4))
-			Return(DOD5)
-		}
-
-		/* Some error happened, but we have to return something */
-		Return (Package() {0x00000400})
+		Store (BCLV, Local0)
+		ShiftRight (Local0, 4, Local0)
+		Return (Local0)
 	}
-
-	Device(DD01)
-	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID1, 0)) {
-				Return (1)
-			} Else {
-				Return (And(0xffff, DID1))
-			}
-		}
-
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 1)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 1)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
-	}
-
-	Device(DD02)
-	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID2, 0)) {
-				Return (2)
-			} Else {
-				Return (And(0xffff, DID2))
-			}
-		}
-
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 2)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 2)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
-	}
-
-
-	Device(DD03)
-	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID3, 0)) {
-				Return (3)
-			} Else {
-				Return (And(0xffff, DID3))
-			}
-		}
-
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 4)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 4)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
-	}
-
-
-	Device(DD04)
-	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID4, 0)) {
-				Return (4)
-			} Else {
-				Return (And(0xffff, DID4))
-			}
-		}
-
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 8)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 4)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
-	}
-
-
-	Device(DD05)
-	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID5, 0)) {
-				Return (5)
-			} Else {
-				Return (And(0xffff, DID5))
-			}
-		}
-
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 16)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 4)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
-	}
-
-#ifdef HAVE_LCD_SCREEN
-	Device (LCD0)
-	{
-		Name (_ADR, 0x0400)
-		Name (BRCT, 0)
-
-		Name (BRIG, Package (0x12)
-		{
-			0x61,
-			0x61,
-			0x2,
-			0x4,
-			0x5,
-			0x7,
-			0x9,
-			0xb,
-			0xd,
-			0x11,
-			0x14,
-			0x17,
-			0x1c,
-			0x20,
-			0x27,
-			0x31,
-			0x41,
-			0x61,
-		})
-
-		Method (_BCL, 0, NotSerialized)
-		{
-			Store (1, BRCT)
-			Return (BRIG)
-		}
-
-		Method (_BCM, 1, NotSerialized)
-		{
-			Store (ShiftLeft (Arg0, 4), ^^BCLV)
-			Store (0x80000000, ^^CR1)
-			Store (0x061a061a, ^^CR2)
-		}
-		Method (_BQC, 0, NotSerialized)
-		{
-			Store (^^BCLV, Local0)
-			ShiftRight (Local0, 4, Local0)
-			Return (Local0)
-		}
-
-		Method(BRID, 1, NotSerialized)
-		{
-			Store (Match (BRIG, MEQ, Arg0, MTR, Zero, 2), Local0)
-			If (LEqual (Local0, Ones))
-			{
-				Return (0x11)
-			}
-			Return (Local0)
-		}
-
-		/* Using Notify is the right way. But Windows doesn't handle
-		   it well. So use both method in a way to avoid double action.
-		 */
-		Method (DECB, 0, NotSerialized)
-		{
-			If (BRCT)
-			{
-				Notify (LCD0, 0x87)
-			} Else {
-				Store (BRID (_BQC ()), Local0)
-				If (LNotEqual (Local0, 2))
-				{
-					Decrement (Local0)
-				}
-				_BCM (DerefOf (Index (BRIG, Local0)))
-			}
-		}
-		Method (INCB, 0, NotSerialized)
-		{
-			If (BRCT)
-			{
-				Notify (LCD0, 0x86)
-			} Else {
-				Store (BRID (_BQC ()), Local0)
-				If (LNotEqual (Local0, 0x11))
-				{
-					Increment (Local0)
-				}
-				_BCM (DerefOf (Index (BRIG, Local0)))
-			}
-		}
-	}
-#endif
+#include <drivers/intel/gma/igd.asl>
 }
diff --git a/src/northbridge/intel/nehalem/gma.c b/src/northbridge/intel/nehalem/gma.c
index 2c1332c..d4217de 100644
--- a/src/northbridge/intel/nehalem/gma.c
+++ b/src/northbridge/intel/nehalem/gma.c
@@ -1071,6 +1071,27 @@
 	res->size = (resource_t) 0x10000000;
 }
 
+const struct i915_gpu_controller_info *
+intel_gma_get_controller_info(void)
+{
+	device_t dev = dev_find_slot(0, PCI_DEVFN(0x2,0));
+	if (!dev) {
+		return NULL;
+	}
+	struct northbridge_intel_nehalem_config *chip = dev->chip_info;
+	return &chip->gfx;
+}
+
+static void gma_ssdt(void)
+{
+	const struct i915_gpu_controller_info *gfx = intel_gma_get_controller_info();
+	if (!gfx) {
+		return;
+	}
+
+	drivers_intel_gma_displays_ssdt_generate(gfx);
+}
+
 static struct pci_operations gma_pci_ops = {
 	.set_subsystem = gma_set_subsystem,
 };
@@ -1079,6 +1100,7 @@
 	.read_resources = gma_read_resources,
 	.set_resources = pci_dev_set_resources,
 	.enable_resources = pci_dev_enable_resources,
+	.acpi_fill_ssdt_generator = gma_ssdt,
 	.init = gma_func0_init,
 	.scan_bus = 0,
 	.enable = 0,
diff --git a/src/northbridge/intel/sandybridge/Kconfig b/src/northbridge/intel/sandybridge/Kconfig
index e306642..7eb6948 100644
--- a/src/northbridge/intel/sandybridge/Kconfig
+++ b/src/northbridge/intel/sandybridge/Kconfig
@@ -23,6 +23,7 @@
 	select MMCONF_SUPPORT
 	select MMCONF_SUPPORT_DEFAULT
 	select CPU_INTEL_MODEL_206AX
+	select INTEL_GMA_ACPI
 
 config NORTHBRIDGE_INTEL_SANDYBRIDGE_NATIVE
 	bool
@@ -31,6 +32,7 @@
 	select MMCONF_SUPPORT_DEFAULT
 	select CPU_INTEL_MODEL_206AX
 	select HAVE_DEBUG_RAM_SETUP
+	select INTEL_GMA_ACPI
 
 config NORTHBRIDGE_INTEL_IVYBRIDGE
 	bool
@@ -38,6 +40,7 @@
 	select MMCONF_SUPPORT
 	select MMCONF_SUPPORT_DEFAULT
 	select CPU_INTEL_MODEL_306AX
+	select INTEL_GMA_ACPI
 
 config NORTHBRIDGE_INTEL_IVYBRIDGE_NATIVE
 	bool
@@ -46,6 +49,7 @@
 	select MMCONF_SUPPORT_DEFAULT
 	select CPU_INTEL_MODEL_306AX
 	select HAVE_DEBUG_RAM_SETUP
+	select INTEL_GMA_ACPI
 
 if NORTHBRIDGE_INTEL_SANDYBRIDGE || NORTHBRIDGE_INTEL_IVYBRIDGE || NORTHBRIDGE_INTEL_IVYBRIDGE_NATIVE || NORTHBRIDGE_INTEL_SANDYBRIDGE_NATIVE
 
diff --git a/src/northbridge/intel/sandybridge/acpi/igd.asl b/src/northbridge/intel/sandybridge/acpi/igd.asl
index 6c9959d..6b02765 100644
--- a/src/northbridge/intel/sandybridge/acpi/igd.asl
+++ b/src/northbridge/intel/sandybridge/acpi/igd.asl
@@ -39,391 +39,40 @@
 			CR2, 32
 	}
 
-	/* Display Output Switching */
-	Method (_DOS, 1)
+	Name (BRIG, Package (0x12)
 	{
-		/* Windows 2000 and Windows XP call _DOS to enable/disable
-		 * Display Output Switching during init and while a switch
-		 * is already active
-		 */
-		Store (And(Arg0, 7), DSEN)
+		0x61,
+		0x61,
+		0x2,
+		0x4,
+		0x5,
+		0x7,
+		0x9,
+		0xb,
+		0xd,
+		0x11,
+		0x14,
+		0x17,
+		0x1c,
+		0x20,
+		0x27,
+		0x31,
+		0x41,
+		0x61,
+	})
+
+	Method (XBCM, 1, NotSerialized)
+	{
+		Store (ShiftLeft (Arg0, 4), BCLV)
+		Store (0x80000000, CR1)
+		Store (0x061a061a, CR2)
 	}
 
-	/* We try to support as many i945 systems as possible,
-	 * so keep the number of DIDs flexible.
-	 */
-	Method (_DOD, 0)
+	Method (XBQC, 0, NotSerialized)
 	{
-		If (LEqual(NDID, 1)) {
-			Name(DOD1, Package() {
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID1), Index(DOD1, 0))
-			Return(DOD1)
-		}
-
-		If (LEqual(NDID, 2)) {
-			Name(DOD2, Package() {
-				0xffffffff,
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID2), Index(DOD2, 0))
-			Store (Or(0x00010000, DID2), Index(DOD2, 1))
-			Return(DOD2)
-		}
-
-		If (LEqual(NDID, 3)) {
-			Name(DOD3, Package() {
-				0xffffffff,
-				0xffffffff,
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID3), Index(DOD3, 0))
-			Store (Or(0x00010000, DID3), Index(DOD3, 1))
-			Store (Or(0x00010000, DID3), Index(DOD3, 2))
-			Return(DOD3)
-		}
-
-		If (LEqual(NDID, 4)) {
-			Name(DOD4, Package() {
-				0xffffffff,
-				0xffffffff,
-				0xffffffff,
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID4), Index(DOD4, 0))
-			Store (Or(0x00010000, DID4), Index(DOD4, 1))
-			Store (Or(0x00010000, DID4), Index(DOD4, 2))
-			Store (Or(0x00010000, DID4), Index(DOD4, 3))
-			Return(DOD4)
-		}
-
-		If (LGreater(NDID, 4)) {
-			Name(DOD5, Package() {
-				0xffffffff,
-				0xffffffff,
-				0xffffffff,
-				0xffffffff,
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID5), Index(DOD5, 0))
-			Store (Or(0x00010000, DID5), Index(DOD5, 1))
-			Store (Or(0x00010000, DID5), Index(DOD5, 2))
-			Store (Or(0x00010000, DID5), Index(DOD5, 3))
-			Store (Or(0x00010000, DID5), Index(DOD5, 4))
-			Return(DOD5)
-		}
-
-		/* Some error happened, but we have to return something */
-		Return (Package() {0x00000400})
+		Store (BCLV, Local0)
+		ShiftRight (Local0, 4, Local0)
+		Return (Local0)
 	}
-
-	Device(DD01)
-	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID1, 0)) {
-				Return (1)
-			} Else {
-				Return (And(0xffff, DID1))
-			}
-		}
-
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 1)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 1)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
-	}
-
-	Device(DD02)
-	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID2, 0)) {
-				Return (2)
-			} Else {
-				Return (And(0xffff, DID2))
-			}
-		}
-
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 2)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 2)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
-	}
-
-
-	Device(DD03)
-	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID3, 0)) {
-				Return (3)
-			} Else {
-				Return (And(0xffff, DID3))
-			}
-		}
-
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 4)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 4)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
-	}
-
-
-	Device(DD04)
-	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID4, 0)) {
-				Return (4)
-			} Else {
-				Return (And(0xffff, DID4))
-			}
-		}
-
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 8)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 4)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
-	}
-
-
-	Device(DD05)
-	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID5, 0)) {
-				Return (5)
-			} Else {
-				Return (And(0xffff, DID5))
-			}
-		}
-
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 16)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 4)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
-	}
-
-#ifdef HAVE_LCD_SCREEN
-	Device (LCD0)
-	{
-		Name (_ADR, 0x0400)
-		Name (BRCT, 0)
-
-		Name (BRIG, Package (0x12)
-		{
-			0x61,
-			0x61,
-			0x2,
-			0x4,
-			0x5,
-			0x7,
-			0x9,
-			0xb,
-			0xd,
-			0x11,
-			0x14,
-			0x17,
-			0x1c,
-			0x20,
-			0x27,
-			0x31,
-			0x41,
-			0x61,
-		})
-
-		Method (_BCL, 0, NotSerialized)
-		{
-			Store (1, BRCT)
-			Return (BRIG)
-		}
-
-		Method (_BCM, 1, NotSerialized)
-		{
-			Store (ShiftLeft (Arg0, 4), ^^BCLV)
-			Store (0x80000000, ^^CR1)
-			Store (0x061a061a, ^^CR2)
-		}
-		Method (_BQC, 0, NotSerialized)
-		{
-			Store (^^BCLV, Local0)
-			ShiftRight (Local0, 4, Local0)
-			Return (Local0)
-		}
-
-		Method(BRID, 1, NotSerialized)
-		{
-			Store (Match (BRIG, MEQ, Arg0, MTR, Zero, 2), Local0)
-			If (LEqual (Local0, Ones))
-			{
-				Return (0x11)
-			}
-			Return (Local0)
-		}
-
-		/* Using Notify is the right way. But Windows doesn't handle
-		   it well. So use both method in a way to avoid double action.
-		 */
-		Method (DECB, 0, NotSerialized)
-		{
-			If (BRCT)
-			{
-				Notify (LCD0, 0x87)
-			} Else {
-				Store (BRID (_BQC ()), Local0)
-				If (LNotEqual (Local0, 2))
-				{
-					Decrement (Local0)
-				}
-				_BCM (DerefOf (Index (BRIG, Local0)))
-			}
-		}
-		Method (INCB, 0, NotSerialized)
-		{
-			If (BRCT)
-			{
-				Notify (LCD0, 0x86)
-			} Else {
-				Store (BRID (_BQC ()), Local0)
-				If (LNotEqual (Local0, 0x11))
-				{
-					Increment (Local0)
-				}
-				_BCM (DerefOf (Index (BRIG, Local0)))
-			}
-		}
-	}
-#endif
+#include <drivers/intel/gma/igd.asl>
 }
diff --git a/src/northbridge/intel/sandybridge/gma.c b/src/northbridge/intel/sandybridge/gma.c
index 7ff0e65..d7ad8fe 100644
--- a/src/northbridge/intel/sandybridge/gma.c
+++ b/src/northbridge/intel/sandybridge/gma.c
@@ -613,6 +613,27 @@
 	}
 }
 
+const struct i915_gpu_controller_info *
+intel_gma_get_controller_info(void)
+{
+	device_t dev = dev_find_slot(0, PCI_DEVFN(0x2,0));
+	if (!dev) {
+		return NULL;
+	}
+	struct northbridge_intel_sandybridge_config *chip = dev->chip_info;
+	return &chip->gfx;
+}
+
+static void gma_ssdt(void)
+{
+	const struct i915_gpu_controller_info *gfx = intel_gma_get_controller_info();
+	if (!gfx) {
+		return;
+	}
+
+	drivers_intel_gma_displays_ssdt_generate(gfx);
+}
+
 static struct pci_operations gma_pci_ops = {
 	.set_subsystem    = gma_set_subsystem,
 };
@@ -621,6 +642,7 @@
 	.read_resources		= pci_dev_read_resources,
 	.set_resources		= pci_dev_set_resources,
 	.enable_resources	= pci_dev_enable_resources,
+	.acpi_fill_ssdt_generator = gma_ssdt,
 	.init			= gma_func0_init,
 	.scan_bus		= 0,
 	.enable			= 0,
diff --git a/src/northbridge/intel/sch/Kconfig b/src/northbridge/intel/sch/Kconfig
index 548416e..cf96232 100644
--- a/src/northbridge/intel/sch/Kconfig
+++ b/src/northbridge/intel/sch/Kconfig
@@ -21,6 +21,7 @@
 	bool
 	select MMCONF_SUPPORT
 	select LATE_CBMEM_INIT
+	select INTEL_GMA_ACPI
 
 if NORTHBRIDGE_INTEL_SCH
 
diff --git a/src/northbridge/intel/sch/acpi/igd.asl b/src/northbridge/intel/sch/acpi/igd.asl
index 8ad70d7..696cc2b 100644
--- a/src/northbridge/intel/sch/acpi/igd.asl
+++ b/src/northbridge/intel/sch/acpi/igd.asl
@@ -22,301 +22,56 @@
 {
 	Name (_ADR, 0x00020000)
 
-	/* Display Output Switching */
-	Method (_DOS, 1)
+	OperationRegion (GFXC, PCI_Config, 0x00, 0x0100)
+	Field (GFXC, DWordAcc, NoLock, Preserve)
 	{
-		/* Windows 2000 and Windows XP call _DOS to enable/disable
-		 * Display Output Switching during init and while a switch
-		 * is already active
-		 */
-		Store (And(Arg0, 7), DSEN)
+		Offset (0x10),
+		BAR0, 64
 	}
 
-	/* We try to support as many i945 systems as possible,
-	 * so keep the number of DIDs flexible.
-	 */
-	Method (_DOD, 0)
+	OperationRegion (GFRG, SystemMemory, And(BAR0, 0xfffffffffffffff0), 0x400000)
+	Field (GFRG, DWordAcc, NoLock, Preserve)
 	{
-		If (LEqual(NDID, 1)) {
-			Name(DOD1, Package() {
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID1), Index(DOD1, 0))
-			Return(DOD1)
-		}
-
-		If (LEqual(NDID, 2)) {
-			Name(DOD2, Package() {
-				0xffffffff,
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID2), Index(DOD2, 0))
-			Store (Or(0x00010000, DID2), Index(DOD2, 1))
-			Return(DOD2)
-		}
-
-		If (LEqual(NDID, 3)) {
-			Name(DOD3, Package() {
-				0xffffffff,
-				0xffffffff,
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID3), Index(DOD3, 0))
-			Store (Or(0x00010000, DID3), Index(DOD3, 1))
-			Store (Or(0x00010000, DID3), Index(DOD3, 2))
-			Return(DOD3)
-		}
-
-		If (LEqual(NDID, 4)) {
-			Name(DOD4, Package() {
-				0xffffffff,
-				0xffffffff,
-				0xffffffff,
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID4), Index(DOD4, 0))
-			Store (Or(0x00010000, DID4), Index(DOD4, 1))
-			Store (Or(0x00010000, DID4), Index(DOD4, 2))
-			Store (Or(0x00010000, DID4), Index(DOD4, 3))
-			Return(DOD4)
-		}
-
-		If (LGreater(NDID, 4)) {
-			Name(DOD5, Package() {
-				0xffffffff,
-				0xffffffff,
-				0xffffffff,
-				0xffffffff,
-				0xffffffff
-			})
-			Store (Or(0x00010000, DID5), Index(DOD5, 0))
-			Store (Or(0x00010000, DID5), Index(DOD5, 1))
-			Store (Or(0x00010000, DID5), Index(DOD5, 2))
-			Store (Or(0x00010000, DID5), Index(DOD5, 3))
-			Store (Or(0x00010000, DID5), Index(DOD5, 4))
-			Return(DOD5)
-		}
-
-		/* Some error happened, but we have to return something */
-		Return (Package() {0x00000400})
+		Offset (0x61250),
+			CR1, 32,
+			BCLV, 16,
+			BCLM, 16,
 	}
 
-	Device(DD01)
+	Name (BRIG, Package (0x12)
 	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID1, 0)) {
-				Return (1)
-			} Else {
-				Return (And(0xffff, DID1))
-			}
-		}
+		0x61,
+		0x61,
+		0x2,
+		0x4,
+		0x5,
+		0x7,
+		0x9,
+		0xb,
+		0xd,
+		0x11,
+		0x14,
+		0x17,
+		0x1c,
+		0x20,
+		0x27,
+		0x31,
+		0x41,
+		0x61,
+	})
 
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 1)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 1)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
+	Method (XBCM, 1, NotSerialized)
+	{
+		Store (ShiftLeft (Arg0, 4), BCLV)
+		Store (0x80000000, CR1)
+		Store (0x0610, BCLM)
 	}
 
-	Device(DD02)
+	Method (XBQC, 0, NotSerialized)
 	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID2, 0)) {
-				Return (2)
-			} Else {
-				Return (And(0xffff, DID2))
-			}
-		}
-
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 2)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 2)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
+		Store (BCLV, Local0)
+		ShiftRight (Local0, 4, Local0)
+		Return (Local0)
 	}
-
-
-	Device(DD03)
-	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID3, 0)) {
-				Return (3)
-			} Else {
-				Return (And(0xffff, DID3))
-			}
-		}
-
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 4)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 4)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
-	}
-
-
-	Device(DD04)
-	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID4, 0)) {
-				Return (4)
-			} Else {
-				Return (And(0xffff, DID4))
-			}
-		}
-
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 8)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 4)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
-	}
-
-
-	Device(DD05)
-	{
-		/* Device Unique ID */
-		Method(_ADR, 0, Serialized)
-		{
-			If(LEqual(DID5, 0)) {
-				Return (5)
-			} Else {
-				Return (And(0xffff, DID5))
-			}
-		}
-
-		/* Device Current Status */
-		Method(_DCS, 0)
-		{
-			TRAP(1)
-			If (And(CSTE, 16)) {
-				Return (0x1f)
-			}
-			Return(0x1d)
-		}
-
-		/* Query Device Graphics State */
-		Method(_DGS, 0)
-		{
-			If (And(NSTE, 4)) {
-				Return(1)
-			}
-			Return(0)
-		}
-
-		/* Device Set State */
-		Method(_DSS, 1)
-		{
-			/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
-			 * display switch was completed
-			 */
-			If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
-				Store (NSTE, CSTE)
-			}
-		}
-	}
-
+#include <drivers/intel/gma/igd.asl>
 }
diff --git a/src/northbridge/intel/sch/acpi/sch.asl b/src/northbridge/intel/sch/acpi/sch.asl
index 42b9f97..162232f 100644
--- a/src/northbridge/intel/sch/acpi/sch.asl
+++ b/src/northbridge/intel/sch/acpi/sch.asl
@@ -79,9 +79,3 @@
 
 // Integrated graphics 0:2.0
 #include "igd.asl"
-
-Scope (\)
-{
-	// backlight control, display switching, lid
-	#include "acpi/video.asl"
-}
diff --git a/src/northbridge/intel/sch/chip.h b/src/northbridge/intel/sch/chip.h
new file mode 100644
index 0000000..33df6c5
--- /dev/null
+++ b/src/northbridge/intel/sch/chip.h
@@ -0,0 +1,30 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2008 coresystems GmbH
+ *               2012 secunet Security Networks AG
+ *
+ * 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; version 2 of the License.
+ *
+ * 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.
+ */
+
+#ifndef NORTHBRIDGE_INTEL_SCH_CHIP_H
+#define NORTHBRIDGE_INTEL_SCH_CHIP_H
+
+#include <drivers/intel/gma/i915.h>
+
+struct northbridge_intel_sch_config {
+	struct i915_gpu_controller_info gfx;
+};
+
+#endif				/* NORTHBRIDGE_INTEL_SCH_CHIP_H */
diff --git a/src/northbridge/intel/sch/gma.c b/src/northbridge/intel/sch/gma.c
index 5728d19..5540eb1 100644
--- a/src/northbridge/intel/sch/gma.c
+++ b/src/northbridge/intel/sch/gma.c
@@ -21,6 +21,8 @@
 #include <device/device.h>
 #include <device/pci.h>
 #include <device/pci_ids.h>
+#include <drivers/intel/gma/i915.h>
+#include "chip.h"
 
 static void gma_func0_init(struct device *dev)
 {
@@ -44,6 +46,27 @@
 	}
 }
 
+const struct i915_gpu_controller_info *
+intel_gma_get_controller_info(void)
+{
+	device_t dev = dev_find_slot(0, PCI_DEVFN(0x2,0));
+	if (!dev) {
+		return NULL;
+	}
+	struct northbridge_intel_sch_config *chip = dev->chip_info;
+	return &chip->gfx;
+}
+
+static void gma_ssdt(void)
+{
+	const struct i915_gpu_controller_info *gfx = intel_gma_get_controller_info();
+	if (!gfx) {
+		return;
+	}
+
+	drivers_intel_gma_displays_ssdt_generate(gfx);
+}
+
 static struct pci_operations gma_pci_ops = {
 	.set_subsystem = gma_set_subsystem,
 };
@@ -52,6 +75,7 @@
 	.read_resources		= pci_dev_read_resources,
 	.set_resources		= pci_dev_set_resources,
 	.enable_resources	= pci_dev_enable_resources,
+	.acpi_fill_ssdt_generator = gma_ssdt,
 	.init			= gma_func0_init,
 	.scan_bus		= 0,
 	.enable			= 0,