1110-mtd-spi-nor-fsl-quad-add-flash-S25FS-extra-support.patch 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. From 034dd6241b55ab2256eecb845e941fa9b45da38e Mon Sep 17 00:00:00 2001
  2. From: Yunhui Cui <yunhui.cui@nxp.com>
  3. Date: Thu, 28 Apr 2016 17:03:57 +0800
  4. Subject: [PATCH 110/113] mtd: spi-nor: fsl-quad: add flash S25FS extra
  5. support
  6. [context adjustment]
  7. not apply changes of arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts
  8. There are some boards have the same QSPI controller but have
  9. different vendor flash, So, the controller can use the same
  10. compatible and share the driver, just for a different flash to do
  11. the appropriate adaptation. Based on this, we need add the vendor
  12. field in spi-nor, Because we will use the field to distribute
  13. corresponding LUT for different flash operations.
  14. Signed-off-by: Yunhui Cui <yunhui.cui@nxp.com>
  15. Signed-off-by: Pratiyush Mohan Srivastava <pratiyush.srivastava@nxp.com>
  16. Signed-off-by: Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>
  17. Integrated-by: Jiang Yutang <yutang.jiang@nxp.com>
  18. ---
  19. drivers/mtd/spi-nor/fsl-quadspi.c | 47 ++++++++++++++++++++++++++++++-------
  20. drivers/mtd/spi-nor/spi-nor.c | 5 ++--
  21. include/linux/mtd/spi-nor.h | 1 +
  22. 3 files changed, 42 insertions(+), 11 deletions(-)
  23. --- a/drivers/mtd/spi-nor/fsl-quadspi.c
  24. +++ b/drivers/mtd/spi-nor/fsl-quadspi.c
  25. @@ -213,6 +213,9 @@
  26. #define QUADSPI_MIN_IOMAP SZ_4M
  27. +#define FLASH_VENDOR_SPANSION_FS "s25fs"
  28. +#define SPANSION_S25FS_FAMILY (1 << 1)
  29. +
  30. enum fsl_qspi_devtype {
  31. FSL_QUADSPI_VYBRID,
  32. FSL_QUADSPI_IMX6SX,
  33. @@ -329,6 +332,18 @@ static inline int has_added_amba_base_in
  34. return q->devtype_data->driver_data & QUADSPI_AMBA_BASE_INTERNAL;
  35. }
  36. +static u32 fsl_get_nor_vendor(struct spi_nor *nor)
  37. +{
  38. + u32 vendor_id;
  39. +
  40. + if (nor->vendor) {
  41. + if (memcmp(nor->vendor, FLASH_VENDOR_SPANSION_FS,
  42. + sizeof(FLASH_VENDOR_SPANSION_FS) - 1))
  43. + vendor_id = SPANSION_S25FS_FAMILY;
  44. + }
  45. + return vendor_id;
  46. +}
  47. +
  48. /*
  49. * R/W functions for big- or little-endian registers:
  50. * The qSPI controller's endian is independent of the CPU core's endian.
  51. @@ -394,13 +409,15 @@ static void fsl_qspi_init_lut(struct fsl
  52. int rxfifo = q->devtype_data->rxfifo;
  53. u32 lut_base;
  54. int i;
  55. - const struct fsl_qspi_devtype_data *devtype_data = q->devtype_data;
  56. + u32 vendor;
  57. struct spi_nor *nor = &q->nor[0];
  58. u8 addrlen = (nor->addr_width == 3) ? ADDR24BIT : ADDR32BIT;
  59. u8 read_op = nor->read_opcode;
  60. u8 read_dm = nor->read_dummy;
  61. + vendor = fsl_get_nor_vendor(nor);
  62. +
  63. fsl_qspi_unlock_lut(q);
  64. /* Clear all the LUT table */
  65. @@ -418,12 +435,25 @@ static void fsl_qspi_init_lut(struct fsl
  66. LUT1(FSL_READ, PAD1, rxfifo),
  67. base + QUADSPI_LUT(lut_base + 1));
  68. } else if (nor->flash_read == SPI_NOR_QUAD) {
  69. - qspi_writel(q, LUT0(CMD, PAD1, read_op) |
  70. - LUT1(ADDR, PAD1, addrlen),
  71. - base + QUADSPI_LUT(lut_base));
  72. - qspi_writel(q, LUT0(DUMMY, PAD1, read_dm) |
  73. - LUT1(FSL_READ, PAD4, rxfifo),
  74. - base + QUADSPI_LUT(lut_base + 1));
  75. + if (q->nor_size == 0x4000000) {
  76. + read_op = 0xEC;
  77. + qspi_writel(q,
  78. + LUT0(CMD, PAD1, read_op) | LUT1(ADDR, PAD4, addrlen),
  79. + base + QUADSPI_LUT(lut_base));
  80. + qspi_writel(q,
  81. + LUT0(MODE, PAD4, 0xff) | LUT1(DUMMY, PAD4, read_dm),
  82. + base + QUADSPI_LUT(lut_base + 1));
  83. + qspi_writel(q,
  84. + LUT0(FSL_READ, PAD4, rxfifo),
  85. + base + QUADSPI_LUT(lut_base + 2));
  86. + } else {
  87. + qspi_writel(q, LUT0(CMD, PAD1, read_op) |
  88. + LUT1(ADDR, PAD1, addrlen),
  89. + base + QUADSPI_LUT(lut_base));
  90. + qspi_writel(q, LUT0(DUMMY, PAD1, read_dm) |
  91. + LUT1(FSL_READ, PAD4, rxfifo),
  92. + base + QUADSPI_LUT(lut_base + 1));
  93. + }
  94. } else if (nor->flash_read == SPI_NOR_DDR_QUAD) {
  95. /* read mode : 1-4-4, such as Spansion s25fl128s. */
  96. qspi_writel(q, LUT0(CMD, PAD1, read_op)
  97. @@ -510,7 +540,8 @@ static void fsl_qspi_init_lut(struct fsl
  98. * use the same value 0x65. But it indicates different meaning.
  99. */
  100. lut_base = SEQID_RDAR_OR_RD_EVCR * 4;
  101. - if (devtype_data->devtype == FSL_QUADSPI_LS2080A) {
  102. +
  103. + if (vendor == SPANSION_S25FS_FAMILY) {
  104. /*
  105. * Read any device register.
  106. * Used for Spansion S25FS-S family flash only.
  107. --- a/drivers/mtd/spi-nor/spi-nor.c
  108. +++ b/drivers/mtd/spi-nor/spi-nor.c
  109. @@ -804,7 +804,6 @@ static const struct flash_info spi_nor_i
  110. { "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
  111. { "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
  112. { "s25fs256s1", INFO6(0x010219, 0x4d0181, 64 * 1024, 512, 0)},
  113. - { "s25fs512s", INFO6(0x010220, 0x4d0081, 128 * 1024, 512, 0)},
  114. { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) },
  115. { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
  116. { "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
  117. @@ -971,11 +970,9 @@ static int spansion_s25fs_disable_4kb_er
  118. ret = nor->read_reg(nor, SPINOR_OP_SPANSION_RDAR, &cr3v, 1);
  119. if (ret)
  120. return ret;
  121. -/*
  122. if (!(cr3v & CR3V_4KB_ERASE_UNABLE))
  123. return -EPERM;
  124. -*/
  125. return 0;
  126. }
  127. @@ -1349,6 +1346,8 @@ int spi_nor_scan(struct spi_nor *nor, co
  128. if (!mtd->name)
  129. mtd->name = dev_name(dev);
  130. + if (info->name)
  131. + nor->vendor = info->name;
  132. mtd->priv = nor;
  133. mtd->type = MTD_NORFLASH;
  134. mtd->writesize = 1;
  135. --- a/include/linux/mtd/spi-nor.h
  136. +++ b/include/linux/mtd/spi-nor.h
  137. @@ -172,6 +172,7 @@ struct spi_nor {
  138. bool sst_write_second;
  139. u32 flags;
  140. u8 cmd_buf[SPI_NOR_MAX_CMD_SIZE];
  141. + char *vendor;
  142. int (*prepare)(struct spi_nor *nor, enum spi_nor_ops ops);
  143. void (*unprepare)(struct spi_nor *nor, enum spi_nor_ops ops);