spansion.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559
  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 clear sticky prorietary SR bits. */
  9. #define USE_CLSR BIT(0)
  10. #define SPINOR_OP_CLSR 0x30 /* Clear status register 1 */
  11. #define SPINOR_OP_RD_ANY_REG 0x65 /* Read any register */
  12. #define SPINOR_OP_WR_ANY_REG 0x71 /* Write any register */
  13. #define SPINOR_REG_CYPRESS_CFR1V 0x00800002
  14. #define SPINOR_REG_CYPRESS_CFR1V_QUAD_EN BIT(1) /* Quad Enable */
  15. #define SPINOR_REG_CYPRESS_CFR2V 0x00800003
  16. #define SPINOR_REG_CYPRESS_CFR2V_MEMLAT_11_24 0xb
  17. #define SPINOR_REG_CYPRESS_CFR3V 0x00800004
  18. #define SPINOR_REG_CYPRESS_CFR3V_PGSZ BIT(4) /* Page size. */
  19. #define SPINOR_REG_CYPRESS_CFR5V 0x00800006
  20. #define SPINOR_REG_CYPRESS_CFR5_BIT6 BIT(6)
  21. #define SPINOR_REG_CYPRESS_CFR5_DDR BIT(1)
  22. #define SPINOR_REG_CYPRESS_CFR5_OPI BIT(0)
  23. #define SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_EN \
  24. (SPINOR_REG_CYPRESS_CFR5_BIT6 | SPINOR_REG_CYPRESS_CFR5_DDR | \
  25. SPINOR_REG_CYPRESS_CFR5_OPI)
  26. #define SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_DS SPINOR_REG_CYPRESS_CFR5_BIT6
  27. #define SPINOR_OP_CYPRESS_RD_FAST 0xee
  28. /* Cypress SPI NOR flash operations. */
  29. #define CYPRESS_NOR_WR_ANY_REG_OP(naddr, addr, ndata, buf) \
  30. SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_ANY_REG, 0), \
  31. SPI_MEM_OP_ADDR(naddr, addr, 0), \
  32. SPI_MEM_OP_NO_DUMMY, \
  33. SPI_MEM_OP_DATA_OUT(ndata, buf, 0))
  34. #define CYPRESS_NOR_RD_ANY_REG_OP(naddr, addr, buf) \
  35. SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RD_ANY_REG, 0), \
  36. SPI_MEM_OP_ADDR(naddr, addr, 0), \
  37. SPI_MEM_OP_NO_DUMMY, \
  38. SPI_MEM_OP_DATA_IN(1, buf, 0))
  39. #define SPANSION_CLSR_OP \
  40. SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_CLSR, 0), \
  41. SPI_MEM_OP_NO_ADDR, \
  42. SPI_MEM_OP_NO_DUMMY, \
  43. SPI_MEM_OP_NO_DATA)
  44. static int cypress_nor_octal_dtr_en(struct spi_nor *nor)
  45. {
  46. struct spi_mem_op op;
  47. u8 *buf = nor->bouncebuf;
  48. int ret;
  49. /* Use 24 dummy cycles for memory array reads. */
  50. *buf = SPINOR_REG_CYPRESS_CFR2V_MEMLAT_11_24;
  51. op = (struct spi_mem_op)
  52. CYPRESS_NOR_WR_ANY_REG_OP(3, SPINOR_REG_CYPRESS_CFR2V, 1, buf);
  53. ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto);
  54. if (ret)
  55. return ret;
  56. nor->read_dummy = 24;
  57. /* Set the octal and DTR enable bits. */
  58. buf[0] = SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_EN;
  59. op = (struct spi_mem_op)
  60. CYPRESS_NOR_WR_ANY_REG_OP(3, SPINOR_REG_CYPRESS_CFR5V, 1, buf);
  61. ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto);
  62. if (ret)
  63. return ret;
  64. /* Read flash ID to make sure the switch was successful. */
  65. ret = spi_nor_read_id(nor, 4, 3, buf, SNOR_PROTO_8_8_8_DTR);
  66. if (ret) {
  67. dev_dbg(nor->dev, "error %d reading JEDEC ID after enabling 8D-8D-8D mode\n", ret);
  68. return ret;
  69. }
  70. if (memcmp(buf, nor->info->id, nor->info->id_len))
  71. return -EINVAL;
  72. return 0;
  73. }
  74. static int cypress_nor_octal_dtr_dis(struct spi_nor *nor)
  75. {
  76. struct spi_mem_op op;
  77. u8 *buf = nor->bouncebuf;
  78. int ret;
  79. /*
  80. * The register is 1-byte wide, but 1-byte transactions are not allowed
  81. * in 8D-8D-8D mode. Since there is no register at the next location,
  82. * just initialize the value to 0 and let the transaction go on.
  83. */
  84. buf[0] = SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_DS;
  85. buf[1] = 0;
  86. op = (struct spi_mem_op)
  87. CYPRESS_NOR_WR_ANY_REG_OP(4, SPINOR_REG_CYPRESS_CFR5V, 2, buf);
  88. ret = spi_nor_write_any_volatile_reg(nor, &op, SNOR_PROTO_8_8_8_DTR);
  89. if (ret)
  90. return ret;
  91. /* Read flash ID to make sure the switch was successful. */
  92. ret = spi_nor_read_id(nor, 0, 0, buf, SNOR_PROTO_1_1_1);
  93. if (ret) {
  94. dev_dbg(nor->dev, "error %d reading JEDEC ID after disabling 8D-8D-8D mode\n", ret);
  95. return ret;
  96. }
  97. if (memcmp(buf, nor->info->id, nor->info->id_len))
  98. return -EINVAL;
  99. return 0;
  100. }
  101. /**
  102. * cypress_nor_quad_enable_volatile() - enable Quad I/O mode in volatile
  103. * register.
  104. * @nor: pointer to a 'struct spi_nor'
  105. *
  106. * It is recommended to update volatile registers in the field application due
  107. * to a risk of the non-volatile registers corruption by power interrupt. This
  108. * function sets Quad Enable bit in CFR1 volatile. If users set the Quad Enable
  109. * bit in the CFR1 non-volatile in advance (typically by a Flash programmer
  110. * before mounting Flash on PCB), the Quad Enable bit in the CFR1 volatile is
  111. * also set during Flash power-up.
  112. *
  113. * Return: 0 on success, -errno otherwise.
  114. */
  115. static int cypress_nor_quad_enable_volatile(struct spi_nor *nor)
  116. {
  117. struct spi_mem_op op;
  118. u8 addr_mode_nbytes = nor->params->addr_mode_nbytes;
  119. u8 cfr1v_written;
  120. int ret;
  121. op = (struct spi_mem_op)
  122. CYPRESS_NOR_RD_ANY_REG_OP(addr_mode_nbytes,
  123. SPINOR_REG_CYPRESS_CFR1V,
  124. nor->bouncebuf);
  125. ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
  126. if (ret)
  127. return ret;
  128. if (nor->bouncebuf[0] & SPINOR_REG_CYPRESS_CFR1V_QUAD_EN)
  129. return 0;
  130. /* Update the Quad Enable bit. */
  131. nor->bouncebuf[0] |= SPINOR_REG_CYPRESS_CFR1V_QUAD_EN;
  132. op = (struct spi_mem_op)
  133. CYPRESS_NOR_WR_ANY_REG_OP(addr_mode_nbytes,
  134. SPINOR_REG_CYPRESS_CFR1V, 1,
  135. nor->bouncebuf);
  136. ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto);
  137. if (ret)
  138. return ret;
  139. cfr1v_written = nor->bouncebuf[0];
  140. /* Read back and check it. */
  141. op = (struct spi_mem_op)
  142. CYPRESS_NOR_RD_ANY_REG_OP(addr_mode_nbytes,
  143. SPINOR_REG_CYPRESS_CFR1V,
  144. nor->bouncebuf);
  145. ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
  146. if (ret)
  147. return ret;
  148. if (nor->bouncebuf[0] != cfr1v_written) {
  149. dev_err(nor->dev, "CFR1: Read back test failed\n");
  150. return -EIO;
  151. }
  152. return 0;
  153. }
  154. /**
  155. * cypress_nor_set_page_size() - Set page size which corresponds to the flash
  156. * configuration.
  157. * @nor: pointer to a 'struct spi_nor'
  158. *
  159. * The BFPT table advertises a 512B or 256B page size depending on part but the
  160. * page size is actually configurable (with the default being 256B). Read from
  161. * CFR3V[4] and set the correct size.
  162. *
  163. * Return: 0 on success, -errno otherwise.
  164. */
  165. static int cypress_nor_set_page_size(struct spi_nor *nor)
  166. {
  167. struct spi_mem_op op =
  168. CYPRESS_NOR_RD_ANY_REG_OP(3, SPINOR_REG_CYPRESS_CFR3V,
  169. nor->bouncebuf);
  170. int ret;
  171. ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
  172. if (ret)
  173. return ret;
  174. if (nor->bouncebuf[0] & SPINOR_REG_CYPRESS_CFR3V_PGSZ)
  175. nor->params->page_size = 512;
  176. else
  177. nor->params->page_size = 256;
  178. return 0;
  179. }
  180. static void cypress_nor_ecc_init(struct spi_nor *nor)
  181. {
  182. /*
  183. * Programming is supported only in 16-byte ECC data unit granularity.
  184. * Byte-programming, bit-walking, or multiple program operations to the
  185. * same ECC data unit without an erase are not allowed.
  186. */
  187. nor->params->writesize = 16;
  188. nor->flags |= SNOR_F_ECC;
  189. }
  190. static int
  191. s25hx_t_post_bfpt_fixup(struct spi_nor *nor,
  192. const struct sfdp_parameter_header *bfpt_header,
  193. const struct sfdp_bfpt *bfpt)
  194. {
  195. /* Replace Quad Enable with volatile version */
  196. nor->params->quad_enable = cypress_nor_quad_enable_volatile;
  197. return cypress_nor_set_page_size(nor);
  198. }
  199. static void s25hx_t_post_sfdp_fixup(struct spi_nor *nor)
  200. {
  201. struct spi_nor_erase_type *erase_type =
  202. nor->params->erase_map.erase_type;
  203. unsigned int i;
  204. /*
  205. * In some parts, 3byte erase opcodes are advertised by 4BAIT.
  206. * Convert them to 4byte erase opcodes.
  207. */
  208. for (i = 0; i < SNOR_ERASE_TYPE_MAX; i++) {
  209. switch (erase_type[i].opcode) {
  210. case SPINOR_OP_SE:
  211. erase_type[i].opcode = SPINOR_OP_SE_4B;
  212. break;
  213. case SPINOR_OP_BE_4K:
  214. erase_type[i].opcode = SPINOR_OP_BE_4K_4B;
  215. break;
  216. default:
  217. break;
  218. }
  219. }
  220. }
  221. static void s25hx_t_late_init(struct spi_nor *nor)
  222. {
  223. /* Fast Read 4B requires mode cycles */
  224. nor->params->reads[SNOR_CMD_READ_FAST].num_mode_clocks = 8;
  225. cypress_nor_ecc_init(nor);
  226. }
  227. static struct spi_nor_fixups s25hx_t_fixups = {
  228. .post_bfpt = s25hx_t_post_bfpt_fixup,
  229. .post_sfdp = s25hx_t_post_sfdp_fixup,
  230. .late_init = s25hx_t_late_init,
  231. };
  232. /**
  233. * cypress_nor_octal_dtr_enable() - Enable octal DTR on Cypress flashes.
  234. * @nor: pointer to a 'struct spi_nor'
  235. * @enable: whether to enable or disable Octal DTR
  236. *
  237. * This also sets the memory access latency cycles to 24 to allow the flash to
  238. * run at up to 200MHz.
  239. *
  240. * Return: 0 on success, -errno otherwise.
  241. */
  242. static int cypress_nor_octal_dtr_enable(struct spi_nor *nor, bool enable)
  243. {
  244. return enable ? cypress_nor_octal_dtr_en(nor) :
  245. cypress_nor_octal_dtr_dis(nor);
  246. }
  247. static void s28hs512t_post_sfdp_fixup(struct spi_nor *nor)
  248. {
  249. /*
  250. * On older versions of the flash the xSPI Profile 1.0 table has the
  251. * 8D-8D-8D Fast Read opcode as 0x00. But it actually should be 0xEE.
  252. */
  253. if (nor->params->reads[SNOR_CMD_READ_8_8_8_DTR].opcode == 0)
  254. nor->params->reads[SNOR_CMD_READ_8_8_8_DTR].opcode =
  255. SPINOR_OP_CYPRESS_RD_FAST;
  256. /* This flash is also missing the 4-byte Page Program opcode bit. */
  257. spi_nor_set_pp_settings(&nor->params->page_programs[SNOR_CMD_PP],
  258. SPINOR_OP_PP_4B, SNOR_PROTO_1_1_1);
  259. /*
  260. * Since xSPI Page Program opcode is backward compatible with
  261. * Legacy SPI, use Legacy SPI opcode there as well.
  262. */
  263. spi_nor_set_pp_settings(&nor->params->page_programs[SNOR_CMD_PP_8_8_8_DTR],
  264. SPINOR_OP_PP_4B, SNOR_PROTO_8_8_8_DTR);
  265. /*
  266. * The xSPI Profile 1.0 table advertises the number of additional
  267. * address bytes needed for Read Status Register command as 0 but the
  268. * actual value for that is 4.
  269. */
  270. nor->params->rdsr_addr_nbytes = 4;
  271. }
  272. static int s28hs512t_post_bfpt_fixup(struct spi_nor *nor,
  273. const struct sfdp_parameter_header *bfpt_header,
  274. const struct sfdp_bfpt *bfpt)
  275. {
  276. return cypress_nor_set_page_size(nor);
  277. }
  278. static void s28hs512t_late_init(struct spi_nor *nor)
  279. {
  280. nor->params->octal_dtr_enable = cypress_nor_octal_dtr_enable;
  281. cypress_nor_ecc_init(nor);
  282. }
  283. static const struct spi_nor_fixups s28hs512t_fixups = {
  284. .post_sfdp = s28hs512t_post_sfdp_fixup,
  285. .post_bfpt = s28hs512t_post_bfpt_fixup,
  286. .late_init = s28hs512t_late_init,
  287. };
  288. static int
  289. s25fs_s_nor_post_bfpt_fixups(struct spi_nor *nor,
  290. const struct sfdp_parameter_header *bfpt_header,
  291. const struct sfdp_bfpt *bfpt)
  292. {
  293. /*
  294. * The S25FS-S chip family reports 512-byte pages in BFPT but
  295. * in reality the write buffer still wraps at the safe default
  296. * of 256 bytes. Overwrite the page size advertised by BFPT
  297. * to get the writes working.
  298. */
  299. nor->params->page_size = 256;
  300. return 0;
  301. }
  302. static const struct spi_nor_fixups s25fs_s_nor_fixups = {
  303. .post_bfpt = s25fs_s_nor_post_bfpt_fixups,
  304. };
  305. static const struct flash_info spansion_nor_parts[] = {
  306. /* Spansion/Cypress -- single (large) sector size only, at least
  307. * for the chips listed here (without boot sectors).
  308. */
  309. { "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64)
  310. NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
  311. { "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128)
  312. NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
  313. { "s25fl128s0", INFO6(0x012018, 0x4d0080, 256 * 1024, 64)
  314. NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
  315. MFR_FLAGS(USE_CLSR)
  316. },
  317. { "s25fl128s1", INFO6(0x012018, 0x4d0180, 64 * 1024, 256)
  318. NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
  319. MFR_FLAGS(USE_CLSR)
  320. },
  321. { "s25fl256s0", INFO6(0x010219, 0x4d0080, 256 * 1024, 128)
  322. NO_SFDP_FLAGS(SPI_NOR_SKIP_SFDP | SPI_NOR_DUAL_READ |
  323. SPI_NOR_QUAD_READ)
  324. MFR_FLAGS(USE_CLSR)
  325. },
  326. { "s25fl256s1", INFO6(0x010219, 0x4d0180, 64 * 1024, 512)
  327. NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
  328. MFR_FLAGS(USE_CLSR)
  329. },
  330. { "s25fl512s", INFO6(0x010220, 0x4d0080, 256 * 1024, 256)
  331. FLAGS(SPI_NOR_HAS_LOCK)
  332. NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
  333. MFR_FLAGS(USE_CLSR)
  334. },
  335. { "s25fs128s1", INFO6(0x012018, 0x4d0181, 64 * 1024, 256)
  336. NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
  337. MFR_FLAGS(USE_CLSR)
  338. .fixups = &s25fs_s_nor_fixups, },
  339. { "s25fs256s0", INFO6(0x010219, 0x4d0081, 256 * 1024, 128)
  340. NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
  341. MFR_FLAGS(USE_CLSR)
  342. },
  343. { "s25fs256s1", INFO6(0x010219, 0x4d0181, 64 * 1024, 512)
  344. NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
  345. MFR_FLAGS(USE_CLSR)
  346. },
  347. { "s25fs512s", INFO6(0x010220, 0x4d0081, 256 * 1024, 256)
  348. NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
  349. MFR_FLAGS(USE_CLSR)
  350. .fixups = &s25fs_s_nor_fixups, },
  351. { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64) },
  352. { "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256) },
  353. { "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024, 64)
  354. NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
  355. MFR_FLAGS(USE_CLSR)
  356. },
  357. { "s25fl129p1", INFO(0x012018, 0x4d01, 64 * 1024, 256)
  358. NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
  359. MFR_FLAGS(USE_CLSR)
  360. },
  361. { "s25sl004a", INFO(0x010212, 0, 64 * 1024, 8) },
  362. { "s25sl008a", INFO(0x010213, 0, 64 * 1024, 16) },
  363. { "s25sl016a", INFO(0x010214, 0, 64 * 1024, 32) },
  364. { "s25sl032a", INFO(0x010215, 0, 64 * 1024, 64) },
  365. { "s25sl064a", INFO(0x010216, 0, 64 * 1024, 128) },
  366. { "s25fl004k", INFO(0xef4013, 0, 64 * 1024, 8)
  367. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
  368. SPI_NOR_QUAD_READ) },
  369. { "s25fl008k", INFO(0xef4014, 0, 64 * 1024, 16)
  370. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
  371. SPI_NOR_QUAD_READ) },
  372. { "s25fl016k", INFO(0xef4015, 0, 64 * 1024, 32)
  373. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
  374. SPI_NOR_QUAD_READ) },
  375. { "s25fl064k", INFO(0xef4017, 0, 64 * 1024, 128)
  376. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
  377. SPI_NOR_QUAD_READ) },
  378. { "s25fl116k", INFO(0x014015, 0, 64 * 1024, 32)
  379. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
  380. SPI_NOR_QUAD_READ) },
  381. { "s25fl132k", INFO(0x014016, 0, 64 * 1024, 64)
  382. NO_SFDP_FLAGS(SECT_4K) },
  383. { "s25fl164k", INFO(0x014017, 0, 64 * 1024, 128)
  384. NO_SFDP_FLAGS(SECT_4K) },
  385. { "s25fl204k", INFO(0x014013, 0, 64 * 1024, 8)
  386. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ) },
  387. { "s25fl208k", INFO(0x014014, 0, 64 * 1024, 16)
  388. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ) },
  389. { "s25fl064l", INFO(0x016017, 0, 64 * 1024, 128)
  390. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
  391. FIXUP_FLAGS(SPI_NOR_4B_OPCODES) },
  392. { "s25fl128l", INFO(0x016018, 0, 64 * 1024, 256)
  393. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
  394. FIXUP_FLAGS(SPI_NOR_4B_OPCODES) },
  395. { "s25fl256l", INFO(0x016019, 0, 64 * 1024, 512)
  396. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
  397. FIXUP_FLAGS(SPI_NOR_4B_OPCODES) },
  398. { "s25hl512t", INFO6(0x342a1a, 0x0f0390, 256 * 1024, 256)
  399. PARSE_SFDP
  400. MFR_FLAGS(USE_CLSR)
  401. .fixups = &s25hx_t_fixups },
  402. { "s25hl01gt", INFO6(0x342a1b, 0x0f0390, 256 * 1024, 512)
  403. PARSE_SFDP
  404. MFR_FLAGS(USE_CLSR)
  405. .fixups = &s25hx_t_fixups },
  406. { "s25hs512t", INFO6(0x342b1a, 0x0f0390, 256 * 1024, 256)
  407. PARSE_SFDP
  408. MFR_FLAGS(USE_CLSR)
  409. .fixups = &s25hx_t_fixups },
  410. { "s25hs01gt", INFO6(0x342b1b, 0x0f0390, 256 * 1024, 512)
  411. PARSE_SFDP
  412. MFR_FLAGS(USE_CLSR)
  413. .fixups = &s25hx_t_fixups },
  414. { "cy15x104q", INFO6(0x042cc2, 0x7f7f7f, 512 * 1024, 1)
  415. FLAGS(SPI_NOR_NO_ERASE) },
  416. { "s28hs512t", INFO(0x345b1a, 0, 256 * 1024, 256)
  417. PARSE_SFDP
  418. .fixups = &s28hs512t_fixups,
  419. },
  420. };
  421. /**
  422. * spansion_nor_clear_sr() - Clear the Status Register.
  423. * @nor: pointer to 'struct spi_nor'.
  424. */
  425. static void spansion_nor_clear_sr(struct spi_nor *nor)
  426. {
  427. int ret;
  428. if (nor->spimem) {
  429. struct spi_mem_op op = SPANSION_CLSR_OP;
  430. spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
  431. ret = spi_mem_exec_op(nor->spimem, &op);
  432. } else {
  433. ret = spi_nor_controller_ops_write_reg(nor, SPINOR_OP_CLSR,
  434. NULL, 0);
  435. }
  436. if (ret)
  437. dev_dbg(nor->dev, "error %d clearing SR\n", ret);
  438. }
  439. /**
  440. * spansion_nor_sr_ready_and_clear() - Query the Status Register to see if the
  441. * flash is ready for new commands and clear it if there are any errors.
  442. * @nor: pointer to 'struct spi_nor'.
  443. *
  444. * Return: 1 if ready, 0 if not ready, -errno on errors.
  445. */
  446. static int spansion_nor_sr_ready_and_clear(struct spi_nor *nor)
  447. {
  448. int ret;
  449. ret = spi_nor_read_sr(nor, nor->bouncebuf);
  450. if (ret)
  451. return ret;
  452. if (nor->bouncebuf[0] & (SR_E_ERR | SR_P_ERR)) {
  453. if (nor->bouncebuf[0] & SR_E_ERR)
  454. dev_err(nor->dev, "Erase Error occurred\n");
  455. else
  456. dev_err(nor->dev, "Programming Error occurred\n");
  457. spansion_nor_clear_sr(nor);
  458. /*
  459. * WEL bit remains set to one when an erase or page program
  460. * error occurs. Issue a Write Disable command to protect
  461. * against inadvertent writes that can possibly corrupt the
  462. * contents of the memory.
  463. */
  464. ret = spi_nor_write_disable(nor);
  465. if (ret)
  466. return ret;
  467. return -EIO;
  468. }
  469. return !(nor->bouncebuf[0] & SR_WIP);
  470. }
  471. static void spansion_nor_late_init(struct spi_nor *nor)
  472. {
  473. if (nor->params->size > SZ_16M) {
  474. nor->flags |= SNOR_F_4B_OPCODES;
  475. /* No small sector erase for 4-byte command set */
  476. nor->erase_opcode = SPINOR_OP_SE;
  477. nor->mtd.erasesize = nor->info->sector_size;
  478. }
  479. if (nor->info->mfr_flags & USE_CLSR)
  480. nor->params->ready = spansion_nor_sr_ready_and_clear;
  481. }
  482. static const struct spi_nor_fixups spansion_nor_fixups = {
  483. .late_init = spansion_nor_late_init,
  484. };
  485. const struct spi_nor_manufacturer spi_nor_spansion = {
  486. .name = "spansion",
  487. .parts = spansion_nor_parts,
  488. .nparts = ARRAY_SIZE(spansion_nor_parts),
  489. .fixups = &spansion_nor_fixups,
  490. };