diff --git a/src/soc/intel/baytrail/baytrail/spi.h b/src/soc/intel/baytrail/baytrail/spi.h index 904e7a1d08..ee1648a135 100644 --- a/src/soc/intel/baytrail/baytrail/spi.h +++ b/src/soc/intel/baytrail/baytrail/spi.h @@ -20,7 +20,25 @@ #ifndef _BAYTRAIL_SPI_H_ #define _BAYTRAIL_SPI_H_ +#include + /* These registers live behind SPI_BASE_ADDRESS. */ +#define HSFSTS 0x04 +# define FLOCKDN (0x1 << 15) +#define PREOP 0x94 +#define OPTYPE 0x96 +#define OPMENU0 0x98 +#define OPMENU1 0x9c +#define LVSCC 0xc4 +# define VCL (0x1 << 23) +# define EO(x) (((x) & 0xff) << 8) +# define WG_1_BYTE (0x0 << 2) +# define WG_64_BYTE (0x1 << 2) +# define BES_256_BYTE (0x0 << 0) +# define BES_4_KB (0x1 << 0) +# define BES_8_KB (0x2 << 0) +# define BES_64_KB (0x3 << 0) +#define UVSCC 0xc8 #define SCS 0xf8 # define SMIWPEN (0x1 << 7) #define BCR 0xfc @@ -32,5 +50,19 @@ # define BCR_LE (0x1 << 1) # define BCR_WPD (0x1 << 0) +/* + * SPI lockdown configuration. + */ +struct spi_config { + uint16_t preop; + uint16_t optype; + uint32_t opmenu[2]; + uint32_t lvscc; + uint32_t uvscc; +}; + +/* Return 0 on success < 0 on failure. */ +int mainboard_get_spi_config(struct spi_config *cfg); + #endif /* _BAYTRAIL_SPI_H_ */ diff --git a/src/soc/intel/baytrail/southcluster.c b/src/soc/intel/baytrail/southcluster.c index c0bfd1e202..3f46f6a3be 100644 --- a/src/soc/intel/baytrail/southcluster.c +++ b/src/soc/intel/baytrail/southcluster.c @@ -423,12 +423,19 @@ static const struct pci_driver southcluster __pci_driver = { .device = LPC_DEVID, }; +int __attribute__((weak)) mainboard_get_spi_config(struct spi_config *cfg) +{ + return -1; +} + static void finalize_chipset(void *unused) { const unsigned long bcr = SPI_BASE_ADDRESS + BCR; const unsigned long gcs = RCBA_BASE_ADDRESS + GCS; const unsigned long gen_pmcon2 = PMC_BASE_ADDRESS + GEN_PMCON2; const unsigned long etr = PMC_BASE_ADDRESS + ETR; + const unsigned long spi = SPI_BASE_ADDRESS; + struct spi_config cfg; /* Set the lock enable on the BIOS control register. */ write32(bcr, read32(bcr) | BCR_LE); @@ -442,6 +449,18 @@ static void finalize_chipset(void *unused) /* Set the CF9 lock. */ write32(etr, read32(etr) | CF9LOCK); + if (mainboard_get_spi_config(&cfg) < 0) { + printk(BIOS_DEBUG, "No SPI lockdown configuration.\n"); + } else { + write16(spi + PREOP, cfg.preop); + write16(spi + OPTYPE, cfg.optype); + write32(spi + OPMENU0, cfg.opmenu[0]); + write32(spi + OPMENU1, cfg.opmenu[1]); + write16(spi + HSFSTS, read16(spi + HSFSTS) | FLOCKDN); + write32(spi + UVSCC, cfg.uvscc); + write32(spi + LVSCC, cfg.lvscc | VCL); + } + printk(BIOS_DEBUG, "Finalizing SMM.\n"); outb(APM_CNT_FINALIZE, APM_CNT); }