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>
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 dd21143..fe0217a 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 @@
/*
* 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);
}
/*