summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNico Huber <nico.h@gmx.de>2018-02-04 15:52:18 +0100
committerMartin Roth <martinroth@google.com>2018-04-05 15:58:37 +0000
commit8e50b6d63dd05bbc23e2d55a35df77ddb1ba4575 (patch)
treeef1cde40dfc31d3b2693eda79b59509d89656eb7
parent385e8fc5a940da9933387b7557e5031f4c4387d2 (diff)
sb/intel/bd82x6x: Let mainboard override SPI opmenu
For some SPI chips (e.g. those with AAI writes), the default OPMENU definitions don't work well. Thus, provide an option to override the defaults in the devicetree. Writing the OPMENU now happens in ramstage instead of the SMM finalize handler. If you let coreboot call the finalize handler, nothing should change. If you call the handler from your payload, OTOH, the OPMENU might have been changed in between, so be careful what you lock. Change-Id: I9ceaf5b2d11365e21a2bebc9c5def1fcf0be8aad Signed-off-by: Nico Huber <nico.h@gmx.de> Reviewed-on: https://review.coreboot.org/23587 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Nicola Corna <nicola@corna.info> Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
-rw-r--r--src/southbridge/intel/bd82x6x/chip.h8
-rw-r--r--src/southbridge/intel/bd82x6x/finalize.c9
-rw-r--r--src/southbridge/intel/bd82x6x/lpc.c28
3 files changed, 38 insertions, 7 deletions
diff --git a/src/southbridge/intel/bd82x6x/chip.h b/src/southbridge/intel/bd82x6x/chip.h
index e1064a721f..ce8a804d50 100644
--- a/src/southbridge/intel/bd82x6x/chip.h
+++ b/src/southbridge/intel/bd82x6x/chip.h
@@ -95,6 +95,14 @@ struct southbridge_intel_bd82x6x_config {
uint32_t spi_uvscc;
uint32_t spi_lvscc;
+ struct {
+ uint8_t opprefixes[2];
+ struct {
+ uint8_t needs_address;
+ uint8_t is_write;
+ uint8_t op;
+ } ops[8];
+ } spi;
};
#endif /* SOUTHBRIDGE_INTEL_BD82X6X_CHIP_H */
diff --git a/src/southbridge/intel/bd82x6x/finalize.c b/src/southbridge/intel/bd82x6x/finalize.c
index 6b38fcd563..f5cd9cc274 100644
--- a/src/southbridge/intel/bd82x6x/finalize.c
+++ b/src/southbridge/intel/bd82x6x/finalize.c
@@ -18,8 +18,9 @@
#include <console/post_codes.h>
#include <cpu/x86/smm.h>
#include <southbridge/intel/common/rcba.h>
-#include "pch.h"
#include <spi-generic.h>
+#include "chip.h"
+#include "pch.h"
void intel_pch_finalize_smm(void)
{
@@ -38,12 +39,6 @@ void intel_pch_finalize_smm(void)
RCBA32(0x3874 + i) = RCBA32(0x3854 + i) | lockmask;
}
- /* Set SPI opcode menu */
- RCBA16(0x3894) = SPI_OPPREFIX;
- RCBA16(0x3896) = SPI_OPTYPE;
- RCBA32(0x3898) = SPI_OPMENU_LOWER;
- RCBA32(0x389c) = SPI_OPMENU_UPPER;
-
/* Lock SPIBAR */
RCBA32_OR(0x3804, (1 << 15));
diff --git a/src/southbridge/intel/bd82x6x/lpc.c b/src/southbridge/intel/bd82x6x/lpc.c
index 67570cd0be..c57eeca769 100644
--- a/src/southbridge/intel/bd82x6x/lpc.c
+++ b/src/southbridge/intel/bd82x6x/lpc.c
@@ -829,6 +829,34 @@ static void southbridge_fill_ssdt(device_t device)
static void lpc_final(struct device *dev)
{
+ u16 spi_opprefix = SPI_OPPREFIX;
+ u16 spi_optype = SPI_OPTYPE;
+ u32 spi_opmenu[2] = { SPI_OPMENU_LOWER, SPI_OPMENU_UPPER };
+
+ /* Configure SPI opcode menu; devicetree may override defaults. */
+ const config_t *const config = dev->chip_info;
+ if (config && config->spi.ops[0].op) {
+ unsigned int i;
+
+ spi_opprefix = 0;
+ spi_optype = 0;
+ spi_opmenu[0] = 0;
+ spi_opmenu[1] = 0;
+ for (i = 0; i < sizeof(spi_opprefix); ++i)
+ spi_opprefix |= config->spi.opprefixes[i] << i * 8;
+ for (i = 0; i < sizeof(spi_opmenu); ++i) {
+ spi_optype |=
+ config->spi.ops[i].is_write << 2 * i |
+ config->spi.ops[i].needs_address << (2 * i + 1);
+ spi_opmenu[i / 4] |=
+ config->spi.ops[i].op << (i % 4) * 8;
+ }
+ }
+ RCBA16(0x3894) = spi_opprefix;
+ RCBA16(0x3896) = spi_optype;
+ RCBA32(0x3898) = spi_opmenu[0];
+ RCBA32(0x389c) = spi_opmenu[1];
+
/* Call SMM finalize() handlers before resume */
if (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)) {
if (IS_ENABLED(CONFIG_INTEL_CHIPSET_LOCKDOWN) ||