diff options
author | Rizwan Qureshi <rizwan.qureshi@intel.com> | 2018-12-31 15:19:16 +0530 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2019-01-21 13:25:31 +0000 |
commit | f9f50936446e8e441238ecfe12ce0fc9e04d491a (patch) | |
tree | 2ce1ff776d013c72c8394da623f801facf7bd100 /src/soc/intel | |
parent | afe15f0a34fd02ef024d48d2b047ecd4ef559d74 (diff) |
drivers/spi: Add controller protection type
Some SPI controllers support both READ and WRITE protection
add a variable to the protect API for the callers to specify
the kind of protection they want (Read/Write/Both).
Also, update the callers and protect API implementation.
BUG=None
BRANCH=None
TEST=test that the mrc cache is protected as expected on soraka.
Also tried if the read protection is applied correctly.
Change-Id: I093884c4768b08a378f21242ac82e430ac013d15
Signed-off-by: Rizwan Qureshi <rizwan.qureshi@intel.com>
Reviewed-on: https://review.coreboot.org/c/30559
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Rudolph <siro@das-labor.org>
Diffstat (limited to 'src/soc/intel')
-rw-r--r-- | src/soc/intel/broadwell/include/soc/spi.h | 1 | ||||
-rw-r--r-- | src/soc/intel/broadwell/spi.c | 24 | ||||
-rw-r--r-- | src/soc/intel/common/block/fast_spi/fast_spi_flash.c | 23 |
3 files changed, 42 insertions, 6 deletions
diff --git a/src/soc/intel/broadwell/include/soc/spi.h b/src/soc/intel/broadwell/include/soc/spi.h index 588af17609..5ad62fd19d 100644 --- a/src/soc/intel/broadwell/include/soc/spi.h +++ b/src/soc/intel/broadwell/include/soc/spi.h @@ -38,6 +38,7 @@ #define SPI_PRR_BASE_SHIFT 0 #define SPI_PRR_LIMIT_SHIFT 16 #define SPI_PRR_WPE (1 << 31) +#define SPI_PRR_RPE (1 << 15) #define SPIBAR_PREOP 0x94 #define SPIBAR_OPTYPE 0x96 diff --git a/src/soc/intel/broadwell/spi.c b/src/soc/intel/broadwell/spi.c index 2317c9a137..de3d061aea 100644 --- a/src/soc/intel/broadwell/spi.c +++ b/src/soc/intel/broadwell/spi.c @@ -615,11 +615,13 @@ static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, /* Use first empty Protected Range Register to cover region of flash */ static int spi_flash_protect(const struct spi_flash *flash, - const struct region *region) + const struct region *region, + const enum ctrlr_prot_type type) { u32 start = region_offset(region); u32 end = start + region_sz(region) - 1; u32 reg; + u32 protect_mask = 0; int prr; /* Find first empty PRR */ @@ -637,12 +639,28 @@ static int spi_flash_protect(const struct spi_flash *flash, 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; + + switch (type) { + case WRITE_PROTECT: + protect_mask |= SPI_PRR_WPE; + break; + case READ_PROTECT: + protect_mask |= SPI_PRR_RPE; + break; + case READ_WRITE_PROTECT: + protect_mask |= (SPI_PRR_RPE | SPI_PRR_WPE); + break; + default: + printk(BIOS_ERR, "ERROR: Seeking invalid protection!\n"); + return -1; + } + + reg |= protect_mask; /* Set the PRR register and verify it is protected */ SPIBAR32(SPI_PRR(prr)) = reg; reg = SPIBAR32(SPI_PRR(prr)); - if (!(reg & SPI_PRR_WPE)) { + if (!(reg & protect_mask)) { printk(BIOS_ERR, "ERROR: Unable to set SPI PRR %d\n", prr); return -1; } diff --git a/src/soc/intel/common/block/fast_spi/fast_spi_flash.c b/src/soc/intel/common/block/fast_spi/fast_spi_flash.c index 4579b19151..65708a6b19 100644 --- a/src/soc/intel/common/block/fast_spi/fast_spi_flash.c +++ b/src/soc/intel/common/block/fast_spi/fast_spi_flash.c @@ -367,11 +367,13 @@ static int fast_spi_flash_ctrlr_setup(const struct spi_slave *dev) * Protected Range (FPR) register if available. */ static int fast_spi_flash_protect(const struct spi_flash *flash, - const struct region *region) + const struct region *region, + const enum ctrlr_prot_type type) { u32 start = region_offset(region); u32 end = start + region_sz(region) - 1; u32 reg; + u32 protect_mask = 0; int fpr; uintptr_t fpr_base; BOILERPLATE_CREATE_CTX(ctx); @@ -391,13 +393,28 @@ static int fast_spi_flash_protect(const struct spi_flash *flash, return -1; } + switch (type) { + case WRITE_PROTECT: + protect_mask |= SPI_FPR_WPE; + break; + case READ_PROTECT: + protect_mask |= SPI_FPR_RPE; + break; + case READ_WRITE_PROTECT: + protect_mask |= (SPI_FPR_RPE | SPI_FPR_WPE); + break; + default: + printk(BIOS_ERR, "ERROR: Seeking invalid protection!\n"); + return -1; + } + /* Set protected range base and limit */ - reg = SPI_FPR(start, end) | SPI_FPR_WPE; + reg = SPI_FPR(start, end) | protect_mask; /* Set the FPR register and verify it is protected */ write32((void *)fpr_base, reg); reg = read32((void *)fpr_base); - if (!(reg & SPI_FPR_WPE)) { + if (!(reg & protect_mask)) { printk(BIOS_ERR, "ERROR: Unable to set SPI FPR %d\n", fpr); return -1; } |