bcm53xx: backport spi-nor changes to add gd25q128 support
authorRafał Miłecki <zajec5@gmail.com>
Wed, 21 Jan 2015 06:53:15 +0000 (06:53 +0000)
committerRafał Miłecki <zajec5@gmail.com>
Wed, 21 Jan 2015 06:53:15 +0000 (06:53 +0000)
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
SVN-Revision: 44069

target/linux/bcm53xx/patches-3.14/004-mtd-spi-nor-from-3.20.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-3.18/004-mtd-spi-nor-from-3.20.patch [new file with mode: 0644]

diff --git a/target/linux/bcm53xx/patches-3.14/004-mtd-spi-nor-from-3.20.patch b/target/linux/bcm53xx/patches-3.14/004-mtd-spi-nor-from-3.20.patch
new file mode 100644 (file)
index 0000000..8a20da6
--- /dev/null
@@ -0,0 +1,116 @@
+--- a/drivers/mtd/spi-nor/spi-nor.c
++++ b/drivers/mtd/spi-nor/spi-nor.c
+@@ -538,6 +538,7 @@ static const struct spi_device_id spi_no
+       /* GigaDevice */
+       { "gd25q32", INFO(0xc84016, 0, 64 * 1024,  64, SECT_4K) },
+       { "gd25q64", INFO(0xc84017, 0, 64 * 1024, 128, SECT_4K) },
++      { "gd25q128", INFO(0xc84018, 0, 64 * 1024, 256, SECT_4K) },
+       /* Intel/Numonyx -- xxxs33b */
+       { "160s33b",  INFO(0x898911, 0, 64 * 1024,  32, 0) },
+@@ -560,14 +561,14 @@ static const struct spi_device_id spi_no
+       { "mx66l1g55g",  INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) },
+       /* Micron */
+-      { "n25q032",     INFO(0x20ba16, 0, 64 * 1024,   64, 0) },
+-      { "n25q064",     INFO(0x20ba17, 0, 64 * 1024,  128, 0) },
+-      { "n25q128a11",  INFO(0x20bb18, 0, 64 * 1024,  256, 0) },
+-      { "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024,  256, 0) },
+-      { "n25q256a",    INFO(0x20ba19, 0, 64 * 1024,  512, SECT_4K) },
+-      { "n25q512a",    INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K) },
+-      { "n25q512ax3",  INFO(0x20ba20, 0, 64 * 1024, 1024, USE_FSR) },
+-      { "n25q00",      INFO(0x20ba21, 0, 64 * 1024, 2048, USE_FSR) },
++      { "n25q032",     INFO(0x20ba16, 0, 64 * 1024,   64, SPI_NOR_QUAD_READ) },
++      { "n25q064",     INFO(0x20ba17, 0, 64 * 1024,  128, SPI_NOR_QUAD_READ) },
++      { "n25q128a11",  INFO(0x20bb18, 0, 64 * 1024,  256, SPI_NOR_QUAD_READ) },
++      { "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024,  256, SPI_NOR_QUAD_READ) },
++      { "n25q256a",    INFO(0x20ba19, 0, 64 * 1024,  512, SECT_4K | SPI_NOR_QUAD_READ) },
++      { "n25q512a",    INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
++      { "n25q512ax3",  INFO(0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
++      { "n25q00",      INFO(0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
+       /* PMC */
+       { "pm25lv512",   INFO(0,        0, 32 * 1024,    2, SECT_4K_PMC) },
+@@ -890,6 +891,45 @@ static int spansion_quad_enable(struct s
+       return 0;
+ }
++static int micron_quad_enable(struct spi_nor *nor)
++{
++      int ret;
++      u8 val;
++
++      ret = nor->read_reg(nor, SPINOR_OP_RD_EVCR, &val, 1);
++      if (ret < 0) {
++              dev_err(nor->dev, "error %d reading EVCR\n", ret);
++              return ret;
++      }
++
++      write_enable(nor);
++
++      /* set EVCR, enable quad I/O */
++      nor->cmd_buf[0] = val & ~EVCR_QUAD_EN_MICRON;
++      ret = nor->write_reg(nor, SPINOR_OP_WD_EVCR, nor->cmd_buf, 1, 0);
++      if (ret < 0) {
++              dev_err(nor->dev, "error while writing EVCR register\n");
++              return ret;
++      }
++
++      ret = spi_nor_wait_till_ready(nor);
++      if (ret)
++              return ret;
++
++      /* read EVCR and check it */
++      ret = nor->read_reg(nor, SPINOR_OP_RD_EVCR, &val, 1);
++      if (ret < 0) {
++              dev_err(nor->dev, "error %d reading EVCR\n", ret);
++              return ret;
++      }
++      if (val & EVCR_QUAD_EN_MICRON) {
++              dev_err(nor->dev, "Micron EVCR Quad bit not clear\n");
++              return -EINVAL;
++      }
++
++      return 0;
++}
++
+ static int set_quad_mode(struct spi_nor *nor, struct flash_info *info)
+ {
+       int status;
+@@ -902,6 +942,13 @@ static int set_quad_mode(struct spi_nor
+                       return -EINVAL;
+               }
+               return status;
++      case CFI_MFR_ST:
++              status = micron_quad_enable(nor);
++              if (status) {
++                      dev_err(nor->dev, "Micron quad-read not enabled\n");
++                      return -EINVAL;
++              }
++              return status;
+       default:
+               status = spansion_quad_enable(nor);
+               if (status) {
+--- a/include/linux/mtd/spi-nor.h
++++ b/include/linux/mtd/spi-nor.h
+@@ -56,6 +56,10 @@
+ /* Used for Spansion flashes only. */
+ #define SPINOR_OP_BRWR                0x17    /* Bank register write */
++/* Used for Micron flashes only. */
++#define SPINOR_OP_RD_EVCR      0x65    /* Read EVCR register */
++#define SPINOR_OP_WD_EVCR      0x61    /* Write EVCR register */
++
+ /* Status Register bits. */
+ #define SR_WIP                        1       /* Write in progress */
+ #define SR_WEL                        2       /* Write enable latch */
+@@ -67,6 +71,9 @@
+ #define SR_QUAD_EN_MX         0x40    /* Macronix Quad I/O */
++/* Enhanced Volatile Configuration Register bits */
++#define EVCR_QUAD_EN_MICRON    0x80    /* Micron Quad I/O */
++
+ /* Flag Status Register bits */
+ #define FSR_READY             0x80
diff --git a/target/linux/bcm53xx/patches-3.18/004-mtd-spi-nor-from-3.20.patch b/target/linux/bcm53xx/patches-3.18/004-mtd-spi-nor-from-3.20.patch
new file mode 100644 (file)
index 0000000..925e883
--- /dev/null
@@ -0,0 +1,116 @@
+--- a/drivers/mtd/spi-nor/spi-nor.c
++++ b/drivers/mtd/spi-nor/spi-nor.c
+@@ -538,6 +538,7 @@ static const struct spi_device_id spi_no
+       /* GigaDevice */
+       { "gd25q32", INFO(0xc84016, 0, 64 * 1024,  64, SECT_4K) },
+       { "gd25q64", INFO(0xc84017, 0, 64 * 1024, 128, SECT_4K) },
++      { "gd25q128", INFO(0xc84018, 0, 64 * 1024, 256, SECT_4K) },
+       /* Intel/Numonyx -- xxxs33b */
+       { "160s33b",  INFO(0x898911, 0, 64 * 1024,  32, 0) },
+@@ -560,14 +561,14 @@ static const struct spi_device_id spi_no
+       { "mx66l1g55g",  INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) },
+       /* Micron */
+-      { "n25q032",     INFO(0x20ba16, 0, 64 * 1024,   64, 0) },
+-      { "n25q064",     INFO(0x20ba17, 0, 64 * 1024,  128, 0) },
+-      { "n25q128a11",  INFO(0x20bb18, 0, 64 * 1024,  256, 0) },
+-      { "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024,  256, 0) },
+-      { "n25q256a",    INFO(0x20ba19, 0, 64 * 1024,  512, SECT_4K) },
+-      { "n25q512a",    INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K) },
+-      { "n25q512ax3",  INFO(0x20ba20, 0, 64 * 1024, 1024, USE_FSR) },
+-      { "n25q00",      INFO(0x20ba21, 0, 64 * 1024, 2048, USE_FSR) },
++      { "n25q032",     INFO(0x20ba16, 0, 64 * 1024,   64, SPI_NOR_QUAD_READ) },
++      { "n25q064",     INFO(0x20ba17, 0, 64 * 1024,  128, SPI_NOR_QUAD_READ) },
++      { "n25q128a11",  INFO(0x20bb18, 0, 64 * 1024,  256, SPI_NOR_QUAD_READ) },
++      { "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024,  256, SPI_NOR_QUAD_READ) },
++      { "n25q256a",    INFO(0x20ba19, 0, 64 * 1024,  512, SECT_4K | SPI_NOR_QUAD_READ) },
++      { "n25q512a",    INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
++      { "n25q512ax3",  INFO(0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
++      { "n25q00",      INFO(0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
+       /* PMC */
+       { "pm25lv512",   INFO(0,        0, 32 * 1024,    2, SECT_4K_PMC) },
+@@ -891,6 +892,45 @@ static int spansion_quad_enable(struct s
+       return 0;
+ }
++static int micron_quad_enable(struct spi_nor *nor)
++{
++      int ret;
++      u8 val;
++
++      ret = nor->read_reg(nor, SPINOR_OP_RD_EVCR, &val, 1);
++      if (ret < 0) {
++              dev_err(nor->dev, "error %d reading EVCR\n", ret);
++              return ret;
++      }
++
++      write_enable(nor);
++
++      /* set EVCR, enable quad I/O */
++      nor->cmd_buf[0] = val & ~EVCR_QUAD_EN_MICRON;
++      ret = nor->write_reg(nor, SPINOR_OP_WD_EVCR, nor->cmd_buf, 1, 0);
++      if (ret < 0) {
++              dev_err(nor->dev, "error while writing EVCR register\n");
++              return ret;
++      }
++
++      ret = spi_nor_wait_till_ready(nor);
++      if (ret)
++              return ret;
++
++      /* read EVCR and check it */
++      ret = nor->read_reg(nor, SPINOR_OP_RD_EVCR, &val, 1);
++      if (ret < 0) {
++              dev_err(nor->dev, "error %d reading EVCR\n", ret);
++              return ret;
++      }
++      if (val & EVCR_QUAD_EN_MICRON) {
++              dev_err(nor->dev, "Micron EVCR Quad bit not clear\n");
++              return -EINVAL;
++      }
++
++      return 0;
++}
++
+ static int set_quad_mode(struct spi_nor *nor, struct flash_info *info)
+ {
+       int status;
+@@ -903,6 +943,13 @@ static int set_quad_mode(struct spi_nor
+                       return -EINVAL;
+               }
+               return status;
++      case CFI_MFR_ST:
++              status = micron_quad_enable(nor);
++              if (status) {
++                      dev_err(nor->dev, "Micron quad-read not enabled\n");
++                      return -EINVAL;
++              }
++              return status;
+       default:
+               status = spansion_quad_enable(nor);
+               if (status) {
+--- a/include/linux/mtd/spi-nor.h
++++ b/include/linux/mtd/spi-nor.h
+@@ -56,6 +56,10 @@
+ /* Used for Spansion flashes only. */
+ #define SPINOR_OP_BRWR                0x17    /* Bank register write */
++/* Used for Micron flashes only. */
++#define SPINOR_OP_RD_EVCR      0x65    /* Read EVCR register */
++#define SPINOR_OP_WD_EVCR      0x61    /* Write EVCR register */
++
+ /* Status Register bits. */
+ #define SR_WIP                        1       /* Write in progress */
+ #define SR_WEL                        2       /* Write enable latch */
+@@ -67,6 +71,9 @@
+ #define SR_QUAD_EN_MX         0x40    /* Macronix Quad I/O */
++/* Enhanced Volatile Configuration Register bits */
++#define EVCR_QUAD_EN_MICRON    0x80    /* Micron Quad I/O */
++
+ /* Flag Status Register bits */
+ #define FSR_READY             0x80