1 /*
2 * Copyright (c) 2020 Peter Bigot Consulting, LLC
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #ifndef ZEPHYR_DRIVERS_FLASH_JESD216_H_
8 #define ZEPHYR_DRIVERS_FLASH_JESD216_H_
9
10 #include <errno.h>
11 #include <zephyr/sys/byteorder.h>
12 #include <zephyr/sys/util.h>
13 #include <zephyr/types.h>
14
15 /* JEDEC Read identification */
16 #define JESD216_CMD_READ_ID SPI_NOR_CMD_RDID
17 #define JESD216_OCMD_READ_ID 0x9F60
18 #define JESD216_READ_ID_LEN 3
19
20 /* Following are structures and constants supporting the JEDEC Serial
21 * Flash Discoverable Parameters standard, JESD216 and its successors,
22 * available at
23 * https://www.jedec.org/standards-documents/docs/jesd216b
24 */
25
26 #define JESD216_CMD_READ_SFDP 0x5A
27 #define JESD216_CMD_BURST_SFDP 0x5B
28 #define JESD216_OCMD_READ_SFDP 0x5AA5
29
30 /* Layout of a JESD216 parameter header. */
31 struct jesd216_param_header {
32 uint8_t id_lsb; /* ID LSB */
33 uint8_t rev_minor; /* Minor revision number */
34 uint8_t rev_major; /* Major revision number */
35 uint8_t len_dw; /* Length of table in 32-bit DWORDs */
36 uint8_t ptp[3]; /* Address of table in SFDP space (LSB@0) */
37 uint8_t id_msb; /* ID MSB */
38 } __packed;
39
40 /* Get the number of bytes required for the parameter table. */
jesd216_param_len(const struct jesd216_param_header * hp)41 static inline uint32_t jesd216_param_len(const struct jesd216_param_header *hp)
42 {
43 return sizeof(uint32_t) * hp->len_dw;
44 }
45
46 /* Get the ID that identifies the content of the parameter table. */
jesd216_param_id(const struct jesd216_param_header * hp)47 static inline uint16_t jesd216_param_id(const struct jesd216_param_header *hp)
48 {
49 return ((uint16_t)hp->id_msb << 8) | hp->id_lsb;
50 }
51
52 /* Get the address within the SFDP where the data for the table is
53 * stored.
54 */
jesd216_param_addr(const struct jesd216_param_header * hp)55 static inline uint32_t jesd216_param_addr(const struct jesd216_param_header *hp)
56 {
57 return ((hp->ptp[2] << 16)
58 | (hp->ptp[1] << 8)
59 | (hp->ptp[0] << 0));
60 }
61
62 /* Layout of the Serial Flash Discoverable Parameters header. */
63 struct jesd216_sfdp_header {
64 uint32_t magic; /* "SFDP" in little endian */
65 uint8_t rev_minor; /* Minor revision number */
66 uint8_t rev_major; /* Major revision number */
67 uint8_t nph; /* Number of parameter headers */
68 uint8_t access; /* Access protocol */
69 struct jesd216_param_header phdr[]; /* Headers */
70 } __packed;
71
72 /* SFDP access protocol for backwards compatibility with JESD216B. */
73 #define JESD216_SFDP_AP_LEGACY 0xFF
74
75 /* The expected value from the jesd216_sfdp::magic field in host byte
76 * order.
77 */
78 #define JESD216_SFDP_MAGIC 0x50444653
79
80 /* All JESD216 data is read from the device in little-endian byte
81 * order. For JEDEC parameter tables defined through JESD216D-01 the
82 * parameters are defined by 32-bit words that may need to be
83 * byte-swapped to extract their information.
84 *
85 * A 16-bit ID from the parameter header is used to identify the
86 * content of each table. The first parameter table in the SFDP
87 * hierarchy must be a Basic Flash Parameter table (ID 0xFF00).
88 */
89
90 /* JESD216D-01 section 6.4: Basic Flash Parameter */
91 #define JESD216_SFDP_PARAM_ID_BFP 0xFF00
92 /* JESD216D-01 section 6.5: Sector Map Parameter */
93 #define JESD216_SFDP_PARAM_ID_SECTOR_MAP 0xFF81
94 /* JESD216D-01 section 6.6: 4-Byte Address Instruction Parameter */
95 #define JESD216_SFDP_PARAM_ID_4B_ADDR_INSTR 0xFF84
96 /* JESD216D-01 section 6.7: xSPI (Profile 1.0) Parameter */
97 #define JESD216_SFDP_PARAM_ID_XSPI_PROFILE_1V0 0xFF05
98 /* JESD216D-01 section 6.8: xSPI (Profile 2.0) Parameter */
99 #define JESD216_SFDP_PARAM_ID_XSPI_PROFILE_2V0 0xFF06
100
101 /* Macro to define the number of bytes required for the SFDP pheader
102 * and @p nph parameter headers.
103 *
104 * @param nph the number of parameter headers to be read. 1 is
105 * sufficient for basic functionality.
106 *
107 * @return required buffer size in bytes.
108 */
109 #define JESD216_SFDP_SIZE(nph) (sizeof(struct jesd216_sfdp_header) \
110 + ((nph) * sizeof(struct jesd216_param_header)))
111
112 /** Extract the magic number from the SFDP structure in host byte order.
113 *
114 * If this compares equal to JESD216_SFDP_MAGIC then the SFDP header
115 * may have been read correctly.
116 */
jesd216_sfdp_magic(const struct jesd216_sfdp_header * hp)117 static inline uint32_t jesd216_sfdp_magic(const struct jesd216_sfdp_header *hp)
118 {
119 return sys_le32_to_cpu(hp->magic);
120 }
121
122 /* Layout of the Basic Flash Parameters table.
123 *
124 * SFDP through JESD216B supported 9 DWORD values. JESD216C extended
125 * this to 17, and JESD216D to 20.
126 *
127 * All values are expected to be stored as little-endian and must be
128 * converted to host byte order to extract the bit fields defined in
129 * the standard. Rather than pre-define layouts to access to all
130 * potential fields this header provides functions for specific fields
131 * known to be important, such as density and erase command support.
132 *
133 * Must be aligned to a DWORD (32-bit) address according to JESD216F.
134 */
135 struct jesd216_bfp {
136 uint32_t dw1;
137 uint32_t dw2;
138 uint32_t dw3;
139 uint32_t dw4;
140 uint32_t dw5;
141 uint32_t dw6;
142 uint32_t dw7;
143 uint32_t dw8;
144 uint32_t dw9;
145 uint32_t dw10[];
146 } __aligned(4);
147
148 /* Provide a few word-specific flags and bitfield ranges for values
149 * that an application or driver might expect to want to extract.
150 *
151 * See the JESD216 specification for the interpretation of these
152 * bitfields.
153 */
154 #define JESD216_SFDP_BFP_DW1_DTRCLK_FLG BIT(19)
155 #define JESD216_SFDP_BFP_DW1_ADDRBYTES_MASK (BIT(17) | BIT(18))
156 #define JESD216_SFDP_BFP_DW1_ADDRBYTES_SHFT 17
157 #define JESD216_SFDP_BFP_DW1_ADDRBYTES_VAL_3B 0
158 #define JESD216_SFDP_BFP_DW1_ADDRBYTES_VAL_3B4B 1
159 #define JESD216_SFDP_BFP_DW1_ADDRBYTES_VAL_4B 2
160 #define JESD216_SFDP_BFP_DW1_4KERASEINSTR_SHFT 8
161 #define JESD216_SFDP_BFP_DW1_4KERASEINSTR_MASK (0xFF << JESD216_SFDP_BFP_DW1_4KERASEINSTR_SHFT)
162 #define JESD216_SFDP_BFP_DW1_WEISWVSR_FLG BIT(4)
163 #define JESD216_SFDP_BFP_DW1_VSRBP_FLG BIT(3)
164 #define JESD216_SFDP_BFP_DW1_WRTGRAN_FLG BIT(2)
165 #define JESD216_SFDP_BFP_DW1_BSERSZ_SHFT 0
166 #define JESD216_SFDP_BFP_DW1_BSERSZ_MASK (0x03 << JESD216_SFDP_BFP_DW1_BSERSZ_SHFT)
167 #define JESD216_SFDP_BFP_DW1_BSERSZ_VAL_4KSUP 0x01
168 #define JESD216_SFDP_BFP_DW1_BSERSZ_VAL_4KNOTSUP 0x03
169
170 #define JESD216_SFDP_BFP_DW12_SUSPRESSUP_FLG BIT(31)
171
172 /* Data can be extracted from the BFP words using these APIs:
173 *
174 * * DW1 (capabilities) use DW1 bitfield macros above or
175 * jesd216_read_support().
176 * * DW2 (density) use jesd216_bfp_density().
177 * * DW3-DW7 (instr) use jesd216_bfp_read_support().
178 * * DW8-DW9 (erase types) use jesd216_bfp_erase().
179 *
180 * JESD216A (16 DW)
181 *
182 * * DW10 (erase times) use jesd216_bfp_erase_type_times().
183 * * DW11 (other times) use jesd216_bfp_decode_dw11().
184 * * DW12-13 (suspend/resume) no API except
185 * JESD216_SFDP_BFP_DW12_SUSPRESSUP_FLG.
186 * * DW14 (deep power down) use jesd216_bfp_decode_dw14().
187 * * DW15-16 no API except jesd216_bfp_read_support().
188 *
189 * JESD216C (20 DW)
190 * * DW17-20 (quad/oct support) no API except jesd216_bfp_read_support().
191 */
192
193 /* Extract the supported address bytes from BFP DW1. */
jesd216_bfp_addrbytes(const struct jesd216_bfp * hp)194 static inline uint8_t jesd216_bfp_addrbytes(const struct jesd216_bfp *hp)
195 {
196 uint32_t dw1 = sys_le32_to_cpu(hp->dw1);
197 uint8_t addr_support = (dw1 & JESD216_SFDP_BFP_DW1_ADDRBYTES_MASK)
198 >> JESD216_SFDP_BFP_DW1_ADDRBYTES_SHFT;
199
200 return addr_support;
201 }
202
203 /* Extract the density of the chip in bits from BFP DW2. */
jesd216_bfp_density(const struct jesd216_bfp * hp)204 static inline uint64_t jesd216_bfp_density(const struct jesd216_bfp *hp)
205 {
206 uint32_t dw = sys_le32_to_cpu(hp->dw2);
207
208 if (dw & BIT(31)) {
209 return BIT64(dw & BIT_MASK(31));
210 }
211 return 1U + (uint64_t)dw;
212 }
213
214 /* Protocol mode enumeration types.
215 *
216 * Modes are identified by fields representing the number of I/O
217 * signals and the data rate in the transfer. The I/O width may be 1,
218 * 2, 4, or 8 I/O signals. The data rate may be single or double.
219 * SDR is assumed; DDR is indicated by a D following the I/O width.
220 *
221 * A transfer has three phases, and width/rate is specified for each
222 * in turn:
223 * * Transfer of the command
224 * * Transfer of the command modifier (e.g. address)
225 * * Transfer of the data.
226 *
227 * Modes explicitly mentioned in JESD216 or JESD251 are given
228 * enumeration values below, which can be used to extract information
229 * about instruction support.
230 */
231 enum jesd216_mode_type {
232 JESD216_MODE_044, /* implied instruction, execute in place */
233 JESD216_MODE_088,
234 JESD216_MODE_111,
235 JESD216_MODE_112,
236 JESD216_MODE_114,
237 JESD216_MODE_118,
238 JESD216_MODE_122,
239 JESD216_MODE_144,
240 JESD216_MODE_188,
241 JESD216_MODE_222,
242 JESD216_MODE_444,
243 JESD216_MODE_44D4D,
244 JESD216_MODE_888,
245 JESD216_MODE_8D8D8D,
246 JESD216_MODE_LIMIT,
247 };
248
249 /* Command to use for fast read operations in a specified protocol
250 * mode.
251 */
252 struct jesd216_instr {
253 uint8_t instr;
254 uint8_t mode_clocks;
255 uint8_t wait_states;
256 };
257
258 /* Determine whether a particular operational mode is supported for
259 * read, and possibly what command may be used.
260 *
261 * @note For @p mode JESD216_MODE_111 this function will return zero
262 * to indicate that standard read (instruction 03h) is supported, but
263 * without providing information on how. SFDP does not provide an
264 * indication of support for 1-1-1 Fast Read (0Bh).
265 *
266 * @param php pointer to the BFP header.
267 *
268 * @param bfp pointer to the BFP table.
269 *
270 * @param mode the desired protocol mode.
271 *
272 * @param res where to store instruction information. Pass a null
273 * pointer to test for support without retrieving instruction
274 * information.
275 *
276 * @retval positive if instruction is supported and *res has been set.
277 *
278 * @retval 0 if instruction is supported but *res has not been set
279 * (e.g. no instruction needed, or instruction cannot be read from
280 * BFP).
281 *
282 * @retval -ENOTSUP if instruction is not supported.
283 */
284 int jesd216_bfp_read_support(const struct jesd216_param_header *php,
285 const struct jesd216_bfp *bfp,
286 enum jesd216_mode_type mode,
287 struct jesd216_instr *res);
288
289 /* Description of a supported erase operation. */
290 struct jesd216_erase_type {
291 /* The command opcode used for an erase operation. */
292 uint8_t cmd;
293
294 /* The value N when the erase operation erases a 2^N byte
295 * region.
296 */
297 uint8_t exp;
298 };
299
300 /* The number of erase types defined in a JESD216 Basic Flash
301 * Parameter table.
302 */
303 #define JESD216_NUM_ERASE_TYPES 4
304
305 /* Extract a supported erase size and command from BFP DW8 or DW9.
306 *
307 * @param bfp pointer to the parameter table.
308 *
309 * @param idx the erase type index, from 1 through 4. Only index 1 is
310 * guaranteed to be present.
311 *
312 * @param etp where to store the command and size used for the erase.
313 *
314 * @retval 0 if the erase type index provided usable information.
315 * @retval -EINVAL if the erase type index is undefined.
316 */
317 int jesd216_bfp_erase(const struct jesd216_bfp *bfp,
318 uint8_t idx,
319 struct jesd216_erase_type *etp);
320
321 /* Extract typical and maximum erase times from DW10.
322 *
323 * @param php pointer to the BFP header.
324 *
325 * @param bfp pointer to the BFP table.
326 *
327 * @param idx the erase type index, from 1 through 4. For meaningful
328 * results the index should be one for which jesd216_bfp_erase()
329 * returns success.
330 *
331 * @param typ_ms where to store the typical erase time (in
332 * milliseconds) for the specified erase type.
333 *
334 * @retval -ENOTSUP if the erase type index is undefined.
335 * @retval positive is a multiplier that converts typical erase times
336 * to maximum erase times.
337 */
338 int jesd216_bfp_erase_type_times(const struct jesd216_param_header *php,
339 const struct jesd216_bfp *bfp,
340 uint8_t idx,
341 uint32_t *typ_ms);
342
343 /* Get the page size from the Basic Flash Parameters.
344 *
345 * @param php pointer to the BFP header.
346 *
347 * @param bfp pointer to the BFP table.
348 *
349 * @return the page size in bytes from the parameters if supported,
350 * otherwise 256.
351 */
jesd216_bfp_page_size(const struct jesd216_param_header * php,const struct jesd216_bfp * bfp)352 static inline uint32_t jesd216_bfp_page_size(const struct jesd216_param_header *php,
353 const struct jesd216_bfp *bfp)
354 {
355 /* Page size introduced in JESD216A */
356 if (php->len_dw < 11) {
357 return 256;
358 }
359
360 uint32_t dw11 = sys_le32_to_cpu(bfp->dw10[1]);
361 uint8_t exp = (dw11 >> 4) & 0x0F;
362
363 return BIT(exp);
364 }
365
366 /* Decoded data from JESD216 DW11. */
367 struct jesd216_bfp_dw11 {
368 /* Typical time for chip (die) erase, in milliseconds */
369 uint16_t chip_erase_ms;
370
371 /* Typical time for first byte program, in microseconds */
372 uint16_t byte_prog_first_us;
373
374 /* Typical time per byte for byte program after first, in
375 * microseconds
376 */
377 uint16_t byte_prog_addl_us;
378
379 /* Typical time for page program, in microseconds */
380 uint16_t page_prog_us;
381
382 /* Multiplier to get maximum time from typical times. */
383 uint16_t typ_max_factor;
384
385 /* Number of bytes in a page. */
386 uint16_t page_size;
387 };
388
389 /* Get data from BFP DW11.
390 *
391 * @param php pointer to the BFP header.
392 *
393 * @param bfp pointer to the BFP table.
394 *
395 * @param res pointer to where to store the decoded data.
396 *
397 * @retval -ENOTSUP if this information is not available from this BFP table.
398 * @retval 0 on successful storage into @c *res.
399 */
400 int jesd216_bfp_decode_dw11(const struct jesd216_param_header *php,
401 const struct jesd216_bfp *bfp,
402 struct jesd216_bfp_dw11 *res);
403
404 /* Decoded data from JESD216 DW14 */
405 struct jesd216_bfp_dw14 {
406 /* Instruction used to enter deep power-down */
407 uint8_t enter_dpd_instr;
408
409 /* Instruction used to exit deep power-down */
410 uint8_t exit_dpd_instr;
411
412 /* Bits defining ways busy status may be polled. */
413 uint8_t poll_options;
414
415 /* Time after issuing exit instruction until device is ready
416 * to accept a command, in nanoseconds.
417 */
418 uint32_t exit_delay_ns;
419 };
420
421 /* Get data from BFP DW14.
422 *
423 * @param php pointer to the BFP header.
424 *
425 * @param bfp pointer to the BFP table.
426 *
427 * @param res pointer to where to store the decoded data.
428 *
429 * @retval -ENOTSUP if this information is not available from this BFP table.
430 * @retval 0 on successful storage into @c *res.
431 */
432 int jesd216_bfp_decode_dw14(const struct jesd216_param_header *php,
433 const struct jesd216_bfp *bfp,
434 struct jesd216_bfp_dw14 *res);
435
436 /* DW15 Quad Enable Requirements specifies status register QE bits.
437 *
438 * Two common configurations are summarized; see the specification for
439 * full details of how to use these values.
440 */
441 enum jesd216_dw15_qer_type {
442 /* No QE status required for 1-1-4 or 1-4-4 mode */
443 JESD216_DW15_QER_NONE = 0,
444 JESD216_DW15_QER_S2B1v1 = 1,
445 /* Bit 6 of SR byte must be set to enable 1-1-4 or 1-4-4 mode.
446 * SR is one byte.
447 */
448 JESD216_DW15_QER_S1B6 = 2,
449 JESD216_DW15_QER_S2B7 = 3,
450 JESD216_DW15_QER_S2B1v4 = 4,
451 JESD216_DW15_QER_S2B1v5 = 5,
452 JESD216_DW15_QER_S2B1v6 = 6,
453 };
454
455 #define JESD216_DW15_QER_VAL_NONE 0
456 #define JESD216_DW15_QER_VAL_S2B1v1 1
457 #define JESD216_DW15_QER_VAL_S1B6 2
458 #define JESD216_DW15_QER_VAL_S2B7 3
459 #define JESD216_DW15_QER_VAL_S2B1v4 4
460 #define JESD216_DW15_QER_VAL_S2B1v5 5
461 #define JESD216_DW15_QER_VAL_S2B1v6 6
462
463 /* Decoded data from JESD216 DW15 */
464 struct jesd216_bfp_dw15 {
465 /* If true clear NVECR bit 4 to disable HOLD/RESET */
466 bool hold_reset_disable: 1;
467 /* Encoded jesd216_dw15_qer_type */
468 unsigned int qer: 3;
469 /* 0-4-4 mode entry method */
470 unsigned int entry_044: 4;
471 /* 0-4-4 mode exit method */
472 unsigned int exit_044: 6;
473 /* True if 0-4-4 mode is supported */
474 bool support_044: 1;
475 /* 4-4-4 mode enable sequences */
476 unsigned int enable_444: 5;
477 /* 4-4-4 mode disable sequences */
478 unsigned int disable_444: 4;
479 };
480
481 /* Get data from BFP DW15.
482 *
483 * @param php pointer to the BFP header.
484 *
485 * @param bfp pointer to the BFP table.
486 *
487 * @param res pointer to where to store the decoded data.
488 *
489 * @retval -ENOTSUP if this information is not available from this BFP table.
490 * @retval 0 on successful storage into @c *res.
491 */
492 int jesd216_bfp_decode_dw15(const struct jesd216_param_header *php,
493 const struct jesd216_bfp *bfp,
494 struct jesd216_bfp_dw15 *res);
495
496 /* Decoded data from JESD216_DW16 */
497 struct jesd216_bfp_dw16 {
498 /* Bits specifying supported modes of entering 4-byte
499 * addressing.
500 */
501 unsigned int enter_4ba: 8;
502
503 /* Bits specifying supported modes of exiting 4-byte
504 * addressing.
505 */
506 unsigned int exit_4ba: 10;
507
508 /* Bits specifying the soft reset and rescue sequence to
509 * restore the device to its power-on state.
510 */
511 unsigned int srrs_support: 6;
512
513 /* Bits specifying how to modify status register 1, and which
514 * bits are non-volatile.
515 */
516 unsigned int sr1_interface: 7;
517 };
518
519 /* Get data from BFP DW16.
520 *
521 * @param php pointer to the BFP header.
522 *
523 * @param bfp pointer to the BFP table.
524 *
525 * @param res pointer to where to store the decoded data.
526 *
527 * @retval -ENOTSUP if this information is not available from this BFP table.
528 * @retval 0 on successful storage into @c *res.
529 */
530 int jesd216_bfp_decode_dw16(const struct jesd216_param_header *php,
531 const struct jesd216_bfp *bfp,
532 struct jesd216_bfp_dw16 *res);
533
534 /* JESD216D-01 section 6.6: 4-Byte Address Instruction Parameter */
535 #define JESD216_SFDP_4B_ADDR_DW1_1S_1S_1S_READ_13_SUP BIT(0)
536 #define JESD216_SFDP_4B_ADDR_DW1_1S_1S_1S_FAST_READ_0C_SUP BIT(1)
537 #define JESD216_SFDP_4B_ADDR_DW1_1S_1S_2_FAST_READ_3C_SUP BIT(2)
538 #define JESD216_SFDP_4B_ADDR_DW1_1S_2S_2S_FAST_READ_BC_SUP BIT(3)
539 #define JESD216_SFDP_4B_ADDR_DW1_1S_1S_4S_FAST_READ_6C_SUP BIT(4)
540 #define JESD216_SFDP_4B_ADDR_DW1_1S_4S_4_FAST_READ_EC_SUP BIT(5)
541 #define JESD216_SFDP_4B_ADDR_DW1_1S_1S_1S_PP_12_SUP BIT(6)
542 #define JESD216_SFDP_4B_ADDR_DW1_1S_1S_4S_PP_34_SUP BIT(7)
543 #define JESD216_SFDP_4B_ADDR_DW1_1S_4S_4S_PP_3E_SUP BIT(8)
544
545 #endif /* ZEPHYR_DRIVERS_FLASH_JESD216_H_ */
546