[coreboot-gerrit] Patch set updated for coreboot: 0e57e4f baytrail: Add support for LPSS and SCC devices in ACPI mode

Aaron Durbin (adurbin@google.com) gerrit at coreboot.org
Fri May 9 17:26:35 CEST 2014


Aaron Durbin (adurbin at google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5004

-gerrit

commit 0e57e4fade664c4d9b136d4307d2ee988f7102ba
Author: Duncan Laurie <dlaurie at chromium.org>
Date:   Tue Dec 10 14:37:42 2013 -0800

    baytrail: Add support for LPSS and SCC devices in ACPI mode
    
    This adds the option to put LPSS and SCC devices into ACPI mode
    by saving their BAR0 and BAR1 base addresses in a new device
    NVS structure that is placed at offset 0x1000 within the global
    NVS table.
    
    The Chrome NVS strcture is padded out to 0xf00 bytes so there
    is a clean offset to work with as it will need to be used by
    depthcharge to know what addresses devices live at.
    
    A few ACPI Mode IRQs are fixed up, DMA1 and DMA2 are swapped and
    the EMMC 4.5 IRQ is changed to 44.
    
    New ACPI code is provided to instantiate the LPSS and SCC devices
    with the magic HID values from Intel so the kernel drivers can
    locate and use them.
    
    The default is still for devices to be in PCI mode so this does
    not have any real effect without it being enabled in the mainboard
    devicetree.
    
    Note: this needs the updated IASL compiler which is in the CQ now
    because it uses the FixedDMA() ACPI operator.
    
    BUG=chrome-os-partner:23505,chrome-os-partner:24380
    CQ-DEPEND=CL:179459,CL:179364
    BRANCH=none
    TEST=manual tests on rambi device:
    
    1) build and boot with devices still in PCI mode and ensure that
    nothing is changed
    
    2) enable lpss_acpi_mode and see I2C devices detected by the kernel
    in ACPI mode.  Note that by itself this breaks trackpad probing so
    that will need to be implemented before it is enabled.
    
    3) enable scc_acpi_mode and see EMMC and SDCard devices detected by
    the kernel in ACPI mode.  Note that this breaks depthcharge use of
    the EMMC because it is not longer discoverable as a PCI device.
    
    Change-Id: I2a007f3c4e0b06ace5172a15c696a8eaad41ed73
    Signed-off-by: Duncan Laurie <dlaurie at chromium.org>
    Reviewed-on: https://chromium-review.googlesource.com/179481
    Reviewed-by: Aaron Durbin <adurbin at chromium.org>
    Signed-off-by: Aaron Durbin <adurbin at chromium.org>
---
 src/soc/intel/baytrail/acpi/device_nvs.asl   |  87 ++++
 src/soc/intel/baytrail/acpi/globalnvs.asl    |  24 +-
 src/soc/intel/baytrail/acpi/lpss.asl         | 670 +++++++++++++++++++++++++++
 src/soc/intel/baytrail/acpi/scc.asl          | 187 ++++++++
 src/soc/intel/baytrail/acpi/southcluster.asl |  14 +-
 src/soc/intel/baytrail/baytrail/device_nvs.h |  59 +++
 src/soc/intel/baytrail/baytrail/iosf.h       |   9 +
 src/soc/intel/baytrail/baytrail/irq.h        |   6 +-
 src/soc/intel/baytrail/baytrail/nvs.h        |  16 +-
 src/soc/intel/baytrail/baytrail/ramstage.h   |   1 +
 src/soc/intel/baytrail/chip.h                |   5 +
 src/soc/intel/baytrail/emmc.c                |   6 +
 src/soc/intel/baytrail/lpss.c                |  58 ++-
 src/soc/intel/baytrail/scc.c                 |  43 ++
 src/soc/intel/baytrail/sd.c                  |   5 +
 15 files changed, 1152 insertions(+), 38 deletions(-)

diff --git a/src/soc/intel/baytrail/acpi/device_nvs.asl b/src/soc/intel/baytrail/acpi/device_nvs.asl
new file mode 100644
index 0000000..fce7b53
--- /dev/null
+++ b/src/soc/intel/baytrail/acpi/device_nvs.asl
@@ -0,0 +1,87 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+/* Device Enabled in ACPI Mode */
+
+S0EN,	8,	// SDMA Enable
+S1EN,	8,	// I2C1 Enable
+S2EN,	8,	// I2C2 Enable
+S3EN,	8,	// I2C3 Enable
+S4EN,	8,	// I2C4 Enable
+S5EN,	8,	// I2C5 Enable
+S6EN,	8,	// I2C6 Enable
+S7EN,	8,	// I2C7 Enable
+S8EN,	8,	// SDMA2 Enable
+S9EN,	8,	// SPI Enable
+SAEN,	8,	// PWM1 Enable
+SBEN,	8,	// PWM2 Enable
+SCEN,	8,	// UART2 Enable
+SDEN,	8,	// UART2 Enable
+C0EN,	8,	// MMC Enable
+C1EN,	8,	// SDIO Enable
+C2EN,	8,	// SD Card Enable
+LPEN,	8,	// LPE Enable
+
+/* BAR 0 */
+
+S0B0,	32,	// SDMA BAR0
+S1B0,	32,	// I2C1 BAR0
+S2B0,	32,	// I2C2 BAR0
+S3B0,	32,	// I2C3 BAR0
+S4B0,	32,	// I2C4 BAR0
+S5B0,	32,	// I2C5 BAR0
+S6B0,	32,	// I2C6 BAR0
+S7B0,	32,	// I2C7 BAR0
+S8B0,	32,	// SDMA2 BAR0
+S9B0,	32,	// SPI BAR0
+SAB0,	32,	// PWM1 BAR0
+SBB0,	32,	// PWM2 BAR0
+SCB0,	32,	// UART1 BAR0
+SDB0,	32,	// UART2 BAR0
+C0B0,	32,	// MMC BAR0
+C1B0,	32,	// SDIO BAR0
+C2B0,	32,	// SD Card BAR0
+LPB0,	32,	// LPE BAR0
+
+/* BAR 1 */
+
+S0B1,	32,	// SDMA BAR1
+S1B1,	32,	// I2C1 BAR1
+S2B1,	32,	// I2C2 BAR1
+S3B1,	32,	// I2C3 BAR1
+S4B1,	32,	// I2C4 BAR1
+S5B1,	32,	// I2C5 BAR1
+S6B1,	32,	// I2C6 BAR1
+S7B1,	32,	// I2C7 BAR1
+S8B1,	32,	// SDMA2 BAR1
+S9B1,	32,	// SPI BAR1
+SAB1,	32,	// PWM1 BAR1
+SBB1,	32,	// PWM2 BAR1
+SCB1,	32,	// UART1 BAR1
+SDB1,	32,	// UART2 BAR1
+C0B1,	32,	// MMC BAR1
+C1B1,	32,	// SDIO BAR1
+C2B1,	32,	// SD Card BAR1
+LPB1,	32,	// LPE BAR1
+
+/* Extra */
+
+LPFW,	32,	// LPE BAR2 Firmware
diff --git a/src/soc/intel/baytrail/acpi/globalnvs.asl b/src/soc/intel/baytrail/acpi/globalnvs.asl
index cd00824..b384cea 100644
--- a/src/soc/intel/baytrail/acpi/globalnvs.asl
+++ b/src/soc/intel/baytrail/acpi/globalnvs.asl
@@ -30,7 +30,7 @@ Name(\PICM, 0)		// IOAPIC/8259
  */
 
 
-OperationRegion (GNVS, SystemMemory, 0xC0DEBABE, 0xf00)
+OperationRegion (GNVS, SystemMemory, 0xC0DEBABE, 0x2000)
 Field (GNVS, ByteAcc, NoLock, Preserve)
 {
 	/* Miscellaneous */
@@ -70,28 +70,12 @@ Field (GNVS, ByteAcc, NoLock, Preserve)
 	TOLM,	 32,	// 0x34 - Top of Low Memory
 	CBMC,	 32,	// 0x38 - coreboot mem console pointer
 
-	/* Serial IO device BARs */
-	Offset (0x60),
-	S0B0,	32,	// 0x60 - D21:F0 Serial IO SDMA BAR0
-	S1B0,	32,	// 0x64 - D21:F1 Serial IO I2C0 BAR0
-	S2B0,	32,	// 0x68 - D21:F2 Serial IO I2C1 BAR0
-	S3B0,	32,	// 0x6c - D21:F3 Serial IO SPI0 BAR0
-	S4B0,	32,	// 0x70 - D21:F4 Serial IO SPI1 BAR0
-	S5B0,	32,	// 0x74 - D21:F5 Serial IO UAR0 BAR0
-	S6B0,	32,	// 0x78 - D21:F6 Serial IO UAR1 BAR0
-	S7B0,	32,	// 0x7c - D23:F0 Serial IO SDIO BAR0
-	S0B1,	32,	// 0x80 - D21:F0 Serial IO SDMA BAR1
-	S1B1,	32,	// 0x84 - D21:F1 Serial IO I2C0 BAR1
-	S2B1,	32,	// 0x88 - D21:F2 Serial IO I2C1 BAR1
-	S3B1,	32,	// 0x8c - D21:F3 Serial IO SPI0 BAR1
-	S4B1,	32,	// 0x90 - D21:F4 Serial IO SPI1 BAR1
-	S5B1,	32,	// 0x94 - D21:F5 Serial IO UAR0 BAR1
-	S6B1,	32,	// 0x98 - D21:F6 Serial IO UAR1 BAR1
-	S7B1,	32,	// 0x9c - D23:F0 Serial IO SDIO BAR1
-
 	/* ChromeOS specific */
 	Offset (0x100),
 	#include <vendorcode/google/chromeos/acpi/gnvs.asl>
+
+	Offset (0x1000),
+	#include <soc/intel/baytrail/acpi/device_nvs.asl>
 }
 
 /* Set flag to enable USB charging in S3 */
diff --git a/src/soc/intel/baytrail/acpi/lpss.asl b/src/soc/intel/baytrail/acpi/lpss.asl
new file mode 100644
index 0000000..f56c6a8
--- /dev/null
+++ b/src/soc/intel/baytrail/acpi/lpss.asl
@@ -0,0 +1,670 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+Device (SDM1)
+{
+	Name (_HID, "INTL9C60")
+	Name (_UID, 1)
+	Name (_DDN, "DMA Controller #1")
+
+	Name (RBUF, ResourceTemplate()
+	{
+		Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
+		Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
+		{
+			LPSS_DMA1_IRQ
+		}
+	})
+
+	Method (_CRS)
+	{
+		CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
+		Store (\S0B0, RBAS)
+		Return (^RBUF)
+	}
+
+	Method (_STA)
+	{
+		If (LEqual (\S0EN, 1)) {
+			Return (0xF)
+		} Else {
+			Return (0x0)
+		}
+	}
+}
+
+Device (SDM2)
+{
+	Name (_HID, "INTL9C60")
+	Name (_UID, 2)
+	Name (_DDN, "DMA Controller #2")
+
+	Name (RBUF, ResourceTemplate()
+	{
+		Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
+		Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
+		{
+			LPSS_DMA2_IRQ
+		}
+	})
+
+	Method (_CRS)
+	{
+		CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
+		Store (\S8B0, RBAS)
+		Return (^RBUF)
+	}
+
+	Method (_STA)
+	{
+		If (LEqual (\S8EN, 1)) {
+			Return (0xF)
+		} Else {
+			Return (0x0)
+		}
+	}
+}
+
+Device (I2C1)
+{
+	Name (_HID, "80860F41")
+	Name (_UID, 1)
+	Name (_DDN, "I2C Controller #1")
+
+	Name (RBUF, ResourceTemplate()
+	{
+		Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
+		Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
+		{
+			LPSS_I2C1_IRQ
+		}
+		FixedDMA (0x10, 0x0, Width32Bit, )
+		FixedDMA (0x11, 0x1, Width32Bit, )
+	})
+
+	Method (_CRS)
+	{
+		CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
+		Store (\S1B0, RBAS)
+		Return (^RBUF)
+	}
+
+	Method (_STA)
+	{
+		If (LEqual (\S1EN, 1)) {
+			Return (0xF)
+		} Else {
+			Return (0x0)
+		}
+	}
+
+	OperationRegion (KEYS, SystemMemory, S1B1, 0x100)
+	Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
+	{
+		Offset (0x84),
+		PSAT, 32,
+	}
+
+	Method (_PS3)
+	{
+		Or (PSAT, 0x00000003, PSAT)
+		Or (PSAT, 0x00000000, PSAT)
+	}
+
+	Method (_PS0)
+	{
+		And (PSAT, 0xfffffffc, PSAT)
+		Or (PSAT, 0x00000000, PSAT)
+	}
+}
+
+Device (I2C2)
+{
+	Name (_HID, "80860F41")
+	Name (_UID, 2)
+	Name (_DDN, "I2C Controller #2")
+
+	Name (RBUF, ResourceTemplate()
+	{
+		Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
+		Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
+		{
+			LPSS_I2C2_IRQ
+		}
+		FixedDMA (0x10, 0x0, Width32Bit, )
+		FixedDMA (0x11, 0x1, Width32Bit, )
+	})
+
+	Method (_CRS)
+	{
+		CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
+		Store (\S2B0, RBAS)
+		Return (^RBUF)
+	}
+
+	Method (_STA)
+	{
+		If (LEqual (\S2EN, 1)) {
+			Return (0xF)
+		} Else {
+			Return (0x0)
+		}
+	}
+
+	OperationRegion (KEYS, SystemMemory, S2B1, 0x100)
+	Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
+	{
+		Offset (0x84),
+		PSAT, 32,
+	}
+
+	Method (_PS3)
+	{
+		Or (PSAT, 0x00000003, PSAT)
+		Or (PSAT, 0x00000000, PSAT)
+	}
+
+	Method (_PS0)
+	{
+		And (PSAT, 0xfffffffc, PSAT)
+		Or (PSAT, 0x00000000, PSAT)
+	}
+}
+
+Device (I2C3)
+{
+	Name (_HID, "80860F41")
+	Name (_UID, 3)
+	Name (_DDN, "I2C Controller #3")
+
+	Name (RBUF, ResourceTemplate()
+	{
+		Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
+		Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
+		{
+			LPSS_I2C3_IRQ
+		}
+		FixedDMA (0x10, 0x0, Width32Bit, )
+		FixedDMA (0x11, 0x1, Width32Bit, )
+	})
+
+	Method (_CRS)
+	{
+		CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
+		Store (\S3B0, RBAS)
+		Return (^RBUF)
+	}
+
+	Method (_STA)
+	{
+		If (LEqual (\S3EN, 1)) {
+			Return (0xF)
+		} Else {
+			Return (0x0)
+		}
+	}
+
+	OperationRegion (KEYS, SystemMemory, S3B1, 0x100)
+	Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
+	{
+		Offset (0x84),
+		PSAT, 32,
+	}
+
+	Method (_PS3)
+	{
+		Or (PSAT, 0x00000003, PSAT)
+		Or (PSAT, 0x00000000, PSAT)
+	}
+
+	Method (_PS0)
+	{
+		And (PSAT, 0xfffffffc, PSAT)
+		Or (PSAT, 0x00000000, PSAT)
+	}
+}
+
+Device (I2C4)
+{
+	Name (_HID, "80860F41")
+	Name (_UID, 4)
+	Name (_DDN, "I2C Controller #4")
+
+	Name (RBUF, ResourceTemplate()
+	{
+		Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
+		Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
+		{
+			LPSS_I2C4_IRQ
+		}
+		FixedDMA (0x10, 0x0, Width32Bit, )
+		FixedDMA (0x11, 0x1, Width32Bit, )
+	})
+
+	Method (_CRS)
+	{
+		CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
+		Store (\S4B0, RBAS)
+		Return (^RBUF)
+	}
+
+	Method (_STA)
+	{
+		If (LEqual (\S4EN, 1)) {
+			Return (0xF)
+		} Else {
+			Return (0x0)
+		}
+	}
+
+	OperationRegion (KEYS, SystemMemory, S4B1, 0x100)
+	Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
+	{
+		Offset (0x84),
+		PSAT, 32,
+	}
+
+	Method (_PS3)
+	{
+		Or (PSAT, 0x00000003, PSAT)
+		Or (PSAT, 0x00000000, PSAT)
+	}
+
+	Method (_PS0)
+	{
+		And (PSAT, 0xfffffffc, PSAT)
+		Or (PSAT, 0x00000000, PSAT)
+	}
+}
+
+Device (I2C5)
+{
+	Name (_HID, "80860F41")
+	Name (_UID, 5)
+	Name (_DDN, "I2C Controller #5")
+
+	Name (RBUF, ResourceTemplate()
+	{
+		Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
+		Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
+		{
+			LPSS_I2C5_IRQ
+		}
+		FixedDMA (0x10, 0x0, Width32Bit, )
+		FixedDMA (0x11, 0x1, Width32Bit, )
+	})
+
+	Method (_CRS)
+	{
+		CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
+		Store (\S5B0, RBAS)
+		Return (^RBUF)
+	}
+
+	Method (_STA)
+	{
+		If (LEqual (\S5EN, 1)) {
+			Return (0xF)
+		} Else {
+			Return (0x0)
+		}
+	}
+
+	OperationRegion (KEYS, SystemMemory, S5B1, 0x100)
+	Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
+	{
+		Offset (0x84),
+		PSAT, 32,
+	}
+
+	Method (_PS3)
+	{
+		Or (PSAT, 0x00000003, PSAT)
+		Or (PSAT, 0x00000000, PSAT)
+	}
+
+	Method (_PS0)
+	{
+		And (PSAT, 0xfffffffc, PSAT)
+		Or (PSAT, 0x00000000, PSAT)
+	}
+}
+
+Device (I2C6)
+{
+	Name (_HID, "80860F41")
+	Name (_UID, 6)
+	Name (_DDN, "I2C Controller #6")
+
+	Name (RBUF, ResourceTemplate()
+	{
+		Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
+		Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
+		{
+			LPSS_I2C6_IRQ
+		}
+		FixedDMA (0x10, 0x0, Width32Bit, )
+		FixedDMA (0x11, 0x1, Width32Bit, )
+	})
+
+	Method (_CRS)
+	{
+		CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
+		Store (\S6B0, RBAS)
+		Return (^RBUF)
+	}
+
+	Method (_STA)
+	{
+		If (LEqual (\S6EN, 1)) {
+			Return (0xF)
+		} Else {
+			Return (0x0)
+		}
+	}
+
+	OperationRegion (KEYS, SystemMemory, S6B1, 0x100)
+	Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
+	{
+		Offset (0x84),
+		PSAT, 32,
+	}
+
+	Method (_PS3)
+	{
+		Or (PSAT, 0x00000003, PSAT)
+		Or (PSAT, 0x00000000, PSAT)
+	}
+
+	Method (_PS0)
+	{
+		And (PSAT, 0xfffffffc, PSAT)
+		Or (PSAT, 0x00000000, PSAT)
+	}
+}
+
+Device (I2C7)
+{
+	Name (_HID, "80860F41")
+	Name (_UID, 7)
+	Name (_DDN, "I2C Controller #7")
+
+	Name (RBUF, ResourceTemplate()
+	{
+		Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
+		Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
+		{
+			LPSS_I2C7_IRQ
+		}
+		FixedDMA (0x10, 0x0, Width32Bit, )
+		FixedDMA (0x11, 0x1, Width32Bit, )
+	})
+
+	Method (_CRS)
+	{
+		CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
+		Store (\S7B0, RBAS)
+		Return (^RBUF)
+	}
+
+	Method (_STA)
+	{
+		If (LEqual (\S7EN, 1)) {
+			Return (0xF)
+		} Else {
+			Return (0x0)
+		}
+	}
+
+	OperationRegion (KEYS, SystemMemory, S7B1, 0x100)
+	Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
+	{
+		Offset (0x84),
+		PSAT, 32,
+	}
+
+	Method (_PS3)
+	{
+		Or (PSAT, 0x00000003, PSAT)
+		Or (PSAT, 0x00000000, PSAT)
+	}
+
+	Method (_PS0)
+	{
+		And (PSAT, 0xfffffffc, PSAT)
+		Or (PSAT, 0x00000000, PSAT)
+	}
+}
+
+Device (SPI1)
+{
+	Name (_HID, "80860F0E")
+	Name (_UID, 1)
+	Name (_DDN, "SPI Controller #2")
+
+	Name (RBUF, ResourceTemplate()
+	{
+		Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
+		Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
+		{
+			LPSS_SPI_IRQ
+		}
+		FixedDMA (0x0, 0x0, Width32Bit, )
+		FixedDMA (0x1, 0x1, Width32Bit, )
+	})
+
+	Method (_CRS)
+	{
+		CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
+		Store (\S9B0, RBAS)
+		Return (^RBUF)
+	}
+
+	Method (_STA)
+	{
+		If (LEqual (\S9EN, 1)) {
+			Return (0xF)
+		} Else {
+			Return (0x0)
+		}
+	}
+
+	OperationRegion (KEYS, SystemMemory, S9B1, 0x100)
+	Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
+	{
+		Offset (0x84),
+		PSAT, 32,
+	}
+
+	Method (_PS3)
+	{
+		Or (PSAT, 0x00000003, PSAT)
+		Or (PSAT, 0x00000000, PSAT)
+	}
+
+	Method (_PS0)
+	{
+		And (PSAT, 0xfffffffc, PSAT)
+		Or (PSAT, 0x00000000, PSAT)
+	}
+}
+
+Device (PWM1)
+{
+	Name (_HID, "80860F09")
+	Name (_UID, 1)
+	Name (_DDN, "PWM Controller #1")
+
+	Name (RBUF, ResourceTemplate()
+	{
+		Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
+	})
+
+	Method (_CRS)
+	{
+		CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
+		Store (\SAB0, RBAS)
+		Return (^RBUF)
+	}
+
+	Method (_STA)
+	{
+		If (LEqual (\SAEN, 1)) {
+			Return (0xF)
+		} Else {
+			Return (0x0)
+		}
+	}
+}
+
+Device (PWM2)
+{
+	Name (_HID, "80860F09")
+	Name (_UID, 2)
+	Name (_DDN, "PWM Controller #2")
+
+	Name (RBUF, ResourceTemplate()
+	{
+		Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
+	})
+
+	Method (_CRS)
+	{
+		CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
+		Store (\SBB0, RBAS)
+		Return (^RBUF)
+	}
+
+	Method (_STA)
+	{
+		If (LEqual (\SBEN, 1)) {
+			Return (0xF)
+		} Else {
+			Return (0x0)
+		}
+	}
+}
+
+Device (UAR1)
+{
+	Name (_HID, "80860F0A")
+	Name (_UID, 1)
+	Name (_DDN, "HS-UART Controller #1")
+
+	Name (RBUF, ResourceTemplate()
+	{
+		Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
+		Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
+		{
+			LPSS_HSUART1_IRQ
+		}
+		FixedDMA (0x2, 0x2, Width32Bit, )
+		FixedDMA (0x3, 0x3, Width32Bit, )
+	})
+
+	Method (_CRS)
+	{
+		CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
+		Store (\SCB0, RBAS)
+		Return (^RBUF)
+	}
+
+	Method (_STA)
+	{
+		If (LEqual (\SCEN, 1)) {
+			Return (0xF)
+		} Else {
+			Return (0x0)
+		}
+	}
+
+	OperationRegion (KEYS, SystemMemory, SCB1, 0x100)
+	Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
+	{
+		Offset (0x84),
+		PSAT, 32,
+	}
+
+	Method (_PS3)
+	{
+		Or (PSAT, 0x00000003, PSAT)
+		Or (PSAT, 0x00000000, PSAT)
+	}
+
+	Method (_PS0)
+	{
+		And (PSAT, 0xfffffffc, PSAT)
+		Or (PSAT, 0x00000000, PSAT)
+	}
+}
+
+Device (UAR2)
+{
+	Name (_HID, "80860F0A")
+	Name (_UID, 2)
+	Name (_DDN, "HS-UART Controller #2")
+
+	Name (RBUF, ResourceTemplate()
+	{
+		Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
+		Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
+		{
+			LPSS_HSUART2_IRQ
+		}
+		FixedDMA (0x4, 0x4, Width32Bit, )
+		FixedDMA (0x5, 0x5, Width32Bit, )
+	})
+
+	Method (_CRS)
+	{
+		CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
+		Store (\SDB0, RBAS)
+		Return (^RBUF)
+	}
+
+	Method (_STA)
+	{
+		If (LEqual (\SDEN, 1)) {
+			Return (0xF)
+		} Else {
+			Return (0x0)
+		}
+	}
+
+	OperationRegion (KEYS, SystemMemory, SDB1, 0x100)
+	Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
+	{
+		Offset (0x84),
+		PSAT, 32,
+	}
+
+	Method (_PS3)
+	{
+		Or (PSAT, 0x00000003, PSAT)
+		Or (PSAT, 0x00000000, PSAT)
+	}
+
+	Method (_PS0)
+	{
+		And (PSAT, 0xfffffffc, PSAT)
+		Or (PSAT, 0x00000000, PSAT)
+	}
+}
diff --git a/src/soc/intel/baytrail/acpi/scc.asl b/src/soc/intel/baytrail/acpi/scc.asl
new file mode 100644
index 0000000..7181fb1
--- /dev/null
+++ b/src/soc/intel/baytrail/acpi/scc.asl
@@ -0,0 +1,187 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+Device (EMMC)
+{
+	Name (_HID, "80860F14")
+	Name (_CID, "PNP0D40")
+	Name (_UID, 1)
+	Name (_DDN, "eMMC Controller 4.5")
+
+	Name (RBUF, ResourceTemplate()
+	{
+		Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
+		Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
+		{
+			SCC_EMMC_IRQ
+		}
+	})
+
+	Method (_CRS)
+	{
+		CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
+		Store (\C0B0, RBAS)
+		Return (^RBUF)
+	}
+
+	Method (_STA)
+	{
+		If (LEqual (\C0EN, 1)) {
+			Return (0xF)
+		} Else {
+			Return (0x0)
+		}
+	}
+
+	OperationRegion (KEYS, SystemMemory, C0B1, 0x100)
+	Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
+	{
+		Offset (0x84),
+		PSAT, 32,
+	}
+
+	Method (_PS3)
+	{
+		Or (PSAT, 0x00000003, PSAT)
+		Or (PSAT, 0x00000000, PSAT)
+	}
+
+	Method (_PS0)
+	{
+		And (PSAT, 0xfffffffc, PSAT)
+		Or (PSAT, 0x00000000, PSAT)
+	}
+
+	Device (EM45)
+	{
+		/* Slot 0, Function 8 */
+		Name (_ADR, 0x8)
+
+		Method (_RMV, 0, NotSerialized)
+		{
+			Return (0)
+		}
+	}
+}
+
+Device (SDIO)
+{
+	Name (_HID, "INT33BB")
+	Name (_CID, "PNP0D40")
+	Name (_UID, 2)
+	Name (_DDN, "SDIO Controller")
+
+	Name (RBUF, ResourceTemplate()
+	{
+		Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
+		Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
+		{
+			SCC_SDIO_IRQ
+		}
+	})
+
+	Method (_CRS)
+	{
+		CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
+		Store (\C1B0, RBAS)
+		Return (^RBUF)
+	}
+
+	Method (_STA)
+	{
+		If (LEqual (\C1EN, 1)) {
+			Return (0xF)
+		} Else {
+			Return (0x0)
+		}
+	}
+
+	OperationRegion (KEYS, SystemMemory, C1B1, 0x100)
+	Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
+	{
+		Offset (0x84),
+		PSAT, 32,
+	}
+
+	Method (_PS3)
+	{
+		Or (PSAT, 0x00000003, PSAT)
+		Or (PSAT, 0x00000000, PSAT)
+	}
+
+	Method (_PS0)
+	{
+		And (PSAT, 0xfffffffc, PSAT)
+		Or (PSAT, 0x00000000, PSAT)
+	}
+}
+
+Device (SDCD)
+{
+	Name (_HID, "80860F16")
+	Name (_CID, "PNP0D40")
+	Name (_UID, 3)
+	Name (_DDN, "SD Card Controller")
+
+	Name (RBUF, ResourceTemplate()
+	{
+		Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
+		Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
+		{
+			SCC_SD_IRQ
+		}
+	})
+
+	Method (_CRS)
+	{
+		CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
+		Store (\C2B0, RBAS)
+		Return (^RBUF)
+	}
+
+	Method (_STA)
+	{
+		If (LEqual (\C2EN, 1)) {
+			Return (0xF)
+		} Else {
+			Return (0x0)
+		}
+	}
+
+	OperationRegion (KEYS, SystemMemory, C2B1, 0x100)
+	Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
+	{
+		Offset (0x84),
+		PSAT, 32,
+	}
+
+	Method (_PS3)
+	{
+		Or (PSAT, 0x00000003, PSAT)
+		Or (PSAT, 0x00000000, PSAT)
+	}
+
+	Method (_PS0)
+	{
+		And (PSAT, 0xfffffffc, PSAT)
+		Or (PSAT, 0x00000000, PSAT)
+	}
+}
diff --git a/src/soc/intel/baytrail/acpi/southcluster.asl b/src/soc/intel/baytrail/acpi/southcluster.asl
index 49349c4..cf27a24 100644
--- a/src/soc/intel/baytrail/acpi/southcluster.asl
+++ b/src/soc/intel/baytrail/acpi/southcluster.asl
@@ -20,6 +20,7 @@
  */
 
 #include <soc/intel/baytrail/baytrail/iomap.h>
+#include <soc/intel/baytrail/baytrail/irq.h>
 
 Scope(\)
 {
@@ -233,5 +234,14 @@ Method (_OSC, 4)
 // IRQ routing for each PCI device
 #include "irqroute.asl"
 
-// GPIO Devices
-#include "gpio.asl"
+Scope (\_SB)
+{
+	// GPIO Devices
+	#include "gpio.asl"
+
+	// LPSS Devices
+	#include "lpss.asl"
+
+	// SCC Devices
+	#include "scc.asl"
+}
diff --git a/src/soc/intel/baytrail/baytrail/device_nvs.h b/src/soc/intel/baytrail/baytrail/device_nvs.h
new file mode 100644
index 0000000..dcb05d2
--- /dev/null
+++ b/src/soc/intel/baytrail/baytrail/device_nvs.h
@@ -0,0 +1,59 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+
+#define LPSS_NVS_SIO_DMA1	0
+#define LPSS_NVS_I2C1		1
+#define LPSS_NVS_I2C2		2
+#define LPSS_NVS_I2C3		3
+#define LPSS_NVS_I2C4		4
+#define LPSS_NVS_I2C5		5
+#define LPSS_NVS_I2C6		6
+#define LPSS_NVS_I2C7		7
+#define LPSS_NVS_SIO_DMA2	8
+#define LPSS_NVS_SPI		9
+#define LPSS_NVS_PWM1		10
+#define LPSS_NVS_PWM2		11
+#define LPSS_NVS_HSUART1	12
+#define LPSS_NVS_HSUART2	13
+
+#define SCC_NVS_MMC		0
+#define SCC_NVS_SDIO		1
+#define SCC_NVS_SD		2
+
+typedef struct {
+	/* Device Enabled in ACPI Mode */
+	u8	lpss_en[14];
+	u8	scc_en[3];
+	u8	lpe_en;
+
+	/* BAR 0 */
+	u32	lpss_bar0[14];
+	u32	scc_bar0[3];
+	u32	lpe_bar0;
+
+	/* BAR 0 */
+	u32	lpss_bar1[14];
+	u32	scc_bar1[3];
+	u32	lpe_bar1;
+
+	/* Extra */
+	u32	lpe_fw; /* LPE Firmware */
+} __attribute__((packed)) device_nvs_t;
diff --git a/src/soc/intel/baytrail/baytrail/iosf.h b/src/soc/intel/baytrail/baytrail/iosf.h
index 3a63d4a..d173901 100644
--- a/src/soc/intel/baytrail/baytrail/iosf.h
+++ b/src/soc/intel/baytrail/baytrail/iosf.h
@@ -211,6 +211,15 @@ void iosf_scc_write(int reg, uint32_t val);
 # define LPSS_CTL_PM_CAP_PRSNT			(1 <<  1)
 
 /*
+ * SCC Registers
+ */
+#define SCC_SD_CTL			0x504
+#define SCC_SDIO_CTL			0x508
+#define SCC_MMC_CTL			0x50c
+# define SCC_CTL_PCI_CFG_DIS			(1 << 0)
+# define SCC_CTL_ACPI_INT_EN			(1 << 1)
+
+/*
  * CCU Registers
  */
 
diff --git a/src/soc/intel/baytrail/baytrail/irq.h b/src/soc/intel/baytrail/baytrail/irq.h
index deffad7..e66fab5 100644
--- a/src/soc/intel/baytrail/baytrail/irq.h
+++ b/src/soc/intel/baytrail/baytrail/irq.h
@@ -45,9 +45,9 @@
 #define LPSS_HSUART1_IRQ		39
 #define LPSS_HSUART2_IRQ		40
 #define LPSS_SPI_IRQ			41
-#define LPSS_DMA2_IRQ			42
-#define LPSS_DMA1_IRQ			43
-#define SCC_EMMC_IRQ			45
+#define LPSS_DMA1_IRQ			42
+#define LPSS_DMA2_IRQ			43
+#define SCC_EMMC_IRQ			44
 #define SCC_SDIO_IRQ			46
 #define SCC_SD_IRQ			47
 #define GPIO_NC_IRQ			48
diff --git a/src/soc/intel/baytrail/baytrail/nvs.h b/src/soc/intel/baytrail/baytrail/nvs.h
index 8243ef3..09dee3a 100644
--- a/src/soc/intel/baytrail/baytrail/nvs.h
+++ b/src/soc/intel/baytrail/baytrail/nvs.h
@@ -18,7 +18,9 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "vendorcode/google/chromeos/gnvs.h"
+#include <vendorcode/google/chromeos/gnvs.h>
+#include <baytrail/device_nvs.h>
+
 typedef struct {
 	/* Miscellaneous */
 	u16	osys; /* 0x00 - Operating System */
@@ -55,15 +57,13 @@ typedef struct {
 	u32	cmem; /* 0x30 - CBMEM TOC */
 	u32	tolm; /* 0x34 - Top of Low Memory */
 	u32	cbmc; /* 0x38 - coreboot memconsole */
-	u8	rsvd5[36];
-
-	/* Serial IO device BARs */
-	u32	s0b[8]; /* 0x60 - 0x7f - BAR0 */
-	u32	s1b[8]; /* 0x80 - 0x9f - BAR1 */
-	u8	rsvd6[96];
+	u8	rsvd3[196];
 
-	/* ChromeOS specific (starts at 0x100)*/
+	/* ChromeOS specific (0x100-0xfff)*/
 	chromeos_acpi_t chromeos;
+
+	/* Baytrail LPSS (0x1000) */
+	device_nvs_t dev;
 } __attribute__((packed)) global_nvs_t;
 
 #ifdef __SMM__
diff --git a/src/soc/intel/baytrail/baytrail/ramstage.h b/src/soc/intel/baytrail/baytrail/ramstage.h
index 217c67b..d2e7e62 100644
--- a/src/soc/intel/baytrail/baytrail/ramstage.h
+++ b/src/soc/intel/baytrail/baytrail/ramstage.h
@@ -34,6 +34,7 @@ void baytrail_run_reference_code(void);
 static inline void baytrail_run_reference_code(void) {}
 #endif
 void baytrail_init_scc(void);
+void scc_enable_acpi_mode(device_t dev, int iosf_reg, int nvs_index);
 
 extern struct pci_operations soc_pci_ops;
 
diff --git a/src/soc/intel/baytrail/chip.h b/src/soc/intel/baytrail/chip.h
index 2cc3fd6..955ecb0 100644
--- a/src/soc/intel/baytrail/chip.h
+++ b/src/soc/intel/baytrail/chip.h
@@ -56,6 +56,11 @@ struct soc_intel_baytrail_config {
 	uint32_t sdcard_cap_low;
 	uint32_t sdcard_cap_high;
 
+	/* Enable devices in ACPI mode */
+	int lpss_acpi_mode;
+	int scc_acpi_mode;
+	int lpe_acpi_mode;
+
 	/*
 	 * Digital Port Hotplug Enable:
 	 *  0x04 = Enabled, 2ms short pulse
diff --git a/src/soc/intel/baytrail/emmc.c b/src/soc/intel/baytrail/emmc.c
index 18c16e8..0a7e9b1 100644
--- a/src/soc/intel/baytrail/emmc.c
+++ b/src/soc/intel/baytrail/emmc.c
@@ -26,8 +26,10 @@
 #include <reg_script.h>
 
 #include <baytrail/iosf.h>
+#include <baytrail/nvs.h>
 #include <baytrail/pci_devs.h>
 #include <baytrail/ramstage.h>
+#include "chip.h"
 
 static const struct reg_script emmc_ops[] = {
 	/* Enable 2ms card stable feature. */
@@ -49,6 +51,7 @@ static const struct reg_script emmc_ops[] = {
 
 static void emmc_init(device_t dev)
 {
+	struct soc_intel_baytrail_config *config = dev->chip_info;
 	struct reg_script ops[] = {
 		REG_SCRIPT_SET_DEV(dev),
 		REG_SCRIPT_NEXT(emmc_ops),
@@ -56,6 +59,9 @@ static void emmc_init(device_t dev)
 	};
 	printk(BIOS_DEBUG, "eMMC init\n");
 	reg_script_run(ops);
+
+	if (config->scc_acpi_mode)
+		scc_enable_acpi_mode(dev, SCC_MMC_CTL, SCC_NVS_MMC);
 }
 
 static struct device_operations device_ops = {
diff --git a/src/soc/intel/baytrail/lpss.c b/src/soc/intel/baytrail/lpss.c
index ccfab38..e009c7d 100644
--- a/src/soc/intel/baytrail/lpss.c
+++ b/src/soc/intel/baytrail/lpss.c
@@ -19,6 +19,7 @@
 
 #include <stdint.h>
 #include <arch/io.h>
+#include <cbmem.h>
 #include <console/console.h>
 #include <device/device.h>
 #include <device/pci.h>
@@ -26,9 +27,49 @@
 #include <reg_script.h>
 
 #include <baytrail/iosf.h>
+#include <baytrail/nvs.h>
 #include <baytrail/pci_devs.h>
 #include <baytrail/ramstage.h>
 
+#include "chip.h"
+
+static void dev_enable_acpi_mode(device_t dev, int iosf_reg, int nvs_index)
+{
+	struct reg_script ops[] = {
+		REG_SCRIPT_SET_DEV(dev),
+		/* Disable PCI interrupt, enable Memory and Bus Master */
+		REG_PCI_OR32(PCI_COMMAND,
+			     PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | (1<<10)),
+		/* Enable ACPI mode */
+		REG_IOSF_OR(IOSF_PORT_LPSS, iosf_reg,
+			    LPSS_CTL_PCI_CFG_DIS | LPSS_CTL_ACPI_INT_EN),
+		REG_SCRIPT_END
+	};
+	struct resource *bar;
+	global_nvs_t *gnvs;
+
+	/* Find ACPI NVS to update BARs */
+	gnvs = (global_nvs_t *)cbmem_find(CBMEM_ID_ACPI_GNVS);
+	if (!gnvs) {
+		printk(BIOS_ERR, "Unable to locate Global NVS\n");
+		return;
+	}
+
+	/* Save BAR0 and BAR1 to ACPI NVS */
+	bar = find_resource(dev, PCI_BASE_ADDRESS_0);
+	if (bar)
+		gnvs->dev.lpss_bar0[nvs_index] = (u32)bar->base;
+
+	bar = find_resource(dev, PCI_BASE_ADDRESS_1);
+	if (bar)
+		gnvs->dev.lpss_bar1[nvs_index] = (u32)bar->base;
+
+	/* Device is enabled in ACPI mode */
+	gnvs->dev.lpss_en[nvs_index] = 1;
+
+	/* Put device in ACPI mode */
+	reg_script_run(ops);
+}
 
 static void dev_enable_snoop_and_pm(device_t dev, int iosf_reg)
 {
@@ -43,12 +84,14 @@ static void dev_enable_snoop_and_pm(device_t dev, int iosf_reg)
 	reg_script_run(ops);
 }
 
-static int dev_ctl_reg(device_t dev)
+static void dev_ctl_reg(device_t dev, int *iosf_reg, int *nvs_index)
 {
-	int iosf_reg = -1;
+	*iosf_reg = -1;
+	*nvs_index = -1;
 #define SET_IOSF_REG(name_) \
 	case PCI_DEVFN(name_ ## _DEV, name_ ## _FUNC): \
-		iosf_reg = LPSS_ ## name_ ## _CTL
+		*iosf_reg = LPSS_ ## name_ ## _CTL; \
+		*nvs_index = LPSS_NVS_ ## name_
 
 	switch (dev->path.pci.devfn) {
 	SET_IOSF_REG(SIO_DMA1);
@@ -80,7 +123,6 @@ static int dev_ctl_reg(device_t dev)
 	SET_IOSF_REG(SPI);
 		break;
 	}
-	return iosf_reg;
 }
 
 static void i2c_disable_resets(device_t dev)
@@ -113,7 +155,10 @@ static void i2c_disable_resets(device_t dev)
 
 static void lpss_init(device_t dev)
 {
-	int iosf_reg = dev_ctl_reg(dev);
+	struct soc_intel_baytrail_config *config = dev->chip_info;
+	int iosf_reg, nvs_index;
+
+	dev_ctl_reg(dev, &iosf_reg, &nvs_index);
 
 	if (iosf_reg < 0) {
 		int slot = PCI_SLOT(dev->path.pci.devfn);
@@ -124,6 +169,9 @@ static void lpss_init(device_t dev)
 	}
 	dev_enable_snoop_and_pm(dev, iosf_reg);
 
+	if (config->lpss_acpi_mode)
+		dev_enable_acpi_mode(dev, iosf_reg, nvs_index);
+
 	i2c_disable_resets(dev);
 }
 
diff --git a/src/soc/intel/baytrail/scc.c b/src/soc/intel/baytrail/scc.c
index af941fa..64792c2 100644
--- a/src/soc/intel/baytrail/scc.c
+++ b/src/soc/intel/baytrail/scc.c
@@ -18,10 +18,15 @@
  */
 
 
+#include <cbmem.h>
 #include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
 #include <reg_script.h>
 
 #include <baytrail/iosf.h>
+#include <baytrail/nvs.h>
 #include <baytrail/ramstage.h>
 
 static const struct reg_script scc_start_dll[] = {
@@ -81,3 +86,41 @@ void baytrail_init_scc(void)
 
 	reg_script_run(scc_after_dll);
 }
+
+void scc_enable_acpi_mode(device_t dev, int iosf_reg, int nvs_index)
+{
+	struct reg_script ops[] = {
+		REG_SCRIPT_SET_DEV(dev),
+		/* Disable PCI interrupt, enable Memory and Bus Master */
+		REG_PCI_OR32(PCI_COMMAND,
+			     PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | (1<<10)),
+		/* Enable ACPI mode */
+		REG_IOSF_OR(IOSF_PORT_SCC, iosf_reg,
+			    SCC_CTL_PCI_CFG_DIS | SCC_CTL_ACPI_INT_EN),
+		REG_SCRIPT_END
+	};
+	struct resource *bar;
+	global_nvs_t *gnvs;
+
+	/* Find ACPI NVS to update BARs */
+	gnvs = (global_nvs_t *)cbmem_find(CBMEM_ID_ACPI_GNVS);
+	if (!gnvs) {
+		printk(BIOS_ERR, "Unable to locate Global NVS\n");
+		return;
+	}
+
+	/* Save BAR0 and BAR1 to ACPI NVS */
+	bar = find_resource(dev, PCI_BASE_ADDRESS_0);
+	if (bar)
+		gnvs->dev.scc_bar0[nvs_index] = (u32)bar->base;
+
+	bar = find_resource(dev, PCI_BASE_ADDRESS_1);
+	if (bar)
+		gnvs->dev.scc_bar1[nvs_index] = (u32)bar->base;
+
+	/* Device is enabled in ACPI mode */
+	gnvs->dev.scc_en[nvs_index] = 1;
+
+	/* Put device in ACPI mode */
+	reg_script_run(ops);
+}
diff --git a/src/soc/intel/baytrail/sd.c b/src/soc/intel/baytrail/sd.c
index 82833c3..97c8628 100644
--- a/src/soc/intel/baytrail/sd.c
+++ b/src/soc/intel/baytrail/sd.c
@@ -24,6 +24,8 @@
 #include <device/pci_ids.h>
 #include <reg_script.h>
 
+#include <baytrail/iosf.h>
+#include <baytrail/nvs.h>
 #include <baytrail/pci_devs.h>
 #include <baytrail/ramstage.h>
 #include "chip.h"
@@ -46,6 +48,9 @@ static void sd_init(device_t dev)
 		pci_write_config32(dev, CAP_OVERRIDE_HIGH,
 		                   config->sdcard_cap_high | USE_CAP_OVERRIDES);
 	}
+
+	if (config->scc_acpi_mode)
+		scc_enable_acpi_mode(dev, SCC_SD_CTL, SCC_NVS_SD);
 }
 
 static const struct device_operations device_ops = {



More information about the coreboot-gerrit mailing list