summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Zeh <werner.zeh@siemens.com>2018-09-19 11:06:22 +0200
committerWerner Zeh <werner.zeh@siemens.com>2018-10-04 04:56:27 +0000
commitd5de063dffe5c0daa56453f669af65dde09e446a (patch)
tree038224eb40dd3c906ce714dc1533942d71143a97
parent0612f8d7d587cb0b559fa1f4ce7fca5282b283d1 (diff)
downloadcoreboot-d5de063dffe5c0daa56453f669af65dde09e446a.tar.xz
mc_apl1: Set up SPI OPCODE menu before locking
In order to enable the OS SPI driver to use the software interface of this controller the OPCODE menu has to be set up properly before locking the controller. This is done on baseboard level so that all variants will get this done as well. Change-Id: I0bf0619ff0610c00325f03d13b6794aee8a62504 Signed-off-by: Werner Zeh <werner.zeh@siemens.com> Reviewed-on: https://review.coreboot.org/28834 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net> Reviewed-by: Mario Scheithauer <mario.scheithauer@siemens.com>
-rw-r--r--src/mainboard/siemens/mc_apl1/mainboard.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/src/mainboard/siemens/mc_apl1/mainboard.c b/src/mainboard/siemens/mc_apl1/mainboard.c
index b81da5f794..1d37d682b2 100644
--- a/src/mainboard/siemens/mc_apl1/mainboard.c
+++ b/src/mainboard/siemens/mc_apl1/mainboard.c
@@ -36,6 +36,51 @@
#define BIOS_MAILBOX_INTERFACE 0x7084
#define RUN_BUSY_STS (1 << 31)
+/*
+ * SPI Opcode Menu setup for SPIBAR lock down
+ * should support most common flash chips.
+ */
+#define SPI_OPMENU_0 0x01 /* WRSR: Write Status Register */
+#define SPI_OPTYPE_0 0x01 /* Write, no address */
+
+#define SPI_OPMENU_1 0x02 /* PP: Page 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_OPMENU_UPPER ((SPI_OPMENU_7 << 24) | (SPI_OPMENU_6 << 16) | \
+ (SPI_OPMENU_5 << 8) | SPI_OPMENU_4)
+#define SPI_OPMENU_LOWER ((SPI_OPMENU_3 << 24) | (SPI_OPMENU_2 << 16) | \
+ (SPI_OPMENU_1 << 8) | SPI_OPMENU_0)
+
+#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))
+
+#define SPI_OPPREFIX ((0x50 << 8) | 0x06) /* EWSR and WREN */
+
+#define SPIBAR_OFFSET 0x3800
+#define SPI_REG_PREOP_OPTYPE 0xa4
+#define SPI_REG_OPMENU_L 0xa8
+#define SPI_REG_OPMENU_H 0xac
+
/** \brief This function can decide if a given MAC address is valid or not.
* Currently, addresses filled with 0xff or 0x00 are not valid.
* @param mac Buffer to the MAC address to check
@@ -197,6 +242,7 @@ static void mainboard_final(void *chip_info)
{
uint16_t cmd = 0;
struct device *dev = NULL;
+ void *spi_base = NULL;
/* Do board specific things */
variant_mainboard_final();
@@ -208,6 +254,15 @@ static void mainboard_final(void *chip_info)
cmd |= PCI_COMMAND_MASTER;
pci_write_config16(dev, PCI_COMMAND, cmd);
}
+ /* Set up SPI OPCODE menu before the controller is locked. */
+ dev = PCH_DEV_SPI;
+ spi_base = (void *)pci_read_config32(dev, PCI_BASE_ADDRESS_0);
+ if (!spi_base)
+ return;
+ write32((spi_base + SPI_REG_PREOP_OPTYPE),
+ ((SPI_OPTYPE << 16) | SPI_OPPREFIX));
+ write32((spi_base + SPI_REG_OPMENU_L), SPI_OPMENU_LOWER);
+ write32((spi_base + SPI_REG_OPMENU_H), SPI_OPMENU_UPPER);
}
/* The following function performs board specific things. */