]> git.ipfire.org Git - thirdparty/u-boot.git/blame - drivers/mtd/nand/raw/sand_nand.c
test: spl: Add a test for NAND
[thirdparty/u-boot.git] / drivers / mtd / nand / raw / sand_nand.c
CommitLineData
bc8e8a4b
SA
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) Sean Anderson <seanga2@gmail.com>
4 */
5
6#define LOG_CATEGORY UCLASS_MTD
7#include <errno.h>
8#include <hexdump.h>
9#include <log.h>
10#include <nand.h>
11#include <os.h>
12#include <rand.h>
8502b5bf
SA
13#include <spl.h>
14#include <system-constants.h>
bc8e8a4b
SA
15#include <dm/device_compat.h>
16#include <dm/read.h>
17#include <dm/uclass.h>
18#include <asm/bitops.h>
19#include <linux/bitmap.h>
20#include <linux/mtd/rawnand.h>
21#include <linux/sizes.h>
22
23enum sand_nand_state {
24 STATE_READY,
25 STATE_IDLE,
26 STATE_READ,
27 STATE_READ_ID,
28 STATE_READ_ONFI,
29 STATE_PARAM_ONFI,
30 STATE_STATUS,
31 STATE_PROG,
32 STATE_ERASE,
33};
34
35static const char *const state_name[] = {
36 [STATE_READY] = "READY",
37 [STATE_IDLE] = "IDLE",
38 [STATE_READ] = "READ",
39 [STATE_READ_ID] = "READ_ID",
40 [STATE_READ_ONFI] = "READ_ONFI",
41 [STATE_PARAM_ONFI] = "PARAM_ONFI",
42 [STATE_STATUS] = "STATUS",
43 [STATE_PROG] = "PROG",
44 [STATE_ERASE] = "ERASE",
45};
46
47/**
48 * struct sand_nand_chip - Per-device private data
49 * @nand: The nand chip
50 * @node: The next device in this controller
51 * @programmed: Bitmap of whether sectors are programmed
52 * @id: ID to report for NAND_CMD_READID
53 * @id_len: Length of @id
54 * @onfi: Three copies of ONFI parameter page
55 * @status: Status to report for NAND_CMD_STATUS
56 * @chunksize: Size of one "chunk" (page + oob) in bytes
57 * @pageize: Size of one page in bytes
58 * @pages: Total number of pages
59 * @pages_per_erase: Number of pages per eraseblock
60 * @err_count: Number of errors to inject per @err_step_bits of data
61 * @err_step_bits: Number of data bits per error "step"
62 * @err_steps: Number of err steps in a page
63 * @cs: Chip select for this device
64 * @state: Current state of the device
65 * @column: Column of the most-recent command
66 * @page_addr: Page address of the most-recent command
67 * @fd: File descriptor for the backing data
68 * @fd_page_addr: Page address that @fd is seek'd to
69 * @selected: Whether this device is selected
70 * @tmp: "Cache" buffer used to store transferred data before committing it
71 * @tmp_dirty: Whether @tmp is dirty (modified) or clean (all ones)
72 *
73 * Data is stored with the OOB area in-line. For example, with 512-byte pages
74 * and and 16-byte OOB areas, the first page would start at offset 0, the second
75 * at offset 528, the third at offset 1056, and so on
76 */
77struct sand_nand_chip {
78 struct nand_chip nand;
79 struct list_head node;
80 long *programmed;
81 const u8 *id;
82 u32 chunksize, pagesize, pages, pages_per_erase;
83 u32 err_count, err_step_bits, err_steps, ecc_bits;
84 unsigned int cs;
85 enum sand_nand_state state;
86 int column, page_addr, fd, fd_page_addr;
87 bool selected, tmp_dirty;
88 u8 status;
89 u8 id_len;
90 u8 tmp[NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE];
91 u8 onfi[sizeof(struct nand_onfi_params) * 3];
92};
93
94#define SAND_DEBUG(chip, fmt, ...) \
95 dev_dbg((chip)->nand.mtd.dev, "%u (%s): " fmt, (chip)->cs, \
96 state_name[(chip)->state], ##__VA_ARGS__)
97
98static inline void to_state(struct sand_nand_chip *chip,
99 enum sand_nand_state new_state)
100{
101 if (new_state != chip->state)
102 SAND_DEBUG(chip, "to state %s\n", state_name[new_state]);
103 chip->state = new_state;
104}
105
106static inline struct sand_nand_chip *to_sand_nand(struct nand_chip *nand)
107{
108 return container_of(nand, struct sand_nand_chip, nand);
109}
110
111struct sand_nand_priv {
112 struct list_head chips;
113};
114
115static int sand_nand_dev_ready(struct mtd_info *mtd)
116{
117 return 1;
118}
119
120static int sand_nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
121{
122 u8 status;
123
124 return nand_status_op(chip, &status) ?: status;
125}
126
127static int sand_nand_seek(struct sand_nand_chip *chip)
128{
129 if (chip->fd_page_addr == chip->page_addr)
130 return 0;
131
132 if (os_lseek(chip->fd, (off_t)chip->page_addr * chip->chunksize,
133 OS_SEEK_SET) < 0) {
134 SAND_DEBUG(chip, "could not seek: %d\n", errno);
135 return -EIO;
136 }
137
138 chip->fd_page_addr = chip->page_addr;
139 return 0;
140}
141
142static void sand_nand_inject_error(struct sand_nand_chip *chip,
143 unsigned int step, unsigned int pos)
144{
145 int byte, index;
146
147 if (pos < chip->err_step_bits) {
148 __change_bit(step * chip->err_step_bits + pos, chip->tmp);
149 return;
150 }
151
152 /*
153 * Only ECC bytes are covered in the OOB area, so
154 * pretend that those are the only bytes which can have
155 * errors.
156 */
157 byte = (pos - chip->err_step_bits + step * chip->ecc_bits) / 8;
158 index = chip->nand.ecc.layout->eccpos[byte];
159 /* Avoid endianness issues by working with bytes */
160 chip->tmp[chip->pagesize + index] ^= BIT(pos & 0x7);
161}
162
163static int sand_nand_read(struct sand_nand_chip *chip)
164{
165 unsigned int i, stop = 0;
166
167 if (chip->column == chip->pagesize)
168 stop = chip->err_step_bits;
169
170 if (test_bit(chip->page_addr, chip->programmed)) {
171 if (sand_nand_seek(chip))
172 return -EIO;
173
174 if (os_read(chip->fd, chip->tmp, chip->chunksize) !=
175 chip->chunksize) {
176 SAND_DEBUG(chip, "could not read: %d\n", errno);
177 return -EIO;
178 }
179 chip->fd_page_addr++;
180 } else if (chip->tmp_dirty) {
181 memset(chip->tmp + chip->column, 0xff,
182 chip->chunksize - chip->column);
183 }
184
185 /*
186 * Inject some errors; this is Method A from "An Efficient Algorithm for
187 * Sequential Random Sampling" (Vitter 87). This is still slow when
188 * generating a lot (dozens) of ECC errors.
189 *
190 * To avoid generating too many errors in any one ECC step, we separate
191 * our error generation by ECC step.
192 */
193 chip->tmp_dirty = true;
194 for (i = 0; i < chip->err_steps; i++) {
195 u32 bit_errors = chip->err_count;
196 unsigned int j = chip->err_step_bits + chip->ecc_bits;
197
198 while (bit_errors) {
199 unsigned int u = rand();
200 float quot = 1ULL << 32;
201
202 do {
203 quot *= j - bit_errors;
204 quot /= j;
205 j--;
206
207 if (j < stop)
208 goto next;
209 } while (u < quot);
210
211 sand_nand_inject_error(chip, i, j);
212 bit_errors--;
213 }
214next:
215 ;
216 }
217
218 return 0;
219}
220
221static void sand_nand_command(struct mtd_info *mtd, unsigned int command,
222 int column, int page_addr)
223{
224 struct nand_chip *nand = mtd_to_nand(mtd);
225 struct sand_nand_chip *chip = to_sand_nand(nand);
226 enum sand_nand_state new_state = chip->state;
227
228 SAND_DEBUG(chip, "command=%02x column=%d page_addr=%d\n", command,
229 column, page_addr);
230
231 if (!chip->selected)
232 return;
233
234 switch (chip->state) {
235 case STATE_READY:
236 if (command == NAND_CMD_RESET)
237 goto reset;
238 break;
239 case STATE_PROG:
240 new_state = STATE_IDLE;
241 if (command != NAND_CMD_PAGEPROG ||
242 test_and_set_bit(chip->page_addr, chip->programmed)) {
243 chip->status |= NAND_STATUS_FAIL;
244 break;
245 }
246
247 if (sand_nand_seek(chip)) {
248 chip->status |= NAND_STATUS_FAIL;
249 break;
250 }
251
252 if (os_write(chip->fd, chip->tmp, chip->chunksize) !=
253 chip->chunksize) {
254 SAND_DEBUG(chip, "could not write: %d\n", errno);
255 chip->status |= NAND_STATUS_FAIL;
256 break;
257 }
258
259 chip->fd_page_addr++;
260 break;
261 case STATE_ERASE:
262 new_state = STATE_IDLE;
263 if (command != NAND_CMD_ERASE2) {
264 chip->status |= NAND_STATUS_FAIL;
265 break;
266 }
267
268 if (chip->page_addr < 0 ||
269 chip->page_addr >= chip->pages ||
270 chip->page_addr % chip->pages_per_erase)
271 chip->status |= NAND_STATUS_FAIL;
272 else
273 bitmap_clear(chip->programmed, chip->page_addr,
274 chip->pages_per_erase);
275 break;
276 default:
277 chip->column = column;
278 chip->page_addr = page_addr;
279 switch (command) {
280 case NAND_CMD_READOOB:
281 if (column >= 0)
282 chip->column += chip->pagesize;
283 fallthrough;
284 case NAND_CMD_READ0:
285 new_state = STATE_IDLE;
286 if (page_addr < 0 || page_addr >= chip->pages)
287 break;
288
289 if (chip->column < 0 || chip->column >= chip->chunksize)
290 break;
291
292 if (sand_nand_read(chip))
293 break;
294
295 chip->page_addr = page_addr;
296 new_state = STATE_READ;
297 break;
298 case NAND_CMD_ERASE1:
299 new_state = STATE_ERASE;
300 chip->status = ~NAND_STATUS_FAIL;
301 break;
302 case NAND_CMD_STATUS:
303 new_state = STATE_STATUS;
304 chip->column = 0;
305 break;
306 case NAND_CMD_SEQIN:
307 new_state = STATE_PROG;
308 chip->status = ~NAND_STATUS_FAIL;
309 if (page_addr < 0 || page_addr >= chip->pages ||
310 chip->column < 0 ||
311 chip->column >= chip->chunksize) {
312 chip->status |= NAND_STATUS_FAIL;
313 } else if (chip->tmp_dirty) {
314 memset(chip->tmp, 0xff, chip->chunksize);
315 chip->tmp_dirty = false;
316 }
317 break;
318 case NAND_CMD_READID:
319 if (chip->onfi[0] && column == 0x20)
320 new_state = STATE_READ_ONFI;
321 else
322 new_state = STATE_READ_ID;
323 chip->column = 0;
324 break;
325 case NAND_CMD_PARAM:
326 if (chip->onfi[0] && !column)
327 new_state = STATE_PARAM_ONFI;
328 else
329 new_state = STATE_IDLE;
330 break;
331 case NAND_CMD_RESET:
332reset:
333 new_state = STATE_IDLE;
334 chip->column = -1;
335 chip->page_addr = -1;
336 chip->status = ~NAND_STATUS_FAIL;
337 break;
338 default:
339 new_state = STATE_IDLE;
340 SAND_DEBUG(chip, "Unsupported command %02x\n", command);
341 }
342 }
343
344 to_state(chip, new_state);
345}
346
347static void sand_nand_select_chip(struct mtd_info *mtd, int n)
348{
349 struct nand_chip *nand = mtd_to_nand(mtd);
350 struct sand_nand_chip *chip = to_sand_nand(nand);
351
352 chip->selected = !n;
353}
354
355static void sand_nand_read_buf(struct mtd_info *mtd, u8 *buf, int len)
356{
357 struct nand_chip *nand = mtd_to_nand(mtd);
358 struct sand_nand_chip *chip = to_sand_nand(nand);
359 unsigned int to_copy;
360 int src_len = 0;
361 const u8 *src = NULL;
362
363 if (!chip->selected)
364 goto copy;
365
366 switch (chip->state) {
367 case STATE_READ:
368 src = chip->tmp;
369 src_len = chip->chunksize;
370 break;
371 case STATE_READ_ID:
372 src = chip->id;
373 src_len = chip->id_len;
374 break;
375 case STATE_READ_ONFI:
376 src = "ONFI";
377 src_len = 4;
378 break;
379 case STATE_PARAM_ONFI:
380 src = chip->onfi;
381 src_len = sizeof(chip->onfi);
382 break;
383 case STATE_STATUS:
384 src = &chip->status;
385 src_len = 1;
386 break;
387 default:
388 break;
389 }
390
391copy:
392 if (chip->column >= 0)
393 to_copy = max(min(len, src_len - chip->column), 0);
394 else
395 to_copy = 0;
396 memcpy(buf, src + chip->column, to_copy);
397 memset(buf + to_copy, 0xff, len - to_copy);
398 chip->column += to_copy;
399
400 if (len == 1) {
401 SAND_DEBUG(chip, "read [ %02x ]\n", buf[0]);
402 } else if (src_len) {
403 SAND_DEBUG(chip, "read %d bytes\n", len);
404#ifdef VERBOSE_DEBUG
405 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, buf, len);
406#endif
407 }
408
409 if (src_len && chip->column == src_len)
410 to_state(chip, STATE_IDLE);
411}
412
413static u8 sand_nand_read_byte(struct mtd_info *mtd)
414{
415 u8 ret;
416
417 sand_nand_read_buf(mtd, &ret, 1);
418 return ret;
419}
420
421static u16 sand_nand_read_word(struct mtd_info *mtd)
422{
423 struct nand_chip *nand = mtd_to_nand(mtd);
424 struct sand_nand_chip *chip = to_sand_nand(nand);
425
426 SAND_DEBUG(chip, "16-bit access unsupported\n");
427 return sand_nand_read_byte(mtd) | 0xff00;
428}
429
430static void sand_nand_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
431{
432 struct nand_chip *nand = mtd_to_nand(mtd);
433 struct sand_nand_chip *chip = to_sand_nand(nand);
434
435 SAND_DEBUG(chip, "write %d bytes\n", len);
436#ifdef VERBOSE_DEBUG
437 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, buf, len);
438#endif
439
440 if (chip->state != STATE_PROG || chip->status & NAND_STATUS_FAIL)
441 return;
442
443 chip->tmp_dirty = true;
444 len = min((unsigned int)len, chip->chunksize - chip->column);
445 memcpy(chip->tmp + chip->column, buf, len);
446 chip->column += len;
447}
448
449static struct nand_chip *nand_chip;
450
451int sand_nand_remove(struct udevice *dev)
452{
453 struct sand_nand_priv *priv = dev_get_priv(dev);
454 struct sand_nand_chip *chip;
455
456 list_for_each_entry(chip, &priv->chips, node) {
457 struct nand_chip *nand = &chip->nand;
458
459 if (nand_chip == nand)
460 nand_chip = NULL;
461
462 nand_unregister(nand_to_mtd(nand));
463 free(chip->programmed);
464 os_close(chip->fd);
465 free(chip);
466 }
467
468 return 0;
469}
470
471static int sand_nand_probe(struct udevice *dev)
472{
473 struct sand_nand_priv *priv = dev_get_priv(dev);
474 struct sand_nand_chip *chip;
475 int ret, devnum = 0;
476 ofnode np;
477
478 INIT_LIST_HEAD(&priv->chips);
479
480 dev_for_each_subnode(np, dev) {
481 struct nand_chip *nand;
482 struct mtd_info *mtd;
483 u32 erasesize, oobsize, pagesize, pages;
484 u32 err_count, err_step_size;
485 off_t expected_size;
486 char filename[30];
487 fdt_addr_t cs;
488 const u8 *id, *onfi;
489 int id_len, onfi_len;
490
491 cs = ofnode_get_addr_size_index_notrans(np, 0, NULL);
492 if (cs == FDT_ADDR_T_NONE) {
493 dev_dbg(dev, "Invalid cs for chip %s\n",
494 ofnode_get_name(np));
495 ret = -ENOENT;
496 goto err;
497 }
498
499 id = ofnode_read_prop(np, "sandbox,id", &id_len);
500 if (!id) {
501 dev_dbg(dev, "No sandbox,id property for chip %s\n",
502 ofnode_get_name(np));
503 ret = -EINVAL;
504 goto err;
505 }
506
507 onfi = ofnode_read_prop(np, "sandbox,onfi", &onfi_len);
508 if (onfi && onfi_len != sizeof(struct nand_onfi_params)) {
509 dev_dbg(dev, "Invalid length %d for onfi params\n",
510 onfi_len);
511 ret = -EINVAL;
512 goto err;
513 }
514
515 ret = ofnode_read_u32(np, "sandbox,erasesize", &erasesize);
516 if (ret) {
517 dev_dbg(dev, "No sandbox,erasesize property for chip %s",
518 ofnode_get_name(np));
519 goto err;
520 }
521
522 ret = ofnode_read_u32(np, "sandbox,oobsize", &oobsize);
523 if (ret) {
524 dev_dbg(dev, "No sandbox,oobsize property for chip %s",
525 ofnode_get_name(np));
526 goto err;
527 }
528
529 ret = ofnode_read_u32(np, "sandbox,pagesize", &pagesize);
530 if (ret) {
531 dev_dbg(dev, "No sandbox,pagesize property for chip %s",
532 ofnode_get_name(np));
533 goto err;
534 }
535
536 ret = ofnode_read_u32(np, "sandbox,pages", &pages);
537 if (ret) {
538 dev_dbg(dev, "No sandbox,pages property for chip %s",
539 ofnode_get_name(np));
540 goto err;
541 }
542
543 ret = ofnode_read_u32(np, "sandbox,err-count", &err_count);
544 if (ret) {
545 dev_dbg(dev,
546 "No sandbox,err-count property for chip %s",
547 ofnode_get_name(np));
548 goto err;
549 }
550
551 ret = ofnode_read_u32(np, "sandbox,err-step-size",
552 &err_step_size);
553 if (ret) {
554 dev_dbg(dev,
555 "No sandbox,err-step-size property for chip %s",
556 ofnode_get_name(np));
557 goto err;
558 }
559
560 chip = calloc(sizeof(*chip), 1);
561 if (!chip) {
562 ret = -ENOMEM;
563 goto err;
564 }
565
566 chip->cs = cs;
567 chip->id = id;
568 chip->id_len = id_len;
569 chip->chunksize = pagesize + oobsize;
570 chip->pagesize = pagesize;
571 chip->pages = pages;
572 chip->pages_per_erase = erasesize / pagesize;
573 memset(chip->tmp, 0xff, chip->chunksize);
574
575 chip->err_count = err_count;
576 chip->err_step_bits = err_step_size * 8;
577 chip->err_steps = pagesize / err_step_size;
578
579 expected_size = (off_t)pages * chip->chunksize;
580 snprintf(filename, sizeof(filename),
581 "/tmp/u-boot.nand%d.XXXXXX", devnum);
582 chip->fd = os_mktemp(filename, expected_size);
583 if (chip->fd < 0) {
584 dev_dbg(dev, "Could not create temp file %s\n",
585 filename);
586 ret = chip->fd;
587 goto err_chip;
588 }
589
590 chip->programmed = calloc(sizeof(long),
591 BITS_TO_LONGS(pages));
592 if (!chip->programmed) {
593 ret = -ENOMEM;
594 goto err_fd;
595 }
596
597 if (onfi) {
598 memcpy(chip->onfi, onfi, onfi_len);
599 memcpy(chip->onfi + onfi_len, onfi, onfi_len);
600 memcpy(chip->onfi + 2 * onfi_len, onfi, onfi_len);
601 }
602
603 nand = &chip->nand;
8502b5bf 604 nand->options = spl_in_proper() ? 0 : NAND_SKIP_BBTSCAN;
bc8e8a4b
SA
605 nand->flash_node = np;
606 nand->dev_ready = sand_nand_dev_ready;
607 nand->cmdfunc = sand_nand_command;
608 nand->waitfunc = sand_nand_wait;
609 nand->select_chip = sand_nand_select_chip;
610 nand->read_byte = sand_nand_read_byte;
611 nand->read_word = sand_nand_read_word;
612 nand->read_buf = sand_nand_read_buf;
613 nand->write_buf = sand_nand_write_buf;
614 nand->ecc.options = NAND_ECC_GENERIC_ERASED_CHECK;
615
616 mtd = nand_to_mtd(nand);
617 mtd->dev = dev;
618
619 ret = nand_scan(mtd, CONFIG_SYS_NAND_MAX_CHIPS);
620 if (ret) {
621 dev_dbg(dev, "Could not scan chip %s: %d\n",
622 ofnode_get_name(np), ret);
623 goto err_prog;
624 }
625 chip->ecc_bits = nand->ecc.layout->eccbytes * 8 /
626 chip->err_steps;
627
628 ret = nand_register(devnum, mtd);
629 if (ret) {
630 dev_dbg(dev, "Could not register nand %d: %d\n", devnum,
631 ret);
632 goto err_prog;
633 }
634
635 if (!nand_chip)
636 nand_chip = nand;
637
638 list_add_tail(&chip->node, &priv->chips);
639 devnum++;
640 continue;
641
642err_prog:
643 free(chip->programmed);
644err_fd:
645 os_close(chip->fd);
646err_chip:
647 free(chip);
648 goto err;
649 }
650
651 return 0;
652
653err:
654 sand_nand_remove(dev);
655 return ret;
656}
657
658static const struct udevice_id sand_nand_ids[] = {
659 { .compatible = "sandbox,nand" },
660 { }
661};
662
663U_BOOT_DRIVER(sand_nand) = {
664 .name = "sand-nand",
665 .id = UCLASS_MTD,
666 .of_match = sand_nand_ids,
667 .probe = sand_nand_probe,
668 .remove = sand_nand_remove,
669 .priv_auto = sizeof(struct sand_nand_priv),
670};
671
672void board_nand_init(void)
673{
674 struct udevice *dev;
675 int err;
676
677 err = uclass_get_device_by_driver(UCLASS_MTD, DM_DRIVER_REF(sand_nand),
678 &dev);
679 if (err && err != -ENODEV)
680 log_info("Failed to get sandbox NAND: %d\n", err);
681}
8502b5bf
SA
682
683#if IS_ENABLED(CONFIG_SPL_BUILD) && IS_ENABLED(CONFIG_SPL_NAND_INIT)
684void nand_deselect(void)
685{
686 nand_chip->select_chip(nand_to_mtd(nand_chip), -1);
687}
688
689static int nand_is_bad_block(int block)
690{
691 struct mtd_info *mtd = nand_to_mtd(nand_chip);
692
693 return mtd_block_isbad(mtd, block << mtd->erasesize_shift);
694}
695
696static int nand_read_page(int block, int page, uchar *dst)
697{
698 struct mtd_info *mtd = nand_to_mtd(nand_chip);
699 loff_t ofs = ((loff_t)block << mtd->erasesize_shift) +
700 ((loff_t)page << mtd->writesize_shift);
701 size_t len = mtd->writesize;
702
703 return nand_read(mtd, ofs, &len, dst);
704}
705
706#include "nand_spl_loaders.c"
707#endif /* CONFIG_SPL_NAND_INIT */