[U-Boot] [PATCH 4/5] sf: Add status register protect for Winbond
George McCollister
george.mccollister at gmail.com
Mon Oct 10 20:58:00 CEST 2016
Winbond parts such as W25Q64FV and Spansion parts such as S25FL128S
support two status register protection bits. Implement sr_protect for
Winbond and Spansion devices.
-------------------------------------------------------
| SRP1 | SRP0 | Method | Description |
-------------------------|-----------------------------
| 0 | 0 | Software | Blocked until write enable |
| 0 | 1 | Hardware | Blocked if WP pin is low |
| 1 | 0 | Power | Blocked until power down |
| 1 | 1 | OTP | Blocked permanently |
-------------------------------------------------------
Not all devices support OTP.
Signed-off-by: George McCollister <george.mccollister at gmail.com>
---
drivers/mtd/spi/sf_internal.h | 1 +
drivers/mtd/spi/spi_flash.c | 57 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 58 insertions(+)
diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h
index 1b576e8..7a97fc4 100644
--- a/drivers/mtd/spi/sf_internal.h
+++ b/drivers/mtd/spi/sf_internal.h
@@ -82,6 +82,7 @@ enum spi_nor_option_flags {
#define SR_BP1 BIT(3) /* Block protect 1 */
#define SR_BP2 BIT(4) /* Block protect 2 */
#define SR_SRP0 BIT(7) /* Status register protect 0 */
+#define SR_SRP1 BIT(0) /* Status register protect 1 */
/* Flash timeout values */
#define SPI_FLASH_PROG_TIMEOUT (2 * CONFIG_SYS_HZ)
diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index 392146b..80e67e6 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -874,6 +874,62 @@ int stm_sr_protect(struct spi_flash *flash, enum srp_method method)
}
#endif
+#if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND)
+/*
+ * Set status register protection method for parts with two protection bits
+ *
+ * Returns negative on errors, 0 on success.
+ */
+int winbond_sr_protect(struct spi_flash *flash, enum srp_method method)
+{
+ u8 status_old[2], status_new[2];
+ u8 mask[2] = {SR_SRP0, SR_SRP1};
+ u8 val[2];
+ u8 cmd;
+ int ret;
+
+ ret = read_sr(flash, &status_old[0]);
+ if (ret < 0)
+ return ret;
+
+ ret = read_cr(flash, &status_old[1]);
+ if (ret < 0)
+ return ret;
+
+ switch (method) {
+ case SRP_SOFTWARE:
+ val[0] = 0;
+ val[1] = 0;
+ break;
+ case SRP_HARDWARE:
+ val[0] = SR_SRP0;
+ val[1] = 0;
+ break;
+ case SRP_POWER:
+ val[0] = 0;
+ val[1] = SR_SRP1;
+ break;
+ case SRP_OTP:
+ val[0] = SR_SRP0;
+ val[1] = SR_SRP1;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ status_new[0] = (status_old[0] & ~mask[0]) | val[0];
+ status_new[1] = (status_old[1] & ~mask[1]) | val[1];
+
+ cmd = CMD_WRITE_STATUS;
+ ret = spi_flash_write_common(flash, &cmd, 1, &status_new, 2);
+ if (ret) {
+ debug("SF: fail to write status register\n");
+ return ret;
+ }
+
+ return 0;
+}
+#endif
#ifdef CONFIG_SPI_FLASH_MACRONIX
static int macronix_quad_enable(struct spi_flash *flash)
@@ -1169,6 +1225,7 @@ int spi_flash_scan(struct spi_flash *flash)
flash->flash_lock = stm_lock;
flash->flash_unlock = stm_unlock;
flash->flash_is_locked = stm_is_locked;
+ flash->sr_protect = winbond_sr_protect;
break;
#endif
default:
--
2.9.3
More information about the U-Boot
mailing list