GNU Linux-libre 6.8.7-gnu
[releases.git] / drivers / mtd / spi-nor / micron-st.c
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
51 static 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
88 static 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
124 static 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
130 static void mt35xu512aba_default_init(struct spi_nor *nor)
131 {
132         nor->params->set_octal_dtr = micron_st_nor_set_octal_dtr;
133 }
134
135 static 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
157 static const struct spi_nor_fixups mt35xu512aba_fixups = {
158         .default_init = mt35xu512aba_default_init,
159         .post_sfdp = mt35xu512aba_post_sfdp_fixup,
160 };
161
162 static 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
184 static 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
192 static struct spi_nor_fixups mt25qu512a_fixups = {
193         .post_bfpt = mt25qu512a_post_bfpt_fixup,
194 };
195
196 static 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
212 static 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
228 static struct spi_nor_fixups n25q00_fixups = {
229         .late_init = st_nor_four_die_late_init,
230 };
231
232 static struct spi_nor_fixups mt25q01_fixups = {
233         .late_init = st_nor_two_die_late_init,
234 };
235
236 static struct spi_nor_fixups mt25q02_fixups = {
237         .late_init = st_nor_four_die_late_init,
238 };
239
240 static 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  */
509 static 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  */
544 static 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  */
571 static 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
619 static 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
626 static 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
639 static 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
644 const 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
651 const 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 };