Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  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};