Linux Audio

Check our new training course

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