Branch data Line data Source code
1 : : // SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
2 : : /* Copyright 2013-2017 IBM Corp. */
3 : :
4 : : #include <stdlib.h>
5 : : #include <stdio.h>
6 : : #include <string.h>
7 : : #include <inttypes.h>
8 : :
9 : : #include "libflash.h"
10 : : #include "libflash-priv.h"
11 : : #include "ecc.h"
12 : : #include "blocklevel.h"
13 : :
14 : : static const struct flash_info flash_info[] = {
15 : : { 0xc22018, 0x01000000, FL_ERASE_ALL | FL_CAN_4B, "Macronix MXxxL12835F"},
16 : : { 0xc22019, 0x02000000, FL_ERASE_ALL | FL_CAN_4B, "Macronix MXxxL25635F"},
17 : : { 0xc2201a, 0x04000000, FL_ERASE_ALL | FL_CAN_4B, "Macronix MXxxL51235F"},
18 : : { 0xc2201b, 0x08000000, FL_ERASE_ALL | FL_CAN_4B, "Macronix MX66L1G45G"},
19 : : { 0xef4018, 0x01000000, FL_ERASE_ALL, "Winbond W25Q128BV" },
20 : : { 0xef4019, 0x02000000, FL_ERASE_ALL | FL_ERASE_64K | FL_CAN_4B |
21 : : FL_ERASE_BULK,
22 : : "Winbond W25Q256BV"},
23 : : { 0x20ba20, 0x04000000, FL_ERASE_4K | FL_ERASE_64K | FL_CAN_4B |
24 : : FL_ERASE_BULK | FL_MICRON_BUGS,
25 : : "Micron N25Qx512Ax" },
26 : : { 0x20ba19, 0x02000000, FL_ERASE_4K | FL_ERASE_64K | FL_CAN_4B |
27 : : FL_ERASE_BULK | FL_MICRON_BUGS,
28 : : "Micron N25Q256Ax" },
29 : : { 0x1940ef, 0x02000000, FL_ERASE_4K | FL_ERASE_64K | FL_CAN_4B |
30 : : FL_ERASE_BULK | FL_MICRON_BUGS,
31 : : "Micron N25Qx256Ax" },
32 : : { 0x4d5444, 0x02000000, FL_ERASE_ALL | FL_CAN_4B, "File Abstraction"},
33 : : { 0x55aa55, 0x00100000, FL_ERASE_ALL | FL_CAN_4B, "TEST_FLASH" },
34 : : { 0xaa55aa, 0x02000000, FL_ERASE_ALL | FL_CAN_4B, "EMULATED_FLASH"},
35 : : };
36 : :
37 : : struct flash_chip {
38 : : struct spi_flash_ctrl *ctrl; /* Controller */
39 : : struct flash_info info; /* Flash info */
40 : : uint32_t tsize; /* Corrected flash size */
41 : : uint32_t min_erase_mask; /* Minimum erase size */
42 : : bool mode_4b; /* Flash currently in 4b mode */
43 : : struct flash_req *cur_req; /* Current request */
44 : : void *smart_buf; /* Buffer for smart writes */
45 : : struct blocklevel_device bl;
46 : : };
47 : :
48 : : #ifndef __SKIBOOT__
49 : : bool libflash_debug;
50 : : #endif
51 : :
52 : 0 : int fl_read_stat(struct spi_flash_ctrl *ct, uint8_t *stat)
53 : : {
54 : 0 : return ct->cmd_rd(ct, CMD_RDSR, false, 0, stat, 1);
55 : : }
56 : :
57 : 0 : static void fl_micron_status(struct spi_flash_ctrl *ct)
58 : : {
59 : 0 : uint8_t flst;
60 : :
61 : : /*
62 : : * After a success status on a write or erase, we
63 : : * need to do that command or some chip variants will
64 : : * lock
65 : : */
66 : 0 : ct->cmd_rd(ct, CMD_MIC_RDFLST, false, 0, &flst, 1);
67 : 0 : }
68 : :
69 : : /* Synchronous write completion, probably need a yield hook */
70 : 0 : int fl_sync_wait_idle(struct spi_flash_ctrl *ct)
71 : : {
72 : 0 : uint8_t stat;
73 : 0 : int rc;
74 : :
75 : : /* XXX Add timeout */
76 : 0 : for (;;) {
77 : 0 : rc = fl_read_stat(ct, &stat);
78 : 0 : if (rc) return rc;
79 : 0 : if (!(stat & STAT_WIP)) {
80 : 0 : if (ct->finfo->flags & FL_MICRON_BUGS)
81 : 0 : fl_micron_status(ct);
82 : 0 : return 0;
83 : : }
84 : : }
85 : : /* return FLASH_ERR_WIP_TIMEOUT; */
86 : : }
87 : :
88 : : /* Exported for internal use */
89 : 0 : int fl_wren(struct spi_flash_ctrl *ct)
90 : : {
91 : 0 : int i, rc;
92 : 0 : uint8_t stat;
93 : :
94 : : /* Some flashes need it to be hammered */
95 : 0 : for (i = 0; i < 1000; i++) {
96 : 0 : rc = ct->cmd_wr(ct, CMD_WREN, false, 0, NULL, 0);
97 : 0 : if (rc) return rc;
98 : 0 : rc = fl_read_stat(ct, &stat);
99 : 0 : if (rc) return rc;
100 : 0 : if (stat & STAT_WIP) {
101 : 0 : FL_ERR("LIBFLASH: WREN has WIP status set !\n");
102 : 0 : rc = fl_sync_wait_idle(ct);
103 : 0 : if (rc)
104 : 0 : return rc;
105 : 0 : continue;
106 : : }
107 : 0 : if (stat & STAT_WEN)
108 : : return 0;
109 : : }
110 : : return FLASH_ERR_WREN_TIMEOUT;
111 : : }
112 : :
113 : 0 : static int flash_read(struct blocklevel_device *bl, uint64_t pos, void *buf, uint64_t len)
114 : : {
115 : 0 : struct flash_chip *c = container_of(bl, struct flash_chip, bl);
116 : 0 : struct spi_flash_ctrl *ct = c->ctrl;
117 : :
118 : : /* XXX Add sanity/bound checking */
119 : :
120 : : /*
121 : : * If the controller supports read and either we are in 3b mode
122 : : * or we are in 4b *and* the controller supports it, then do a
123 : : * high level read.
124 : : */
125 : 0 : if ((!c->mode_4b || ct->set_4b) && ct->read)
126 : 0 : return ct->read(ct, pos, buf, len);
127 : :
128 : : /* Otherwise, go manual if supported */
129 : 0 : if (!ct->cmd_rd)
130 : : return FLASH_ERR_CTRL_CMD_UNSUPPORTED;
131 : 0 : return ct->cmd_rd(ct, CMD_READ, true, pos, buf, len);
132 : : }
133 : :
134 : : #define COPY_BUFFER_LENGTH 4096
135 : :
136 : : /*
137 : : * This provides a wrapper around flash_read on ECCed data
138 : : * len is length of data without ECC attached
139 : : */
140 : 0 : int flash_read_corrected(struct blocklevel_device *bl, uint32_t pos, void *buf,
141 : : uint32_t len, bool ecc)
142 : : {
143 : 0 : struct ecc64 *bufecc;
144 : 0 : uint32_t copylen;
145 : 0 : int rc;
146 : 0 : uint8_t ret;
147 : :
148 : 0 : if (!ecc)
149 : 0 : return flash_read(bl, pos, buf, len);
150 : :
151 : : /* Copy the buffer in chunks */
152 : 0 : bufecc = malloc(ecc_buffer_size(COPY_BUFFER_LENGTH));
153 : 0 : if (!bufecc)
154 : : return FLASH_ERR_MALLOC_FAILED;
155 : :
156 : 0 : while (len > 0) {
157 : : /* What's left to copy? */
158 : 0 : copylen = MIN(len, COPY_BUFFER_LENGTH);
159 : :
160 : : /* Read ECCed data from flash */
161 : 0 : rc = flash_read(bl, pos, bufecc, ecc_buffer_size(copylen));
162 : 0 : if (rc)
163 : 0 : goto err;
164 : :
165 : : /* Extract data from ECCed data */
166 : 0 : ret = memcpy_from_ecc(buf, bufecc, copylen);
167 : 0 : if (ret) {
168 : 0 : rc = FLASH_ERR_ECC_INVALID;
169 : 0 : goto err;
170 : : }
171 : :
172 : : /* Update for next copy */
173 : 0 : len -= copylen;
174 : 0 : buf = (uint8_t *)buf + copylen;
175 : 0 : pos += ecc_buffer_size(copylen);
176 : : }
177 : :
178 : : rc = 0;
179 : :
180 : 0 : err:
181 : 0 : free(bufecc);
182 : 0 : return rc;
183 : : }
184 : :
185 : 0 : static void fl_get_best_erase(struct flash_chip *c, uint32_t dst, uint32_t size,
186 : : uint32_t *chunk, uint8_t *cmd)
187 : : {
188 : : /* Smaller than 32k, use 4k */
189 : 0 : if ((dst & 0x7fff) || (size < 0x8000)) {
190 : 0 : *chunk = 0x1000;
191 : 0 : *cmd = CMD_SE;
192 : 0 : return;
193 : : }
194 : : /* Smaller than 64k and 32k is supported, use it */
195 : 0 : if ((c->info.flags & FL_ERASE_32K) &&
196 : 0 : ((dst & 0xffff) || (size < 0x10000))) {
197 : 0 : *chunk = 0x8000;
198 : 0 : *cmd = CMD_BE32K;
199 : 0 : return;
200 : : }
201 : : /* If 64K is not supported, use whatever smaller size is */
202 : 0 : if (!(c->info.flags & FL_ERASE_64K)) {
203 : 0 : if (c->info.flags & FL_ERASE_32K) {
204 : 0 : *chunk = 0x8000;
205 : 0 : *cmd = CMD_BE32K;
206 : : } else {
207 : 0 : *chunk = 0x1000;
208 : 0 : *cmd = CMD_SE;
209 : : }
210 : 0 : return;
211 : : }
212 : : /* Allright, let's go for 64K */
213 : 0 : *chunk = 0x10000;
214 : 0 : *cmd = CMD_BE;
215 : : }
216 : :
217 : 0 : static int flash_erase(struct blocklevel_device *bl, uint64_t dst, uint64_t size)
218 : : {
219 : 0 : struct flash_chip *c = container_of(bl, struct flash_chip, bl);
220 : 0 : struct spi_flash_ctrl *ct = c->ctrl;
221 : 0 : uint32_t chunk;
222 : 0 : uint8_t cmd;
223 : 0 : int rc;
224 : :
225 : : /* Some sanity checking */
226 : 0 : if (((dst + size) <= dst) || !size || (dst + size) > c->tsize)
227 : : return FLASH_ERR_PARM_ERROR;
228 : :
229 : : /* Check boundaries fit erase blocks */
230 : 0 : if ((dst | size) & c->min_erase_mask)
231 : : return FLASH_ERR_ERASE_BOUNDARY;
232 : :
233 : 0 : FL_DBG("LIBFLASH: Erasing 0x%" PRIx64"..0%" PRIx64 "...\n",
234 : : dst, dst + size);
235 : :
236 : : /* Use controller erase if supported */
237 : 0 : if (ct->erase)
238 : 0 : return ct->erase(ct, dst, size);
239 : :
240 : : /* Allright, loop as long as there's something to erase */
241 : 0 : while(size) {
242 : : /* How big can we make it based on alignent & size */
243 : 0 : fl_get_best_erase(c, dst, size, &chunk, &cmd);
244 : :
245 : : /* Poke write enable */
246 : 0 : rc = fl_wren(ct);
247 : 0 : if (rc)
248 : 0 : return rc;
249 : :
250 : : /* Send erase command */
251 : 0 : rc = ct->cmd_wr(ct, cmd, true, dst, NULL, 0);
252 : 0 : if (rc)
253 : 0 : return rc;
254 : :
255 : : /* Wait for write complete */
256 : 0 : rc = fl_sync_wait_idle(ct);
257 : 0 : if (rc)
258 : 0 : return rc;
259 : :
260 : 0 : size -= chunk;
261 : 0 : dst += chunk;
262 : : }
263 : : return 0;
264 : : }
265 : :
266 : 0 : int flash_erase_chip(struct flash_chip *c)
267 : : {
268 : 0 : struct spi_flash_ctrl *ct = c->ctrl;
269 : 0 : int rc;
270 : :
271 : : /* XXX TODO: Fallback to using normal erases */
272 : 0 : if (!(c->info.flags & (FL_ERASE_CHIP|FL_ERASE_BULK)))
273 : : return FLASH_ERR_CHIP_ER_NOT_SUPPORTED;
274 : :
275 : 0 : FL_DBG("LIBFLASH: Erasing chip...\n");
276 : :
277 : : /* Use controller erase if supported */
278 : 0 : if (ct->erase)
279 : 0 : return ct->erase(ct, 0, 0xffffffff);
280 : :
281 : 0 : rc = fl_wren(ct);
282 : 0 : if (rc) return rc;
283 : :
284 : 0 : if (c->info.flags & FL_ERASE_CHIP)
285 : 0 : rc = ct->cmd_wr(ct, CMD_CE, false, 0, NULL, 0);
286 : : else
287 : 0 : rc = ct->cmd_wr(ct, CMD_MIC_BULK_ERASE, false, 0, NULL, 0);
288 : 0 : if (rc)
289 : : return rc;
290 : :
291 : : /* Wait for write complete */
292 : 0 : return fl_sync_wait_idle(ct);
293 : : }
294 : :
295 : 0 : static int fl_wpage(struct flash_chip *c, uint32_t dst, const void *src,
296 : : uint32_t size)
297 : : {
298 : 0 : struct spi_flash_ctrl *ct = c->ctrl;
299 : 0 : int rc;
300 : :
301 : 0 : if (size < 1 || size > 0x100)
302 : : return FLASH_ERR_BAD_PAGE_SIZE;
303 : :
304 : 0 : rc = fl_wren(ct);
305 : 0 : if (rc) return rc;
306 : :
307 : 0 : rc = ct->cmd_wr(ct, CMD_PP, true, dst, src, size);
308 : 0 : if (rc)
309 : : return rc;
310 : :
311 : : /* Wait for write complete */
312 : 0 : return fl_sync_wait_idle(ct);
313 : : }
314 : :
315 : 0 : static int flash_write(struct blocklevel_device *bl, uint32_t dst, const void *src,
316 : : uint32_t size, bool verify)
317 : : {
318 : 0 : struct flash_chip *c = container_of(bl, struct flash_chip, bl);
319 : 0 : struct spi_flash_ctrl *ct = c->ctrl;
320 : 0 : uint32_t todo = size;
321 : 0 : uint32_t d = dst;
322 : 0 : const void *s = src;
323 : 0 : uint8_t vbuf[0x100];
324 : 0 : int rc;
325 : :
326 : : /* Some sanity checking */
327 : 0 : if (((dst + size) <= dst) || !size || (dst + size) > c->tsize)
328 : : return FLASH_ERR_PARM_ERROR;
329 : :
330 : 0 : FL_DBG("LIBFLASH: Writing to 0x%08x..0%08x...\n", dst, dst + size);
331 : :
332 : : /*
333 : : * If the controller supports write and either we are in 3b mode
334 : : * or we are in 4b *and* the controller supports it, then do a
335 : : * high level write.
336 : : */
337 : 0 : if ((!c->mode_4b || ct->set_4b) && ct->write) {
338 : 0 : rc = ct->write(ct, dst, src, size);
339 : 0 : if (rc)
340 : : return rc;
341 : 0 : goto writing_done;
342 : : }
343 : :
344 : : /* Otherwise, go manual if supported */
345 : 0 : if (!ct->cmd_wr)
346 : : return FLASH_ERR_CTRL_CMD_UNSUPPORTED;
347 : :
348 : : /* Iterate for each page to write */
349 : 0 : while(todo) {
350 : 0 : uint32_t chunk;
351 : :
352 : : /* Handle misaligned start */
353 : 0 : chunk = 0x100 - (d & 0xff);
354 : 0 : if (chunk > todo)
355 : : chunk = todo;
356 : :
357 : 0 : rc = fl_wpage(c, d, s, chunk);
358 : 0 : if (rc) return rc;
359 : 0 : d += chunk;
360 : 0 : s += chunk;
361 : 0 : todo -= chunk;
362 : : }
363 : :
364 : 0 : writing_done:
365 : 0 : if (!verify)
366 : : return 0;
367 : :
368 : : /* Verify */
369 : 0 : FL_DBG("LIBFLASH: Verifying...\n");
370 : :
371 : 0 : while(size) {
372 : 0 : uint32_t chunk;
373 : :
374 : 0 : chunk = sizeof(vbuf);
375 : 0 : if (chunk > size)
376 : 0 : chunk = size;
377 : 0 : rc = flash_read(bl, dst, vbuf, chunk);
378 : 0 : if (rc) return rc;
379 : 0 : if (memcmp(vbuf, src, chunk)) {
380 : 0 : FL_ERR("LIBFLASH: Miscompare at 0x%08x\n", dst);
381 : 0 : return FLASH_ERR_VERIFY_FAILURE;
382 : : }
383 : 0 : dst += chunk;
384 : 0 : src += chunk;
385 : 0 : size -= chunk;
386 : : }
387 : : return 0;
388 : : }
389 : :
390 : 0 : int flash_write_corrected(struct blocklevel_device *bl, uint32_t pos, const void *buf,
391 : : uint32_t len, bool verify, bool ecc)
392 : : {
393 : 0 : struct ecc64 *bufecc;
394 : 0 : uint32_t copylen, copylen_minus_ecc;
395 : 0 : int rc;
396 : 0 : uint8_t ret;
397 : :
398 : 0 : if (!ecc)
399 : 0 : return flash_write(bl, pos, buf, len, verify);
400 : :
401 : : /* Copy the buffer in chunks */
402 : 0 : bufecc = malloc(ecc_buffer_size(COPY_BUFFER_LENGTH));
403 : 0 : if (!bufecc)
404 : : return FLASH_ERR_MALLOC_FAILED;
405 : :
406 : 0 : while (len > 0) {
407 : : /* What's left to copy? */
408 : 0 : copylen = MIN(len, COPY_BUFFER_LENGTH);
409 : 0 : copylen_minus_ecc = ecc_buffer_size_minus_ecc(copylen);
410 : :
411 : : /* Add the ecc byte to the data */
412 : 0 : ret = memcpy_to_ecc(bufecc, buf, copylen_minus_ecc);
413 : 0 : if (ret) {
414 : 0 : rc = FLASH_ERR_ECC_INVALID;
415 : 0 : goto err;
416 : : }
417 : :
418 : : /* Write ECCed data to the flash */
419 : 0 : rc = flash_write(bl, pos, bufecc, copylen, verify);
420 : 0 : if (rc)
421 : 0 : goto err;
422 : :
423 : : /* Update for next copy */
424 : 0 : len -= copylen_minus_ecc;
425 : 0 : buf = (uint8_t *)buf + copylen_minus_ecc;
426 : 0 : pos += copylen;
427 : : }
428 : :
429 : : rc = 0;
430 : :
431 : 0 : err:
432 : 0 : free(bufecc);
433 : 0 : return rc;
434 : : }
435 : :
436 : : enum sm_comp_res {
437 : : sm_no_change,
438 : : sm_need_write,
439 : : sm_need_erase,
440 : : };
441 : :
442 : 0 : static enum sm_comp_res flash_smart_comp(struct flash_chip *c,
443 : : const void *src,
444 : : uint32_t offset, uint32_t size)
445 : : {
446 : 0 : uint8_t *b = c->smart_buf + offset;
447 : 0 : const uint8_t *s = src;
448 : 0 : bool is_same = true;
449 : 0 : uint32_t i;
450 : :
451 : : /* SRC DEST NEED_ERASE
452 : : * 0 1 0
453 : : * 1 1 0
454 : : * 0 0 0
455 : : * 1 0 1
456 : : */
457 : 0 : for (i = 0; i < size; i++) {
458 : : /* Any bit need to be set, need erase */
459 : 0 : if (s[i] & ~b[i])
460 : : return sm_need_erase;
461 : 0 : if (is_same && (b[i] != s[i]))
462 : 0 : is_same = false;
463 : : }
464 : 0 : return is_same ? sm_no_change : sm_need_write;
465 : : }
466 : :
467 : 0 : static int flash_smart_write(struct blocklevel_device *bl, uint64_t dst, const void *src, uint64_t size)
468 : : {
469 : 0 : struct flash_chip *c = container_of(bl, struct flash_chip, bl);
470 : 0 : uint32_t er_size = c->min_erase_mask + 1;
471 : 0 : uint32_t end = dst + size;
472 : 0 : int rc;
473 : :
474 : : /* Some sanity checking */
475 : 0 : if (end <= dst || !size || end > c->tsize) {
476 : 0 : FL_DBG("LIBFLASH: Smart write param error\n");
477 : 0 : return FLASH_ERR_PARM_ERROR;
478 : : }
479 : :
480 : 0 : FL_DBG("LIBFLASH: Smart writing to 0x%" PRIx64 "..0%" PRIx64 "...\n",
481 : : dst, dst + size);
482 : :
483 : : /* As long as we have something to write ... */
484 : 0 : while(dst < end) {
485 : 0 : uint32_t page, off, chunk;
486 : 0 : enum sm_comp_res sr;
487 : :
488 : : /* Figure out which erase page we are in and read it */
489 : 0 : page = dst & ~c->min_erase_mask;
490 : 0 : off = dst & c->min_erase_mask;
491 : 0 : FL_DBG("LIBFLASH: reading page 0x%08x..0x%08x...\n",
492 : : page, page + er_size);
493 : 0 : rc = flash_read(bl, page, c->smart_buf, er_size);
494 : 0 : if (rc) {
495 : 0 : FL_DBG("LIBFLASH: ...error %d!\n", rc);
496 : 0 : return rc;
497 : : }
498 : :
499 : : /* Locate the chunk of data we are working on */
500 : 0 : chunk = er_size - off;
501 : 0 : if (size < chunk)
502 : 0 : chunk = size;
503 : :
504 : : /* Compare against what we are writing and ff */
505 : 0 : sr = flash_smart_comp(c, src, off, chunk);
506 : 0 : switch(sr) {
507 : 0 : case sm_no_change:
508 : : /* Identical, skip it */
509 : 0 : FL_DBG("LIBFLASH: ...same !\n");
510 : : break;
511 : 0 : case sm_need_write:
512 : : /* Just needs writing over */
513 : 0 : FL_DBG("LIBFLASH: ...need write !\n");
514 : 0 : rc = flash_write(bl, dst, src, chunk, true);
515 : 0 : if (rc) {
516 : 0 : FL_DBG("LIBFLASH: Write error %d !\n", rc);
517 : 0 : return rc;
518 : : }
519 : : break;
520 : 0 : case sm_need_erase:
521 : 0 : FL_DBG("LIBFLASH: ...need erase !\n");
522 : 0 : rc = flash_erase(bl, page, er_size);
523 : 0 : if (rc) {
524 : 0 : FL_DBG("LIBFLASH: erase error %d !\n", rc);
525 : 0 : return rc;
526 : : }
527 : : /* Then update the portion of the buffer and write the block */
528 : 0 : memcpy(c->smart_buf + off, src, chunk);
529 : 0 : rc = flash_write(bl, page, c->smart_buf, er_size, true);
530 : 0 : if (rc) {
531 : 0 : FL_DBG("LIBFLASH: write error %d !\n", rc);
532 : 0 : return rc;
533 : : }
534 : : break;
535 : : }
536 : 0 : dst += chunk;
537 : 0 : src += chunk;
538 : 0 : size -= chunk;
539 : : }
540 : : return 0;
541 : : }
542 : :
543 : 0 : int flash_smart_write_corrected(struct blocklevel_device *bl, uint32_t dst, const void *src,
544 : : uint32_t size, bool ecc)
545 : : {
546 : 0 : struct ecc64 *buf;
547 : 0 : int rc;
548 : :
549 : 0 : if (!ecc)
550 : 0 : return flash_smart_write(bl, dst, src, size);
551 : :
552 : 0 : buf = malloc(ecc_buffer_size(size));
553 : 0 : if (!buf)
554 : : return FLASH_ERR_MALLOC_FAILED;
555 : :
556 : 0 : rc = memcpy_to_ecc(buf, src, size);
557 : 0 : if (rc) {
558 : 0 : rc = FLASH_ERR_ECC_INVALID;
559 : 0 : goto out;
560 : : }
561 : :
562 : 0 : rc = flash_smart_write(bl, dst, buf, ecc_buffer_size(size));
563 : :
564 : 0 : out:
565 : 0 : free(buf);
566 : 0 : return rc;
567 : : }
568 : :
569 : 0 : static int fl_chip_id(struct spi_flash_ctrl *ct, uint8_t *id_buf,
570 : : uint32_t *id_size)
571 : : {
572 : 0 : int rc;
573 : 0 : uint8_t stat;
574 : :
575 : : /* Check initial status */
576 : 0 : rc = fl_read_stat(ct, &stat);
577 : 0 : if (rc)
578 : : return rc;
579 : :
580 : : /* If stuck writing, wait for idle */
581 : 0 : if (stat & STAT_WIP) {
582 : 0 : FL_ERR("LIBFLASH: Flash in writing state ! Waiting...\n");
583 : 0 : rc = fl_sync_wait_idle(ct);
584 : 0 : if (rc)
585 : : return rc;
586 : : } else
587 : 0 : FL_DBG("LIBFLASH: Init status: %02x\n", stat);
588 : :
589 : : /* Fallback to get ID manually */
590 : 0 : rc = ct->cmd_rd(ct, CMD_RDID, false, 0, id_buf, 3);
591 : 0 : if (rc)
592 : : return rc;
593 : 0 : *id_size = 3;
594 : :
595 : 0 : return 0;
596 : : }
597 : :
598 : 0 : static int flash_identify(struct flash_chip *c)
599 : : {
600 : 0 : struct spi_flash_ctrl *ct = c->ctrl;
601 : 0 : const struct flash_info *info = NULL;
602 : 0 : uint32_t iid, id_size;
603 : : #define MAX_ID_SIZE 16
604 : 0 : uint8_t id[MAX_ID_SIZE];
605 : 0 : int rc, i;
606 : :
607 : 0 : if (ct->chip_id) {
608 : : /* High level controller interface */
609 : 0 : id_size = MAX_ID_SIZE;
610 : 0 : rc = ct->chip_id(ct, id, &id_size);
611 : : } else
612 : 0 : rc = fl_chip_id(ct, id, &id_size);
613 : 0 : if (rc)
614 : : return rc;
615 : 0 : if (id_size < 3)
616 : : return FLASH_ERR_CHIP_UNKNOWN;
617 : :
618 : : /* Convert to a dword for lookup */
619 : 0 : iid = id[0];
620 : 0 : iid = (iid << 8) | id[1];
621 : 0 : iid = (iid << 8) | id[2];
622 : :
623 : 0 : FL_DBG("LIBFLASH: Flash ID: %02x.%02x.%02x (%06x)\n",
624 : : id[0], id[1], id[2], iid);
625 : :
626 : : /* Lookup in flash_info */
627 : 0 : for (i = 0; i < ARRAY_SIZE(flash_info); i++) {
628 : 0 : info = &flash_info[i];
629 : 0 : if (info->id == iid)
630 : : break;
631 : : }
632 : 0 : if (!info || info->id != iid)
633 : : return FLASH_ERR_CHIP_UNKNOWN;
634 : :
635 : 0 : c->info = *info;
636 : 0 : c->tsize = info->size;
637 : 0 : ct->finfo = &c->info;
638 : :
639 : : /*
640 : : * Let controller know about our settings and possibly
641 : : * override them
642 : : */
643 : 0 : if (ct->setup) {
644 : 0 : rc = ct->setup(ct, &c->tsize);
645 : 0 : if (rc)
646 : : return rc;
647 : : }
648 : :
649 : : /* Calculate min erase granularity */
650 : 0 : if (c->info.flags & FL_ERASE_4K)
651 : 0 : c->min_erase_mask = 0xfff;
652 : 0 : else if (c->info.flags & FL_ERASE_32K)
653 : 0 : c->min_erase_mask = 0x7fff;
654 : 0 : else if (c->info.flags & FL_ERASE_64K)
655 : 0 : c->min_erase_mask = 0xffff;
656 : : else {
657 : : /* No erase size ? oops ... */
658 : 0 : FL_ERR("LIBFLASH: No erase sizes !\n");
659 : 0 : return FLASH_ERR_CTRL_CONFIG_MISMATCH;
660 : : }
661 : :
662 : 0 : FL_DBG("LIBFLASH: Found chip %s size %dM erase granule: %dK\n",
663 : : c->info.name, c->tsize >> 20, (c->min_erase_mask + 1) >> 10);
664 : :
665 : : return 0;
666 : : }
667 : :
668 : 0 : static int flash_set_4b(struct flash_chip *c, bool enable)
669 : : {
670 : 0 : struct spi_flash_ctrl *ct = c->ctrl;
671 : 0 : int rc;
672 : :
673 : : /* Don't have low level interface, assume all is well */
674 : 0 : if (!ct->cmd_wr)
675 : : return 0;
676 : :
677 : : /* Some flash chips want this */
678 : 0 : rc = fl_wren(ct);
679 : 0 : if (rc) {
680 : 0 : FL_ERR("LIBFLASH: Error %d enabling write for set_4b\n", rc);
681 : : /* Ignore the error & move on (could be wrprotect chip) */
682 : : }
683 : :
684 : : /* Ignore error in case chip is write protected */
685 : 0 : return ct->cmd_wr(ct, enable ? CMD_EN4B : CMD_EX4B, false, 0, NULL, 0);
686 : : }
687 : :
688 : 0 : int flash_force_4b_mode(struct flash_chip *c, bool enable_4b)
689 : : {
690 : 0 : struct spi_flash_ctrl *ct = c->ctrl;
691 : 0 : int rc = FLASH_ERR_4B_NOT_SUPPORTED;
692 : :
693 : : /*
694 : : * We only allow force 4b if both controller and flash do 4b
695 : : * as this is mainly used if a 3rd party tries to directly
696 : : * access a direct mapped read region
697 : : */
698 : 0 : if (enable_4b && !((c->info.flags & FL_CAN_4B) && ct->set_4b))
699 : : return rc;
700 : :
701 : : /* Only send to flash directly on controllers that implement
702 : : * the low level callbacks
703 : : */
704 : 0 : if (ct->cmd_wr) {
705 : 0 : rc = flash_set_4b(c, enable_4b);
706 : 0 : if (rc)
707 : : return rc;
708 : : }
709 : :
710 : : /* Then inform the controller */
711 : 0 : if (ct->set_4b)
712 : 0 : rc = ct->set_4b(ct, enable_4b);
713 : : return rc;
714 : : }
715 : :
716 : 0 : static int flash_configure(struct flash_chip *c)
717 : : {
718 : 0 : struct spi_flash_ctrl *ct = c->ctrl;
719 : 0 : int rc;
720 : :
721 : : /* Crop flash size if necessary */
722 : 0 : if (c->tsize > 0x01000000 && !(c->info.flags & FL_CAN_4B)) {
723 : 0 : FL_ERR("LIBFLASH: Flash chip cropped to 16M, no 4b mode\n");
724 : 0 : c->tsize = 0x01000000;
725 : : }
726 : :
727 : : /* If flash chip > 16M, enable 4b mode */
728 : 0 : if (c->tsize > 0x01000000) {
729 : 0 : FL_DBG("LIBFLASH: Flash >16MB, enabling 4B mode...\n");
730 : :
731 : : /* Set flash to 4b mode if we can */
732 : 0 : if (ct->cmd_wr) {
733 : 0 : rc = flash_set_4b(c, true);
734 : 0 : if (rc) {
735 : 0 : FL_ERR("LIBFLASH: Failed to set flash 4b mode\n");
736 : 0 : return rc;
737 : : }
738 : : }
739 : :
740 : :
741 : : /* Set controller to 4b mode if supported */
742 : 0 : if (ct->set_4b) {
743 : 0 : FL_DBG("LIBFLASH: Enabling controller 4B mode...\n");
744 : 0 : rc = ct->set_4b(ct, true);
745 : 0 : if (rc) {
746 : 0 : FL_ERR("LIBFLASH: Failed to set controller 4b mode\n");
747 : 0 : return rc;
748 : : }
749 : : }
750 : : } else {
751 : 0 : FL_DBG("LIBFLASH: Flash <=16MB, disabling 4B mode...\n");
752 : :
753 : : /*
754 : : * If flash chip supports 4b mode, make sure we disable
755 : : * it in case it was left over by the previous user
756 : : */
757 : 0 : if (c->info.flags & FL_CAN_4B) {
758 : 0 : rc = flash_set_4b(c, false);
759 : 0 : if (rc) {
760 : 0 : FL_ERR("LIBFLASH: Failed to"
761 : : " clear flash 4b mode\n");
762 : 0 : return rc;
763 : : }
764 : : }
765 : : /* Set controller to 3b mode if mode switch is supported */
766 : 0 : if (ct->set_4b) {
767 : 0 : FL_DBG("LIBFLASH: Disabling controller 4B mode...\n");
768 : 0 : rc = ct->set_4b(ct, false);
769 : 0 : if (rc) {
770 : 0 : FL_ERR("LIBFLASH: Failed to"
771 : : " clear controller 4b mode\n");
772 : 0 : return rc;
773 : : }
774 : : }
775 : : }
776 : : return 0;
777 : : }
778 : :
779 : 0 : static int flash_get_info(struct blocklevel_device *bl, const char **name,
780 : : uint64_t *total_size, uint32_t *erase_granule)
781 : : {
782 : 0 : struct flash_chip *c = container_of(bl, struct flash_chip, bl);
783 : 0 : if (name)
784 : 0 : *name = c->info.name;
785 : 0 : if (total_size)
786 : 0 : *total_size = c->tsize;
787 : 0 : if (erase_granule)
788 : 0 : *erase_granule = c->min_erase_mask + 1;
789 : 0 : return 0;
790 : : }
791 : :
792 : 0 : int flash_init(struct spi_flash_ctrl *ctrl, struct blocklevel_device **bl,
793 : : struct flash_chip **flash_chip)
794 : : {
795 : 0 : struct flash_chip *c;
796 : 0 : int rc;
797 : :
798 : 0 : if (!bl)
799 : : return FLASH_ERR_PARM_ERROR;
800 : :
801 : 0 : *bl = NULL;
802 : :
803 : 0 : c = malloc(sizeof(struct flash_chip));
804 : 0 : if (!c)
805 : : return FLASH_ERR_MALLOC_FAILED;
806 : 0 : memset(c, 0, sizeof(*c));
807 : 0 : c->ctrl = ctrl;
808 : :
809 : 0 : rc = flash_identify(c);
810 : 0 : if (rc) {
811 : 0 : FL_ERR("LIBFLASH: Flash identification failed\n");
812 : 0 : goto bail;
813 : : }
814 : 0 : c->smart_buf = malloc(c->min_erase_mask + 1);
815 : 0 : if (!c->smart_buf) {
816 : 0 : FL_ERR("LIBFLASH: Failed to allocate smart buffer !\n");
817 : 0 : rc = FLASH_ERR_MALLOC_FAILED;
818 : 0 : goto bail;
819 : : }
820 : 0 : rc = flash_configure(c);
821 : 0 : if (rc)
822 : 0 : FL_ERR("LIBFLASH: Flash configuration failed\n");
823 : 0 : bail:
824 : 0 : if (rc) {
825 : 0 : free(c);
826 : 0 : return rc;
827 : : }
828 : :
829 : : /* The flash backend doesn't support reiniting it */
830 : 0 : c->bl.keep_alive = true;
831 : 0 : c->bl.reacquire = NULL;
832 : 0 : c->bl.release = NULL;
833 : 0 : c->bl.read = &flash_read;
834 : 0 : c->bl.write = &flash_smart_write;
835 : 0 : c->bl.erase = &flash_erase;
836 : 0 : c->bl.get_info = &flash_get_info;
837 : 0 : c->bl.erase_mask = c->min_erase_mask;
838 : 0 : c->bl.flags = WRITE_NEED_ERASE;
839 : :
840 : 0 : *bl = &(c->bl);
841 : 0 : if (flash_chip)
842 : 0 : *flash_chip = c;
843 : :
844 : : return 0;
845 : : }
846 : :
847 : 0 : void flash_exit(struct blocklevel_device *bl)
848 : : {
849 : : /* XXX Make sure we are idle etc... */
850 : 0 : if (bl) {
851 : 0 : struct flash_chip *c = container_of(bl, struct flash_chip, bl);
852 : 0 : free(c->smart_buf);
853 : 0 : free(c);
854 : : }
855 : 0 : }
856 : :
857 : 0 : void flash_exit_close(struct blocklevel_device *bl, void (*close)(struct spi_flash_ctrl *ctrl))
858 : : {
859 : 0 : if (bl) {
860 : 0 : struct flash_chip *c = container_of(bl, struct flash_chip, bl);
861 : 0 : close(c->ctrl);
862 : 0 : free(c);
863 : : }
864 : 0 : }
|