浏览代码

spi: add config option to enable the WP pin function on st micron flashes

enable the W#/Vpp signal to disable writing to the status
register on ST MICRON flashes like the N25Q128 thorugh
the new config option CONFIG_SYS_SPI_ST_ENABLE_WP_PIN

Signed-off-by: Heiko Schocher <hs@denx.de>
Cc: Jagannadha Sutradharudu Teki <jagannadh.teki@gmail.com>
Heiko Schocher 11 年之前
父节点
当前提交
562f8df18d
共有 3 个文件被更改,包括 45 次插入0 次删除
  1. 11 0
      README
  2. 4 0
      drivers/mtd/spi/sf_internal.h
  3. 30 0
      drivers/mtd/spi/sf_probe.c

+ 11 - 0
README

@@ -2930,6 +2930,17 @@ CBFS (Coreboot Filesystem) support
 		memories can be connected with a given cs line.
 		currently Xilinx Zynq qspi support these type of connections.
 
+		CONFIG_SYS_SPI_ST_ENABLE_WP_PIN
+		enable the W#/Vpp signal to disable writing to the status
+		register on ST MICRON flashes like the N25Q128.
+		The status register write enable/disable bit, combined with
+		the W#/VPP signal provides hardware data protection for the
+		device as follows: When the enable/disable bit is set to 1,
+		and the W#/VPP signal is driven LOW, the status register
+		nonvolatile bits become read-only and the WRITE STATUS REGISTER
+		operation will not execute. The only way to exit this
+		hardware-protected mode is to drive W#/VPP HIGH.
+
 - SystemACE Support:
 		CONFIG_SYSTEMACE
 

+ 4 - 0
drivers/mtd/spi/sf_internal.h

@@ -60,6 +60,10 @@
 #define STATUS_QEB_MXIC			(1 << 6)
 #define STATUS_PEC			(1 << 7)
 
+#ifdef CONFIG_SYS_SPI_ST_ENABLE_WP_PIN
+#define STATUS_SRWD			(1 << 7) /* SR write protect */
+#endif
+
 /* Flash timeout values */
 #define SPI_FLASH_PROG_TIMEOUT		(2 * CONFIG_SYS_HZ)
 #define SPI_FLASH_PAGE_ERASE_TIMEOUT	(5 * CONFIG_SYS_HZ)

+ 30 - 0
drivers/mtd/spi/sf_probe.c

@@ -281,6 +281,34 @@ int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash)
 }
 #endif /* CONFIG_OF_CONTROL */
 
+#ifdef CONFIG_SYS_SPI_ST_ENABLE_WP_PIN
+/* enable the W#/Vpp signal to disable writing to the status register */
+static int spi_enable_wp_pin(struct spi_flash *flash)
+{
+	u8 status;
+	int ret;
+
+	ret = spi_flash_cmd_read_status(flash, &status);
+	if (ret < 0)
+		return ret;
+
+	ret = spi_flash_cmd_write_status(flash, STATUS_SRWD);
+	if (ret < 0)
+		return ret;
+
+	ret = spi_flash_cmd_write_disable(flash);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+#else
+static int spi_enable_wp_pin(struct spi_flash *flash)
+{
+	return 0;
+}
+#endif
+
 static struct spi_flash *spi_flash_probe_slave(struct spi_slave *spi)
 {
 	struct spi_flash *flash = NULL;
@@ -351,6 +379,8 @@ static struct spi_flash *spi_flash_probe_slave(struct spi_slave *spi)
 		puts(" Full access #define CONFIG_SPI_FLASH_BAR\n");
 	}
 #endif
+	if (spi_enable_wp_pin(flash))
+		puts("Enable WP pin failed\n");
 
 	/* Release spi bus */
 	spi_release_bus(spi);