diff options
Diffstat (limited to 'package/boot/uboot-layerscape/patches/0086-driver-spi-add-spansion-s25fs-s-family-protect-unpro.patch')
-rw-r--r-- | package/boot/uboot-layerscape/patches/0086-driver-spi-add-spansion-s25fs-s-family-protect-unpro.patch | 233 |
1 files changed, 0 insertions, 233 deletions
diff --git a/package/boot/uboot-layerscape/patches/0086-driver-spi-add-spansion-s25fs-s-family-protect-unpro.patch b/package/boot/uboot-layerscape/patches/0086-driver-spi-add-spansion-s25fs-s-family-protect-unpro.patch deleted file mode 100644 index 008b601..0000000 --- a/package/boot/uboot-layerscape/patches/0086-driver-spi-add-spansion-s25fs-s-family-protect-unpro.patch +++ /dev/null @@ -1,233 +0,0 @@ -From 986172ece10eee928ce66597d76f3f40ac3d25f7 Mon Sep 17 00:00:00 2001 -From: Yunhui Cui <yunhui.cui@nxp.com> -Date: Mon, 8 Aug 2016 14:24:13 +0800 -Subject: [PATCH 86/93] driver: spi: add spansion s25fs-s family - protect/unprotect - -In order to support spansion s25fs512s flash protect/unprotect: - -[1] Fill callbak flash->lock/unlock/is_locked by spansion_lock/ -unlock/is_locked. - -[2] Achieve protect/unprotected by operating sr1nv, cr1nv. - -Signed-off-by: Yunhui Cui <yunhui.cui@nxp.com> ---- - drivers/mtd/spi/spi_flash.c | 194 +++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 194 insertions(+) - -diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c -index e04bd55..87a92e9 100644 ---- a/drivers/mtd/spi/spi_flash.c -+++ b/drivers/mtd/spi/spi_flash.c -@@ -877,6 +877,193 @@ int stm_unlock(struct spi_flash *flash, u32 ofs, size_t len) - } - #endif - -+#if defined(CONFIG_SPI_FLASH_SPANSION) -+/* -+ * Return 1 if the entire region is locked, 0 otherwise -+ */ -+static int spansion_is_locked_sr(struct spi_flash *flash, u32 ofs, u32 len, -+ u8 sr) -+{ -+ loff_t lock_offs; -+ u32 lock_len; -+ -+ stm_get_locked_range(flash, sr, &lock_offs, &lock_len); -+ -+ return (ofs + len <= lock_offs + lock_len) && (ofs >= lock_offs); -+} -+ -+/* -+ * Check if a region of the flash is (completely) locked. See spansion_lock() for -+ * more info. -+ * -+ * Returns 1 if entire region is locked, 0 if any portion is unlocked, and -+ * negative on errors. -+ */ -+int spansion_is_locked(struct spi_flash *flash, u32 ofs, size_t len) -+{ -+ u8 cmd[4]; -+ u32 sr1nv_offset = 0x0; -+ u8 sr1nv; -+ int ret; -+ -+ cmd[0] = CMD_SPANSION_RDAR; -+ cmd[1] = sr1nv_offset >> 16; -+ cmd[2] = sr1nv_offset >> 8; -+ cmd[3] = sr1nv_offset >> 0; -+ -+ ret = spi_flash_cmd_read(flash->spi, cmd, 4, &sr1nv, 1); -+ if (ret) -+ return -EIO; -+ -+ return spansion_is_locked_sr(flash, ofs, len, sr1nv); -+} -+ -+/* -+ * Lock a region of the flash. Compatible with Spansion s25fs-s family flash. -+ * Supports only the block protection bits BP{0,1,2} in the Status Register-1 -+ * Non-Volatile(SR1NV). -+ * -+ * Sample table portion for 64MB flash (S25FS512S): -+ * Configuration Register-1 Non-Volatile(CR1NV[5])== 0 -+ * -+ * | BP2 | BP1 | BP0 | Prot Length | Protected Portion -+ * ------------------------------------------------------------ -+ * | 0 | 0 | 0 | NONE | NONE -+ * | 0 | 0 | 1 | 1 MB | Upper 1/64 -+ * | 0 | 1 | 0 | 2 MB | Upper 1/32 -+ * | 0 | 1 | 1 | 4 MB | Upper 1/16 -+ * | 1 | 0 | 0 | 8 MB | Upper 1/8 -+ * | 1 | 0 | 1 | 16 MB | Upper 1/4 -+ * | 1 | 1 | 0 | 32 MB | Upper 1/2 -+ * | 1 | 1 | 1 | 64 MB | ALL -+ * -+ * When CR1NV[5] == 1, the Lower memory array are protected. -+ * -+ * Returns negative on errors, 0 on success. -+ */ -+int spansion_lock(struct spi_flash *flash, u32 ofs, size_t len) -+{ -+ u8 status_old, status_new; -+ u8 mask = SR_BP2 | SR_BP1 | SR_BP0; -+ u8 shift = ffs(mask) - 1, pow, val; -+ int ret; -+ u8 cmd[4]; -+ u32 sr1nv_offset = 0x0; -+ u8 sr1nv; -+ -+ cmd[0] = CMD_SPANSION_RDAR; -+ cmd[1] = sr1nv_offset >> 16; -+ cmd[2] = sr1nv_offset >> 8; -+ cmd[3] = sr1nv_offset >> 0; -+ -+ ret = spi_flash_cmd_read(flash->spi, cmd, 4, &sr1nv, 1); -+ if (ret) -+ return -EIO; -+ status_old = sr1nv; -+ -+ /* SPI NOR always locks to the end */ -+ if (ofs + len != flash->size) { -+ /* Does combined region extend to end? */ -+ if (!stm_is_locked_sr(flash, ofs + len, flash->size - ofs - len, -+ status_old)) -+ return -EINVAL; -+ len = flash->size - ofs; -+ } -+ -+ /* -+ * Need smallest pow such that: -+ * -+ * 1 / (2^pow) <= (len / size) -+ * -+ * so (assuming power-of-2 size) we do: -+ * -+ * pow = ceil(log2(size / len)) = log2(size) - floor(log2(len)) -+ */ -+ pow = ilog2(flash->size) - ilog2(len); -+ val = mask - (pow << shift); -+ if (val & ~mask) -+ return -EINVAL; -+ -+ /* Don't "lock" with no region! */ -+ if (!(val & mask)) -+ return -EINVAL; -+ -+ status_new = (status_old & ~mask) | val; -+ -+ /* Only modify protection if it will not unlock other areas */ -+ if ((status_new & mask) <= (status_old & mask)) -+ return -EINVAL; -+ -+ cmd[0] = CMD_SPANSION_WRAR; -+ ret = spi_flash_cmd_write(flash->spi, cmd, 4, &status_new, 1); -+ if (ret) -+ return -EIO; -+ -+ return 0; -+} -+ -+/* -+ * Unlock a region of the flash. See spansion_lock() for more info -+ * -+ * Returns negative on errors, 0 on success. -+ */ -+int spansion_unlock(struct spi_flash *flash, u32 ofs, size_t len) -+{ -+ uint8_t status_old, status_new; -+ u8 mask = SR_BP2 | SR_BP1 | SR_BP0; -+ u8 shift = ffs(mask) - 1, pow, val; -+ int ret; -+ -+ u8 cmd[4]; -+ u32 sr1nv_offset = 0x0; -+ u8 sr1nv; -+ -+ cmd[0] = CMD_SPANSION_RDAR; -+ cmd[1] = sr1nv_offset >> 16; -+ cmd[2] = sr1nv_offset >> 8; -+ cmd[3] = sr1nv_offset >> 0; -+ -+ ret = spi_flash_cmd_read(flash->spi, cmd, 4, &sr1nv, 1); -+ if (ret) -+ return -EIO; -+ status_old = sr1nv; -+ -+ /* Cannot unlock; would unlock larger region than requested */ -+ if (spansion_is_locked_sr(flash, ofs - flash->erase_size, flash->erase_size, -+ status_old)) -+ return -EINVAL; -+ /* -+ * Need largest pow such that: -+ * -+ * 1 / (2^pow) >= (len / size) -+ * -+ * so (assuming power-of-2 size) we do: -+ * -+ * pow = floor(log2(size / len)) = log2(size) - ceil(log2(len)) -+ */ -+ pow = ilog2(flash->size) - order_base_2(flash->size - (ofs + len)); -+ if (ofs + len == flash->size) { -+ val = 0; /* fully unlocked */ -+ } else { -+ val = mask - (pow << shift); -+ /* Some power-of-two sizes are not supported */ -+ if (val & ~mask) -+ return -EINVAL; -+ } -+ status_new = (status_old & ~mask) | val; -+ -+ /* Only modify protection if it will not lock other areas */ -+ if ((status_new & mask) >= (status_old & mask)) -+ return -EINVAL; -+ -+ cmd[0] = CMD_SPANSION_WRAR; -+ ret = spi_flash_cmd_write(flash->spi, cmd, 4, &status_new, 1); -+ if (ret) -+ return -EIO; -+ -+ return 0; -+} -+#endif - - #ifdef CONFIG_SPI_FLASH_MACRONIX - static int spi_flash_set_qeb_mxic(struct spi_flash *flash) -@@ -1132,6 +1319,13 @@ int spi_flash_scan(struct spi_flash *flash) - flash->flash_is_locked = stm_is_locked; - #endif - break; -+#if defined(CONFIG_SPI_FLASH_SPANSION) -+ case SPI_FLASH_CFI_MFR_SPANSION: -+ flash->flash_lock = spansion_lock; -+ flash->flash_unlock = spansion_unlock; -+ flash->flash_is_locked = spansion_is_locked; -+#endif -+ break; - default: - debug("SF: Lock ops not supported for %02x flash\n", idcode[0]); - } --- -1.7.9.5 - |