[coreboot-gerrit] Patch set updated for coreboot: intel/apollolake: Enable SPI properly in bootblock and ramstage

Furquan Shaikh (furquan@google.com) gerrit at coreboot.org
Mon Jun 20 19:33:54 CEST 2016


Furquan Shaikh (furquan at google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/15209

-gerrit

commit 193da5d4e88532802710fa21c21b78a76913ff38
Author: Furquan Shaikh <furquan at google.com>
Date:   Wed Jun 15 17:13:20 2016 -0700

    intel/apollolake: Enable SPI properly in bootblock and ramstage
    
    Bootblock:
       - Temporary BAR needs to be assigned for SPI device until PCI
       enumeration is done by ramstage which allocates a new BAR.
       - Call spi_init to allow bootblock/verstage to write/erase on flash.
    
    Ramstage:
       - spi_init needs to run in ramstage to allow write protect to be
       disabled for eventlog and NVRAM updates. This needs to be done pretty
       early so that any init calls(e.g. mainboard_ec_init) writing to flash
       work properly.
    
    Verified with this change that there are no more flash write/erase
    errors for ELOG/NVRAM.
    
    BUG=chrome-os-partner:54283
    
    Change-Id: Iff840e055548485e6521889fcf264a10fb5d9491
    Signed-off-by: Furquan Shaikh <furquan at google.com>
---
 src/soc/intel/apollolake/Makefile.inc          |  1 +
 src/soc/intel/apollolake/bootblock/bootblock.c | 32 ++++++++++++++++++++++++++
 src/soc/intel/apollolake/chip.c                | 14 +++++++++++
 src/soc/intel/apollolake/include/soc/iomap.h   |  3 +++
 4 files changed, 50 insertions(+)

diff --git a/src/soc/intel/apollolake/Makefile.inc b/src/soc/intel/apollolake/Makefile.inc
index 38ed07d..a840ad5 100644
--- a/src/soc/intel/apollolake/Makefile.inc
+++ b/src/soc/intel/apollolake/Makefile.inc
@@ -15,6 +15,7 @@ bootblock-y += car.c
 bootblock-y += gpio.c
 bootblock-y += lpc_lib.c
 bootblock-y += mmap_boot.c
+bootblock-y += spi.c
 bootblock-y += tsc_freq.c
 bootblock-$(CONFIG_SOC_UART_DEBUG) += uart_early.c
 
diff --git a/src/soc/intel/apollolake/bootblock/bootblock.c b/src/soc/intel/apollolake/bootblock/bootblock.c
index ca402e9..deec368 100644
--- a/src/soc/intel/apollolake/bootblock/bootblock.c
+++ b/src/soc/intel/apollolake/bootblock/bootblock.c
@@ -25,6 +25,7 @@
 #include <soc/northbridge.h>
 #include <soc/pci_devs.h>
 #include <soc/uart.h>
+#include <spi-generic.h>
 #include <timestamp.h>
 
 static const struct pad_config tpm_spi_configs[] = {
@@ -101,6 +102,35 @@ static void cache_bios_region(void)
 	set_var_mtrr(mtrr, 4ULL*GiB - rom_size, rom_size, MTRR_TYPE_WRPROT);
 }
 
+/*
+ * Program temporary BAR for SPI in case any of the stages before ramstage need
+ * to access SPI MMIO regs. Ramstage will assign a new BAR during PCI
+ * enumeration.
+ */
+static void enable_spibar(void)
+{
+	device_t dev = SPI_DEV;
+	uint8_t val;
+
+	/* Disable Bus Master and MMIO space. */
+	val = pci_read_config8(dev, PCI_COMMAND);
+	val &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
+	pci_write_config8(dev, PCI_COMMAND, val);
+
+	/* Program Temporary BAR for SPI */
+	pci_write_config32(dev, PCI_BASE_ADDRESS_0,
+			   PRERAM_SPI_BASE_ADDRESS |
+			   PCI_BASE_ADDRESS_SPACE_MEMORY);
+
+	/* Enable Bus Master and MMIO Space */
+	val = pci_read_config8(dev, PCI_COMMAND);
+	val |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+	pci_write_config8(dev, PCI_COMMAND, val);
+
+	/* Initialize SPI to allow BIOS to write/erase on flash. */
+	spi_init();
+}
+
 void bootblock_soc_early_init(void)
 {
 	/* Prepare UART for serial console. */
@@ -112,5 +142,7 @@ void bootblock_soc_early_init(void)
 
 	enable_pm_timer();
 
+	enable_spibar();
+
 	cache_bios_region();
 }
diff --git a/src/soc/intel/apollolake/chip.c b/src/soc/intel/apollolake/chip.c
index 94a101f..4fa4ce4 100644
--- a/src/soc/intel/apollolake/chip.c
+++ b/src/soc/intel/apollolake/chip.c
@@ -31,6 +31,7 @@
 #include <soc/intel/common/vbt.h>
 #include <soc/nvs.h>
 #include <soc/pci_devs.h>
+#include <spi-generic.h>
 
 #include "chip.h"
 
@@ -164,3 +165,16 @@ BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD, BS_ON_EXIT, fsp_notify_dummy,
 						(void *) READY_TO_BOOT);
 BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, fsp_notify_dummy,
 						(void *) READY_TO_BOOT);
+
+/*
+ * spi_init() needs to run unconditionally on every boot (including resume) to
+ * allow write protect to be disabled for eventlog and nvram updates. This needs
+ * to be done as early as possible in ramstage. Thus, add a callback for entry
+ * into BS_PRE_DEVICE.
+ */
+static void spi_init_cb(void *unused)
+{
+	spi_init();
+}
+
+BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, spi_init_cb, NULL);
diff --git a/src/soc/intel/apollolake/include/soc/iomap.h b/src/soc/intel/apollolake/include/soc/iomap.h
index e676ba5..716c2a6 100644
--- a/src/soc/intel/apollolake/include/soc/iomap.h
+++ b/src/soc/intel/apollolake/include/soc/iomap.h
@@ -30,4 +30,7 @@
 #define PMC_BAR0			0xfe042000
 #define PMC_BAR1			0xfe044000
 
+/* Temporary BAR for SPI until PCI enumeration assigns a BAR in ramstage. */
+#define PRERAM_SPI_BASE_ADDRESS	0xfe010000
+
 #endif /* _SOC_APOLLOLAKE_IOMAP_H_ */



More information about the coreboot-gerrit mailing list