From mboxrd@z Thu Jan 1 00:00:00 1970 From: George McCollister Date: Mon, 10 Oct 2016 13:58:00 -0500 Subject: [U-Boot] [PATCH 4/5] sf: Add status register protect for Winbond In-Reply-To: <20161010185801.27991-1-george.mccollister@gmail.com> References: <20161010185801.27991-1-george.mccollister@gmail.com> Message-ID: <20161010185801.27991-5-george.mccollister@gmail.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de 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 --- 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