2 * sheevaplug nand flash driver
4 * for now separate from (inferno's) os/port/flashnand.c because the flash
5 * seems newer, and has different commands, but that is nand-chip specific,
6 * not sheevaplug-specific. they should be merged in future.
8 * the sheevaplug has a hynix 4gbit flash chip: hy27uf084g2m.
9 * 2048 byte pages, with 64 spare bytes each; erase block size is 128k.
11 * it has a "glueless" interface, at 0xf9000000. that's the address
12 * of the data register. the command and address registers are those
13 * or'ed with 1 and 2 respectively.
15 * linux uses this layout for the nand flash (from address 0 onwards):
18 * 507mb for file system
20 * this is not so relevant here except for ecc. the first two areas
21 * (u-boot and kernel) are expected to have 4-bit ecc per 512 bytes
22 * (but calculated from last byte to first), bad erase blocks skipped.
23 * the file system area has 1-bit ecc per 256 bytes.
27 #include "../port/lib.h"
32 #include "../port/error.h"
34 #include "../port/flashif.h"
35 #include "../port/nandecc.h"
40 Nopage = ~0ul, /* cache is empty */
52 typedef struct Nandreg Nandreg;
53 typedef struct Nandtab Nandtab;
54 typedef struct Cache Cache;
56 struct Nandreg { /* hw registers */
59 uchar _pad0[0x70 - 0x20];
73 ulong pgsize; /* r->pagesize */
74 char *page; /* of pgsize bytes */
80 Readid = 0x90, /* needs 1 0-address write */
84 * needs 5 address writes followed by Readstart,
85 * Readstartcache or Restartcopy.
89 Readstartcache = 0x31,
91 /* after Readstartcache, to stop reading next pages */
94 /* needs 5 address writes, the data, and -start or -cache */
99 Copyback = 0x85, /* followed by Programstart */
101 /* 3 address writes for block followed by Erasestart */
107 Randomwritestart= 0xe0,
112 SIdle = 1<<5, /* doesn't seem to come on ever */
114 SNotprotected = 1<<7,
116 Srdymask = SReady, /* was SIdle|SReady */
119 Nandtab nandtab[] = {
120 {Hynix, Hy27UF084G2M, 512*MB, "Hy27UF084G2M"},
121 {Samsung, 0xdc, 512*MB, "Samsung 2Gb"},
127 nandcmd(Flash *f, uchar b)
129 uchar *p = (uchar *)((ulong)f->addr|1);
136 nandaddr(Flash *f, uchar b)
138 uchar *p = (uchar *)((ulong)f->addr|2);
147 return *(uchar *)f->addr;
151 nandreadn(Flash *f, uchar *buf, long n)
160 nandwrite(Flash *f, uchar b)
162 *(uchar *)f->addr = b;
167 nandwriten(Flash *f, uchar *buf, long n)
179 Nandreg *nand = (Nandreg*)soc.nand;
181 nand->ctl |= NandActCEBoot;
188 Nandreg *nand = (Nandreg*)soc.nand;
190 nand->ctl &= ~NandActCEBoot;
195 void mmuidmap(uintptr phys, int mbs);
198 findflash(Flash *f, uintptr pa, uchar *id4p)
202 uchar maker, device, id3, id4;
206 f->addr = (void *)pa;
208 /* make sure controller is idle */
214 nandcmd(f, Readstatus);
217 for (i = 10; i > 0 && !(sts & SReady); i--) {
220 nandcmd(f, Readstatus);
231 device = nandread(f);
239 for(i = 0; i < nelem(nandtab); i++) {
241 if(chip->vid == maker && chip->did == device)
248 flashat(Flash *f, uintptr pa)
250 return findflash(f, pa, nil) != nil;
259 static int blocksizes[4] = { 64*1024, 128*1024, 256*1024, 0 };
260 static int pagesizes[4] = { 1024, 2*1024, 0, 0 };
261 static int spares[2] = { 8, 16 }; /* per 512 bytes */
266 chip = findflash(f, (uintptr)f->addr, &id4);
270 f->devid = chip->did;
271 f->size = chip->size;
276 r->pagesize = pagesizes[id4 & MASK(2)];
277 r->erasesize = blocksizes[(id4 >> 4) & MASK(2)];
278 if (r->pagesize == 0 || r->erasesize == 0) {
279 iprint("flashkw: bogus flash sizes\n");
282 r->n = f->size / r->erasesize;
285 assert(ispow2(r->pagesize));
286 r->pageshift = log2(r->pagesize);
287 assert(ispow2(r->erasesize));
288 r->eraseshift = log2(r->erasesize);
289 assert(r->eraseshift >= r->pageshift);
290 if (cache.page == nil) {
291 cache.pgsize = r->pagesize;
292 cache.page = smalloc(r->pagesize);
295 r->spares = r->pagesize / 512 * spares[(id4 >> 2) & 1];
296 print("#F0: kwnand: %s %,lud bytes pagesize %lud erasesize %,lud"
297 " spares per page %lud\n", chip->name, f->size, r->pagesize,
298 r->erasesize, r->spares);
309 nandcmd(f, Readstatus);
310 for(cnt = 100; cnt > 0 && (nandread(f) & Srdymask) != Srdymask;
313 nandcmd(f, Readstatus);
315 if((sts & Srdymask) == Srdymask)
317 print("flashkw: flash ctlr busy, sts %#ux: resetting\n", sts);
325 erasezone(Flash *f, Flashregion *r, ulong offset)
332 print("flashkw: erasezone: offset %#lux, region nblocks %d,"
333 " start %#lux, end %#lux\n", offset, r->n, r->start,
335 print(" erasesize %lud, pagesize %lud\n",
336 r->erasesize, r->pagesize);
338 assert(r->erasesize != 0);
339 if(offset & (r->erasesize - 1)) {
340 print("flashkw: erase offset %lud not block aligned\n", offset);
343 page = offset >> r->pageshift;
344 block = page >> (r->eraseshift - r->pageshift);
346 print("flashkw: erase: block %#lux\n", block);
348 /* make sure controller is idle */
349 if(ctlrwait(f) < 0) {
350 print("flashkw: erase: flash busy\n");
357 nandaddr(f, page>>0);
358 nandaddr(f, page>>8);
359 nandaddr(f, page>>16);
360 nandcmd(f, Erasestart);
362 /* invalidate cache on any erasure (slight overkill) */
363 cache.pageno = Nopage;
365 /* have to wait until flash is done. typically ~2ms */
367 nandcmd(f, Readstatus);
368 for(i = 0; i < 100; i++) {
373 print("flashkw: erase: failed, block %#lux\n",
381 print("flashkw: erase timeout, block %#lux\n", block);
387 flcachepage(Flash *f, ulong page, uchar *buf)
389 Flashregion *r = &f->regions[0];
391 assert(cache.pgsize == r->pagesize);
394 /* permit i/o directly to or from the cache */
395 if (buf != (uchar *)cache.page)
396 memmove(cache.page, buf, cache.pgsize);
400 write1page(Flash *f, ulong offset, void *buf)
406 Flashregion *r = &f->regions[0];
410 oob = smalloc(r->spares);
412 page = offset >> r->pageshift;
414 print("flashkw: write nand offset %#lux page %#lux\n",
417 if(offset & (r->pagesize - 1)) {
418 print("flashkw: write offset %lud not page aligned\n", offset);
423 memset(oob, 0xff, r->spares);
424 assert(r->spares >= 24);
425 eccp = oob + r->spares - 24;
426 for(i = 0; i < r->pagesize / 256; i++) {
434 if(ctlrwait(f) < 0) {
435 print("flashkw: write: nand not ready & idle\n");
439 /* write, only whole pages for now, no sub-pages */
444 nandaddr(f, page>>0);
445 nandaddr(f, page>>8);
446 nandaddr(f, page>>16);
447 nandwriten(f, buf, r->pagesize);
448 nandwriten(f, oob, r->spares);
449 nandcmd(f, Programstart);
452 nandcmd(f, Readstatus);
453 for(i = 0; i < 100; i++) {
458 print("flashkw: write failed, page %#lux\n",
468 flcachepage(f, page, buf);
469 print("flashkw: write timeout for page %#lux\n", page);
474 read1page(Flash *f, ulong offset, void *buf)
479 Flashregion *r = &f->regions[0];
483 oob = smalloc(r->spares);
485 assert(r->pagesize != 0);
486 addr = offset & (r->pagesize - 1);
487 page = offset >> r->pageshift;
489 print("flashkw: read1page: read addr %#lux:"
490 " must read aligned page\n", addr);
494 /* satisfy request from cache if possible */
495 if (f == cache.flif && page == cache.pageno &&
496 r->pagesize == cache.pgsize) {
497 memmove(buf, cache.page, r->pagesize);
502 print("flashkw: read offset %#lux addr %#lux page %#lux\n",
507 nandaddr(f, addr>>0);
508 nandaddr(f, addr>>8);
509 nandaddr(f, page>>0);
510 nandaddr(f, page>>8);
511 nandaddr(f, page>>16);
512 nandcmd(f, Readstart);
516 nandreadn(f, buf, r->pagesize);
517 nandreadn(f, oob, r->spares);
521 /* verify/correct data. last 8*3 bytes is ecc, per 256 bytes. */
523 assert(r->spares >= 24);
524 eccp = oob + r->spares - 24;
525 for(i = 0; i < r->pagesize / 256; i++) {
526 w = eccp[0] << 8 | eccp[1] << 0 | eccp[2] << 16;
528 switch(nandecccorrect(p, nandecc(p), &w, 1)) {
529 case NandEccErrorBad:
530 print("(page %d)\n", i);
532 case NandEccErrorOneBit:
533 case NandEccErrorOneBitInEcc:
534 print("(page %d)\n", i);
536 case NandEccErrorGood:
542 flcachepage(f, page, buf);
547 * read a page at offset into cache, copy fragment from buf into it
548 * at pagoff, and rewrite that page.
551 rewrite(Flash *f, ulong offset, ulong pagoff, void *buf, ulong size)
553 if (read1page(f, offset, cache.page) < 0)
555 memmove(&cache.page[pagoff], buf, size);
556 return write1page(f, offset, cache.page);
559 /* there are no alignment constraints on offset, buf, nor n */
561 write(Flash *f, ulong offset, void *buf, long n)
563 uint un, frag, pagoff;
566 Flashregion *r = &f->regions[0];
569 panic("flashkw: write: non-positive count %ld", n);
571 assert(r->pagesize != 0);
572 pgsize = r->pagesize;
574 /* if a partial first page exists, update the first page with it. */
576 pagoff = offset % pgsize;
578 frag = pgsize - pagoff;
579 if (frag > un) /* might not extend to end of page */
581 if (rewrite(f, offset - pagoff, pagoff, p, frag) < 0)
588 /* copy whole pages */
589 while (un >= pgsize) {
590 if (write1page(f, offset, p) < 0)
597 /* if a partial last page exists, update the last page with it. */
599 return rewrite(f, offset, 0, p, un);
603 /* there are no alignment constraints on offset, buf, nor n */
605 read(Flash *f, ulong offset, void *buf, long n)
607 uint un, frag, pagoff;
610 Flashregion *r = &f->regions[0];
613 panic("flashkw: read: non-positive count %ld", n);
615 assert(r->pagesize != 0);
616 pgsize = r->pagesize;
618 /* if partial 1st page, read it into cache & copy fragment to buf */
620 pagoff = offset % pgsize;
622 frag = pgsize - pagoff;
623 if (frag > un) /* might not extend to end of page */
625 if (read1page(f, offset - pagoff, cache.page) < 0)
628 memmove(p, &cache.page[pagoff], frag);
633 /* copy whole pages */
634 while (un >= pgsize) {
635 if (read1page(f, offset, p) < 0)
642 /* if partial last page, read into cache & copy initial fragment to buf */
644 if (read1page(f, offset, cache.page) < 0)
646 memmove(p, cache.page, un);
659 f->erasezone = erasezone;
663 cache.pageno = Nopage;
670 addflashcard("nand", reset);