summaryrefslogtreecommitdiff
path: root/src/soc
diff options
context:
space:
mode:
authorBarnali Sarkar <barnali.sarkar@intel.com>2017-07-19 16:09:56 +0530
committerAaron Durbin <adurbin@chromium.org>2017-07-25 14:56:13 +0000
commit8e51319b03894d7a838db247a4969ccef8969c13 (patch)
treed690c03b8b8c688f3981cf3bd78fcf0845ecb7ab /src/soc
parent4635787895a5f30b573e1e34ddbf723588ff847a (diff)
soc/intel/common/block: Modify fast_spi_lock_bar function
Use 16bit write to avoid touching the upper two bytes that may cause write cycle to fail in case a prior transaction has not completed. This function sets the WRSDIS(Bit 11) and FLOCKDN (Bit 15) of the SPIBAR + BIOS_HSFSTS_CTL. While WRSDIS is lockable with FLOCKDN, writing both in the same cycle is guaranteed to work by design. Avoid read->modify->write operation not to clear the RW1C bits unintentionally. Change-Id: Ia7880aaca0ed64150c994d49786a0a008bbaa98b Signed-off-by: Barnali Sarkar <barnali.sarkar@intel.com> Reviewed-on: https://review.coreboot.org/20643 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net> Reviewed-by: Aaron Durbin <adurbin@chromium.org> Reviewed-by: Furquan Shaikh <furquan@google.com>
Diffstat (limited to 'src/soc')
-rw-r--r--src/soc/intel/common/block/fast_spi/fast_spi.c12
-rw-r--r--src/soc/intel/common/block/fast_spi/fast_spi_def.h1
2 files changed, 9 insertions, 4 deletions
diff --git a/src/soc/intel/common/block/fast_spi/fast_spi.c b/src/soc/intel/common/block/fast_spi/fast_spi.c
index dd21143798..fe0217adad 100644
--- a/src/soc/intel/common/block/fast_spi/fast_spi.c
+++ b/src/soc/intel/common/block/fast_spi/fast_spi.c
@@ -134,15 +134,19 @@ void fast_spi_set_opcode_menu(void)
/*
* Lock FAST_SPIBAR.
+ * Use 16bit write to avoid touching two upper bytes what may cause the write
+ * cycle to fail in case a prior transaction has not completed.
+ * While WRSDIS is lockable with FLOCKDN, writing both in the same
+ * cycle is guaranteed to work by design.
+ *
+ * Avoid read->modify->write not to clear RW1C bits unintentionally.
*/
void fast_spi_lock_bar(void)
{
void *spibar = fast_spi_get_bar();
- uint32_t hsfs;
+ const uint16_t hsfs = SPIBAR_HSFSTS_FLOCKDN | SPIBAR_HSFSTS_WRSDIS;
- hsfs = read32(spibar + SPIBAR_HSFSTS_CTL);
- hsfs |= SPIBAR_HSFSTS_FLOCKDN;
- write32(spibar + SPIBAR_HSFSTS_CTL, hsfs);
+ write16(spibar + SPIBAR_HSFSTS_CTL, hsfs);
}
/*
diff --git a/src/soc/intel/common/block/fast_spi/fast_spi_def.h b/src/soc/intel/common/block/fast_spi/fast_spi_def.h
index d28f39cdf3..8e06df28de 100644
--- a/src/soc/intel/common/block/fast_spi/fast_spi_def.h
+++ b/src/soc/intel/common/block/fast_spi/fast_spi_def.h
@@ -70,6 +70,7 @@
#define SPIBAR_HSFSTS_FLOCKDN (1 << 15)
#define SPIBAR_HSFSTS_FDV (1 << 14)
#define SPIBAR_HSFSTS_FDOPSS (1 << 13)
+#define SPIBAR_HSFSTS_WRSDIS (1 << 11)
#define SPIBAR_HSFSTS_SAF_CE (1 << 8)
#define SPIBAR_HSFSTS_SAF_ACTIVE (1 << 7)
#define SPIBAR_HSFSTS_SAF_LE (1 << 6)