spansion.c 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171
  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/bitfield.h>
  7. #include <linux/device.h>
  8. #include <linux/errno.h>
  9. #include <linux/mtd/spi-nor.h>
  10. #include "core.h"
  11. /* flash_info mfr_flag. Used to clear sticky prorietary SR bits. */
  12. #define USE_CLSR BIT(0)
  13. #define USE_CLPEF BIT(1)
  14. #define SPINOR_OP_CLSR 0x30 /* Clear status register 1 */
  15. #define SPINOR_OP_CLPEF 0x82 /* Clear program/erase failure flags */
  16. #define SPINOR_OP_CYPRESS_EX4B 0xB8 /* Exit 4-byte address mode */
  17. #define SPINOR_OP_CYPRESS_DIE_ERASE 0x61 /* Chip (die) erase */
  18. #define SPINOR_OP_RD_ANY_REG 0x65 /* Read any register */
  19. #define SPINOR_OP_WR_ANY_REG 0x71 /* Write any register */
  20. #define SPINOR_REG_CYPRESS_VREG 0x00800000
  21. #define SPINOR_REG_CYPRESS_STR1 0x0
  22. #define SPINOR_REG_CYPRESS_STR1V \
  23. (SPINOR_REG_CYPRESS_VREG + SPINOR_REG_CYPRESS_STR1)
  24. #define SPINOR_REG_CYPRESS_CFR1 0x2
  25. #define SPINOR_REG_CYPRESS_CFR1_QUAD_EN BIT(1) /* Quad Enable */
  26. #define SPINOR_REG_CYPRESS_CFR2 0x3
  27. #define SPINOR_REG_CYPRESS_CFR2V \
  28. (SPINOR_REG_CYPRESS_VREG + SPINOR_REG_CYPRESS_CFR2)
  29. #define SPINOR_REG_CYPRESS_CFR2_MEMLAT_MASK GENMASK(3, 0)
  30. #define SPINOR_REG_CYPRESS_CFR2_MEMLAT_11_24 0xb
  31. #define SPINOR_REG_CYPRESS_CFR2_ADRBYT BIT(7)
  32. #define SPINOR_REG_CYPRESS_CFR3 0x4
  33. #define SPINOR_REG_CYPRESS_CFR3_PGSZ BIT(4) /* Page size. */
  34. #define SPINOR_REG_CYPRESS_CFR5 0x6
  35. #define SPINOR_REG_CYPRESS_CFR5_BIT6 BIT(6)
  36. #define SPINOR_REG_CYPRESS_CFR5_DDR BIT(1)
  37. #define SPINOR_REG_CYPRESS_CFR5_OPI BIT(0)
  38. #define SPINOR_REG_CYPRESS_CFR5_OCT_DTR_EN \
  39. (SPINOR_REG_CYPRESS_CFR5_BIT6 | SPINOR_REG_CYPRESS_CFR5_DDR | \
  40. SPINOR_REG_CYPRESS_CFR5_OPI)
  41. #define SPINOR_REG_CYPRESS_CFR5_OCT_DTR_DS SPINOR_REG_CYPRESS_CFR5_BIT6
  42. #define SPINOR_OP_CYPRESS_RD_FAST 0xee
  43. #define SPINOR_REG_CYPRESS_ARCFN 0x00000006
  44. /* Cypress SPI NOR flash operations. */
  45. #define CYPRESS_NOR_WR_ANY_REG_OP(naddr, addr, ndata, buf) \
  46. SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_ANY_REG, 0), \
  47. SPI_MEM_OP_ADDR(naddr, addr, 0), \
  48. SPI_MEM_OP_NO_DUMMY, \
  49. SPI_MEM_OP_DATA_OUT(ndata, buf, 0))
  50. #define CYPRESS_NOR_RD_ANY_REG_OP(naddr, addr, ndummy, buf) \
  51. SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RD_ANY_REG, 0), \
  52. SPI_MEM_OP_ADDR(naddr, addr, 0), \
  53. SPI_MEM_OP_DUMMY(ndummy, 0), \
  54. SPI_MEM_OP_DATA_IN(1, buf, 0))
  55. #define CYPRESS_NOR_EN4B_EX4B_OP(enable) \
  56. SPI_MEM_OP(SPI_MEM_OP_CMD(enable ? SPINOR_OP_EN4B : \
  57. SPINOR_OP_CYPRESS_EX4B, 0), \
  58. SPI_MEM_OP_NO_ADDR, \
  59. SPI_MEM_OP_NO_DUMMY, \
  60. SPI_MEM_OP_NO_DATA)
  61. #define SPANSION_OP(opcode) \
  62. SPI_MEM_OP(SPI_MEM_OP_CMD(opcode, 0), \
  63. SPI_MEM_OP_NO_ADDR, \
  64. SPI_MEM_OP_NO_DUMMY, \
  65. SPI_MEM_OP_NO_DATA)
  66. /**
  67. * struct spansion_nor_params - Spansion private parameters.
  68. * @clsr: Clear Status Register or Clear Program and Erase Failure Flag
  69. * opcode.
  70. */
  71. struct spansion_nor_params {
  72. u8 clsr;
  73. };
  74. /**
  75. * spansion_nor_clear_sr() - Clear the Status Register.
  76. * @nor: pointer to 'struct spi_nor'.
  77. */
  78. static void spansion_nor_clear_sr(struct spi_nor *nor)
  79. {
  80. const struct spansion_nor_params *priv_params = nor->params->priv;
  81. int ret;
  82. if (nor->spimem) {
  83. struct spi_mem_op op = SPANSION_OP(priv_params->clsr);
  84. spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
  85. ret = spi_mem_exec_op(nor->spimem, &op);
  86. } else {
  87. ret = spi_nor_controller_ops_write_reg(nor, SPINOR_OP_CLSR,
  88. NULL, 0);
  89. }
  90. if (ret)
  91. dev_dbg(nor->dev, "error %d clearing SR\n", ret);
  92. }
  93. static int cypress_nor_sr_ready_and_clear_reg(struct spi_nor *nor, u64 addr)
  94. {
  95. struct spi_nor_flash_parameter *params = nor->params;
  96. struct spi_mem_op op =
  97. CYPRESS_NOR_RD_ANY_REG_OP(params->addr_mode_nbytes, addr,
  98. 0, nor->bouncebuf);
  99. int ret;
  100. if (nor->reg_proto == SNOR_PROTO_8_8_8_DTR) {
  101. op.addr.nbytes = nor->addr_nbytes;
  102. op.dummy.nbytes = params->rdsr_dummy;
  103. op.data.nbytes = 2;
  104. }
  105. ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
  106. if (ret)
  107. return ret;
  108. if (nor->bouncebuf[0] & (SR_E_ERR | SR_P_ERR)) {
  109. if (nor->bouncebuf[0] & SR_E_ERR)
  110. dev_err(nor->dev, "Erase Error occurred\n");
  111. else
  112. dev_err(nor->dev, "Programming Error occurred\n");
  113. spansion_nor_clear_sr(nor);
  114. ret = spi_nor_write_disable(nor);
  115. if (ret)
  116. return ret;
  117. return -EIO;
  118. }
  119. return !(nor->bouncebuf[0] & SR_WIP);
  120. }
  121. /**
  122. * cypress_nor_sr_ready_and_clear() - Query the Status Register of each die by
  123. * using Read Any Register command to see if the whole flash is ready for new
  124. * commands and clear it if there are any errors.
  125. * @nor: pointer to 'struct spi_nor'.
  126. *
  127. * Return: 1 if ready, 0 if not ready, -errno on errors.
  128. */
  129. static int cypress_nor_sr_ready_and_clear(struct spi_nor *nor)
  130. {
  131. struct spi_nor_flash_parameter *params = nor->params;
  132. u64 addr;
  133. int ret;
  134. u8 i;
  135. for (i = 0; i < params->n_dice; i++) {
  136. addr = params->vreg_offset[i] + SPINOR_REG_CYPRESS_STR1;
  137. ret = cypress_nor_sr_ready_and_clear_reg(nor, addr);
  138. if (ret < 0)
  139. return ret;
  140. else if (ret == 0)
  141. return 0;
  142. }
  143. return 1;
  144. }
  145. static int cypress_nor_set_memlat(struct spi_nor *nor, u64 addr)
  146. {
  147. struct spi_mem_op op;
  148. u8 *buf = nor->bouncebuf;
  149. int ret;
  150. u8 addr_mode_nbytes = nor->params->addr_mode_nbytes;
  151. op = (struct spi_mem_op)
  152. CYPRESS_NOR_RD_ANY_REG_OP(addr_mode_nbytes, addr, 0, buf);
  153. ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
  154. if (ret)
  155. return ret;
  156. /* Use 24 dummy cycles for memory array reads. */
  157. *buf &= ~SPINOR_REG_CYPRESS_CFR2_MEMLAT_MASK;
  158. *buf |= FIELD_PREP(SPINOR_REG_CYPRESS_CFR2_MEMLAT_MASK,
  159. SPINOR_REG_CYPRESS_CFR2_MEMLAT_11_24);
  160. op = (struct spi_mem_op)
  161. CYPRESS_NOR_WR_ANY_REG_OP(addr_mode_nbytes, addr, 1, buf);
  162. ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto);
  163. if (ret)
  164. return ret;
  165. nor->read_dummy = 24;
  166. return 0;
  167. }
  168. static int cypress_nor_set_octal_dtr_bits(struct spi_nor *nor, u64 addr)
  169. {
  170. struct spi_mem_op op;
  171. u8 *buf = nor->bouncebuf;
  172. /* Set the octal and DTR enable bits. */
  173. buf[0] = SPINOR_REG_CYPRESS_CFR5_OCT_DTR_EN;
  174. op = (struct spi_mem_op)
  175. CYPRESS_NOR_WR_ANY_REG_OP(nor->params->addr_mode_nbytes,
  176. addr, 1, buf);
  177. return spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto);
  178. }
  179. static int cypress_nor_octal_dtr_en(struct spi_nor *nor)
  180. {
  181. const struct spi_nor_flash_parameter *params = nor->params;
  182. u8 *buf = nor->bouncebuf;
  183. u64 addr;
  184. int i, ret;
  185. for (i = 0; i < params->n_dice; i++) {
  186. addr = params->vreg_offset[i] + SPINOR_REG_CYPRESS_CFR2;
  187. ret = cypress_nor_set_memlat(nor, addr);
  188. if (ret)
  189. return ret;
  190. addr = params->vreg_offset[i] + SPINOR_REG_CYPRESS_CFR5;
  191. ret = cypress_nor_set_octal_dtr_bits(nor, addr);
  192. if (ret)
  193. return ret;
  194. }
  195. /* Read flash ID to make sure the switch was successful. */
  196. ret = spi_nor_read_id(nor, nor->addr_nbytes, 3, buf,
  197. SNOR_PROTO_8_8_8_DTR);
  198. if (ret) {
  199. dev_dbg(nor->dev, "error %d reading JEDEC ID after enabling 8D-8D-8D mode\n", ret);
  200. return ret;
  201. }
  202. if (memcmp(buf, nor->info->id->bytes, nor->info->id->len))
  203. return -EINVAL;
  204. return 0;
  205. }
  206. static int cypress_nor_set_single_spi_bits(struct spi_nor *nor, u64 addr)
  207. {
  208. struct spi_mem_op op;
  209. u8 *buf = nor->bouncebuf;
  210. /*
  211. * The register is 1-byte wide, but 1-byte transactions are not allowed
  212. * in 8D-8D-8D mode. Since there is no register at the next location,
  213. * just initialize the value to 0 and let the transaction go on.
  214. */
  215. buf[0] = SPINOR_REG_CYPRESS_CFR5_OCT_DTR_DS;
  216. buf[1] = 0;
  217. op = (struct spi_mem_op)
  218. CYPRESS_NOR_WR_ANY_REG_OP(nor->addr_nbytes, addr, 2, buf);
  219. return spi_nor_write_any_volatile_reg(nor, &op, SNOR_PROTO_8_8_8_DTR);
  220. }
  221. static int cypress_nor_octal_dtr_dis(struct spi_nor *nor)
  222. {
  223. const struct spi_nor_flash_parameter *params = nor->params;
  224. u8 *buf = nor->bouncebuf;
  225. u64 addr;
  226. int i, ret;
  227. for (i = 0; i < params->n_dice; i++) {
  228. addr = params->vreg_offset[i] + SPINOR_REG_CYPRESS_CFR5;
  229. ret = cypress_nor_set_single_spi_bits(nor, addr);
  230. if (ret)
  231. return ret;
  232. }
  233. /* Read flash ID to make sure the switch was successful. */
  234. ret = spi_nor_read_id(nor, 0, 0, buf, SNOR_PROTO_1_1_1);
  235. if (ret) {
  236. dev_dbg(nor->dev, "error %d reading JEDEC ID after disabling 8D-8D-8D mode\n", ret);
  237. return ret;
  238. }
  239. if (memcmp(buf, nor->info->id->bytes, nor->info->id->len))
  240. return -EINVAL;
  241. return 0;
  242. }
  243. static int cypress_nor_quad_enable_volatile_reg(struct spi_nor *nor, u64 addr)
  244. {
  245. struct spi_mem_op op;
  246. u8 addr_mode_nbytes = nor->params->addr_mode_nbytes;
  247. u8 cfr1v_written;
  248. int ret;
  249. op = (struct spi_mem_op)
  250. CYPRESS_NOR_RD_ANY_REG_OP(addr_mode_nbytes, addr, 0,
  251. nor->bouncebuf);
  252. ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
  253. if (ret)
  254. return ret;
  255. if (nor->bouncebuf[0] & SPINOR_REG_CYPRESS_CFR1_QUAD_EN)
  256. return 0;
  257. /* Update the Quad Enable bit. */
  258. nor->bouncebuf[0] |= SPINOR_REG_CYPRESS_CFR1_QUAD_EN;
  259. op = (struct spi_mem_op)
  260. CYPRESS_NOR_WR_ANY_REG_OP(addr_mode_nbytes, addr, 1,
  261. nor->bouncebuf);
  262. ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto);
  263. if (ret)
  264. return ret;
  265. cfr1v_written = nor->bouncebuf[0];
  266. /* Read back and check it. */
  267. op = (struct spi_mem_op)
  268. CYPRESS_NOR_RD_ANY_REG_OP(addr_mode_nbytes, addr, 0,
  269. nor->bouncebuf);
  270. ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
  271. if (ret)
  272. return ret;
  273. if (nor->bouncebuf[0] != cfr1v_written) {
  274. dev_err(nor->dev, "CFR1: Read back test failed\n");
  275. return -EIO;
  276. }
  277. return 0;
  278. }
  279. /**
  280. * cypress_nor_quad_enable_volatile() - enable Quad I/O mode in volatile
  281. * register.
  282. * @nor: pointer to a 'struct spi_nor'
  283. *
  284. * It is recommended to update volatile registers in the field application due
  285. * to a risk of the non-volatile registers corruption by power interrupt. This
  286. * function sets Quad Enable bit in CFR1 volatile. If users set the Quad Enable
  287. * bit in the CFR1 non-volatile in advance (typically by a Flash programmer
  288. * before mounting Flash on PCB), the Quad Enable bit in the CFR1 volatile is
  289. * also set during Flash power-up.
  290. *
  291. * Return: 0 on success, -errno otherwise.
  292. */
  293. static int cypress_nor_quad_enable_volatile(struct spi_nor *nor)
  294. {
  295. struct spi_nor_flash_parameter *params = nor->params;
  296. u64 addr;
  297. u8 i;
  298. int ret;
  299. for (i = 0; i < params->n_dice; i++) {
  300. addr = params->vreg_offset[i] + SPINOR_REG_CYPRESS_CFR1;
  301. ret = cypress_nor_quad_enable_volatile_reg(nor, addr);
  302. if (ret)
  303. return ret;
  304. }
  305. return 0;
  306. }
  307. static int cypress_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable)
  308. {
  309. int ret;
  310. struct spi_mem_op op = CYPRESS_NOR_EN4B_EX4B_OP(enable);
  311. spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
  312. ret = spi_mem_exec_op(nor->spimem, &op);
  313. if (ret)
  314. dev_dbg(nor->dev, "error %d setting 4-byte mode\n", ret);
  315. return ret;
  316. }
  317. /**
  318. * cypress_nor_determine_addr_mode_by_sr1() - Determine current address mode
  319. * (3 or 4-byte) by querying status
  320. * register 1 (SR1).
  321. * @nor: pointer to a 'struct spi_nor'
  322. * @addr_mode: ponter to a buffer where we return the determined
  323. * address mode.
  324. *
  325. * This function tries to determine current address mode by comparing SR1 value
  326. * from RDSR1(no address), RDAR(3-byte address), and RDAR(4-byte address).
  327. *
  328. * Return: 0 on success, -errno otherwise.
  329. */
  330. static int cypress_nor_determine_addr_mode_by_sr1(struct spi_nor *nor,
  331. u8 *addr_mode)
  332. {
  333. struct spi_mem_op op =
  334. CYPRESS_NOR_RD_ANY_REG_OP(3, SPINOR_REG_CYPRESS_STR1V, 0,
  335. nor->bouncebuf);
  336. bool is3byte, is4byte;
  337. int ret;
  338. ret = spi_nor_read_sr(nor, &nor->bouncebuf[1]);
  339. if (ret)
  340. return ret;
  341. ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
  342. if (ret)
  343. return ret;
  344. is3byte = (nor->bouncebuf[0] == nor->bouncebuf[1]);
  345. op = (struct spi_mem_op)
  346. CYPRESS_NOR_RD_ANY_REG_OP(4, SPINOR_REG_CYPRESS_STR1V, 0,
  347. nor->bouncebuf);
  348. ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
  349. if (ret)
  350. return ret;
  351. is4byte = (nor->bouncebuf[0] == nor->bouncebuf[1]);
  352. if (is3byte == is4byte)
  353. return -EIO;
  354. if (is3byte)
  355. *addr_mode = 3;
  356. else
  357. *addr_mode = 4;
  358. return 0;
  359. }
  360. /**
  361. * cypress_nor_set_addr_mode_nbytes() - Set the number of address bytes mode of
  362. * current address mode.
  363. * @nor: pointer to a 'struct spi_nor'
  364. *
  365. * Determine current address mode by reading SR1 with different methods, then
  366. * query CFR2V[7] to confirm. If determination is failed, force enter to 4-byte
  367. * address mode.
  368. *
  369. * Return: 0 on success, -errno otherwise.
  370. */
  371. static int cypress_nor_set_addr_mode_nbytes(struct spi_nor *nor)
  372. {
  373. struct spi_mem_op op;
  374. u8 addr_mode;
  375. int ret;
  376. /*
  377. * Read SR1 by RDSR1 and RDAR(3- AND 4-byte addr). Use write enable
  378. * that sets bit-1 in SR1.
  379. */
  380. ret = spi_nor_write_enable(nor);
  381. if (ret)
  382. return ret;
  383. ret = cypress_nor_determine_addr_mode_by_sr1(nor, &addr_mode);
  384. if (ret) {
  385. ret = spi_nor_set_4byte_addr_mode(nor, true);
  386. if (ret)
  387. return ret;
  388. return spi_nor_write_disable(nor);
  389. }
  390. ret = spi_nor_write_disable(nor);
  391. if (ret)
  392. return ret;
  393. /*
  394. * Query CFR2V and make sure no contradiction between determined address
  395. * mode and CFR2V[7].
  396. */
  397. op = (struct spi_mem_op)
  398. CYPRESS_NOR_RD_ANY_REG_OP(addr_mode, SPINOR_REG_CYPRESS_CFR2V,
  399. 0, nor->bouncebuf);
  400. ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
  401. if (ret)
  402. return ret;
  403. if (nor->bouncebuf[0] & SPINOR_REG_CYPRESS_CFR2_ADRBYT) {
  404. if (addr_mode != 4)
  405. return spi_nor_set_4byte_addr_mode(nor, true);
  406. } else {
  407. if (addr_mode != 3)
  408. return spi_nor_set_4byte_addr_mode(nor, true);
  409. }
  410. nor->params->addr_nbytes = addr_mode;
  411. nor->params->addr_mode_nbytes = addr_mode;
  412. return 0;
  413. }
  414. /**
  415. * cypress_nor_get_page_size() - Get flash page size configuration.
  416. * @nor: pointer to a 'struct spi_nor'
  417. *
  418. * The BFPT table advertises a 512B or 256B page size depending on part but the
  419. * page size is actually configurable (with the default being 256B). Read from
  420. * CFR3V[4] and set the correct size.
  421. *
  422. * Return: 0 on success, -errno otherwise.
  423. */
  424. static int cypress_nor_get_page_size(struct spi_nor *nor)
  425. {
  426. struct spi_mem_op op =
  427. CYPRESS_NOR_RD_ANY_REG_OP(nor->params->addr_mode_nbytes,
  428. 0, 0, nor->bouncebuf);
  429. struct spi_nor_flash_parameter *params = nor->params;
  430. int ret;
  431. u8 i;
  432. /*
  433. * Use the minimum common page size configuration. Programming 256-byte
  434. * under 512-byte page size configuration is safe.
  435. */
  436. params->page_size = 256;
  437. for (i = 0; i < params->n_dice; i++) {
  438. op.addr.val = params->vreg_offset[i] + SPINOR_REG_CYPRESS_CFR3;
  439. ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
  440. if (ret)
  441. return ret;
  442. if (!(nor->bouncebuf[0] & SPINOR_REG_CYPRESS_CFR3_PGSZ))
  443. return 0;
  444. }
  445. params->page_size = 512;
  446. return 0;
  447. }
  448. static void cypress_nor_ecc_init(struct spi_nor *nor)
  449. {
  450. /*
  451. * Programming is supported only in 16-byte ECC data unit granularity.
  452. * Byte-programming, bit-walking, or multiple program operations to the
  453. * same ECC data unit without an erase are not allowed.
  454. */
  455. nor->params->writesize = 16;
  456. nor->flags |= SNOR_F_ECC;
  457. }
  458. static int
  459. s25fs256t_post_bfpt_fixup(struct spi_nor *nor,
  460. const struct sfdp_parameter_header *bfpt_header,
  461. const struct sfdp_bfpt *bfpt)
  462. {
  463. struct spi_mem_op op;
  464. int ret;
  465. /* Assign 4-byte address mode method that is not determined in BFPT */
  466. nor->params->set_4byte_addr_mode = cypress_nor_set_4byte_addr_mode;
  467. ret = cypress_nor_set_addr_mode_nbytes(nor);
  468. if (ret)
  469. return ret;
  470. /* Read Architecture Configuration Register (ARCFN) */
  471. op = (struct spi_mem_op)
  472. CYPRESS_NOR_RD_ANY_REG_OP(nor->params->addr_mode_nbytes,
  473. SPINOR_REG_CYPRESS_ARCFN, 1,
  474. nor->bouncebuf);
  475. ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
  476. if (ret)
  477. return ret;
  478. /* ARCFN value must be 0 if uniform sector is selected */
  479. if (nor->bouncebuf[0])
  480. return -ENODEV;
  481. return 0;
  482. }
  483. static int s25fs256t_post_sfdp_fixup(struct spi_nor *nor)
  484. {
  485. struct spi_nor_flash_parameter *params = nor->params;
  486. /*
  487. * S25FS256T does not define the SCCR map, but we would like to use the
  488. * same code base for both single and multi chip package devices, thus
  489. * set the vreg_offset and n_dice to be able to do so.
  490. */
  491. params->vreg_offset = devm_kmalloc(nor->dev, sizeof(u32), GFP_KERNEL);
  492. if (!params->vreg_offset)
  493. return -ENOMEM;
  494. params->vreg_offset[0] = SPINOR_REG_CYPRESS_VREG;
  495. params->n_dice = 1;
  496. /* PP_1_1_4_4B is supported but missing in 4BAIT. */
  497. params->hwcaps.mask |= SNOR_HWCAPS_PP_1_1_4;
  498. spi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP_1_1_4],
  499. SPINOR_OP_PP_1_1_4_4B,
  500. SNOR_PROTO_1_1_4);
  501. return cypress_nor_get_page_size(nor);
  502. }
  503. static int s25fs256t_late_init(struct spi_nor *nor)
  504. {
  505. cypress_nor_ecc_init(nor);
  506. return 0;
  507. }
  508. static const struct spi_nor_fixups s25fs256t_fixups = {
  509. .post_bfpt = s25fs256t_post_bfpt_fixup,
  510. .post_sfdp = s25fs256t_post_sfdp_fixup,
  511. .late_init = s25fs256t_late_init,
  512. };
  513. static int
  514. s25hx_t_post_bfpt_fixup(struct spi_nor *nor,
  515. const struct sfdp_parameter_header *bfpt_header,
  516. const struct sfdp_bfpt *bfpt)
  517. {
  518. int ret;
  519. /* Assign 4-byte address mode method that is not determined in BFPT */
  520. nor->params->set_4byte_addr_mode = cypress_nor_set_4byte_addr_mode;
  521. ret = cypress_nor_set_addr_mode_nbytes(nor);
  522. if (ret)
  523. return ret;
  524. /* Replace Quad Enable with volatile version */
  525. nor->params->quad_enable = cypress_nor_quad_enable_volatile;
  526. return 0;
  527. }
  528. static int s25hx_t_post_sfdp_fixup(struct spi_nor *nor)
  529. {
  530. struct spi_nor_flash_parameter *params = nor->params;
  531. struct spi_nor_erase_type *erase_type = params->erase_map.erase_type;
  532. unsigned int i;
  533. if (!params->n_dice || !params->vreg_offset) {
  534. dev_err(nor->dev, "%s failed. The volatile register offset could not be retrieved from SFDP.\n",
  535. __func__);
  536. return -EOPNOTSUPP;
  537. }
  538. /* The 2 Gb parts duplicate info and advertise 4 dice instead of 2. */
  539. if (params->size == SZ_256M)
  540. params->n_dice = 2;
  541. /*
  542. * In some parts, 3byte erase opcodes are advertised by 4BAIT.
  543. * Convert them to 4byte erase opcodes.
  544. */
  545. for (i = 0; i < SNOR_ERASE_TYPE_MAX; i++) {
  546. switch (erase_type[i].opcode) {
  547. case SPINOR_OP_SE:
  548. erase_type[i].opcode = SPINOR_OP_SE_4B;
  549. break;
  550. case SPINOR_OP_BE_4K:
  551. erase_type[i].opcode = SPINOR_OP_BE_4K_4B;
  552. break;
  553. default:
  554. break;
  555. }
  556. }
  557. return cypress_nor_get_page_size(nor);
  558. }
  559. static int s25hx_t_late_init(struct spi_nor *nor)
  560. {
  561. struct spi_nor_flash_parameter *params = nor->params;
  562. /* Fast Read 4B requires mode cycles */
  563. params->reads[SNOR_CMD_READ_FAST].num_mode_clocks = 8;
  564. params->ready = cypress_nor_sr_ready_and_clear;
  565. cypress_nor_ecc_init(nor);
  566. params->die_erase_opcode = SPINOR_OP_CYPRESS_DIE_ERASE;
  567. return 0;
  568. }
  569. static const struct spi_nor_fixups s25hx_t_fixups = {
  570. .post_bfpt = s25hx_t_post_bfpt_fixup,
  571. .post_sfdp = s25hx_t_post_sfdp_fixup,
  572. .late_init = s25hx_t_late_init,
  573. };
  574. /**
  575. * cypress_nor_set_octal_dtr() - Enable or disable octal DTR on Cypress flashes.
  576. * @nor: pointer to a 'struct spi_nor'
  577. * @enable: whether to enable or disable Octal DTR
  578. *
  579. * This also sets the memory access latency cycles to 24 to allow the flash to
  580. * run at up to 200MHz.
  581. *
  582. * Return: 0 on success, -errno otherwise.
  583. */
  584. static int cypress_nor_set_octal_dtr(struct spi_nor *nor, bool enable)
  585. {
  586. return enable ? cypress_nor_octal_dtr_en(nor) :
  587. cypress_nor_octal_dtr_dis(nor);
  588. }
  589. static int s28hx_t_post_sfdp_fixup(struct spi_nor *nor)
  590. {
  591. struct spi_nor_flash_parameter *params = nor->params;
  592. if (!params->n_dice || !params->vreg_offset) {
  593. dev_err(nor->dev, "%s failed. The volatile register offset could not be retrieved from SFDP.\n",
  594. __func__);
  595. return -EOPNOTSUPP;
  596. }
  597. /* The 2 Gb parts duplicate info and advertise 4 dice instead of 2. */
  598. if (params->size == SZ_256M)
  599. params->n_dice = 2;
  600. /*
  601. * On older versions of the flash the xSPI Profile 1.0 table has the
  602. * 8D-8D-8D Fast Read opcode as 0x00. But it actually should be 0xEE.
  603. */
  604. if (params->reads[SNOR_CMD_READ_8_8_8_DTR].opcode == 0)
  605. params->reads[SNOR_CMD_READ_8_8_8_DTR].opcode =
  606. SPINOR_OP_CYPRESS_RD_FAST;
  607. /* This flash is also missing the 4-byte Page Program opcode bit. */
  608. spi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP],
  609. SPINOR_OP_PP_4B, SNOR_PROTO_1_1_1);
  610. /*
  611. * Since xSPI Page Program opcode is backward compatible with
  612. * Legacy SPI, use Legacy SPI opcode there as well.
  613. */
  614. spi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP_8_8_8_DTR],
  615. SPINOR_OP_PP_4B, SNOR_PROTO_8_8_8_DTR);
  616. /*
  617. * The xSPI Profile 1.0 table advertises the number of additional
  618. * address bytes needed for Read Status Register command as 0 but the
  619. * actual value for that is 4.
  620. */
  621. params->rdsr_addr_nbytes = 4;
  622. return cypress_nor_get_page_size(nor);
  623. }
  624. static int s28hx_t_post_bfpt_fixup(struct spi_nor *nor,
  625. const struct sfdp_parameter_header *bfpt_header,
  626. const struct sfdp_bfpt *bfpt)
  627. {
  628. /* Assign 4-byte address mode method that is not determined in BFPT */
  629. nor->params->set_4byte_addr_mode = cypress_nor_set_4byte_addr_mode;
  630. return cypress_nor_set_addr_mode_nbytes(nor);
  631. }
  632. static int s28hx_t_late_init(struct spi_nor *nor)
  633. {
  634. struct spi_nor_flash_parameter *params = nor->params;
  635. params->set_octal_dtr = cypress_nor_set_octal_dtr;
  636. params->ready = cypress_nor_sr_ready_and_clear;
  637. cypress_nor_ecc_init(nor);
  638. return 0;
  639. }
  640. static const struct spi_nor_fixups s28hx_t_fixups = {
  641. .post_sfdp = s28hx_t_post_sfdp_fixup,
  642. .post_bfpt = s28hx_t_post_bfpt_fixup,
  643. .late_init = s28hx_t_late_init,
  644. };
  645. static int
  646. s25fs_s_nor_post_bfpt_fixups(struct spi_nor *nor,
  647. const struct sfdp_parameter_header *bfpt_header,
  648. const struct sfdp_bfpt *bfpt)
  649. {
  650. /*
  651. * The S25FS-S chip family reports 512-byte pages in BFPT but
  652. * in reality the write buffer still wraps at the safe default
  653. * of 256 bytes. Overwrite the page size advertised by BFPT
  654. * to get the writes working.
  655. */
  656. nor->params->page_size = 256;
  657. return 0;
  658. }
  659. static void s25fs_s_nor_smpt_read_dummy(const struct spi_nor *nor,
  660. u8 *read_dummy)
  661. {
  662. /*
  663. * The configuration detection dwords in S25FS-S SMPT has 65h as
  664. * command instruction and 'variable' as configuration detection command
  665. * latency. Set 8 dummy cycles as it is factory default for 65h (read
  666. * any register) op.
  667. */
  668. *read_dummy = 8;
  669. }
  670. static void s25fs_s_nor_smpt_map_id_dummy(const struct spi_nor *nor, u8 *map_id)
  671. {
  672. /*
  673. * The S25FS512S chip supports:
  674. * - Hybrid sector option which has physical set of eight 4-KB sectors
  675. * and one 224-KB sector at the top or bottom of address space with
  676. * all remaining sectors of 256-KB
  677. * - Uniform sector option which has uniform 256-KB sectors
  678. *
  679. * On the other hand, the datasheet rev.O Table 71 on page 153 JEDEC
  680. * Sector Map Parameter Dword-6 Config. Detect-3 does use CR3NV[1] to
  681. * discern 64-KB(CR3NV[1]=0) and 256-KB(CR3NV[1]=1) uniform sectors
  682. * device configuration. And in section 7.5.5.1 Configuration Register 3
  683. * Non-volatile (CR3NV) page 61, the CR3NV[1] is RFU Reserved for Future
  684. * Use and set to 0, which means 64-KB uniform. Since the device does
  685. * not support 64-KB uniform sectors in any configuration, parsing SMPT
  686. * table cannot find a valid sector map entry and fails. Fix this up by
  687. * setting SMPT by overwriting the CR3NV[1] value to 1, as the table
  688. * expects.
  689. */
  690. if (nor->params->size == SZ_64M)
  691. *map_id |= BIT(0);
  692. }
  693. static const struct spi_nor_fixups s25fs_s_nor_fixups = {
  694. .post_bfpt = s25fs_s_nor_post_bfpt_fixups,
  695. .smpt_read_dummy = s25fs_s_nor_smpt_read_dummy,
  696. .smpt_map_id = s25fs_s_nor_smpt_map_id_dummy,
  697. };
  698. static const struct flash_info spansion_nor_parts[] = {
  699. {
  700. .id = SNOR_ID(0x01, 0x02, 0x12),
  701. .name = "s25sl004a",
  702. .size = SZ_512K,
  703. }, {
  704. .id = SNOR_ID(0x01, 0x02, 0x13),
  705. .name = "s25sl008a",
  706. .size = SZ_1M,
  707. }, {
  708. .id = SNOR_ID(0x01, 0x02, 0x14),
  709. .name = "s25sl016a",
  710. .size = SZ_2M,
  711. }, {
  712. .id = SNOR_ID(0x01, 0x02, 0x15, 0x4d, 0x00),
  713. .name = "s25sl032p",
  714. .size = SZ_4M,
  715. .no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  716. }, {
  717. .id = SNOR_ID(0x01, 0x02, 0x15),
  718. .name = "s25sl032a",
  719. .size = SZ_4M,
  720. }, {
  721. .id = SNOR_ID(0x01, 0x02, 0x16, 0x4d, 0x00),
  722. .name = "s25sl064p",
  723. .size = SZ_8M,
  724. .no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  725. }, {
  726. .id = SNOR_ID(0x01, 0x02, 0x16),
  727. .name = "s25sl064a",
  728. .size = SZ_8M,
  729. }, {
  730. .id = SNOR_ID(0x01, 0x02, 0x19, 0x4d, 0x00, 0x80),
  731. .name = "s25fl256s0",
  732. .size = SZ_32M,
  733. .sector_size = SZ_256K,
  734. .no_sfdp_flags = SPI_NOR_SKIP_SFDP | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  735. .mfr_flags = USE_CLSR,
  736. }, {
  737. .id = SNOR_ID(0x01, 0x02, 0x19, 0x4d, 0x00, 0x81),
  738. .name = "s25fs256s0",
  739. .size = SZ_32M,
  740. .sector_size = SZ_256K,
  741. .no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  742. .mfr_flags = USE_CLSR,
  743. }, {
  744. .id = SNOR_ID(0x01, 0x02, 0x19, 0x4d, 0x01, 0x80),
  745. .name = "s25fl256s1",
  746. .size = SZ_32M,
  747. .no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  748. .mfr_flags = USE_CLSR,
  749. }, {
  750. .id = SNOR_ID(0x01, 0x02, 0x19, 0x4d, 0x01, 0x81),
  751. .name = "s25fs256s1",
  752. .size = SZ_32M,
  753. .no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  754. .mfr_flags = USE_CLSR,
  755. }, {
  756. .id = SNOR_ID(0x01, 0x02, 0x20, 0x4d, 0x00, 0x80),
  757. .name = "s25fl512s",
  758. .size = SZ_64M,
  759. .sector_size = SZ_256K,
  760. .flags = SPI_NOR_HAS_LOCK,
  761. .no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  762. .mfr_flags = USE_CLSR,
  763. }, {
  764. .id = SNOR_ID(0x01, 0x02, 0x20, 0x4d, 0x00, 0x81),
  765. .name = "s25fs512s",
  766. .size = SZ_64M,
  767. .sector_size = SZ_256K,
  768. .no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  769. .mfr_flags = USE_CLSR,
  770. .fixups = &s25fs_s_nor_fixups,
  771. }, {
  772. .id = SNOR_ID(0x01, 0x20, 0x18, 0x03, 0x00),
  773. .name = "s25sl12800",
  774. .size = SZ_16M,
  775. .sector_size = SZ_256K,
  776. }, {
  777. .id = SNOR_ID(0x01, 0x20, 0x18, 0x03, 0x01),
  778. .name = "s25sl12801",
  779. .size = SZ_16M,
  780. }, {
  781. .id = SNOR_ID(0x01, 0x20, 0x18, 0x4d, 0x00, 0x80),
  782. .name = "s25fl128s0",
  783. .size = SZ_16M,
  784. .sector_size = SZ_256K,
  785. .no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  786. .mfr_flags = USE_CLSR,
  787. }, {
  788. .id = SNOR_ID(0x01, 0x20, 0x18, 0x4d, 0x00),
  789. .name = "s25fl129p0",
  790. .size = SZ_16M,
  791. .sector_size = SZ_256K,
  792. .no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  793. .mfr_flags = USE_CLSR,
  794. }, {
  795. .id = SNOR_ID(0x01, 0x20, 0x18, 0x4d, 0x01, 0x80),
  796. .name = "s25fl128s1",
  797. .size = SZ_16M,
  798. .no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  799. .mfr_flags = USE_CLSR,
  800. }, {
  801. .id = SNOR_ID(0x01, 0x20, 0x18, 0x4d, 0x01, 0x81),
  802. .name = "s25fs128s1",
  803. .size = SZ_16M,
  804. .no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  805. .mfr_flags = USE_CLSR,
  806. .fixups = &s25fs_s_nor_fixups,
  807. }, {
  808. .id = SNOR_ID(0x01, 0x20, 0x18, 0x4d, 0x01),
  809. .name = "s25fl129p1",
  810. .size = SZ_16M,
  811. .no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  812. .mfr_flags = USE_CLSR,
  813. }, {
  814. .id = SNOR_ID(0x01, 0x40, 0x13),
  815. .name = "s25fl204k",
  816. .size = SZ_512K,
  817. .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ,
  818. }, {
  819. .id = SNOR_ID(0x01, 0x40, 0x14),
  820. .name = "s25fl208k",
  821. .size = SZ_1M,
  822. .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ,
  823. }, {
  824. .id = SNOR_ID(0x01, 0x40, 0x15),
  825. .name = "s25fl116k",
  826. .size = SZ_2M,
  827. .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  828. }, {
  829. .id = SNOR_ID(0x01, 0x40, 0x16),
  830. .name = "s25fl132k",
  831. .size = SZ_4M,
  832. .no_sfdp_flags = SECT_4K,
  833. }, {
  834. .id = SNOR_ID(0x01, 0x40, 0x17),
  835. .name = "s25fl164k",
  836. .size = SZ_8M,
  837. .no_sfdp_flags = SECT_4K,
  838. }, {
  839. .id = SNOR_ID(0x01, 0x60, 0x17),
  840. .name = "s25fl064l",
  841. .size = SZ_8M,
  842. .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  843. .fixup_flags = SPI_NOR_4B_OPCODES,
  844. }, {
  845. .id = SNOR_ID(0x01, 0x60, 0x18),
  846. .name = "s25fl128l",
  847. .size = SZ_16M,
  848. .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  849. .fixup_flags = SPI_NOR_4B_OPCODES,
  850. }, {
  851. .id = SNOR_ID(0x01, 0x60, 0x19),
  852. .name = "s25fl256l",
  853. .size = SZ_32M,
  854. .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  855. .fixup_flags = SPI_NOR_4B_OPCODES,
  856. }, {
  857. .id = SNOR_ID(0x04, 0x2c, 0xc2, 0x7f, 0x7f, 0x7f),
  858. .name = "cy15x104q",
  859. .size = SZ_512K,
  860. .sector_size = SZ_512K,
  861. .flags = SPI_NOR_NO_ERASE,
  862. }, {
  863. .id = SNOR_ID(0x34, 0x2a, 0x1a, 0x0f, 0x03, 0x90),
  864. .name = "s25hl512t",
  865. .mfr_flags = USE_CLPEF,
  866. .fixups = &s25hx_t_fixups
  867. }, {
  868. .id = SNOR_ID(0x34, 0x2a, 0x1b, 0x0f, 0x03, 0x90),
  869. .name = "s25hl01gt",
  870. .mfr_flags = USE_CLPEF,
  871. .fixups = &s25hx_t_fixups
  872. }, {
  873. .id = SNOR_ID(0x34, 0x2a, 0x1c, 0x0f, 0x00, 0x90),
  874. .name = "s25hl02gt",
  875. .mfr_flags = USE_CLPEF,
  876. .fixups = &s25hx_t_fixups
  877. }, {
  878. .id = SNOR_ID(0x34, 0x2b, 0x19, 0x0f, 0x08, 0x90),
  879. .name = "s25fs256t",
  880. .mfr_flags = USE_CLPEF,
  881. .fixups = &s25fs256t_fixups
  882. }, {
  883. .id = SNOR_ID(0x34, 0x2b, 0x1a, 0x0f, 0x03, 0x90),
  884. .name = "s25hs512t",
  885. .mfr_flags = USE_CLPEF,
  886. .fixups = &s25hx_t_fixups
  887. }, {
  888. .id = SNOR_ID(0x34, 0x2b, 0x1b, 0x0f, 0x03, 0x90),
  889. .name = "s25hs01gt",
  890. .mfr_flags = USE_CLPEF,
  891. .fixups = &s25hx_t_fixups
  892. }, {
  893. .id = SNOR_ID(0x34, 0x2b, 0x1c, 0x0f, 0x00, 0x90),
  894. .name = "s25hs02gt",
  895. .mfr_flags = USE_CLPEF,
  896. .fixups = &s25hx_t_fixups
  897. }, {
  898. /* S28HL256T */
  899. .id = SNOR_ID(0x34, 0x5a, 0x19),
  900. .mfr_flags = USE_CLPEF,
  901. .fixups = &s28hx_t_fixups,
  902. }, {
  903. .id = SNOR_ID(0x34, 0x5a, 0x1a),
  904. .name = "s28hl512t",
  905. .mfr_flags = USE_CLPEF,
  906. .fixups = &s28hx_t_fixups,
  907. }, {
  908. .id = SNOR_ID(0x34, 0x5a, 0x1b),
  909. .name = "s28hl01gt",
  910. .mfr_flags = USE_CLPEF,
  911. .fixups = &s28hx_t_fixups,
  912. }, {
  913. /* S28HL02GT */
  914. .id = SNOR_ID(0x34, 0x5a, 0x1c),
  915. .mfr_flags = USE_CLPEF,
  916. .fixups = &s28hx_t_fixups,
  917. }, {
  918. .id = SNOR_ID(0x34, 0x5b, 0x19),
  919. .mfr_flags = USE_CLPEF,
  920. .fixups = &s28hx_t_fixups,
  921. }, {
  922. .id = SNOR_ID(0x34, 0x5b, 0x1a),
  923. .name = "s28hs512t",
  924. .mfr_flags = USE_CLPEF,
  925. .fixups = &s28hx_t_fixups,
  926. }, {
  927. .id = SNOR_ID(0x34, 0x5b, 0x1b),
  928. .name = "s28hs01gt",
  929. .mfr_flags = USE_CLPEF,
  930. .fixups = &s28hx_t_fixups,
  931. }, {
  932. .id = SNOR_ID(0x34, 0x5b, 0x1c),
  933. .name = "s28hs02gt",
  934. .mfr_flags = USE_CLPEF,
  935. .fixups = &s28hx_t_fixups,
  936. }, {
  937. .id = SNOR_ID(0xef, 0x40, 0x13),
  938. .name = "s25fl004k",
  939. .size = SZ_512K,
  940. .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  941. }, {
  942. .id = SNOR_ID(0xef, 0x40, 0x14),
  943. .name = "s25fl008k",
  944. .size = SZ_1M,
  945. .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  946. }, {
  947. .id = SNOR_ID(0xef, 0x40, 0x15),
  948. .name = "s25fl016k",
  949. .size = SZ_2M,
  950. .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  951. }, {
  952. .id = SNOR_ID(0xef, 0x40, 0x17),
  953. .name = "s25fl064k",
  954. .size = SZ_8M,
  955. .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  956. }
  957. };
  958. /**
  959. * spansion_nor_sr_ready_and_clear() - Query the Status Register to see if the
  960. * flash is ready for new commands and clear it if there are any errors.
  961. * @nor: pointer to 'struct spi_nor'.
  962. *
  963. * Return: 1 if ready, 0 if not ready, -errno on errors.
  964. */
  965. static int spansion_nor_sr_ready_and_clear(struct spi_nor *nor)
  966. {
  967. int ret;
  968. ret = spi_nor_read_sr(nor, nor->bouncebuf);
  969. if (ret)
  970. return ret;
  971. if (nor->bouncebuf[0] & (SR_E_ERR | SR_P_ERR)) {
  972. if (nor->bouncebuf[0] & SR_E_ERR)
  973. dev_err(nor->dev, "Erase Error occurred\n");
  974. else
  975. dev_err(nor->dev, "Programming Error occurred\n");
  976. spansion_nor_clear_sr(nor);
  977. /*
  978. * WEL bit remains set to one when an erase or page program
  979. * error occurs. Issue a Write Disable command to protect
  980. * against inadvertent writes that can possibly corrupt the
  981. * contents of the memory.
  982. */
  983. ret = spi_nor_write_disable(nor);
  984. if (ret)
  985. return ret;
  986. return -EIO;
  987. }
  988. return !(nor->bouncebuf[0] & SR_WIP);
  989. }
  990. static int spansion_nor_late_init(struct spi_nor *nor)
  991. {
  992. struct spi_nor_flash_parameter *params = nor->params;
  993. struct spansion_nor_params *priv_params;
  994. u8 mfr_flags = nor->info->mfr_flags;
  995. if (params->size > SZ_16M) {
  996. nor->flags |= SNOR_F_4B_OPCODES;
  997. /* No small sector erase for 4-byte command set */
  998. nor->erase_opcode = SPINOR_OP_SE;
  999. nor->mtd.erasesize = nor->info->sector_size ?:
  1000. SPI_NOR_DEFAULT_SECTOR_SIZE;
  1001. }
  1002. if (mfr_flags & (USE_CLSR | USE_CLPEF)) {
  1003. priv_params = devm_kmalloc(nor->dev, sizeof(*priv_params),
  1004. GFP_KERNEL);
  1005. if (!priv_params)
  1006. return -ENOMEM;
  1007. if (mfr_flags & USE_CLSR)
  1008. priv_params->clsr = SPINOR_OP_CLSR;
  1009. else if (mfr_flags & USE_CLPEF)
  1010. priv_params->clsr = SPINOR_OP_CLPEF;
  1011. params->priv = priv_params;
  1012. params->ready = spansion_nor_sr_ready_and_clear;
  1013. }
  1014. return 0;
  1015. }
  1016. static const struct spi_nor_fixups spansion_nor_fixups = {
  1017. .late_init = spansion_nor_late_init,
  1018. };
  1019. const struct spi_nor_manufacturer spi_nor_spansion = {
  1020. .name = "spansion",
  1021. .parts = spansion_nor_parts,
  1022. .nparts = ARRAY_SIZE(spansion_nor_parts),
  1023. .fixups = &spansion_nor_fixups,
  1024. };