micron-st.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658
  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. /* flash_info mfr_flag. Used to read proprietary FSR register. */
  9. #define USE_FSR BIT(0)
  10. #define SPINOR_OP_MT_DIE_ERASE 0xc4 /* Chip (die) erase opcode */
  11. #define SPINOR_OP_RDFSR 0x70 /* Read flag status register */
  12. #define SPINOR_OP_CLFSR 0x50 /* Clear flag status register */
  13. #define SPINOR_OP_MT_DTR_RD 0xfd /* Fast Read opcode in DTR mode */
  14. #define SPINOR_OP_MT_RD_ANY_REG 0x85 /* Read volatile register */
  15. #define SPINOR_OP_MT_WR_ANY_REG 0x81 /* Write volatile register */
  16. #define SPINOR_REG_MT_CFR0V 0x00 /* For setting octal DTR mode */
  17. #define SPINOR_REG_MT_CFR1V 0x01 /* For setting dummy cycles */
  18. #define SPINOR_REG_MT_CFR1V_DEF 0x1f /* Default dummy cycles */
  19. #define SPINOR_MT_OCT_DTR 0xe7 /* Enable Octal DTR. */
  20. #define SPINOR_MT_EXSPI 0xff /* Enable Extended SPI (default) */
  21. /* Flag Status Register bits */
  22. #define FSR_READY BIT(7) /* Device status, 0 = Busy, 1 = Ready */
  23. #define FSR_E_ERR BIT(5) /* Erase operation status */
  24. #define FSR_P_ERR BIT(4) /* Program operation status */
  25. #define FSR_PT_ERR BIT(1) /* Protection error bit */
  26. /* Micron ST SPI NOR flash operations. */
  27. #define MICRON_ST_NOR_WR_ANY_REG_OP(naddr, addr, ndata, buf) \
  28. SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_MT_WR_ANY_REG, 0), \
  29. SPI_MEM_OP_ADDR(naddr, addr, 0), \
  30. SPI_MEM_OP_NO_DUMMY, \
  31. SPI_MEM_OP_DATA_OUT(ndata, buf, 0))
  32. #define MICRON_ST_RDFSR_OP(buf) \
  33. SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDFSR, 0), \
  34. SPI_MEM_OP_NO_ADDR, \
  35. SPI_MEM_OP_NO_DUMMY, \
  36. SPI_MEM_OP_DATA_IN(1, buf, 0))
  37. #define MICRON_ST_CLFSR_OP \
  38. SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_CLFSR, 0), \
  39. SPI_MEM_OP_NO_ADDR, \
  40. SPI_MEM_OP_NO_DUMMY, \
  41. SPI_MEM_OP_NO_DATA)
  42. static int micron_st_nor_octal_dtr_en(struct spi_nor *nor)
  43. {
  44. struct spi_mem_op op;
  45. u8 *buf = nor->bouncebuf;
  46. int ret;
  47. u8 addr_mode_nbytes = nor->params->addr_mode_nbytes;
  48. /* Use 20 dummy cycles for memory array reads. */
  49. *buf = 20;
  50. op = (struct spi_mem_op)
  51. MICRON_ST_NOR_WR_ANY_REG_OP(addr_mode_nbytes,
  52. SPINOR_REG_MT_CFR1V, 1, buf);
  53. ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto);
  54. if (ret)
  55. return ret;
  56. buf[0] = SPINOR_MT_OCT_DTR;
  57. op = (struct spi_mem_op)
  58. MICRON_ST_NOR_WR_ANY_REG_OP(addr_mode_nbytes,
  59. SPINOR_REG_MT_CFR0V, 1, buf);
  60. ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto);
  61. if (ret)
  62. return ret;
  63. /* Read flash ID to make sure the switch was successful. */
  64. ret = spi_nor_read_id(nor, 0, 8, buf, SNOR_PROTO_8_8_8_DTR);
  65. if (ret) {
  66. dev_dbg(nor->dev, "error %d reading JEDEC ID after enabling 8D-8D-8D mode\n", ret);
  67. return ret;
  68. }
  69. if (memcmp(buf, nor->info->id->bytes, nor->info->id->len))
  70. return -EINVAL;
  71. return 0;
  72. }
  73. static int micron_st_nor_octal_dtr_dis(struct spi_nor *nor)
  74. {
  75. struct spi_mem_op op;
  76. u8 *buf = nor->bouncebuf;
  77. int ret;
  78. /*
  79. * The register is 1-byte wide, but 1-byte transactions are not allowed
  80. * in 8D-8D-8D mode. The next register is the dummy cycle configuration
  81. * register. Since the transaction needs to be at least 2 bytes wide,
  82. * set the next register to its default value. This also makes sense
  83. * because the value was changed when enabling 8D-8D-8D mode, it should
  84. * be reset when disabling.
  85. */
  86. buf[0] = SPINOR_MT_EXSPI;
  87. buf[1] = SPINOR_REG_MT_CFR1V_DEF;
  88. op = (struct spi_mem_op)
  89. MICRON_ST_NOR_WR_ANY_REG_OP(nor->addr_nbytes,
  90. SPINOR_REG_MT_CFR0V, 2, buf);
  91. ret = spi_nor_write_any_volatile_reg(nor, &op, SNOR_PROTO_8_8_8_DTR);
  92. if (ret)
  93. return ret;
  94. /* Read flash ID to make sure the switch was successful. */
  95. ret = spi_nor_read_id(nor, 0, 0, buf, SNOR_PROTO_1_1_1);
  96. if (ret) {
  97. dev_dbg(nor->dev, "error %d reading JEDEC ID after disabling 8D-8D-8D mode\n", ret);
  98. return ret;
  99. }
  100. if (memcmp(buf, nor->info->id->bytes, nor->info->id->len))
  101. return -EINVAL;
  102. return 0;
  103. }
  104. static int micron_st_nor_set_octal_dtr(struct spi_nor *nor, bool enable)
  105. {
  106. return enable ? micron_st_nor_octal_dtr_en(nor) :
  107. micron_st_nor_octal_dtr_dis(nor);
  108. }
  109. static void mt35xu512aba_default_init(struct spi_nor *nor)
  110. {
  111. nor->params->set_octal_dtr = micron_st_nor_set_octal_dtr;
  112. }
  113. static int mt35xu512aba_post_sfdp_fixup(struct spi_nor *nor)
  114. {
  115. /* Set the Fast Read settings. */
  116. nor->params->hwcaps.mask |= SNOR_HWCAPS_READ_8_8_8_DTR;
  117. spi_nor_set_read_settings(&nor->params->reads[SNOR_CMD_READ_8_8_8_DTR],
  118. 0, 20, SPINOR_OP_MT_DTR_RD,
  119. SNOR_PROTO_8_8_8_DTR);
  120. nor->cmd_ext_type = SPI_NOR_EXT_REPEAT;
  121. nor->params->rdsr_dummy = 8;
  122. nor->params->rdsr_addr_nbytes = 0;
  123. /*
  124. * The BFPT quad enable field is set to a reserved value so the quad
  125. * enable function is ignored by spi_nor_parse_bfpt(). Make sure we
  126. * disable it.
  127. */
  128. nor->params->quad_enable = NULL;
  129. return 0;
  130. }
  131. static const struct spi_nor_fixups mt35xu512aba_fixups = {
  132. .default_init = mt35xu512aba_default_init,
  133. .post_sfdp = mt35xu512aba_post_sfdp_fixup,
  134. };
  135. static const struct flash_info micron_nor_parts[] = {
  136. {
  137. .id = SNOR_ID(0x2c, 0x5b, 0x1a),
  138. .name = "mt35xu512aba",
  139. .sector_size = SZ_128K,
  140. .size = SZ_64M,
  141. .no_sfdp_flags = SECT_4K | SPI_NOR_OCTAL_READ |
  142. SPI_NOR_OCTAL_DTR_READ | SPI_NOR_OCTAL_DTR_PP,
  143. .mfr_flags = USE_FSR,
  144. .fixup_flags = SPI_NOR_4B_OPCODES | SPI_NOR_IO_MODE_EN_VOLATILE,
  145. .fixups = &mt35xu512aba_fixups,
  146. }, {
  147. .id = SNOR_ID(0x2c, 0x5b, 0x1c),
  148. .name = "mt35xu02g",
  149. .sector_size = SZ_128K,
  150. .size = SZ_256M,
  151. .no_sfdp_flags = SECT_4K | SPI_NOR_OCTAL_READ,
  152. .mfr_flags = USE_FSR,
  153. .fixup_flags = SPI_NOR_4B_OPCODES,
  154. },
  155. };
  156. static int mt25qu512a_post_bfpt_fixup(struct spi_nor *nor,
  157. const struct sfdp_parameter_header *bfpt_header,
  158. const struct sfdp_bfpt *bfpt)
  159. {
  160. nor->flags &= ~SNOR_F_HAS_16BIT_SR;
  161. return 0;
  162. }
  163. static struct spi_nor_fixups mt25qu512a_fixups = {
  164. .post_bfpt = mt25qu512a_post_bfpt_fixup,
  165. };
  166. static int st_nor_four_die_late_init(struct spi_nor *nor)
  167. {
  168. struct spi_nor_flash_parameter *params = nor->params;
  169. params->die_erase_opcode = SPINOR_OP_MT_DIE_ERASE;
  170. params->n_dice = 4;
  171. /*
  172. * Unfortunately the die erase opcode does not have a 4-byte opcode
  173. * correspondent for these flashes. The SFDP 4BAIT table fails to
  174. * consider the die erase too. We're forced to enter in the 4 byte
  175. * address mode in order to benefit of the die erase.
  176. */
  177. return spi_nor_set_4byte_addr_mode(nor, true);
  178. }
  179. static int st_nor_two_die_late_init(struct spi_nor *nor)
  180. {
  181. struct spi_nor_flash_parameter *params = nor->params;
  182. params->die_erase_opcode = SPINOR_OP_MT_DIE_ERASE;
  183. params->n_dice = 2;
  184. /*
  185. * Unfortunately the die erase opcode does not have a 4-byte opcode
  186. * correspondent for these flashes. The SFDP 4BAIT table fails to
  187. * consider the die erase too. We're forced to enter in the 4 byte
  188. * address mode in order to benefit of the die erase.
  189. */
  190. return spi_nor_set_4byte_addr_mode(nor, true);
  191. }
  192. static struct spi_nor_fixups n25q00_fixups = {
  193. .late_init = st_nor_four_die_late_init,
  194. };
  195. static struct spi_nor_fixups mt25q01_fixups = {
  196. .late_init = st_nor_two_die_late_init,
  197. };
  198. static struct spi_nor_fixups mt25q02_fixups = {
  199. .late_init = st_nor_four_die_late_init,
  200. };
  201. static const struct flash_info st_nor_parts[] = {
  202. {
  203. .name = "m25p05-nonjedec",
  204. .sector_size = SZ_32K,
  205. .size = SZ_64K,
  206. }, {
  207. .name = "m25p10-nonjedec",
  208. .sector_size = SZ_32K,
  209. .size = SZ_128K,
  210. }, {
  211. .name = "m25p20-nonjedec",
  212. .size = SZ_256K,
  213. }, {
  214. .name = "m25p40-nonjedec",
  215. .size = SZ_512K,
  216. }, {
  217. .name = "m25p80-nonjedec",
  218. .size = SZ_1M,
  219. }, {
  220. .name = "m25p16-nonjedec",
  221. .size = SZ_2M,
  222. }, {
  223. .name = "m25p32-nonjedec",
  224. .size = SZ_4M,
  225. }, {
  226. .name = "m25p64-nonjedec",
  227. .size = SZ_8M,
  228. }, {
  229. .name = "m25p128-nonjedec",
  230. .sector_size = SZ_256K,
  231. .size = SZ_16M,
  232. }, {
  233. .id = SNOR_ID(0x20, 0x20, 0x10),
  234. .name = "m25p05",
  235. .sector_size = SZ_32K,
  236. .size = SZ_64K,
  237. }, {
  238. .id = SNOR_ID(0x20, 0x20, 0x11),
  239. .name = "m25p10",
  240. .sector_size = SZ_32K,
  241. .size = SZ_128K,
  242. }, {
  243. .id = SNOR_ID(0x20, 0x20, 0x12),
  244. .name = "m25p20",
  245. .size = SZ_256K,
  246. }, {
  247. .id = SNOR_ID(0x20, 0x20, 0x13),
  248. .name = "m25p40",
  249. .size = SZ_512K,
  250. }, {
  251. .id = SNOR_ID(0x20, 0x20, 0x14),
  252. .name = "m25p80",
  253. .size = SZ_1M,
  254. }, {
  255. .id = SNOR_ID(0x20, 0x20, 0x15),
  256. .name = "m25p16",
  257. .size = SZ_2M,
  258. }, {
  259. .id = SNOR_ID(0x20, 0x20, 0x16),
  260. .name = "m25p32",
  261. .size = SZ_4M,
  262. }, {
  263. .id = SNOR_ID(0x20, 0x20, 0x17),
  264. .name = "m25p64",
  265. .size = SZ_8M,
  266. }, {
  267. .id = SNOR_ID(0x20, 0x20, 0x18),
  268. .name = "m25p128",
  269. .sector_size = SZ_256K,
  270. .size = SZ_16M,
  271. }, {
  272. .id = SNOR_ID(0x20, 0x40, 0x11),
  273. .name = "m45pe10",
  274. .size = SZ_128K,
  275. }, {
  276. .id = SNOR_ID(0x20, 0x40, 0x14),
  277. .name = "m45pe80",
  278. .size = SZ_1M,
  279. }, {
  280. .id = SNOR_ID(0x20, 0x40, 0x15),
  281. .name = "m45pe16",
  282. .size = SZ_2M,
  283. }, {
  284. .id = SNOR_ID(0x20, 0x63, 0x16),
  285. .name = "m25px32-s1",
  286. .size = SZ_4M,
  287. .no_sfdp_flags = SECT_4K,
  288. }, {
  289. .id = SNOR_ID(0x20, 0x71, 0x14),
  290. .name = "m25px80",
  291. .size = SZ_1M,
  292. }, {
  293. .id = SNOR_ID(0x20, 0x71, 0x15),
  294. .name = "m25px16",
  295. .size = SZ_2M,
  296. .no_sfdp_flags = SECT_4K,
  297. }, {
  298. .id = SNOR_ID(0x20, 0x71, 0x16),
  299. .name = "m25px32",
  300. .size = SZ_4M,
  301. .no_sfdp_flags = SECT_4K,
  302. }, {
  303. .id = SNOR_ID(0x20, 0x71, 0x17),
  304. .name = "m25px64",
  305. .size = SZ_8M,
  306. }, {
  307. .id = SNOR_ID(0x20, 0x73, 0x16),
  308. .name = "m25px32-s0",
  309. .size = SZ_4M,
  310. .no_sfdp_flags = SECT_4K,
  311. }, {
  312. .id = SNOR_ID(0x20, 0x80, 0x12),
  313. .name = "m25pe20",
  314. .size = SZ_256K,
  315. }, {
  316. .id = SNOR_ID(0x20, 0x80, 0x14),
  317. .name = "m25pe80",
  318. .size = SZ_1M,
  319. }, {
  320. .id = SNOR_ID(0x20, 0x80, 0x15),
  321. .name = "m25pe16",
  322. .size = SZ_2M,
  323. .no_sfdp_flags = SECT_4K,
  324. }, {
  325. .id = SNOR_ID(0x20, 0xba, 0x16),
  326. .name = "n25q032",
  327. .size = SZ_4M,
  328. .no_sfdp_flags = SPI_NOR_QUAD_READ,
  329. }, {
  330. .id = SNOR_ID(0x20, 0xba, 0x17),
  331. .name = "n25q064",
  332. .size = SZ_8M,
  333. .no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ,
  334. }, {
  335. .id = SNOR_ID(0x20, 0xba, 0x18),
  336. .name = "n25q128a13",
  337. .size = SZ_16M,
  338. .flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP |
  339. SPI_NOR_BP3_SR_BIT6,
  340. .no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ,
  341. .mfr_flags = USE_FSR,
  342. }, {
  343. .id = SNOR_ID(0x20, 0xba, 0x19, 0x10, 0x44, 0x00),
  344. .name = "mt25ql256a",
  345. .size = SZ_32M,
  346. .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  347. .fixup_flags = SPI_NOR_4B_OPCODES,
  348. .mfr_flags = USE_FSR,
  349. }, {
  350. .id = SNOR_ID(0x20, 0xba, 0x19),
  351. .name = "n25q256a",
  352. .size = SZ_32M,
  353. .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  354. .mfr_flags = USE_FSR,
  355. }, {
  356. .id = SNOR_ID(0x20, 0xba, 0x20, 0x10, 0x44, 0x00),
  357. .name = "mt25ql512a",
  358. .size = SZ_64M,
  359. .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  360. .fixup_flags = SPI_NOR_4B_OPCODES,
  361. .mfr_flags = USE_FSR,
  362. }, {
  363. .id = SNOR_ID(0x20, 0xba, 0x20),
  364. .name = "n25q512ax3",
  365. .size = SZ_64M,
  366. .flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP |
  367. SPI_NOR_BP3_SR_BIT6,
  368. .no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ,
  369. .mfr_flags = USE_FSR,
  370. }, {
  371. .id = SNOR_ID(0x20, 0xba, 0x21),
  372. .name = "n25q00",
  373. .size = SZ_128M,
  374. .flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP |
  375. SPI_NOR_BP3_SR_BIT6,
  376. .no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ,
  377. .mfr_flags = USE_FSR,
  378. .fixups = &n25q00_fixups,
  379. }, {
  380. .id = SNOR_ID(0x20, 0xba, 0x22),
  381. .name = "mt25ql02g",
  382. .size = SZ_256M,
  383. .no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ,
  384. .mfr_flags = USE_FSR,
  385. .fixups = &mt25q02_fixups,
  386. }, {
  387. .id = SNOR_ID(0x20, 0xbb, 0x15),
  388. .name = "n25q016a",
  389. .size = SZ_2M,
  390. .no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ,
  391. }, {
  392. .id = SNOR_ID(0x20, 0xbb, 0x16),
  393. .name = "n25q032a",
  394. .size = SZ_4M,
  395. .no_sfdp_flags = SPI_NOR_QUAD_READ,
  396. }, {
  397. .id = SNOR_ID(0x20, 0xbb, 0x17),
  398. .name = "n25q064a",
  399. .size = SZ_8M,
  400. .flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP |
  401. SPI_NOR_BP3_SR_BIT6,
  402. .no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ,
  403. }, {
  404. .id = SNOR_ID(0x20, 0xbb, 0x18),
  405. .name = "n25q128a11",
  406. .size = SZ_16M,
  407. .flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP |
  408. SPI_NOR_BP3_SR_BIT6,
  409. .no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ,
  410. .mfr_flags = USE_FSR,
  411. }, {
  412. .id = SNOR_ID(0x20, 0xbb, 0x19, 0x10, 0x44, 0x00),
  413. .name = "mt25qu256a",
  414. .size = SZ_32M,
  415. .flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP |
  416. SPI_NOR_BP3_SR_BIT6,
  417. .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  418. .fixup_flags = SPI_NOR_4B_OPCODES,
  419. .mfr_flags = USE_FSR,
  420. }, {
  421. .id = SNOR_ID(0x20, 0xbb, 0x19),
  422. .name = "n25q256ax1",
  423. .size = SZ_32M,
  424. .no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ,
  425. .mfr_flags = USE_FSR,
  426. }, {
  427. .id = SNOR_ID(0x20, 0xbb, 0x20, 0x10, 0x44, 0x00),
  428. .name = "mt25qu512a",
  429. .flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP |
  430. SPI_NOR_BP3_SR_BIT6,
  431. .mfr_flags = USE_FSR,
  432. .fixups = &mt25qu512a_fixups,
  433. }, {
  434. .id = SNOR_ID(0x20, 0xbb, 0x20),
  435. .name = "n25q512a",
  436. .size = SZ_64M,
  437. .flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP |
  438. SPI_NOR_BP3_SR_BIT6,
  439. .no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ,
  440. .mfr_flags = USE_FSR,
  441. }, {
  442. .id = SNOR_ID(0x20, 0xbb, 0x21, 0x10, 0x44, 0x00),
  443. .name = "mt25qu01g",
  444. .mfr_flags = USE_FSR,
  445. .fixups = &mt25q01_fixups,
  446. }, {
  447. .id = SNOR_ID(0x20, 0xbb, 0x21),
  448. .name = "n25q00a",
  449. .size = SZ_128M,
  450. .no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ,
  451. .mfr_flags = USE_FSR,
  452. .fixups = &n25q00_fixups,
  453. }, {
  454. .id = SNOR_ID(0x20, 0xbb, 0x22),
  455. .name = "mt25qu02g",
  456. .size = SZ_256M,
  457. .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  458. .mfr_flags = USE_FSR,
  459. .fixups = &mt25q02_fixups,
  460. }
  461. };
  462. /**
  463. * micron_st_nor_read_fsr() - Read the Flag Status Register.
  464. * @nor: pointer to 'struct spi_nor'
  465. * @fsr: pointer to a DMA-able buffer where the value of the
  466. * Flag Status Register will be written. Should be at least 2
  467. * bytes.
  468. *
  469. * Return: 0 on success, -errno otherwise.
  470. */
  471. static int micron_st_nor_read_fsr(struct spi_nor *nor, u8 *fsr)
  472. {
  473. int ret;
  474. if (nor->spimem) {
  475. struct spi_mem_op op = MICRON_ST_RDFSR_OP(fsr);
  476. if (nor->reg_proto == SNOR_PROTO_8_8_8_DTR) {
  477. op.addr.nbytes = nor->params->rdsr_addr_nbytes;
  478. op.dummy.nbytes = nor->params->rdsr_dummy;
  479. /*
  480. * We don't want to read only one byte in DTR mode. So,
  481. * read 2 and then discard the second byte.
  482. */
  483. op.data.nbytes = 2;
  484. }
  485. spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
  486. ret = spi_mem_exec_op(nor->spimem, &op);
  487. } else {
  488. ret = spi_nor_controller_ops_read_reg(nor, SPINOR_OP_RDFSR, fsr,
  489. 1);
  490. }
  491. if (ret)
  492. dev_dbg(nor->dev, "error %d reading FSR\n", ret);
  493. return ret;
  494. }
  495. /**
  496. * micron_st_nor_clear_fsr() - Clear the Flag Status Register.
  497. * @nor: pointer to 'struct spi_nor'.
  498. */
  499. static void micron_st_nor_clear_fsr(struct spi_nor *nor)
  500. {
  501. int ret;
  502. if (nor->spimem) {
  503. struct spi_mem_op op = MICRON_ST_CLFSR_OP;
  504. spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
  505. ret = spi_mem_exec_op(nor->spimem, &op);
  506. } else {
  507. ret = spi_nor_controller_ops_write_reg(nor, SPINOR_OP_CLFSR,
  508. NULL, 0);
  509. }
  510. if (ret)
  511. dev_dbg(nor->dev, "error %d clearing FSR\n", ret);
  512. }
  513. /**
  514. * micron_st_nor_ready() - Query the Status Register as well as the Flag Status
  515. * Register to see if the flash is ready for new commands. If there are any
  516. * errors in the FSR clear them.
  517. * @nor: pointer to 'struct spi_nor'.
  518. *
  519. * Return: 1 if ready, 0 if not ready, -errno on errors.
  520. */
  521. static int micron_st_nor_ready(struct spi_nor *nor)
  522. {
  523. int sr_ready, ret;
  524. sr_ready = spi_nor_sr_ready(nor);
  525. if (sr_ready < 0)
  526. return sr_ready;
  527. ret = micron_st_nor_read_fsr(nor, nor->bouncebuf);
  528. if (ret) {
  529. /*
  530. * Some controllers, such as Intel SPI, do not support low
  531. * level operations such as reading the flag status
  532. * register. They only expose small amount of high level
  533. * operations to the software. If this is the case we use
  534. * only the status register value.
  535. */
  536. return ret == -EOPNOTSUPP ? sr_ready : ret;
  537. }
  538. if (nor->bouncebuf[0] & (FSR_E_ERR | FSR_P_ERR)) {
  539. if (nor->bouncebuf[0] & FSR_E_ERR)
  540. dev_err(nor->dev, "Erase operation failed.\n");
  541. else
  542. dev_err(nor->dev, "Program operation failed.\n");
  543. if (nor->bouncebuf[0] & FSR_PT_ERR)
  544. dev_err(nor->dev,
  545. "Attempted to modify a protected sector.\n");
  546. micron_st_nor_clear_fsr(nor);
  547. /*
  548. * WEL bit remains set to one when an erase or page program
  549. * error occurs. Issue a Write Disable command to protect
  550. * against inadvertent writes that can possibly corrupt the
  551. * contents of the memory.
  552. */
  553. ret = spi_nor_write_disable(nor);
  554. if (ret)
  555. return ret;
  556. return -EIO;
  557. }
  558. return sr_ready && !!(nor->bouncebuf[0] & FSR_READY);
  559. }
  560. static void micron_st_nor_default_init(struct spi_nor *nor)
  561. {
  562. nor->flags |= SNOR_F_HAS_LOCK;
  563. nor->flags &= ~SNOR_F_HAS_16BIT_SR;
  564. nor->params->quad_enable = NULL;
  565. }
  566. static int micron_st_nor_late_init(struct spi_nor *nor)
  567. {
  568. struct spi_nor_flash_parameter *params = nor->params;
  569. if (nor->info->mfr_flags & USE_FSR)
  570. params->ready = micron_st_nor_ready;
  571. if (!params->set_4byte_addr_mode)
  572. params->set_4byte_addr_mode = spi_nor_set_4byte_addr_mode_wren_en4b_ex4b;
  573. return 0;
  574. }
  575. static const struct spi_nor_fixups micron_st_nor_fixups = {
  576. .default_init = micron_st_nor_default_init,
  577. .late_init = micron_st_nor_late_init,
  578. };
  579. const struct spi_nor_manufacturer spi_nor_micron = {
  580. .name = "micron",
  581. .parts = micron_nor_parts,
  582. .nparts = ARRAY_SIZE(micron_nor_parts),
  583. .fixups = &micron_st_nor_fixups,
  584. };
  585. const struct spi_nor_manufacturer spi_nor_st = {
  586. .name = "st",
  587. .parts = st_nor_parts,
  588. .nparts = ARRAY_SIZE(st_nor_parts),
  589. .fixups = &micron_st_nor_fixups,
  590. };