macronix.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2005, Intec Automation Inc.
  4. * Copyright (C) 2014, Freescale Semiconductor, Inc.
  5. */
  6. #include <linux/mtd/spi-nor.h>
  7. #include "core.h"
  8. static int
  9. mx25l25635_post_bfpt_fixups(struct spi_nor *nor,
  10. const struct sfdp_parameter_header *bfpt_header,
  11. const struct sfdp_bfpt *bfpt)
  12. {
  13. /*
  14. * MX25L25635F supports 4B opcodes but MX25L25635E does not.
  15. * Unfortunately, Macronix has re-used the same JEDEC ID for both
  16. * variants which prevents us from defining a new entry in the parts
  17. * table.
  18. * We need a way to differentiate MX25L25635E and MX25L25635F, and it
  19. * seems that the F version advertises support for Fast Read 4-4-4 in
  20. * its BFPT table.
  21. */
  22. if (bfpt->dwords[BFPT_DWORD(5)] & BFPT_DWORD5_FAST_READ_4_4_4)
  23. nor->flags |= SNOR_F_4B_OPCODES;
  24. return 0;
  25. }
  26. static const struct spi_nor_fixups mx25l25635_fixups = {
  27. .post_bfpt = mx25l25635_post_bfpt_fixups,
  28. };
  29. static const struct flash_info macronix_nor_parts[] = {
  30. /* Macronix */
  31. { "mx25l512e", INFO(0xc22010, 0, 64 * 1024, 1)
  32. NO_SFDP_FLAGS(SECT_4K) },
  33. { "mx25l2005a", INFO(0xc22012, 0, 64 * 1024, 4)
  34. NO_SFDP_FLAGS(SECT_4K) },
  35. { "mx25l4005a", INFO(0xc22013, 0, 64 * 1024, 8)
  36. NO_SFDP_FLAGS(SECT_4K) },
  37. { "mx25l8005", INFO(0xc22014, 0, 64 * 1024, 16) },
  38. { "mx25l1606e", INFO(0xc22015, 0, 64 * 1024, 32)
  39. NO_SFDP_FLAGS(SECT_4K) },
  40. { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64)
  41. NO_SFDP_FLAGS(SECT_4K) },
  42. { "mx25l3255e", INFO(0xc29e16, 0, 64 * 1024, 64)
  43. NO_SFDP_FLAGS(SECT_4K) },
  44. { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128)
  45. NO_SFDP_FLAGS(SECT_4K) },
  46. { "mx25u2033e", INFO(0xc22532, 0, 64 * 1024, 4)
  47. NO_SFDP_FLAGS(SECT_4K) },
  48. { "mx25u3235f", INFO(0xc22536, 0, 64 * 1024, 64)
  49. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
  50. SPI_NOR_QUAD_READ) },
  51. { "mx25u4035", INFO(0xc22533, 0, 64 * 1024, 8)
  52. NO_SFDP_FLAGS(SECT_4K) },
  53. { "mx25u8035", INFO(0xc22534, 0, 64 * 1024, 16)
  54. NO_SFDP_FLAGS(SECT_4K) },
  55. { "mx25u6435f", INFO(0xc22537, 0, 64 * 1024, 128)
  56. NO_SFDP_FLAGS(SECT_4K) },
  57. { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256)
  58. FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_4BIT_BP)
  59. NO_SFDP_FLAGS(SECT_4K) },
  60. { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256) },
  61. { "mx25r1635f", INFO(0xc22815, 0, 64 * 1024, 32)
  62. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
  63. SPI_NOR_QUAD_READ) },
  64. { "mx25r3235f", INFO(0xc22816, 0, 64 * 1024, 64)
  65. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
  66. SPI_NOR_QUAD_READ) },
  67. { "mx25u12835f", INFO(0xc22538, 0, 64 * 1024, 256)
  68. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
  69. SPI_NOR_QUAD_READ) },
  70. { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512)
  71. NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
  72. .fixups = &mx25l25635_fixups },
  73. { "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512)
  74. NO_SFDP_FLAGS(SECT_4K)
  75. FIXUP_FLAGS(SPI_NOR_4B_OPCODES) },
  76. { "mx25u51245g", INFO(0xc2253a, 0, 64 * 1024, 1024)
  77. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
  78. FIXUP_FLAGS(SPI_NOR_4B_OPCODES) },
  79. { "mx25v8035f", INFO(0xc22314, 0, 64 * 1024, 16)
  80. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
  81. SPI_NOR_QUAD_READ) },
  82. { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512) },
  83. { "mx66l51235f", INFO(0xc2201a, 0, 64 * 1024, 1024)
  84. NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
  85. FIXUP_FLAGS(SPI_NOR_4B_OPCODES) },
  86. { "mx66u51235f", INFO(0xc2253a, 0, 64 * 1024, 1024)
  87. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
  88. FIXUP_FLAGS(SPI_NOR_4B_OPCODES) },
  89. { "mx66l1g45g", INFO(0xc2201b, 0, 64 * 1024, 2048)
  90. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
  91. SPI_NOR_QUAD_READ) },
  92. { "mx66l1g55g", INFO(0xc2261b, 0, 64 * 1024, 2048)
  93. NO_SFDP_FLAGS(SPI_NOR_QUAD_READ) },
  94. { "mx66u2g45g", INFO(0xc2253c, 0, 64 * 1024, 4096)
  95. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
  96. FIXUP_FLAGS(SPI_NOR_4B_OPCODES) },
  97. };
  98. static void macronix_nor_default_init(struct spi_nor *nor)
  99. {
  100. nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable;
  101. nor->params->set_4byte_addr_mode = spi_nor_set_4byte_addr_mode;
  102. }
  103. static const struct spi_nor_fixups macronix_nor_fixups = {
  104. .default_init = macronix_nor_default_init,
  105. };
  106. const struct spi_nor_manufacturer spi_nor_macronix = {
  107. .name = "macronix",
  108. .parts = macronix_nor_parts,
  109. .nparts = ARRAY_SIZE(macronix_nor_parts),
  110. .fixups = &macronix_nor_fixups,
  111. };