diff options
Diffstat (limited to 'src/soc/intel/broadwell/spi.c')
-rw-r--r-- | src/soc/intel/broadwell/spi.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/src/soc/intel/broadwell/spi.c b/src/soc/intel/broadwell/spi.c index 6d2f103d8a..0fca05951b 100644 --- a/src/soc/intel/broadwell/spi.c +++ b/src/soc/intel/broadwell/spi.c @@ -29,6 +29,8 @@ #include <device/pci_ids.h> #include <spi-generic.h> #include <soc/pci_devs.h> +#include <soc/rcba.h> +#include <soc/spi.h> #ifdef __SMM__ #define pci_read_config_byte(dev, reg, targ)\ @@ -637,3 +639,40 @@ int spi_xfer(struct spi_slave *slave, const void *dout, return 0; } + +/* Use first empty Protected Range Register to cover region of flash */ +int spi_flash_protect(u32 start, u32 size) +{ + u32 end = start + size - 1; + u32 reg; + int prr; + + /* Find first empty PRR */ + for (prr = 0; prr < SPI_PRR_MAX; prr++) { + reg = SPIBAR32(SPI_PRR(prr)); + if (reg == 0) + break; + } + if (prr >= SPI_PRR_MAX) { + printk(BIOS_ERR, "ERROR: No SPI PRR free!\n"); + return -1; + } + + /* Set protected range base and limit */ + reg = ((end >> SPI_PRR_SHIFT) & SPI_PRR_MASK); + reg <<= SPI_PRR_LIMIT_SHIFT; + reg |= ((start >> SPI_PRR_SHIFT) & SPI_PRR_MASK); + reg |= SPI_PRR_WPE; + + /* Set the PRR register and verify it is protected */ + SPIBAR32(SPI_PRR(prr)) = reg; + reg = SPIBAR32(SPI_PRR(prr)); + if (!(reg & SPI_PRR_WPE)) { + printk(BIOS_ERR, "ERROR: Unable to set SPI PRR %d\n", prr); + return -1; + } + + printk(BIOS_INFO, "%s: PRR %d is enabled for range 0x%08x-0x%08x\n", + __func__, prr, start, end); + return 0; +} |