aboutsummaryrefslogtreecommitdiffstats
path: root/package/boot/uboot-layerscape/patches/0086-driver-spi-add-spansion-s25fs-s-family-protect-unpro.patch
diff options
context:
space:
mode:
authorYutang Jiang <yutang.jiang@nxp.com>2016-10-29 00:18:23 +0800
committerJohn Crispin <john@phrozen.org>2016-10-31 17:00:10 +0100
commit15a14cf1665ef3d8b5c77cce69b52d131340e3b3 (patch)
treebd544b24bd3e7fc7efc61f80e1755274971c5582 /package/boot/uboot-layerscape/patches/0086-driver-spi-add-spansion-s25fs-s-family-protect-unpro.patch
parentc6c731fe311f7da42777ffd31804a4f6aa3f8e19 (diff)
downloadupstream-15a14cf1665ef3d8b5c77cce69b52d131340e3b3.tar.gz
upstream-15a14cf1665ef3d8b5c77cce69b52d131340e3b3.tar.bz2
upstream-15a14cf1665ef3d8b5c77cce69b52d131340e3b3.zip
layerscape: add 64b/32b target for ls1012ardb device
The QorIQ LS1012A processor, optimized for battery-backed or USB-powered, integrates a single ARM Cortex-A53 core with a hardware packet forwarding engine and high-speed interfaces to deliver line-rate networking performance. QorIQ LS1012A Reference Design System (LS1012ARDB) is a high-performance development platform, with a complete debugging environment. The LS1012ARDB board supports the QorIQ LS1012A processor and is optimized to support the high-bandwidth DDR3L memory and a full complement of high-speed SerDes ports. LEDE/OPENWRT will auto strip executable program file while make. So we need select CONFIG_NO_STRIP=y while make menuconfig to avoid the ppfe network fiemware be destroyed, then run make to build ls1012ardb firmware. The fsl-quadspi flash with jffs2 fs is unstable and arise some failed message. This issue have noticed the IP owner for investigate, hope he can solve it earlier. So the ls1012ardb now also provide a xx-firmware.ext4.bin as default firmware, and the uboot bootcmd will run wrtboot_ext4rfs for "rootfstype=ext4" bootargs. Signed-off-by: Yutang Jiang <yutang.jiang@nxp.com>
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.patch233
1 files changed, 233 insertions, 0 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
new file mode 100644
index 0000000000..008b6012d0
--- /dev/null
+++ b/package/boot/uboot-layerscape/patches/0086-driver-spi-add-spansion-s25fs-s-family-protect-unpro.patch
@@ -0,0 +1,233 @@
+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
+