[coreboot-gerrit] New patch to review for coreboot: 54b8e0b baytrail/rambi: spi, charger, and audio updates

Isaac Christensen (isaac.christensen@se-eng.com) gerrit at coreboot.org
Thu Sep 18 02:13:01 CEST 2014


Isaac Christensen (isaac.christensen at se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/6933

-gerrit

commit 54b8e0bf594e1efd9de6e301d1786ae7b1205ad7
Author: Aaron Durbin <adurbin at chromium.org>
Date:   Wed Feb 5 14:55:26 2014 -0600

    baytrail/rambi: spi, charger, and audio updates
    
    baytrail: combine SPI configuration in romstage
    Reviewed-on: https://chromium-review.googlesource.com/185140
    (cherry picked from commit 4e7f0e8ae1138e478ae7106d54719cf05e13b402)
    
    baytrail: lock down registers before handoff
    Reviewed-on: https://chromium-review.googlesource.com/185200
    (cherry picked from commit 82cce4d2b46ccc554b71efa179b5d95756e2ad5e)
    
    baytrail: invoke SMM finalization on handoff
    Reviewed-on: https://chromium-review.googlesource.com/185201
    (cherry picked from commit 1b50affb1fdda52a5986c9429713930ed517a86a)
    
    rambi: don't invoke SMM finalization
    Reviewed-on: https://chromium-review.googlesource.com/185202
    (cherry picked from commit 6eff475dae7f4536eb846ccf6d51fce262b8ffef)
    
    rambi: remove handling of APM_CNT_FINALIZE
    Reviewed-on: https://chromium-review.googlesource.com/185203
    (cherry picked from commit 9fc310d7e2730466cc7fcc84999502a2d4d08bab)
    
    baytrail: don't increment boot count on S3 resume
    Reviewed-on: https://chromium-review.googlesource.com/185381
    (cherry picked from commit 940a0fa4df1ce335229eb6f80143b93a84ba358c)
    
    rambi: enable HDA device
    Reviewed-on: https://chromium-review.googlesource.com/184574
    (cherry picked from commit 334f2a5c7c6540e744b6aaf7e1da0b55e1368196)
    
    baytrail: lock down spi controller according to mainboard
    Reviewed-on: https://chromium-review.googlesource.com/185631
    (cherry picked from commit 696ece68cb6d522c248e800f168e675e4b4a7317)
    
    rambi: implement mainboard_get_spi_config() to lock dow spi controller
    Reviewed-on: https://chromium-review.googlesource.com/185632
    (cherry picked from commit 1d9ba15858fd421a4fe5a47f7171273128e89524)
    
    baytrail: introduce ssus_disable_internal_pull()
    Reviewed-on: https://chromium-review.googlesource.com/185740
    (cherry picked from commit 9d6056dd70b27183dab6a4656f4f9612ae870a4d)
    
    rambi: fix write-protect gpio reading at romstage
    Reviewed-on: https://chromium-review.googlesource.com/185741
    (cherry picked from commit c64627689b1afec59be6fdab323d5492046f0bc7)
    
    baytrail: DPTF: implement charger current limit
    Reviewed-on: https://chromium-review.googlesource.com/185759
    (cherry picked from commit 287e8936613a7a83281ff692b20383dacf7fcaf6)
    
    rambi: Enable charger participant and define states
    Reviewed-on: https://chromium-review.googlesource.com/185760
    (cherry picked from commit 2f62a11927ecf10cb2c76a9f5d368d4050404137)
    
    baytrail: increase command wait timeout
    Reviewed-on: https://chromium-review.googlesource.com/185874
    (cherry picked from commit 962a79ef72169b5d52fc746d1889d3b652fd9bcc)
    
    baytrail: make caching MRC data more robust
    Reviewed-on: https://chromium-review.googlesource.com/185875
    (cherry picked from commit b5e10ad47b9e4f330caaee4faf69702f24d6bdd8)
    
    baytrail: upgrade MRC wrapper header
    Reviewed-on: https://chromium-review.googlesource.com/186391
    (cherry picked from commit 8c1a62f1f4261d4f38aacbbb353c9d6218ec2885)
    
    rambi: instruct MRC to use weaker memory ODT settings
    Reviewed-on: https://chromium-review.googlesource.com/186420
    (cherry picked from commit b9329126ca08d20ce1d8c5db0fcabd39140c7292)
    
    rambi: Move touch wakeup resource GPIO to separate device
    Reviewed-on: https://chromium-review.googlesource.com/186932
    (cherry picked from commit ba44e2e04f9469c629cb61a911c8cd339f52b0ef)
    
    baytrail: Set some MSRs related to turbo power
    Reviewed-on: https://chromium-review.googlesource.com/186933
    (cherry picked from commit 76b25df5a31914ae58d47d17af448216011e425c)
    
    baytrail: change power consumption number for ACPI_C3/C6FS.
    Reviewed-on: https://chromium-review.googlesource.com/186934
    (cherry picked from commit 5192e2464fbb88ea6fc117070240c9733e34f065)
    
    baytrail: Fix use of ConcatenateResTemplate() in ACPI LPE device
    Reviewed-on: https://chromium-review.googlesource.com/186928
    (cherry picked from commit 8d1ab5de1d43b0790d140f6d0e36a990a5049ece)
    
    baytrail: Disable P-state HW coordination on 4-core SKU
    Reviewed-on: https://chromium-review.googlesource.com/187575
    (cherry picked from commit c19c0f1d7cb3cb2635766c186ba9598933424a78)
    
    baytrail: DPTF: Enable mainboard-specific _PDL
    Reviewed-on: https://chromium-review.googlesource.com/187576
    (cherry picked from commit 5412ac5c07bee22017a0ee6d1e2433917b98ea87)
    
    rambi: Apply DPTF tuning parameters
    Reviewed-on: https://chromium-review.googlesource.com/187577
    (cherry picked from commit 932a5a3803ceaf430ad2934b371ac0886c25efca)
    
    rambi : change lpe_codec_clk_freq to 19.2
    Reviewed-on: https://chromium-review.googlesource.com/187594
    (cherry picked from commit f64cb1ae77076ad5ec994670f4a83dc561ea80c4)
    
    Squashed 25 commits for baytrail/rambi.
    
    Change-Id: Ibe628ac974d117a09361f7f3131a488911ddd27d
    Signed-off-by: Isaac Christensen <isaac.christensen at se-eng.com>
---
 src/mainboard/google/rambi/Makefile.inc       |  1 +
 src/mainboard/google/rambi/acpi/dptf.asl      | 30 +++++++----
 src/mainboard/google/rambi/acpi/mainboard.asl | 62 +++++++++-------------
 src/mainboard/google/rambi/chromeos.c         | 11 ++++
 src/mainboard/google/rambi/devicetree.cb      |  4 +-
 src/mainboard/google/rambi/mainboard.c        |  2 -
 src/mainboard/google/rambi/mainboard_smi.c    | 12 -----
 src/mainboard/google/rambi/romstage.c         | 13 ++---
 src/mainboard/google/rambi/w25q64.c           | 74 +++++++++++++++++++++++++++
 src/soc/intel/baytrail/acpi.c                 |  7 +--
 src/soc/intel/baytrail/acpi/dptf/charger.asl  | 43 ++++++++++++----
 src/soc/intel/baytrail/acpi/dptf/cpu.asl      |  5 +-
 src/soc/intel/baytrail/acpi/dptf/dptf.asl     |  5 ++
 src/soc/intel/baytrail/acpi/lpe.asl           |  2 +-
 src/soc/intel/baytrail/baytrail/gpio.h        |  6 +++
 src/soc/intel/baytrail/baytrail/lpc.h         |  4 ++
 src/soc/intel/baytrail/baytrail/mrc_wrapper.h |  3 +-
 src/soc/intel/baytrail/baytrail/msr.h         |  7 +++
 src/soc/intel/baytrail/baytrail/spi.h         | 37 ++++++++++++++
 src/soc/intel/baytrail/cpu.c                  | 30 +++++++++++
 src/soc/intel/baytrail/mrc_cache.c            | 13 +++--
 src/soc/intel/baytrail/nvm.c                  |  6 +--
 src/soc/intel/baytrail/romstage/romstage.c    | 37 +++++++-------
 src/soc/intel/baytrail/southcluster.c         | 52 +++++++++++++++++++
 src/soc/intel/baytrail/spi.c                  |  2 +-
 25 files changed, 352 insertions(+), 116 deletions(-)

diff --git a/src/mainboard/google/rambi/Makefile.inc b/src/mainboard/google/rambi/Makefile.inc
index 572baaa..52e1855 100644
--- a/src/mainboard/google/rambi/Makefile.inc
+++ b/src/mainboard/google/rambi/Makefile.inc
@@ -24,5 +24,6 @@ ramstage-y += chromeos.c
 ramstage-y += gpio.c
 ramstage-$(CONFIG_EC_GOOGLE_CHROMEEC) += ec.c
 ramstage-y += irqroute.c
+ramstage-y += w25q64.c
 
 smm-$(CONFIG_HAVE_SMI_HANDLER) += mainboard_smi.c
diff --git a/src/mainboard/google/rambi/acpi/dptf.asl b/src/mainboard/google/rambi/acpi/dptf.asl
index 51237dc..975c939 100644
--- a/src/mainboard/google/rambi/acpi/dptf.asl
+++ b/src/mainboard/google/rambi/acpi/dptf.asl
@@ -1,9 +1,9 @@
-#define DPTF_CPU_PASSIVE	60
-#define DPTF_CPU_CRITICAL	70
+#define DPTF_CPU_PASSIVE	80
+#define DPTF_CPU_CRITICAL	90
 
 #define DPTF_TSR0_SENSOR_ID	1
 #define DPTF_TSR0_SENSOR_NAME	"TMP432_Internal"
-#define DPTF_TSR0_PASSIVE	60
+#define DPTF_TSR0_PASSIVE	48
 #define DPTF_TSR0_CRITICAL	70
 
 #define DPTF_TSR1_SENSOR_ID	2
@@ -13,28 +13,40 @@
 
 #define DPTF_TSR2_SENSOR_ID	3
 #define DPTF_TSR2_SENSOR_NAME	"TMP432_CPU_bottom"
-#define DPTF_TSR2_PASSIVE	60
+#define DPTF_TSR2_PASSIVE	55
 #define DPTF_TSR2_CRITICAL	70
 
-#undef DPTF_ENABLE_CHARGER
+#define DPTF_ENABLE_CHARGER
+
+/* Charger performance states, board-specific values from charger and EC */
+Name (CHPS, Package () {
+	Package () { 0, 0, 0, 0, 255, 0x6a4, "mA", 0 },	/* 1.7A (MAX) */
+	Package () { 0, 0, 0, 0, 24, 0x600, "mA", 0 },	/* 1.5A */
+	Package () { 0, 0, 0, 0, 16, 0x400, "mA", 0 },	/* 1.0A */
+	Package () { 0, 0, 0, 0, 8, 0x200, "mA", 0 },	/* 0.5A */
+	Package () { 0, 0, 0, 0, 0, 0x000, "mA", 0 },	/* 0.0A */
+})
+
+/* Mainboard specific _PDL is 1GHz */
+Name (MPDL, 8)
 
 Name (DTRT, Package () {
 	/* CPU Throttle Effect on CPU */
 	Package () { \_SB.DPTF.TCPU, \_SB.DPTF.TCPU, 100, 50, 0, 0, 0, 0 },
 
 	/* CPU Effect on Temp Sensor 0 */
-	Package () { \_SB.DPTF.TCPU, \_SB.DPTF.TSR0, 100, 50, 0, 0, 0, 0 },
+	Package () { \_SB.DPTF.TCPU, \_SB.DPTF.TSR0, 100, 600, 0, 0, 0, 0 },
 
 #ifdef DPTF_ENABLE_CHARGER
 	/* Charger Effect on Temp Sensor 1 */
-	Package () { \_SB.DPTF.TCHG, \_SB.DPTF.TSR1, 200, 50, 0, 0, 0, 0 },
+	Package () { \_SB.DPTF.TCHG, \_SB.DPTF.TSR1, 200, 600, 0, 0, 0, 0 },
 #endif
 
 	/* CPU Effect on Temp Sensor 1 */
-	Package () { \_SB.DPTF.TCPU, \_SB.DPTF.TSR1, 100, 50, 0, 0, 0, 0 },
+	Package () { \_SB.DPTF.TCPU, \_SB.DPTF.TSR1, 100, 600, 0, 0, 0, 0 },
 
 	/* CPU Effect on Temp Sensor 2 */
-	Package () { \_SB.DPTF.TCPU, \_SB.DPTF.TSR2, 100, 50, 0, 0, 0, 0 },
+	Package () { \_SB.DPTF.TCPU, \_SB.DPTF.TSR2, 100, 600, 0, 0, 0, 0 },
 })
 
 /* Include Baytrail DPTF */
diff --git a/src/mainboard/google/rambi/acpi/mainboard.asl b/src/mainboard/google/rambi/acpi/mainboard.asl
index 1f5b7a1..f0f7a4c 100644
--- a/src/mainboard/google/rambi/acpi/mainboard.asl
+++ b/src/mainboard/google/rambi/acpi/mainboard.asl
@@ -25,8 +25,8 @@ Scope (\_SB)
 {
 	Device (LID0)
 	{
-		Name(_HID, EisaId("PNP0C0D"))
-		Method(_LID, 0)
+		Name (_HID, EisaId ("PNP0C0D"))
+		Method (_LID, 0)
 		{
 			Store (\_SB.PCI0.LPCB.EC0.LIDS, \LIDS)
 			Return (\LIDS)
@@ -35,15 +35,18 @@ Scope (\_SB)
 
 	Device (PWRB)
 	{
-		Name(_HID, EisaId("PNP0C0C"))
+		Name (_HID, EisaId ("PNP0C0C"))
+		Name (_UID, 1)
 	}
 
+	/* Wake device for touchpad */
 	Device (TPAD)
 	{
 		Name (_HID, EisaId ("PNP0C0E"))
 		Name (_UID, 1)
+		Name (_PRW, Package() { BOARD_TRACKPAD_WAKE_GPIO, 0x3 })
 
-		Name (_CRS, ResourceTemplate()
+		Name (RBUF, ResourceTemplate()
 		{
 			Interrupt (ResourceConsumer, Edge, ActiveLow)
 			{
@@ -51,25 +54,23 @@ Scope (\_SB)
 			}
 		})
 
-		Method (_STA)
+		Method (_CRS)
 		{
-			/* Disable if I2C1 is in ACPI mode */
-			If (LEqual (\S1EN, 1)) {
-				Return (0x0)
-			} Else {
-				Return (0xF)
+			/* Only return interrupt if I2C1 is PCI mode */
+			If (LEqual (\S1EN, 0)) {
+				Return (^RBUF)
 			}
 		}
-
-		Name (_PRW, Package() { BOARD_TRACKPAD_WAKE_GPIO, 0x3 })
 	}
 
+	/* Wake device for touchscreen */
 	Device (TSCR)
 	{
 		Name (_HID, EisaId ("PNP0C0E"))
 		Name (_UID, 2)
+		Name (_PRW, Package() { BOARD_TOUCHSCREEN_WAKE_GPIO, 0x3 })
 
-		Name (_CRS, ResourceTemplate()
+		Name (RBUF, ResourceTemplate()
 		{
 			Interrupt (ResourceConsumer, Edge, ActiveLow)
 			{
@@ -77,17 +78,13 @@ Scope (\_SB)
 			}
 		})
 
-		Method (_STA)
+		Method (_CRS)
 		{
-			/* Disable if I2C6 is in ACPI mode */
-			If (LEqual (\S6EN, 1)) {
-				Return (0x0)
-			} Else {
-				Return (0xF)
+			/* Only return interrupt if I2C6 is PCI mode */
+			If (LEqual (\S6EN, 0)) {
+				Return (^RBUF)
 			}
 		}
-
-		Name (_PRW, Package() { BOARD_TOUCHSCREEN_WAKE_GPIO, 0x3 })
 	}
 }
 
@@ -107,7 +104,7 @@ Scope (\_SB.I2C1)
 				ControllerInitiated,      // SlaveMode
 				400000,                   // ConnectionSpeed
 				AddressingMode7Bit,       // AddressingMode
-				"\_SB.I2C1",              // ResourceSource
+				"\\_SB.I2C1",             // ResourceSource
 			)
 			Interrupt (ResourceConsumer, Edge, ActiveLow)
 			{
@@ -131,7 +128,6 @@ Scope (\_SB.I2C1)
 	Device (ATPA)
 	{
 		Name (_HID, "ATML0000")
-		Name (_CID, EisaId ("PNP0C0E"))
 		Name (_DDN, "Atmel Touchpad")
 		Name (_UID, 2)
 		Name (ISTP, 1) /* Touchpad */
@@ -143,7 +139,7 @@ Scope (\_SB.I2C1)
 				ControllerInitiated,      // SlaveMode
 				400000,                   // ConnectionSpeed
 				AddressingMode7Bit,       // AddressingMode
-				"\_SB.I2C1",              // ResourceSource
+				"\\_SB.I2C1",             // ResourceSource
 			)
 			Interrupt (ResourceConsumer, Edge, ActiveLow)
 			{
@@ -162,14 +158,11 @@ Scope (\_SB.I2C1)
 
 		/* Allow device to power off in S0 */
 		Name (_S0W, 4)
-
-		Name (_PRW, Package() { BOARD_TRACKPAD_WAKE_GPIO, 0x3 })
 	}
 
 	Device (ETPA)
 	{
 		Name (_HID, "ELAN0000")
-		Name (_CID, EisaId ("PNP0C0E"))
 		Name (_DDN, "Elan Touchpad")
 		Name (_UID, 3)
 		Name (ISTP, 1) /* Touchpad */
@@ -181,7 +174,7 @@ Scope (\_SB.I2C1)
 				ControllerInitiated,      // SlaveMode
 				400000,                   // ConnectionSpeed
 				AddressingMode7Bit,       // AddressingMode
-				"\_SB.I2C1",              // ResourceSource
+				"\\_SB.I2C1",             // ResourceSource
 			)
 			Interrupt (ResourceConsumer, Edge, ActiveLow)
 			{
@@ -200,8 +193,6 @@ Scope (\_SB.I2C1)
 
 		/* Allow device to power off in S0 */
 		Name (_S0W, 4)
-
-		Name (_PRW, Package() { BOARD_TRACKPAD_WAKE_GPIO, 0x3 })
 	}
 }
 
@@ -226,7 +217,7 @@ Scope (\_SB.I2C2)
 				ControllerInitiated,      // SlaveMode
 				400000,                   // ConnectionSpeed
 				AddressingMode7Bit,       // AddressingMode
-				"\_SB.I2C2",              // ResourceSource
+				"\\_SB.I2C2",             // ResourceSource
 			)
 			Interrupt (ResourceConsumer, Edge, ActiveLow)
 			{
@@ -266,7 +257,7 @@ Scope (\_SB.I2C5)
 				ControllerInitiated,      // SlaveMode
 				400000,                   // ConnectionSpeed
 				AddressingMode7Bit,       // AddressingMode
-				"\_SB.I2C5",              // ResourceSource
+				"\\_SB.I2C5",             // ResourceSource
 			)
 			Interrupt (ResourceConsumer, Edge, ActiveLow)
 			{
@@ -301,7 +292,7 @@ Scope (\_SB.I2C6)
 				ControllerInitiated,      // SlaveMode
 				400000,                   // ConnectionSpeed
 				AddressingMode7Bit,       // AddressingMode
-				"\_SB.I2C6",              // ResourceSource
+				"\\_SB.I2C6",             // ResourceSource
 			)
 			Interrupt (ResourceConsumer, Edge, ActiveLow)
 			{
@@ -325,7 +316,6 @@ Scope (\_SB.I2C6)
 	Device (ATSA)
 	{
 		Name (_HID, "ATML0001")
-		Name (_CID, EisaId ("PNP0C0E"))
 		Name (_DDN, "Atmel Touchscreen")
 		Name (_UID, 5)
 		Name (ISTP, 0) /* TouchScreen */
@@ -337,7 +327,7 @@ Scope (\_SB.I2C6)
 				ControllerInitiated,      // SlaveMode
 				400000,                   // ConnectionSpeed
 				AddressingMode7Bit,       // AddressingMode
-				"\_SB.I2C6",              // ResourceSource
+				"\\_SB.I2C6",             // ResourceSource
 			)
 			Interrupt (ResourceConsumer, Edge, ActiveLow)
 			{
@@ -356,8 +346,6 @@ Scope (\_SB.I2C6)
 
 		/* Allow device to power off in S0 */
 		Name (_S0W, 4)
-
-		Name (_PRW, Package() { BOARD_TOUCHSCREEN_WAKE_GPIO, 0x3 })
 	}
 }
 
diff --git a/src/mainboard/google/rambi/chromeos.c b/src/mainboard/google/rambi/chromeos.c
index 27af118..0c3fe2a 100644
--- a/src/mainboard/google/rambi/chromeos.c
+++ b/src/mainboard/google/rambi/chromeos.c
@@ -96,6 +96,17 @@ int get_recovery_mode_switch(void)
 
 int get_write_protect_state(void)
 {
+	/*
+	 * The vboot loader queries this function in romstage. The GPIOs have
+	 * not been set up yet as that configuration is done in ramstage. The
+	 * hardware defaults to an input but there is a 20K pulldown. Externally
+	 * there is a 10K pullup. Disable the internal pull in romstage so that
+	 * there isn't any ambiguity in the reading.
+	 */
+#if defined(__PRE_RAM__)
+	ssus_disable_internal_pull(WP_STATUS_PAD);
+#endif
+
 	/* WP is enabled when the pin is reading high. */
 	return ssus_get_gpio(WP_STATUS_PAD);
 }
diff --git a/src/mainboard/google/rambi/devicetree.cb b/src/mainboard/google/rambi/devicetree.cb
index 79a2d22..95b2b3a 100644
--- a/src/mainboard/google/rambi/devicetree.cb
+++ b/src/mainboard/google/rambi/devicetree.cb
@@ -24,7 +24,7 @@ chip soc/intel/baytrail
 	register "usb2_per_port_rcomp_hs_pullup3" = "0x0300401d"
 
 	# LPE audio codec settings
-	register "lpe_codec_clk_freq" = "25" # 25MHz clock
+	register "lpe_codec_clk_freq" = "19" # 19.2MHz clock
 	register "lpe_codec_clk_num" = "0"   # PMC_PLT_CLK[0]
 
 	# SD Card controller
@@ -73,7 +73,7 @@ chip soc/intel/baytrail
 		device pci 18.6 on  end # I2C6
 		device pci 18.7 off end # I2C7
 		device pci 1a.0 on  end # TXE
-		device pci 1b.0 off end # HDA
+		device pci 1b.0 on  end # HDA
 		device pci 1c.0 on  end # PCIE_PORT1
 		device pci 1c.1 on  end # PCIE_PORT2
 		device pci 1c.2 off end # PCIE_PORT3
diff --git a/src/mainboard/google/rambi/mainboard.c b/src/mainboard/google/rambi/mainboard.c
index 49e9ab5..f8c80ae 100644
--- a/src/mainboard/google/rambi/mainboard.c
+++ b/src/mainboard/google/rambi/mainboard.c
@@ -39,8 +39,6 @@
 
 void mainboard_suspend_resume(void)
 {
-	/* Call SMM finalize() handlers before resume */
-	outb(0xcb, 0xb2);
 }
 
 #if CONFIG_VGA_ROM_RUN
diff --git a/src/mainboard/google/rambi/mainboard_smi.c b/src/mainboard/google/rambi/mainboard_smi.c
index 09a8580..f2bb7e9 100644
--- a/src/mainboard/google/rambi/mainboard_smi.c
+++ b/src/mainboard/google/rambi/mainboard_smi.c
@@ -126,21 +126,9 @@ void mainboard_smi_sleep(uint8_t slp_typ)
 	while (google_chromeec_get_event() != 0);
 }
 
-#define APMC_FINALIZE 0xcb
-
-static int mainboard_finalized = 0;
-
 int mainboard_smi_apmc(uint8_t apmc)
 {
 	switch (apmc) {
-	case APMC_FINALIZE:
-		if (mainboard_finalized) {
-			printk(BIOS_DEBUG, "SMI#: Already finalized\n");
-			return 0;
-		}
-
-		mainboard_finalized = 1;
-		break;
 	case APM_CNT_ACPI_ENABLE:
 		google_chromeec_set_smi_mask(0);
 		/* Clear all pending events */
diff --git a/src/mainboard/google/rambi/romstage.c b/src/mainboard/google/rambi/romstage.c
index 48fe387..7c505e7 100644
--- a/src/mainboard/google/rambi/romstage.c
+++ b/src/mainboard/google/rambi/romstage.c
@@ -42,12 +42,6 @@ static const uint32_t dual_channel_config =
 #define GPIO_SSUS_38_PAD 50
 #define GPIO_SSUS_39_PAD 58
 
-static inline void disable_internal_pull(int pad)
-{
-	const int pull_mask = ~(0xf << 7);
-	write32(ssus_pconf0(pad), read32(ssus_pconf0(pad)) & pull_mask);
-}
-
 static void *get_spd_pointer(char *spd_file_content, int total_spds, int *dual)
 {
 	int ram_id = 0;
@@ -55,9 +49,9 @@ static void *get_spd_pointer(char *spd_file_content, int total_spds, int *dual)
 	/* The ram_id[2:0] pullups on rambi are too large for the default 20K
 	 * pulldown on the pad. Therefore, disable the internal pull resistor to
 	 * read high values correctly. */
-	disable_internal_pull(GPIO_SSUS_37_PAD);
-	disable_internal_pull(GPIO_SSUS_38_PAD);
-	disable_internal_pull(GPIO_SSUS_39_PAD);
+	ssus_disable_internal_pull(GPIO_SSUS_37_PAD);
+	ssus_disable_internal_pull(GPIO_SSUS_38_PAD);
+	ssus_disable_internal_pull(GPIO_SSUS_39_PAD);
 
 	ram_id |= (ssus_get_gpio(GPIO_SSUS_37_PAD) << 0);
 	ram_id |= (ssus_get_gpio(GPIO_SSUS_38_PAD) << 1);
@@ -85,6 +79,7 @@ void mainboard_romstage_entry(struct romstage_params *rp)
 		.mainboard = {
 			.dram_type = DRAM_DDR3L,
 			.dram_info_location = DRAM_INFO_SPD_MEM,
+			.weaker_odt_settings = 1,
 		},
 	};
 
diff --git a/src/mainboard/google/rambi/w25q64.c b/src/mainboard/google/rambi/w25q64.c
new file mode 100644
index 0000000..dbc26e4
--- /dev/null
+++ b/src/mainboard/google/rambi/w25q64.c
@@ -0,0 +1,74 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 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 <string.h>
+#include <baytrail/spi.h>
+
+/*
+ * SPI lockdown configuration W25Q64FW.
+ */
+#define SPI_OPMENU_0 0x01 /* WRSR: Write Status Register */
+#define SPI_OPTYPE_0 0x01 /* Write, no address */
+
+#define SPI_OPMENU_1 0x02 /* BYPR: Byte Program */
+#define SPI_OPTYPE_1 0x03 /* Write, address required */
+
+#define SPI_OPMENU_2 0x03 /* READ: Read Data */
+#define SPI_OPTYPE_2 0x02 /* Read, address required */
+
+#define SPI_OPMENU_3 0x05 /* RDSR: Read Status Register */
+#define SPI_OPTYPE_3 0x00 /* Read, no address */
+
+#define SPI_OPMENU_4 0x20 /* SE20: Sector Erase 0x20 */
+#define SPI_OPTYPE_4 0x03 /* Write, address required */
+
+#define SPI_OPMENU_5 0x9f /* RDID: Read ID */
+#define SPI_OPTYPE_5 0x00 /* Read, no address */
+
+#define SPI_OPMENU_6 0xd8 /* BED8: Block Erase 0xd8 */
+#define SPI_OPTYPE_6 0x03 /* Write, address required */
+
+#define SPI_OPMENU_7 0x0b /* FAST: Fast Read */
+#define SPI_OPTYPE_7 0x02 /* Read, address required */
+
+#define SPI_OPPREFIX ((0x50 << 8) | 0x06) /* EWSR and WREN */
+#define SPI_OPTYPE ((SPI_OPTYPE_7 << 14) | (SPI_OPTYPE_6 << 12) | \
+		    (SPI_OPTYPE_5 << 10) | (SPI_OPTYPE_4 <<  8) | \
+		    (SPI_OPTYPE_3 <<  6) | (SPI_OPTYPE_2 <<  4) | \
+		    (SPI_OPTYPE_1 <<  2) | (SPI_OPTYPE_0 <<  0))
+#define SPI_OPMENU_UPPER ((SPI_OPMENU_7 << 24) | (SPI_OPMENU_6 << 16) | \
+			  (SPI_OPMENU_5 <<  8) | (SPI_OPMENU_4 <<  0))
+#define SPI_OPMENU_LOWER ((SPI_OPMENU_3 << 24) | (SPI_OPMENU_2 << 16) | \
+			  (SPI_OPMENU_1 <<  8) | (SPI_OPMENU_0 <<  0))
+#define SPI_VSCC (WG_64_BYTE | EO(0x20) | BES_4_KB)
+
+static const struct spi_config spi_config = {
+	.preop = SPI_OPPREFIX,
+	.optype = SPI_OPTYPE,
+	.opmenu = { SPI_OPMENU_LOWER, SPI_OPMENU_UPPER },
+	.lvscc =  SPI_VSCC,
+	.uvscc =  SPI_VSCC,
+};
+
+int mainboard_get_spi_config(struct spi_config *cfg)
+{
+	memcpy(cfg, &spi_config, sizeof(*cfg));
+
+	return 0;
+}
diff --git a/src/soc/intel/baytrail/acpi.c b/src/soc/intel/baytrail/acpi.c
index 1ab1eb3..67e8c0c 100644
--- a/src/soc/intel/baytrail/acpi.c
+++ b/src/soc/intel/baytrail/acpi.c
@@ -73,7 +73,7 @@ static acpi_cstate_t cstate_map[] = {
 		/* C6FS with full L2 shrink */
 		.ctype = 3, /* ACPI C3 */
 		.latency = 1500, /* 1.5ms worst case */
-		.power = 10,
+		.power = 1,
 		.resource = MWAIT_RES(5, 2),
 	}
 };
@@ -353,8 +353,9 @@ static int generate_P_state_entries(int core, int cores_per_package)
 	vid_max = pattrs->iacore_vids[IACORE_MAX];
 	vid_min = pattrs->iacore_vids[IACORE_LFM];
 
-	/* Hardware coordination of P-states */
-	coord_type = HW_ALL;
+	/* Set P-states coordination type based on MSR disable bit */
+	msr = rdmsr(MSR_PMG_CST_CONFIG_CONTROL);
+	coord_type = (msr.lo & SINGLE_PCTL) ? SW_ALL : HW_ALL;
 
 	/* Max Non-Turbo Frequency */
 	clock_max = (ratio_max * pattrs->bclk_khz) / 1000;
diff --git a/src/soc/intel/baytrail/acpi/dptf/charger.asl b/src/soc/intel/baytrail/acpi/dptf/charger.asl
index 7560f13..7c7f62f 100644
--- a/src/soc/intel/baytrail/acpi/dptf/charger.asl
+++ b/src/soc/intel/baytrail/acpi/dptf/charger.asl
@@ -14,23 +14,46 @@ Device (TCHG)
 		}
 	}
 
-	Name (PPSS, Package ()
+	/* Return charger performance states defined by mainboard */
+	Method (PPSS)
 	{
-		Package () { 0, 0, 0, 0, 0, 0x880, "mA", 0 }, /* 2.1A */
-		Package () { 0, 0, 0, 0, 1, 0x800, "mA", 0 }, /* 2.0A */
-		Package () { 0, 0, 0, 0, 2, 0x600, "mA", 0 }, /* 1.5A */
-		Package () { 0, 0, 0, 0, 3, 0x400, "mA", 0 }, /* 1.0A */
-		Package () { 0, 0, 0, 0, 4, 0x200, "mA", 0 }, /* 0.5A */
-		Package () { 0, 0, 0, 0, 5, 0x000, "mA", 0 }, /* 0.0A */
-	})
+		Return (\_SB.CHPS)
+	}
 
+	/* Return maximum charger current limit */
 	Method (PPPC)
 	{
+		/* Convert size of PPSS table to index */
+		Store (SizeOf (\_SB.CHPS), Local0)
+		Decrement (Local0)
+
+		/* Check if charging is disabled (AC removed) */
+		If (LEqual (\PWRS, Zero)) {
+			/* Return last power state */
+			Return (Local0)
+		} Else {
+			/* Return highest power state */
+			Return (0)
+		}
+
 		Return (0)
 	}
 
-	Method (SPPC, 1, Serialized)
+	/* Set charger current limit */
+	Method (SPPC, 1)
+	{
+		/* Retrieve Control (index 4) for specified PPSS level */
+		Store (DeRefOf (Index (DeRefOf (Index
+			(\_SB.CHPS, ToInteger (Arg0))), 4)), Local0)
+
+		/* Pass Control value to EC to limit charging */
+		\_SB.PCI0.LPCB.EC0.CHGS (Local0)
+	}
+
+	/* Initialize charger participant */
+	Method (INIT)
 	{
-		/* TODO: Tell EC to limit battery charging */
+		/* Disable charge limit */
+		\_SB.PCI0.LPCB.EC0.CHGD ()
 	}
 }
diff --git a/src/soc/intel/baytrail/acpi/dptf/cpu.asl b/src/soc/intel/baytrail/acpi/dptf/cpu.asl
index 93d434b..89f9b8b 100644
--- a/src/soc/intel/baytrail/acpi/dptf/cpu.asl
+++ b/src/soc/intel/baytrail/acpi/dptf/cpu.asl
@@ -115,7 +115,10 @@ Device (TCPU)
 
 	Method (_PDL)
 	{
-		If (CondRefOf (\_PR.CPU0._PSS)) {
+		/* Check for mainboard specific _PDL override */
+		If (CondRefOf (\_SB.MPDL)) {
+			Return (\_SB.MPDL)
+		} ElseIf (CondRefOf (\_PR.CPU0._PSS)) {
 			Store (SizeOf (\_PR.CPU0._PSS ()), Local0)
 			Decrement (Local0)
 			Return (Local0)
diff --git a/src/soc/intel/baytrail/acpi/dptf/dptf.asl b/src/soc/intel/baytrail/acpi/dptf/dptf.asl
index a54478c..9ebfb8c 100644
--- a/src/soc/intel/baytrail/acpi/dptf/dptf.asl
+++ b/src/soc/intel/baytrail/acpi/dptf/dptf.asl
@@ -36,6 +36,11 @@ Device (DPTF)
 		If (LEqual (DeRefOf (Index (IDSP, 0)), Arg0)) {
 			/* Initialize Thermal Devices */
 			^TINI ()
+
+#ifdef DPTF_ENABLE_CHARGER
+			/* Initialize Charger Device */
+			^TCHG.INIT ()
+#endif
 		}
 
 		Return (Arg3)
diff --git a/src/soc/intel/baytrail/acpi/lpe.asl b/src/soc/intel/baytrail/acpi/lpe.asl
index 71a2746..dfa555c 100644
--- a/src/soc/intel/baytrail/acpi/lpe.asl
+++ b/src/soc/intel/baytrail/acpi/lpe.asl
@@ -74,7 +74,7 @@ Device (LPEA)
 
 		/* Append any Mainboard defined GPIOs */
 		If (CondRefOf (^GBUF, Local0)) {
-			ConcatenateResTemplate (^RBUF, Local0, Local1)
+			ConcatenateResTemplate (^RBUF, ^GBUF, Local1)
 			Return (Local1)
 		}
 
diff --git a/src/soc/intel/baytrail/baytrail/gpio.h b/src/soc/intel/baytrail/baytrail/gpio.h
index 05fcf7d..a5ba6a3 100644
--- a/src/soc/intel/baytrail/baytrail/gpio.h
+++ b/src/soc/intel/baytrail/baytrail/gpio.h
@@ -378,4 +378,10 @@ static inline int ssus_get_gpio(int pad)
 	return read32(val_addr) & PAD_VAL_HIGH;
 }
 
+static inline void ssus_disable_internal_pull(int pad)
+{
+	const uint32_t pull_mask = ~(0xf << 7);
+	write32(ssus_pconf0(pad), read32(ssus_pconf0(pad)) & pull_mask);
+}
+
 #endif /* _BAYTRAIL_GPIO_H_ */
diff --git a/src/soc/intel/baytrail/baytrail/lpc.h b/src/soc/intel/baytrail/baytrail/lpc.h
index 31de310..2f6256c 100644
--- a/src/soc/intel/baytrail/baytrail/lpc.h
+++ b/src/soc/intel/baytrail/baytrail/lpc.h
@@ -47,4 +47,8 @@ enum baytrail_stepping {
 	STEP_C0,
 };
 
+/* Registers behind the RCBA_BASE_ADDRESS bar. */
+#define GCS		0x00
+# define BILD		(1 << 0)
+
 #endif /* _BAYTRAIL_LPC_H_ */
diff --git a/src/soc/intel/baytrail/baytrail/mrc_wrapper.h b/src/soc/intel/baytrail/baytrail/mrc_wrapper.h
index 893debc..fc18f0c 100644
--- a/src/soc/intel/baytrail/baytrail/mrc_wrapper.h
+++ b/src/soc/intel/baytrail/baytrail/mrc_wrapper.h
@@ -28,7 +28,7 @@
 #ifndef _MRC_WRAPPER_H_
 #define _MRC_WRAPPER_H_
 
-#define MRC_PARAMS_VER  3
+#define MRC_PARAMS_VER  4
 
 #define NUM_CHANNELS 2
 
@@ -60,6 +60,7 @@ enum mrc_wrapper_error {
 struct mrc_mainboard_params {
 	int dram_type;
 	int dram_info_location; /* DRAM_INFO_* */
+	int weaker_odt_settings; /* Apply weaker on-die-termination settings. */
 	int spd_addrs[NUM_CHANNELS];
 	void *dram_data[NUM_CHANNELS]; /* SPD or Timing specific data. */
 } __attribute__((packed));
diff --git a/src/soc/intel/baytrail/baytrail/msr.h b/src/soc/intel/baytrail/baytrail/msr.h
index dd03af0..656d26a 100644
--- a/src/soc/intel/baytrail/baytrail/msr.h
+++ b/src/soc/intel/baytrail/baytrail/msr.h
@@ -24,12 +24,16 @@
 #define MSR_BSEL_CR_OVERCLOCK_CONTROL	0xcd
 #define MSR_PLATFORM_INFO		0xce
 #define MSR_PMG_CST_CONFIG_CONTROL	0xe2
+#define 	SINGLE_PCTL			(1 << 11)
 #define MSR_POWER_MISC			0x120
+#define 	ENABLE_ULFM_AUTOCM_MASK		(1 << 2)
+#define 	ENABLE_INDP_AUTOCM_MASK		(1 << 3)
 #define MSR_IA32_PERF_CTL		0x199
 #define MSR_IA32_MISC_ENABLES		0x1a0
 #define MSR_POWER_CTL			0x1fc
 #define MSR_PKG_POWER_SKU_UNIT		0x606
 #define MSR_PKG_POWER_LIMIT		0x610
+#define MSR_PP1_POWER_LIMIT		0x638
 #define MSR_IACORE_RATIOS		0x66a
 #define MSR_IACORE_TURBO_RATIOS		0x66c
 #define MSR_IACORE_VIDS			0x66b
@@ -37,6 +41,9 @@
 #define MSR_PKG_TURBO_CFG1		0x670
 #define MSR_CPU_TURBO_WKLD_CFG1		0x671
 #define MSR_CPU_TURBO_WKLD_CFG2		0x672
+#define MSR_CPU_THERM_CFG1		0x673
+#define MSR_CPU_THERM_CFG2		0x674
+#define MSR_CPU_THERM_SENS_CFG		0x675
 
 /* Read BCLK from MSR */
 unsigned bus_freq_khz(void);
diff --git a/src/soc/intel/baytrail/baytrail/spi.h b/src/soc/intel/baytrail/baytrail/spi.h
index 2b7e26e..9c0c29d 100644
--- a/src/soc/intel/baytrail/baytrail/spi.h
+++ b/src/soc/intel/baytrail/baytrail/spi.h
@@ -20,11 +20,48 @@
 #ifndef _BAYTRAIL_SPI_H_
 #define _BAYTRAIL_SPI_H_
 
+#include <stdint.h>
+
 /* These registers live behind SPI_BASE_ADDRESS. */
+#define HSFSTS				0x04
+# define FLOCKDN			(0x1 << 15)
+#define PREOP				0x94
+#define OPTYPE				0x96
+#define OPMENU0				0x98
+#define OPMENU1				0x9c
+#define LVSCC				0xc4
+# define VCL				(0x1 << 23)
+# define EO(x)				(((x) & 0xff) << 8)
+# define WG_1_BYTE			(0x0 << 2)
+# define WG_64_BYTE			(0x1 << 2)
+# define BES_256_BYTE			(0x0 << 0)
+# define BES_4_KB			(0x1 << 0)
+# define BES_8_KB			(0x2 << 0)
+# define BES_64_KB			(0x3 << 0)
+#define UVSCC				0xc8
+#define SCS				0xf8
+# define SMIWPEN			(0x1 << 7)
 #define BCR				0xfc
+# define EISS				(0x1 << 5)
 # define SRC_MASK			(0x3 << 2)
 # define SRC_CACHE_NO_PREFETCH		(0x0 << 2)
 # define SRC_NO_CACHE_NO_PREFETCH	(0x1 << 2)
 # define SRC_CACHE_PREFETCH		(0x2 << 2)
+# define BCR_LE				(0x1 << 1)
+# define BCR_WPD			(0x1 << 0)
+
+/*
+ * SPI lockdown configuration.
+ */
+struct spi_config {
+	uint16_t preop;
+	uint16_t optype;
+	uint32_t opmenu[2];
+	uint32_t lvscc;
+	uint32_t uvscc;
+};
+
+/* Return 0 on success < 0 on failure. */
+int mainboard_get_spi_config(struct spi_config *cfg);
 
 #endif /* _BAYTRAIL_SPI_H_ */
diff --git a/src/soc/intel/baytrail/cpu.c b/src/soc/intel/baytrail/cpu.c
index 15efab9..1bbcb08 100644
--- a/src/soc/intel/baytrail/cpu.c
+++ b/src/soc/intel/baytrail/cpu.c
@@ -55,9 +55,13 @@ static int adjust_apic_id(int index, int apic_id)
 const struct reg_script package_msr_script[] = {
 	/* Set Package TDP to ~7W */
 	REG_MSR_WRITE(MSR_PKG_POWER_LIMIT, 0x3880fa),
+	REG_MSR_RMW(MSR_PP1_POWER_LIMIT, ~(0x7f << 17), 0),
 	REG_MSR_WRITE(MSR_PKG_TURBO_CFG1, 0x702),
 	REG_MSR_WRITE(MSR_CPU_TURBO_WKLD_CFG1, 0x200b),
 	REG_MSR_WRITE(MSR_CPU_TURBO_WKLD_CFG2, 0),
+	REG_MSR_WRITE(MSR_CPU_THERM_CFG1, 0x00000305),
+	REG_MSR_WRITE(MSR_CPU_THERM_CFG2, 0x0405500d),
+	REG_MSR_WRITE(MSR_CPU_THERM_SENS_CFG, 0x27),
 	REG_SCRIPT_END
 };
 
@@ -71,6 +75,29 @@ const struct reg_script core_msr_script[] = {
 	REG_SCRIPT_END
 };
 
+/* Enable hardware coordination for 2-core, disable for 4-core */
+static void baytrail_set_pstate_coord(void)
+{
+	const struct pattrs *pattrs = pattrs_get();
+	msr_t pmg_cst = rdmsr(MSR_PMG_CST_CONFIG_CONTROL);
+	msr_t power_misc = rdmsr(MSR_POWER_MISC);
+
+	if (pattrs->num_cpus > 2) {
+		/* Disable hardware coordination */
+		pmg_cst.lo |= SINGLE_PCTL;
+		power_misc.lo &= ~(ENABLE_ULFM_AUTOCM_MASK |
+				   ENABLE_INDP_AUTOCM_MASK);
+	} else {
+		/* Enable hardware coordination */
+		pmg_cst.lo &= ~SINGLE_PCTL;
+		power_misc.lo |= (ENABLE_ULFM_AUTOCM_MASK |
+				  ENABLE_INDP_AUTOCM_MASK);
+	}
+
+	wrmsr(MSR_PMG_CST_CONFIG_CONTROL, pmg_cst);
+	wrmsr(MSR_POWER_MISC, power_misc);
+}
+
 void baytrail_init_cpus(device_t dev)
 {
 	struct bus *cpu_bus = dev->link_list;
@@ -114,6 +141,9 @@ static void baytrail_core_init(device_t cpu)
 	/* Set core MSRs */
 	reg_script_run(core_msr_script);
 
+	/* Set P-State coordination */
+	baytrail_set_pstate_coord();
+
 	/* Set this core to max frequency ratio */
 	set_max_freq();
 }
diff --git a/src/soc/intel/baytrail/mrc_cache.c b/src/soc/intel/baytrail/mrc_cache.c
index ae0afe7..f12f3ef 100644
--- a/src/soc/intel/baytrail/mrc_cache.c
+++ b/src/soc/intel/baytrail/mrc_cache.c
@@ -174,8 +174,8 @@ int mrc_cache_stash_data(void *data, size_t size)
 		return -1;
 	}
 
-	/* Clear alignment padding bytes. */
-	memset(&cache->data[size], 0, cbmem_size - size);
+	/* Clear alignment padding bytes at end of data. */
+	memset(&cache->data[size], 0, cbmem_size - size - sizeof(*cache));
 
 	printk(BIOS_DEBUG, "Relocate MRC DATA from %p to %p (%zu bytes)\n",
 	       data, cache, size);
@@ -206,7 +206,7 @@ static int mrc_slot_valid(const struct mrc_data_region *region,
 	size = to_save->size + sizeof(*to_save);
 	slot_end = slot_begin + size;
 
-	if (slot_begin < region_begin || slot_begin > region_end)
+	if (slot_begin < region_begin || slot_begin >= region_end)
 		return 0;
 
 	if (size > region->size)
@@ -285,8 +285,11 @@ static void update_mrc_cache(void *unused)
 		next_slot = region.base;
 	}
 
-	nvm_write((void *)next_slot, current_boot,
-	          current_boot->size + sizeof(*current_boot));
+	if (nvm_write((void *)next_slot, current_boot,
+	               current_boot->size + sizeof(*current_boot))) {
+		printk(BIOS_DEBUG, "Failure writing MRC cache to %p.\n",
+		       next_slot);
+	}
 }
 
 BOOT_STATE_INIT_ENTRIES(mrc_cache_update) = {
diff --git a/src/soc/intel/baytrail/nvm.c b/src/soc/intel/baytrail/nvm.c
index 0cc64f5..0cd42cc 100644
--- a/src/soc/intel/baytrail/nvm.c
+++ b/src/soc/intel/baytrail/nvm.c
@@ -70,8 +70,7 @@ int nvm_erase(void *start, size_t size)
 {
 	if (nvm_init() < 0)
 		return -1;
-	flash->erase(flash, to_flash_offset(start), size);
-	return 0;
+	return flash->erase(flash, to_flash_offset(start), size);
 }
 
 /* Write data to NVM. Returns 0 on success < 0 on error.  */
@@ -79,6 +78,5 @@ int nvm_write(void *start, const void *data, size_t size)
 {
 	if (nvm_init() < 0)
 		return -1;
-	flash->write(flash, to_flash_offset(start), size, data);
-	return 0;
+	return flash->write(flash, to_flash_offset(start), size, data);
 }
diff --git a/src/soc/intel/baytrail/romstage/romstage.c b/src/soc/intel/baytrail/romstage/romstage.c
index 3a1d65d..1c08f33 100644
--- a/src/soc/intel/baytrail/romstage/romstage.c
+++ b/src/soc/intel/baytrail/romstage/romstage.c
@@ -98,9 +98,19 @@ static void program_base_addresses(void)
 
 static void spi_init(void)
 {
+	const unsigned long scs = SPI_BASE_ADDRESS + SCS;
 	const unsigned long bcr = SPI_BASE_ADDRESS + BCR;
-	/* Enable caching and prefetching in the SPI controller. */
-	write32(bcr, (read32(bcr) & ~SRC_MASK) | SRC_CACHE_PREFETCH);
+	uint32_t reg;
+
+	/* Disable generating SMI when setting WPD bit. */
+	write32(scs, read32(scs) & ~SMIWPEN);
+	/*
+	 * Enable caching and prefetching in the SPI controller. Disable
+	 * the SMM-only BIOS write and set WPD bit.
+	 */
+	reg = (read32(bcr) & ~SRC_MASK) | SRC_CACHE_PREFETCH | BCR_WPD;
+	reg &= ~EISS;
+	write32(bcr, reg);
 }
 
 static inline void mark_ts(struct romstage_params *rp, uint64_t ts)
@@ -239,15 +249,17 @@ void romstage_common(struct romstage_params *params)
 
 	mark_ts(params, timestamp_get());
 
-#if CONFIG_ELOG_BOOT_COUNT
-	boot_count_increment();
-#endif
-
 	ps = fill_power_state();
 	prev_sleep_state = chipset_prev_sleep_state(ps);
 
 	printk(BIOS_DEBUG, "prev_sleep_state = S%d\n", prev_sleep_state);
 
+#if CONFIG_ELOG_BOOT_COUNT
+	if (prev_sleep_state != 3)
+		boot_count_increment();
+#endif
+
+
 	/* Initialize RAM */
 	raminit(params->mrc_params, prev_sleep_state);
 
@@ -268,21 +280,8 @@ void romstage_common(struct romstage_params *params)
 	timestamp_add(TS_AFTER_INITRAM, ts64_to_tsc(params->ts.times[3]));
 }
 
-static void open_up_spi(void)
-{
-	const uintptr_t sbase = SPI_BASE_ADDRESS;
-
-	/* Disable generating SMI when setting WPD bit. */
-	write32(sbase + 0xf8, read32(sbase + 0xf8) & ~(1 << 7));
-	/* Disable the SMM-only BIOS write and set WPD bit. */
-	write32(sbase + 0xfc, 1 | (read32(sbase + 0xfc) & ~(1 << 5)));
-}
-
 void asmlinkage romstage_after_car(void)
 {
-	/* Allow BIOS to program SPI part. */
-	open_up_spi();
-
 	timestamp_add_now(TS_END_ROMSTAGE);
 
 	/* Load the ramstage. */
diff --git a/src/soc/intel/baytrail/southcluster.c b/src/soc/intel/baytrail/southcluster.c
index bcce792..49e4c91 100644
--- a/src/soc/intel/baytrail/southcluster.c
+++ b/src/soc/intel/baytrail/southcluster.c
@@ -20,8 +20,10 @@
 
 #include <stdint.h>
 #include <arch/io.h>
+#include <bootstate.h>
 #include <cbmem.h>
 #include <console/console.h>
+#include <cpu/x86/smm.h>
 #include <device/device.h>
 #include <device/pci.h>
 #include <device/pci_ids.h>
@@ -35,6 +37,7 @@
 #include <baytrail/pci_devs.h>
 #include <baytrail/pmc.h>
 #include <baytrail/ramstage.h>
+#include <baytrail/spi.h>
 #include "chip.h"
 
 static inline void
@@ -482,3 +485,52 @@ static const struct pci_driver southcluster __pci_driver = {
 	.vendor		= PCI_VENDOR_ID_INTEL,
 	.device		= LPC_DEVID,
 };
+
+int __attribute__((weak)) mainboard_get_spi_config(struct spi_config *cfg)
+{
+	return -1;
+}
+
+static void finalize_chipset(void *unused)
+{
+	const unsigned long bcr = SPI_BASE_ADDRESS + BCR;
+	const unsigned long gcs = RCBA_BASE_ADDRESS + GCS;
+	const unsigned long gen_pmcon2 = PMC_BASE_ADDRESS + GEN_PMCON2;
+	const unsigned long etr = PMC_BASE_ADDRESS + ETR;
+	const unsigned long spi = SPI_BASE_ADDRESS;
+	struct spi_config cfg;
+
+	/* Set the lock enable on the BIOS control register. */
+	write32(bcr, read32(bcr) | BCR_LE);
+
+	/* Set BIOS lock down bit controlling boot block size and swapping. */
+	write32(gcs, read32(gcs) | BILD);
+
+	/* Lock sleep stretching policy and set SMI lock. */
+	write32(gen_pmcon2, read32(gen_pmcon2) | SLPSX_STR_POL_LOCK | SMI_LOCK);
+
+	/*  Set the CF9 lock. */
+	write32(etr, read32(etr) | CF9LOCK);
+
+	if (mainboard_get_spi_config(&cfg) < 0) {
+		printk(BIOS_DEBUG, "No SPI lockdown configuration.\n");
+	} else {
+		write16(spi + PREOP, cfg.preop);
+		write16(spi + OPTYPE, cfg.optype);
+		write32(spi + OPMENU0, cfg.opmenu[0]);
+		write32(spi + OPMENU1, cfg.opmenu[1]);
+		write16(spi + HSFSTS, read16(spi + HSFSTS) | FLOCKDN);
+		write32(spi + UVSCC, cfg.uvscc);
+		write32(spi + LVSCC, cfg.lvscc | VCL);
+	}
+
+	printk(BIOS_DEBUG, "Finalizing SMM.\n");
+	outb(APM_CNT_FINALIZE, APM_CNT);
+}
+
+BOOT_STATE_INIT_ENTRIES(finalize_bscb) = {
+	BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY,
+	                      finalize_chipset, NULL),
+	BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD, BS_ON_EXIT,
+	                      finalize_chipset, NULL),
+};
diff --git a/src/soc/intel/baytrail/spi.c b/src/soc/intel/baytrail/spi.c
index 0dc980f..8677b61 100644
--- a/src/soc/intel/baytrail/spi.c
+++ b/src/soc/intel/baytrail/spi.c
@@ -481,7 +481,7 @@ static int spi_setup_offset(spi_transaction *trans)
  */
 static int ich_status_poll(u16 bitmask, int wait_til_set)
 {
-	int timeout = 6000; /* This will result in 60 ms */
+	int timeout = 40000; /* This will result in 400 ms */
 	u16 status = 0;
 
 	while (timeout--) {



More information about the coreboot-gerrit mailing list