summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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) ||