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>
This commit is contained in:
Nico Huber 2018-02-04 15:52:18 +01:00 committed by Martin Roth
parent 385e8fc5a9
commit 8e50b6d63d
3 changed files with 38 additions and 7 deletions

View File

@ -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 */

View File

@ -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));

View File

@ -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) ||