kernel: unlock MX25L6406E with 4 bit Block Protect
authorSieng Piaw Liew <liew.s.piaw@gmail.com>
Fri, 9 Oct 2020 09:01:20 +0000 (17:01 +0800)
committerÁlvaro Fernández Rojas <noltari@gmail.com>
Wed, 9 Dec 2020 07:42:26 +0000 (08:42 +0100)
Hacked in basic support for 4 bit Block Protection register, copied from
linux-master. Needed to unlock Innacomm W3400V's SPI flash MX25L6406E,
compatible with MX25L6405D.

Signed-off-by: Sieng Piaw Liew <liew.s.piaw@gmail.com>
[Amend commit description, refresh patch]
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
target/linux/generic/hack-5.4/400-unlock_mx25l6406e_with_4bit_block_protect.patch [new file with mode: 0644]

diff --git a/target/linux/generic/hack-5.4/400-unlock_mx25l6406e_with_4bit_block_protect.patch b/target/linux/generic/hack-5.4/400-unlock_mx25l6406e_with_4bit_block_protect.patch
new file mode 100644 (file)
index 0000000..e25fdcd
--- /dev/null
@@ -0,0 +1,69 @@
+--- a/drivers/mtd/spi-nor/spi-nor.c
++++ b/drivers/mtd/spi-nor/spi-nor.c
+@@ -196,7 +196,7 @@ struct flash_info {
+       u16             page_size;
+       u16             addr_width;
+-      u16             flags;
++      u32             flags;
+ #define SECT_4K                       BIT(0)  /* SPINOR_OP_BE_4K works uniformly */
+ #define SPI_NOR_NO_ERASE      BIT(1)  /* No erase command needed */
+ #define SST_WRITE             BIT(2)  /* use SST byte programming */
+@@ -233,6 +233,10 @@ struct flash_info {
+ #define SPI_NOR_SKIP_SFDP     BIT(13) /* Skip parsing of SFDP tables */
+ #define USE_CLSR              BIT(14) /* use CLSR command */
+ #define SPI_NOR_OCTAL_READ    BIT(15) /* Flash supports Octal Read */
++#define SPI_NOR_4BIT_BP               BIT(17) /*
++                                       * Flash SR has 4 bit fields (BP0-3)
++                                       * for block protection.
++                                       */
+       /* Part specific fixup hooks. */
+       const struct spi_nor_fixups *fixups;
+@@ -1983,6 +1987,9 @@ static int spi_nor_clear_sr_bp(struct sp
+       int ret;
+       u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
++      if (nor->flags & SNOR_F_HAS_4BIT_BP)
++              mask |= SR_BP3;
++
+       ret = read_sr(nor);
+       if (ret < 0) {
+               dev_err(nor->dev, "error while reading status register\n");
+@@ -2335,7 +2342,7 @@ static const struct flash_info spi_nor_i
+       { "mx25l1606e",  INFO(0xc22015, 0, 64 * 1024,  32, SECT_4K) },
+       { "mx25l3205d",  INFO(0xc22016, 0, 64 * 1024,  64, SECT_4K) },
+       { "mx25l3255e",  INFO(0xc29e16, 0, 64 * 1024,  64, SECT_4K) },
+-      { "mx25l6405d",  INFO(0xc22017, 0, 64 * 1024, 128, SECT_4K) },
++      { "mx25l6405d",  INFO(0xc22017, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_4BIT_BP) },
+       { "mx25u2033e",  INFO(0xc22532, 0, 64 * 1024,   4, SECT_4K) },
+       { "mx25u3235f",  INFO(0xc22536, 0, 64 * 1024,  64,
+                        SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+@@ -5024,6 +5031,9 @@ int spi_nor_scan(struct spi_nor *nor, co
+       if (info->flags & USE_CLSR)
+               nor->flags |= SNOR_F_USE_CLSR;
++      if (info->flags & SPI_NOR_4BIT_BP)
++              nor->flags |= SNOR_F_HAS_4BIT_BP;
++
+       if (info->flags & SPI_NOR_NO_ERASE)
+               mtd->flags |= MTD_NO_ERASE;
+--- a/include/linux/mtd/spi-nor.h
++++ b/include/linux/mtd/spi-nor.h
+@@ -127,6 +127,7 @@
+ #define SR_BP0                        BIT(2)  /* Block protect 0 */
+ #define SR_BP1                        BIT(3)  /* Block protect 1 */
+ #define SR_BP2                        BIT(4)  /* Block protect 2 */
++#define SR_BP3                        BIT(5)  /* Block protect 3 */
+ #define SR_TB                 BIT(5)  /* Top/Bottom protect */
+ #define SR_SRWD                       BIT(7)  /* SR write protect */
+ /* Spansion/Cypress specific status bits */
+@@ -243,6 +244,7 @@ enum spi_nor_option_flags {
+       SNOR_F_4B_OPCODES       = BIT(6),
+       SNOR_F_HAS_4BAIT        = BIT(7),
+       SNOR_F_HAS_LOCK         = BIT(8),
++      SNOR_F_HAS_4BIT_BP      = BIT(12),
+ };
+ /**