]> git.ipfire.org Git - people/ms/u-boot.git/blame - common/cmd_doc.c
Patch by Kenneth Johansson, 30 Jun 2003:
[people/ms/u-boot.git] / common / cmd_doc.c
CommitLineData
c609719b
WD
1/*
2 * Driver for Disk-On-Chip 2000 and Millennium
3 * (c) 1999 Machine Vision Holdings, Inc.
4 * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
5 *
6 * $Id: doc2000.c,v 1.46 2001/10/02 15:05:13 dwmw2 Exp $
7 */
8
9#include <common.h>
10#include <config.h>
11#include <command.h>
12#include <malloc.h>
13#include <asm/io.h>
14
15#ifdef CONFIG_SHOW_BOOT_PROGRESS
16# include <status_led.h>
17# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg)
18#else
19# define SHOW_BOOT_PROGRESS(arg)
20#endif
21
22#if (CONFIG_COMMANDS & CFG_CMD_DOC)
23
ac6dbb85 24#include <linux/mtd/nftl.h>
c609719b
WD
25#include <linux/mtd/nand.h>
26#include <linux/mtd/nand_ids.h>
27#include <linux/mtd/doc2000.h>
28#include <linux/mtd/nftl.h>
29
30#ifdef CFG_DOC_SUPPORT_2000
31#define DoC_is_2000(doc) (doc->ChipID == DOC_ChipID_Doc2k)
32#else
33#define DoC_is_2000(doc) (0)
34#endif
35
36#ifdef CFG_DOC_SUPPORT_MILLENNIUM
37#define DoC_is_Millennium(doc) (doc->ChipID == DOC_ChipID_DocMil)
38#else
39#define DoC_is_Millennium(doc) (0)
40#endif
41
42/* CFG_DOC_PASSIVE_PROBE:
43 In order to ensure that the BIOS checksum is correct at boot time, and
44 hence that the onboard BIOS extension gets executed, the DiskOnChip
45 goes into reset mode when it is read sequentially: all registers
46 return 0xff until the chip is woken up again by writing to the
47 DOCControl register.
48
49 Unfortunately, this means that the probe for the DiskOnChip is unsafe,
50 because one of the first things it does is write to where it thinks
51 the DOCControl register should be - which may well be shared memory
52 for another device. I've had machines which lock up when this is
53 attempted. Hence the possibility to do a passive probe, which will fail
54 to detect a chip in reset mode, but is at least guaranteed not to lock
55 the machine.
56
57 If you have this problem, uncomment the following line:
58#define CFG_DOC_PASSIVE_PROBE
59*/
60
61#undef DOC_DEBUG
62#undef ECC_DEBUG
63#undef PSYCHO_DEBUG
64#undef NFTL_DEBUG
65
66static struct DiskOnChip doc_dev_desc[CFG_MAX_DOC_DEVICE];
67
68/* Current DOC Device */
69static int curr_device = -1;
70
71/* ------------------------------------------------------------------------- */
72
73int do_doc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
74{
75 int rcode = 0;
76
77 switch (argc) {
78 case 0:
79 case 1:
80 printf ("Usage:\n%s\n", cmdtp->usage);
81 return 1;
82 case 2:
8bde7f77 83 if (strcmp(argv[1],"info") == 0) {
c609719b
WD
84 int i;
85
86 putc ('\n');
87
88 for (i=0; i<CFG_MAX_DOC_DEVICE; ++i) {
89 if(doc_dev_desc[i].ChipID == DOC_ChipID_UNKNOWN)
90 continue; /* list only known devices */
91 printf ("Device %d: ", i);
92 doc_print(&doc_dev_desc[i]);
93 }
94 return 0;
95
96 } else if (strcmp(argv[1],"device") == 0) {
97 if ((curr_device < 0) || (curr_device >= CFG_MAX_DOC_DEVICE)) {
98 puts ("\nno devices available\n");
99 return 1;
100 }
101 printf ("\nDevice %d: ", curr_device);
102 doc_print(&doc_dev_desc[curr_device]);
103 return 0;
104 }
105 printf ("Usage:\n%s\n", cmdtp->usage);
106 return 1;
107 case 3:
108 if (strcmp(argv[1],"device") == 0) {
109 int dev = (int)simple_strtoul(argv[2], NULL, 10);
110
111 printf ("\nDevice %d: ", dev);
112 if (dev >= CFG_MAX_DOC_DEVICE) {
113 puts ("unknown device\n");
114 return 1;
115 }
116 doc_print(&doc_dev_desc[dev]);
117 /*doc_print (dev);*/
118
119 if (doc_dev_desc[dev].ChipID == DOC_ChipID_UNKNOWN) {
120 return 1;
121 }
122
123 curr_device = dev;
124
125 puts ("... is now current device\n");
126
127 return 0;
128 }
129
130 printf ("Usage:\n%s\n", cmdtp->usage);
131 return 1;
132 default:
133 /* at least 4 args */
134
135 if (strcmp(argv[1],"read") == 0 || strcmp(argv[1],"write") == 0) {
136 ulong addr = simple_strtoul(argv[2], NULL, 16);
137 ulong off = simple_strtoul(argv[3], NULL, 16);
138 ulong size = simple_strtoul(argv[4], NULL, 16);
139 int cmd = (strcmp(argv[1],"read") == 0);
140 int ret, total;
141
142 printf ("\nDOC %s: device %d offset %ld, size %ld ... ",
143 cmd ? "read" : "write", curr_device, off, size);
144
145 ret = doc_rw(doc_dev_desc + curr_device, cmd, off, size,
146 &total, (u_char*)addr);
147
148 printf ("%d bytes %s: %s\n", total, cmd ? "read" : "write",
149 ret ? "ERROR" : "OK");
150
151 return ret;
152 } else if (strcmp(argv[1],"erase") == 0) {
153 ulong off = simple_strtoul(argv[2], NULL, 16);
154 ulong size = simple_strtoul(argv[3], NULL, 16);
155 int ret;
156
157 printf ("\nDOC erase: device %d offset %ld, size %ld ... ",
158 curr_device, off, size);
159
160 ret = doc_erase (doc_dev_desc + curr_device, off, size);
161
162 printf("%s\n", ret ? "ERROR" : "OK");
163
164 return ret;
165 } else {
166 printf ("Usage:\n%s\n", cmdtp->usage);
167 rcode = 1;
168 }
169
170 return rcode;
171 }
172}
0d498393
WD
173U_BOOT_CMD(
174 doc, 5, 1, do_doc,
8bde7f77
WD
175 "doc - Disk-On-Chip sub-system\n",
176 "info - show available DOC devices\n"
177 "doc device [dev] - show or set current device\n"
178 "doc read addr off size\n"
179 "doc write addr off size - read/write `size'"
180 " bytes starting at offset `off'\n"
181 " to/from memory address `addr'\n"
182 "doc erase off size - erase `size' bytes of DOC from offset `off'\n"
183);
c609719b
WD
184
185int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
186{
187 char *boot_device = NULL;
188 char *ep;
189 int dev;
190 ulong cnt;
191 ulong addr;
192 ulong offset = 0;
193 image_header_t *hdr;
194 int rcode = 0;
195
196 switch (argc) {
197 case 1:
198 addr = CFG_LOAD_ADDR;
199 boot_device = getenv ("bootdevice");
200 break;
201 case 2:
202 addr = simple_strtoul(argv[1], NULL, 16);
203 boot_device = getenv ("bootdevice");
204 break;
205 case 3:
206 addr = simple_strtoul(argv[1], NULL, 16);
207 boot_device = argv[2];
208 break;
209 case 4:
210 addr = simple_strtoul(argv[1], NULL, 16);
211 boot_device = argv[2];
212 offset = simple_strtoul(argv[3], NULL, 16);
213 break;
214 default:
215 printf ("Usage:\n%s\n", cmdtp->usage);
216 SHOW_BOOT_PROGRESS (-1);
217 return 1;
218 }
219
220 if (!boot_device) {
221 puts ("\n** No boot device **\n");
222 SHOW_BOOT_PROGRESS (-1);
223 return 1;
224 }
225
226 dev = simple_strtoul(boot_device, &ep, 16);
227
228 if ((dev >= CFG_MAX_DOC_DEVICE) ||
229 (doc_dev_desc[dev].ChipID == DOC_ChipID_UNKNOWN)) {
230 printf ("\n** Device %d not available\n", dev);
231 SHOW_BOOT_PROGRESS (-1);
232 return 1;
233 }
234
235 printf ("\nLoading from device %d: %s at 0x%lX (offset 0x%lX)\n",
236 dev, doc_dev_desc[dev].name, doc_dev_desc[dev].physadr,
237 offset);
238
239 if (doc_rw (doc_dev_desc + dev, 1, offset,
240 SECTORSIZE, NULL, (u_char *)addr)) {
241 printf ("** Read error on %d\n", dev);
242 SHOW_BOOT_PROGRESS (-1);
243 return 1;
244 }
245
246 hdr = (image_header_t *)addr;
247
248 if (hdr->ih_magic == IH_MAGIC) {
249
250 print_image_hdr (hdr);
251
252 cnt = (hdr->ih_size + sizeof(image_header_t));
253 cnt -= SECTORSIZE;
254 } else {
255 puts ("\n** Bad Magic Number **\n");
256 SHOW_BOOT_PROGRESS (-1);
257 return 1;
258 }
259
260 if (doc_rw (doc_dev_desc + dev, 1, offset + SECTORSIZE, cnt,
261 NULL, (u_char *)(addr+SECTORSIZE))) {
262 printf ("** Read error on %d\n", dev);
263 SHOW_BOOT_PROGRESS (-1);
264 return 1;
265 }
266
267 /* Loading ok, update default load address */
268
269 load_addr = addr;
270
271 /* Check if we should attempt an auto-start */
272 if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) {
273 char *local_args[2];
274 extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
275
276 local_args[0] = argv[0];
277 local_args[1] = NULL;
278
279 printf ("Automatic boot of image at addr 0x%08lX ...\n", addr);
280
281 do_bootm (cmdtp, 0, 1, local_args);
282 rcode = 1;
283 }
284 return rcode;
285}
286
0d498393
WD
287U_BOOT_CMD(
288 docboot, 4, 1, do_docboot,
8bde7f77
WD
289 "docboot - boot from DOC device\n",
290 "loadAddr dev\n"
291);
292
c609719b
WD
293int doc_rw (struct DiskOnChip* this, int cmd,
294 loff_t from, size_t len,
295 size_t * retlen, u_char * buf)
296{
297 int noecc, ret = 0, n, total = 0;
298 char eccbuf[6];
299
300 while(len) {
301 /* The ECC will not be calculated correctly if
302 less than 512 is written or read */
303 noecc = (from != (from | 0x1ff) + 1) || (len < 0x200);
304
305 if (cmd)
306 ret = doc_read_ecc(this, from, len,
307 &n, (u_char*)buf,
308 noecc ? NULL : eccbuf);
309 else
310 ret = doc_write_ecc(this, from, len,
311 &n, (u_char*)buf,
312 noecc ? NULL : eccbuf);
313
314 if (ret)
315 break;
316
317 from += n;
318 buf += n;
319 total += n;
320 len -= n;
321 }
322
323 if (retlen)
324 *retlen = total;
325
326 return ret;
327}
328
329void doc_print(struct DiskOnChip *this) {
330 printf("%s at 0x%lX,\n"
331 "\t %d chip%s %s, size %d MB, \n"
332 "\t total size %ld MB, sector size %ld kB\n",
333 this->name, this->physadr, this->numchips,
334 this->numchips>1 ? "s" : "", this->chips_name,
335 1 << (this->chipshift - 20),
336 this->totlen >> 20, this->erasesize >> 10);
337
338 if (this->nftl_found) {
339 struct NFTLrecord *nftl = &this->nftl;
340 unsigned long bin_size, flash_size;
341
342 bin_size = nftl->nb_boot_blocks * this->erasesize;
343 flash_size = (nftl->nb_blocks - nftl->nb_boot_blocks) * this->erasesize;
344
345 printf("\t NFTL boot record:\n"
346 "\t Binary partition: size %ld%s\n"
347 "\t Flash disk partition: size %ld%s, offset 0x%lx\n",
348 bin_size > (1 << 20) ? bin_size >> 20 : bin_size >> 10,
349 bin_size > (1 << 20) ? "MB" : "kB",
350 flash_size > (1 << 20) ? flash_size >> 20 : flash_size >> 10,
351 flash_size > (1 << 20) ? "MB" : "kB", bin_size);
352 } else {
353 puts ("\t No NFTL boot record found.\n");
354 }
355}
356
357/* ------------------------------------------------------------------------- */
358
359/* This function is needed to avoid calls of the __ashrdi3 function. */
360static int shr(int val, int shift) {
361 return val >> shift;
362}
363
364/* Perform the required delay cycles by reading from the appropriate register */
365static void DoC_Delay(struct DiskOnChip *doc, unsigned short cycles)
366{
367 volatile char dummy;
368 int i;
369
370 for (i = 0; i < cycles; i++) {
371 if (DoC_is_Millennium(doc))
372 dummy = ReadDOC(doc->virtadr, NOP);
373 else
374 dummy = ReadDOC(doc->virtadr, DOCStatus);
375 }
376
377}
378
379/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
380static int _DoC_WaitReady(struct DiskOnChip *doc)
381{
382 unsigned long docptr = doc->virtadr;
383 unsigned long start = get_timer(0);
384
385#ifdef PSYCHO_DEBUG
386 puts ("_DoC_WaitReady called for out-of-line wait\n");
387#endif
388
389 /* Out-of-line routine to wait for chip response */
390 while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
391#ifdef CFG_DOC_SHORT_TIMEOUT
392 /* it seems that after a certain time the DoC deasserts
393 * the CDSN_CTRL_FR_B although it is not ready...
394 * using a short timout solve this (timer increments every ms) */
395 if (get_timer(start) > 10) {
396 return DOC_ETIMEOUT;
397 }
398#else
399 if (get_timer(start) > 10 * 1000) {
400 puts ("_DoC_WaitReady timed out.\n");
401 return DOC_ETIMEOUT;
402 }
403#endif
404 udelay(1);
8bde7f77 405 }
c609719b
WD
406
407 return 0;
408}
409
410static int DoC_WaitReady(struct DiskOnChip *doc)
411{
412 unsigned long docptr = doc->virtadr;
413 /* This is inline, to optimise the common case, where it's ready instantly */
414 int ret = 0;
415
416 /* 4 read form NOP register should be issued in prior to the read from CDSNControl
417 see Software Requirement 11.4 item 2. */
418 DoC_Delay(doc, 4);
419
420 if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B))
421 /* Call the out-of-line routine to wait */
422 ret = _DoC_WaitReady(doc);
423
424 /* issue 2 read from NOP register after reading from CDSNControl register
425 see Software Requirement 11.4 item 2. */
426 DoC_Delay(doc, 2);
427
428 return ret;
429}
430
431/* DoC_Command: Send a flash command to the flash chip through the CDSN Slow IO register to
432 bypass the internal pipeline. Each of 4 delay cycles (read from the NOP register) is
433 required after writing to CDSN Control register, see Software Requirement 11.4 item 3. */
434
435static inline int DoC_Command(struct DiskOnChip *doc, unsigned char command,
436 unsigned char xtraflags)
437{
438 unsigned long docptr = doc->virtadr;
439
440 if (DoC_is_2000(doc))
441 xtraflags |= CDSN_CTRL_FLASH_IO;
442
443 /* Assert the CLE (Command Latch Enable) line to the flash chip */
444 WriteDOC(xtraflags | CDSN_CTRL_CLE | CDSN_CTRL_CE, docptr, CDSNControl);
445 DoC_Delay(doc, 4); /* Software requirement 11.4.3 for Millennium */
446
447 if (DoC_is_Millennium(doc))
448 WriteDOC(command, docptr, CDSNSlowIO);
449
450 /* Send the command */
451 WriteDOC_(command, docptr, doc->ioreg);
452
453 /* Lower the CLE line */
454 WriteDOC(xtraflags | CDSN_CTRL_CE, docptr, CDSNControl);
455 DoC_Delay(doc, 4); /* Software requirement 11.4.3 for Millennium */
456
457 /* Wait for the chip to respond - Software requirement 11.4.1 (extended for any command) */
458 return DoC_WaitReady(doc);
459}
460
461/* DoC_Address: Set the current address for the flash chip through the CDSN Slow IO register to
462 bypass the internal pipeline. Each of 4 delay cycles (read from the NOP register) is
463 required after writing to CDSN Control register, see Software Requirement 11.4 item 3. */
464
465static int DoC_Address(struct DiskOnChip *doc, int numbytes, unsigned long ofs,
466 unsigned char xtraflags1, unsigned char xtraflags2)
467{
468 unsigned long docptr;
469 int i;
470
471 docptr = doc->virtadr;
472
473 if (DoC_is_2000(doc))
474 xtraflags1 |= CDSN_CTRL_FLASH_IO;
475
476 /* Assert the ALE (Address Latch Enable) line to the flash chip */
477 WriteDOC(xtraflags1 | CDSN_CTRL_ALE | CDSN_CTRL_CE, docptr, CDSNControl);
478
479 DoC_Delay(doc, 4); /* Software requirement 11.4.3 for Millennium */
480
481 /* Send the address */
482 /* Devices with 256-byte page are addressed as:
483 Column (bits 0-7), Page (bits 8-15, 16-23, 24-31)
484 * there is no device on the market with page256
485 and more than 24 bits.
486 Devices with 512-byte page are addressed as:
487 Column (bits 0-7), Page (bits 9-16, 17-24, 25-31)
488 * 25-31 is sent only if the chip support it.
489 * bit 8 changes the read command to be sent
490 (NAND_CMD_READ0 or NAND_CMD_READ1).
491 */
492
493 if (numbytes == ADDR_COLUMN || numbytes == ADDR_COLUMN_PAGE) {
494 if (DoC_is_Millennium(doc))
495 WriteDOC(ofs & 0xff, docptr, CDSNSlowIO);
496 WriteDOC_(ofs & 0xff, docptr, doc->ioreg);
497 }
498
499 if (doc->page256) {
500 ofs = ofs >> 8;
501 } else {
502 ofs = ofs >> 9;
503 }
504
505 if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE) {
506 for (i = 0; i < doc->pageadrlen; i++, ofs = ofs >> 8) {
507 if (DoC_is_Millennium(doc))
508 WriteDOC(ofs & 0xff, docptr, CDSNSlowIO);
509 WriteDOC_(ofs & 0xff, docptr, doc->ioreg);
510 }
511 }
512
513 DoC_Delay(doc, 2); /* Needed for some slow flash chips. mf. */
514
515 /* FIXME: The SlowIO's for millennium could be replaced by
516 a single WritePipeTerm here. mf. */
517
518 /* Lower the ALE line */
519 WriteDOC(xtraflags1 | xtraflags2 | CDSN_CTRL_CE, docptr,
520 CDSNControl);
521
522 DoC_Delay(doc, 4); /* Software requirement 11.4.3 for Millennium */
523
524 /* Wait for the chip to respond - Software requirement 11.4.1 */
525 return DoC_WaitReady(doc);
526}
527
528/* Read a buffer from DoC, taking care of Millennium odditys */
529static void DoC_ReadBuf(struct DiskOnChip *doc, u_char * buf, int len)
530{
531 volatile int dummy;
532 int modulus = 0xffff;
533 unsigned long docptr;
534 int i;
535
536 docptr = doc->virtadr;
537
538 if (len <= 0)
539 return;
540
541 if (DoC_is_Millennium(doc)) {
542 /* Read the data via the internal pipeline through CDSN IO register,
543 see Pipelined Read Operations 11.3 */
544 dummy = ReadDOC(docptr, ReadPipeInit);
545
546 /* Millennium should use the LastDataRead register - Pipeline Reads */
547 len--;
548
549 /* This is needed for correctly ECC calculation */
550 modulus = 0xff;
551 }
552
553 for (i = 0; i < len; i++)
554 buf[i] = ReadDOC_(docptr, doc->ioreg + (i & modulus));
555
556 if (DoC_is_Millennium(doc)) {
557 buf[i] = ReadDOC(docptr, LastDataRead);
558 }
559}
560
561/* Write a buffer to DoC, taking care of Millennium odditys */
562static void DoC_WriteBuf(struct DiskOnChip *doc, const u_char * buf, int len)
563{
564 unsigned long docptr;
565 int i;
566
567 docptr = doc->virtadr;
568
569 if (len <= 0)
570 return;
571
572 for (i = 0; i < len; i++)
573 WriteDOC_(buf[i], docptr, doc->ioreg + i);
574
575 if (DoC_is_Millennium(doc)) {
576 WriteDOC(0x00, docptr, WritePipeTerm);
577 }
578}
579
580
581/* DoC_SelectChip: Select a given flash chip within the current floor */
582
583static inline int DoC_SelectChip(struct DiskOnChip *doc, int chip)
584{
585 unsigned long docptr = doc->virtadr;
586
587 /* Software requirement 11.4.4 before writing DeviceSelect */
588 /* Deassert the CE line to eliminate glitches on the FCE# outputs */
589 WriteDOC(CDSN_CTRL_WP, docptr, CDSNControl);
590 DoC_Delay(doc, 4); /* Software requirement 11.4.3 for Millennium */
591
592 /* Select the individual flash chip requested */
593 WriteDOC(chip, docptr, CDSNDeviceSelect);
594 DoC_Delay(doc, 4);
595
596 /* Reassert the CE line */
597 WriteDOC(CDSN_CTRL_CE | CDSN_CTRL_FLASH_IO | CDSN_CTRL_WP, docptr,
598 CDSNControl);
599 DoC_Delay(doc, 4); /* Software requirement 11.4.3 for Millennium */
600
601 /* Wait for it to be ready */
602 return DoC_WaitReady(doc);
603}
604
605/* DoC_SelectFloor: Select a given floor (bank of flash chips) */
606
607static inline int DoC_SelectFloor(struct DiskOnChip *doc, int floor)
608{
609 unsigned long docptr = doc->virtadr;
610
611 /* Select the floor (bank) of chips required */
612 WriteDOC(floor, docptr, FloorSelect);
613
614 /* Wait for the chip to be ready */
615 return DoC_WaitReady(doc);
616}
617
618/* DoC_IdentChip: Identify a given NAND chip given {floor,chip} */
619
620static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
621{
622 int mfr, id, i;
623 volatile char dummy;
624
625 /* Page in the required floor/chip */
626 DoC_SelectFloor(doc, floor);
627 DoC_SelectChip(doc, chip);
628
629 /* Reset the chip */
630 if (DoC_Command(doc, NAND_CMD_RESET, CDSN_CTRL_WP)) {
631#ifdef DOC_DEBUG
632 printf("DoC_Command (reset) for %d,%d returned true\n",
633 floor, chip);
634#endif
635 return 0;
636 }
637
638
639 /* Read the NAND chip ID: 1. Send ReadID command */
640 if (DoC_Command(doc, NAND_CMD_READID, CDSN_CTRL_WP)) {
641#ifdef DOC_DEBUG
642 printf("DoC_Command (ReadID) for %d,%d returned true\n",
643 floor, chip);
644#endif
645 return 0;
646 }
647
648 /* Read the NAND chip ID: 2. Send address byte zero */
649 DoC_Address(doc, ADDR_COLUMN, 0, CDSN_CTRL_WP, 0);
650
651 /* Read the manufacturer and device id codes from the device */
652
653 /* CDSN Slow IO register see Software Requirement 11.4 item 5. */
654 dummy = ReadDOC(doc->virtadr, CDSNSlowIO);
655 DoC_Delay(doc, 2);
656 mfr = ReadDOC_(doc->virtadr, doc->ioreg);
657
658 /* CDSN Slow IO register see Software Requirement 11.4 item 5. */
659 dummy = ReadDOC(doc->virtadr, CDSNSlowIO);
660 DoC_Delay(doc, 2);
661 id = ReadDOC_(doc->virtadr, doc->ioreg);
662
663 /* No response - return failure */
664 if (mfr == 0xff || mfr == 0)
665 return 0;
666
667 /* Check it's the same as the first chip we identified.
668 * M-Systems say that any given DiskOnChip device should only
669 * contain _one_ type of flash part, although that's not a
670 * hardware restriction. */
671 if (doc->mfr) {
672 if (doc->mfr == mfr && doc->id == id)
673 return 1; /* This is another the same the first */
674 else
675 printf("Flash chip at floor %d, chip %d is different:\n",
676 floor, chip);
677 }
678
679 /* Print and store the manufacturer and ID codes. */
680 for (i = 0; nand_flash_ids[i].name != NULL; i++) {
681 if (mfr == nand_flash_ids[i].manufacture_id &&
682 id == nand_flash_ids[i].model_id) {
683#ifdef DOC_DEBUG
684 printf("Flash chip found: Manufacturer ID: %2.2X, "
685 "Chip ID: %2.2X (%s)\n", mfr, id,
686 nand_flash_ids[i].name);
687#endif
688 if (!doc->mfr) {
689 doc->mfr = mfr;
690 doc->id = id;
691 doc->chipshift =
692 nand_flash_ids[i].chipshift;
693 doc->page256 = nand_flash_ids[i].page256;
694 doc->pageadrlen =
695 nand_flash_ids[i].pageadrlen;
696 doc->erasesize =
697 nand_flash_ids[i].erasesize;
698 doc->chips_name =
699 nand_flash_ids[i].name;
700 return 1;
701 }
702 return 0;
703 }
704 }
705
706
707#ifdef DOC_DEBUG
708 /* We haven't fully identified the chip. Print as much as we know. */
709 printf("Unknown flash chip found: %2.2X %2.2X\n",
710 id, mfr);
711#endif
712
713 return 0;
714}
715
716/* DoC_ScanChips: Find all NAND chips present in a DiskOnChip, and identify them */
717
718static void DoC_ScanChips(struct DiskOnChip *this)
719{
720 int floor, chip;
721 int numchips[MAX_FLOORS];
722 int maxchips = MAX_CHIPS;
723 int ret = 1;
724
725 this->numchips = 0;
726 this->mfr = 0;
727 this->id = 0;
728
729 if (DoC_is_Millennium(this))
730 maxchips = MAX_CHIPS_MIL;
731
732 /* For each floor, find the number of valid chips it contains */
733 for (floor = 0; floor < MAX_FLOORS; floor++) {
734 ret = 1;
735 numchips[floor] = 0;
736 for (chip = 0; chip < maxchips && ret != 0; chip++) {
737
738 ret = DoC_IdentChip(this, floor, chip);
739 if (ret) {
740 numchips[floor]++;
741 this->numchips++;
742 }
743 }
744 }
745
746 /* If there are none at all that we recognise, bail */
747 if (!this->numchips) {
748 puts ("No flash chips recognised.\n");
749 return;
750 }
751
752 /* Allocate an array to hold the information for each chip */
753 this->chips = malloc(sizeof(struct Nand) * this->numchips);
754 if (!this->chips) {
755 puts ("No memory for allocating chip info structures\n");
756 return;
757 }
758
759 ret = 0;
760
761 /* Fill out the chip array with {floor, chipno} for each
762 * detected chip in the device. */
763 for (floor = 0; floor < MAX_FLOORS; floor++) {
764 for (chip = 0; chip < numchips[floor]; chip++) {
765 this->chips[ret].floor = floor;
766 this->chips[ret].chip = chip;
767 this->chips[ret].curadr = 0;
768 this->chips[ret].curmode = 0x50;
769 ret++;
770 }
771 }
772
773 /* Calculate and print the total size of the device */
774 this->totlen = this->numchips * (1 << this->chipshift);
775
776#ifdef DOC_DEBUG
777 printf("%d flash chips found. Total DiskOnChip size: %ld MB\n",
778 this->numchips, this->totlen >> 20);
779#endif
780}
781
782/* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the
783 * various device information of the NFTL partition and Bad Unit Table. Update
784 * the ReplUnitTable[] table accroding to the Bad Unit Table. ReplUnitTable[]
785 * is used for management of Erase Unit in other routines in nftl.c and nftlmount.c
786 */
787static int find_boot_record(struct NFTLrecord *nftl)
788{
789 struct nftl_uci1 h1;
790 struct nftl_oob oob;
791 unsigned int block, boot_record_count = 0;
792 int retlen;
793 u8 buf[SECTORSIZE];
794 struct NFTLMediaHeader *mh = &nftl->MediaHdr;
795 unsigned int i;
796
797 nftl->MediaUnit = BLOCK_NIL;
798 nftl->SpareMediaUnit = BLOCK_NIL;
799
800 /* search for a valid boot record */
801 for (block = 0; block < nftl->nb_blocks; block++) {
802 int ret;
803
804 /* Check for ANAND header first. Then can whinge if it's found but later
805 checks fail */
806 if ((ret = doc_read_ecc(nftl->mtd, block * nftl->EraseSize, SECTORSIZE,
807 &retlen, buf, NULL))) {
808 static int warncount = 5;
809
810 if (warncount) {
811 printf("Block read at 0x%x failed\n", block * nftl->EraseSize);
812 if (!--warncount)
813 puts ("Further failures for this block will not be printed\n");
814 }
815 continue;
816 }
817
818 if (retlen < 6 || memcmp(buf, "ANAND", 6)) {
819 /* ANAND\0 not found. Continue */
820#ifdef PSYCHO_DEBUG
821 printf("ANAND header not found at 0x%x\n", block * nftl->EraseSize);
822#endif
823 continue;
824 }
825
826#ifdef NFTL_DEBUG
827 printf("ANAND header found at 0x%x\n", block * nftl->EraseSize);
828#endif
829
830 /* To be safer with BIOS, also use erase mark as discriminant */
831 if ((ret = doc_read_oob(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8,
832 8, &retlen, (char *)&h1) < 0)) {
833#ifdef NFTL_DEBUG
834 printf("ANAND header found at 0x%x, but OOB data read failed\n",
835 block * nftl->EraseSize);
836#endif
837 continue;
838 }
839
840 /* OK, we like it. */
841
842 if (boot_record_count) {
843 /* We've already processed one. So we just check if
844 this one is the same as the first one we found */
845 if (memcmp(mh, buf, sizeof(struct NFTLMediaHeader))) {
846#ifdef NFTL_DEBUG
847 printf("NFTL Media Headers at 0x%x and 0x%x disagree.\n",
848 nftl->MediaUnit * nftl->EraseSize, block * nftl->EraseSize);
849#endif
850 /* if (debug) Print both side by side */
851 return -1;
852 }
853 if (boot_record_count == 1)
854 nftl->SpareMediaUnit = block;
855
856 boot_record_count++;
857 continue;
858 }
859
860 /* This is the first we've seen. Copy the media header structure into place */
861 memcpy(mh, buf, sizeof(struct NFTLMediaHeader));
862
863 /* Do some sanity checks on it */
864 if (mh->UnitSizeFactor != 0xff) {
865 puts ("Sorry, we don't support UnitSizeFactor "
866 "of != 1 yet.\n");
867 return -1;
868 }
869
870 nftl->nb_boot_blocks = le16_to_cpu(mh->FirstPhysicalEUN);
871 if ((nftl->nb_boot_blocks + 2) >= nftl->nb_blocks) {
872 printf ("NFTL Media Header sanity check failed:\n"
873 "nb_boot_blocks (%d) + 2 > nb_blocks (%d)\n",
874 nftl->nb_boot_blocks, nftl->nb_blocks);
875 return -1;
876 }
877
878 nftl->numvunits = le32_to_cpu(mh->FormattedSize) / nftl->EraseSize;
879 if (nftl->numvunits > (nftl->nb_blocks - nftl->nb_boot_blocks - 2)) {
880 printf ("NFTL Media Header sanity check failed:\n"
881 "numvunits (%d) > nb_blocks (%d) - nb_boot_blocks(%d) - 2\n",
882 nftl->numvunits,
883 nftl->nb_blocks,
884 nftl->nb_boot_blocks);
885 return -1;
886 }
887
888 nftl->nr_sects = nftl->numvunits * (nftl->EraseSize / SECTORSIZE);
889
890 /* If we're not using the last sectors in the device for some reason,
891 reduce nb_blocks accordingly so we forget they're there */
892 nftl->nb_blocks = le16_to_cpu(mh->NumEraseUnits) + le16_to_cpu(mh->FirstPhysicalEUN);
893
894 /* read the Bad Erase Unit Table and modify ReplUnitTable[] accordingly */
895 for (i = 0; i < nftl->nb_blocks; i++) {
896 if ((i & (SECTORSIZE - 1)) == 0) {
897 /* read one sector for every SECTORSIZE of blocks */
898 if ((ret = doc_read_ecc(nftl->mtd, block * nftl->EraseSize +
899 i + SECTORSIZE, SECTORSIZE,
900 &retlen, buf, (char *)&oob)) < 0) {
901 puts ("Read of bad sector table failed\n");
902 return -1;
903 }
904 }
905 /* mark the Bad Erase Unit as RESERVED in ReplUnitTable */
906 if (buf[i & (SECTORSIZE - 1)] != 0xff)
907 nftl->ReplUnitTable[i] = BLOCK_RESERVED;
908 }
909
910 nftl->MediaUnit = block;
911 boot_record_count++;
912
913 } /* foreach (block) */
914
915 return boot_record_count?0:-1;
916}
917
918/* This routine is made available to other mtd code via
919 * inter_module_register. It must only be accessed through
920 * inter_module_get which will bump the use count of this module. The
921 * addresses passed back in mtd are valid as long as the use count of
922 * this module is non-zero, i.e. between inter_module_get and
923 * inter_module_put. Keith Owens <kaos@ocs.com.au> 29 Oct 2000.
924 */
925static void DoC2k_init(struct DiskOnChip* this)
926{
927 struct NFTLrecord *nftl;
928
929 switch (this->ChipID) {
930 case DOC_ChipID_Doc2k:
931 this->name = "DiskOnChip 2000";
932 this->ioreg = DoC_2k_CDSN_IO;
933 break;
934 case DOC_ChipID_DocMil:
935 this->name = "DiskOnChip Millennium";
936 this->ioreg = DoC_Mil_CDSN_IO;
937 break;
938 }
939
940#ifdef DOC_DEBUG
941 printf("%s found at address 0x%lX\n", this->name,
942 this->physadr);
943#endif
944
945 this->totlen = 0;
946 this->numchips = 0;
947
948 this->curfloor = -1;
949 this->curchip = -1;
950
951 /* Ident all the chips present. */
952 DoC_ScanChips(this);
953
954 nftl = &this->nftl;
955
956 /* Get physical parameters */
957 nftl->EraseSize = this->erasesize;
8bde7f77 958 nftl->nb_blocks = this->totlen / this->erasesize;
c609719b
WD
959 nftl->mtd = this;
960
961 if (find_boot_record(nftl) != 0)
962 this->nftl_found = 0;
963 else
964 this->nftl_found = 1;
965
966 printf("%s @ 0x%lX, %ld MB\n", this->name, this->physadr, this->totlen >> 20);
967}
968
969int doc_read_ecc(struct DiskOnChip* this, loff_t from, size_t len,
970 size_t * retlen, u_char * buf, u_char * eccbuf)
971{
972 unsigned long docptr;
973 struct Nand *mychip;
974 unsigned char syndrome[6];
975 volatile char dummy;
976 int i, len256 = 0, ret=0;
977
978 docptr = this->virtadr;
979
980 /* Don't allow read past end of device */
981 if (from >= this->totlen) {
982 puts ("Out of flash\n");
983 return DOC_EINVAL;
984 }
985
986 /* Don't allow a single read to cross a 512-byte block boundary */
987 if (from + len > ((from | 0x1ff) + 1))
988 len = ((from | 0x1ff) + 1) - from;
989
990 /* The ECC will not be calculated correctly if less than 512 is read */
991 if (len != 0x200 && eccbuf)
992 printf("ECC needs a full sector read (adr: %lx size %lx)\n",
993 (long) from, (long) len);
994
995#ifdef PHYCH_DEBUG
996 printf("DoC_Read (adr: %lx size %lx)\n", (long) from, (long) len);
997#endif
998
999 /* Find the chip which is to be used and select it */
1000 mychip = &this->chips[shr(from, this->chipshift)];
1001
1002 if (this->curfloor != mychip->floor) {
1003 DoC_SelectFloor(this, mychip->floor);
1004 DoC_SelectChip(this, mychip->chip);
1005 } else if (this->curchip != mychip->chip) {
1006 DoC_SelectChip(this, mychip->chip);
1007 }
1008
1009 this->curfloor = mychip->floor;
1010 this->curchip = mychip->chip;
1011
1012 DoC_Command(this,
1013 (!this->page256
1014 && (from & 0x100)) ? NAND_CMD_READ1 : NAND_CMD_READ0,
1015 CDSN_CTRL_WP);
1016 DoC_Address(this, ADDR_COLUMN_PAGE, from, CDSN_CTRL_WP,
1017 CDSN_CTRL_ECC_IO);
1018
1019 if (eccbuf) {
1020 /* Prime the ECC engine */
1021 WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
1022 WriteDOC(DOC_ECC_EN, docptr, ECCConf);
1023 } else {
1024 /* disable the ECC engine */
1025 WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
1026 WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
1027 }
1028
1029 /* treat crossing 256-byte sector for 2M x 8bits devices */
1030 if (this->page256 && from + len > (from | 0xff) + 1) {
1031 len256 = (from | 0xff) + 1 - from;
1032 DoC_ReadBuf(this, buf, len256);
1033
1034 DoC_Command(this, NAND_CMD_READ0, CDSN_CTRL_WP);
1035 DoC_Address(this, ADDR_COLUMN_PAGE, from + len256,
1036 CDSN_CTRL_WP, CDSN_CTRL_ECC_IO);
1037 }
1038
1039 DoC_ReadBuf(this, &buf[len256], len - len256);
1040
1041 /* Let the caller know we completed it */
1042 *retlen = len;
1043
1044 if (eccbuf) {
1045 /* Read the ECC data through the DiskOnChip ECC logic */
1046 /* Note: this will work even with 2M x 8bit devices as */
1047 /* they have 8 bytes of OOB per 256 page. mf. */
1048 DoC_ReadBuf(this, eccbuf, 6);
1049
1050 /* Flush the pipeline */
1051 if (DoC_is_Millennium(this)) {
1052 dummy = ReadDOC(docptr, ECCConf);
1053 dummy = ReadDOC(docptr, ECCConf);
1054 i = ReadDOC(docptr, ECCConf);
1055 } else {
1056 dummy = ReadDOC(docptr, 2k_ECCStatus);
1057 dummy = ReadDOC(docptr, 2k_ECCStatus);
1058 i = ReadDOC(docptr, 2k_ECCStatus);
1059 }
1060
1061 /* Check the ECC Status */
1062 if (i & 0x80) {
1063 int nb_errors;
1064 /* There was an ECC error */
1065#ifdef ECC_DEBUG
1066 printf("DiskOnChip ECC Error: Read at %lx\n", (long)from);
1067#endif
1068 /* Read the ECC syndrom through the DiskOnChip ECC logic.
1069 These syndrome will be all ZERO when there is no error */
1070 for (i = 0; i < 6; i++) {
1071 syndrome[i] =
1072 ReadDOC(docptr, ECCSyndrome0 + i);
1073 }
8bde7f77 1074 nb_errors = doc_decode_ecc(buf, syndrome);
c609719b
WD
1075
1076#ifdef ECC_DEBUG
1077 printf("Errors corrected: %x\n", nb_errors);
1078#endif
8bde7f77 1079 if (nb_errors < 0) {
c609719b
WD
1080 /* We return error, but have actually done the read. Not that
1081 this can be told to user-space, via sys_read(), but at least
1082 MTD-aware stuff can know about it by checking *retlen */
1083 printf("ECC Errors at %lx\n", (long)from);
1084 ret = DOC_EECC;
8bde7f77 1085 }
c609719b
WD
1086 }
1087
1088#ifdef PSYCHO_DEBUG
1089 printf("ECC DATA at %lxB: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
1090 (long)from, eccbuf[0], eccbuf[1], eccbuf[2],
1091 eccbuf[3], eccbuf[4], eccbuf[5]);
1092#endif
1093
1094 /* disable the ECC engine */
1095 WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
1096 }
1097
1098 /* according to 11.4.1, we need to wait for the busy line
8bde7f77 1099 * drop if we read to the end of the page. */
c609719b
WD
1100 if(0 == ((from + *retlen) & 0x1ff))
1101 {
1102 DoC_WaitReady(this);
1103 }
1104
1105 return ret;
1106}
1107
1108int doc_write_ecc(struct DiskOnChip* this, loff_t to, size_t len,
1109 size_t * retlen, const u_char * buf,
1110 u_char * eccbuf)
1111{
1112 int di; /* Yes, DI is a hangover from when I was disassembling the binary driver */
1113 unsigned long docptr;
1114 volatile char dummy;
1115 int len256 = 0;
1116 struct Nand *mychip;
1117
1118 docptr = this->virtadr;
1119
1120 /* Don't allow write past end of device */
1121 if (to >= this->totlen) {
1122 puts ("Out of flash\n");
1123 return DOC_EINVAL;
1124 }
1125
1126 /* Don't allow a single write to cross a 512-byte block boundary */
1127 if (to + len > ((to | 0x1ff) + 1))
1128 len = ((to | 0x1ff) + 1) - to;
1129
1130 /* The ECC will not be calculated correctly if less than 512 is written */
1131 if (len != 0x200 && eccbuf)
1132 printf("ECC needs a full sector write (adr: %lx size %lx)\n",
1133 (long) to, (long) len);
1134
1135 /* printf("DoC_Write (adr: %lx size %lx)\n", (long) to, (long) len); */
1136
1137 /* Find the chip which is to be used and select it */
1138 mychip = &this->chips[shr(to, this->chipshift)];
1139
1140 if (this->curfloor != mychip->floor) {
1141 DoC_SelectFloor(this, mychip->floor);
1142 DoC_SelectChip(this, mychip->chip);
1143 } else if (this->curchip != mychip->chip) {
1144 DoC_SelectChip(this, mychip->chip);
1145 }
1146
1147 this->curfloor = mychip->floor;
1148 this->curchip = mychip->chip;
1149
1150 /* Set device to main plane of flash */
1151 DoC_Command(this, NAND_CMD_RESET, CDSN_CTRL_WP);
1152 DoC_Command(this,
1153 (!this->page256
1154 && (to & 0x100)) ? NAND_CMD_READ1 : NAND_CMD_READ0,
1155 CDSN_CTRL_WP);
1156
1157 DoC_Command(this, NAND_CMD_SEQIN, 0);
1158 DoC_Address(this, ADDR_COLUMN_PAGE, to, 0, CDSN_CTRL_ECC_IO);
1159
1160 if (eccbuf) {
1161 /* Prime the ECC engine */
1162 WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
1163 WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf);
1164 } else {
1165 /* disable the ECC engine */
1166 WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
1167 WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
1168 }
1169
1170 /* treat crossing 256-byte sector for 2M x 8bits devices */
1171 if (this->page256 && to + len > (to | 0xff) + 1) {
1172 len256 = (to | 0xff) + 1 - to;
1173 DoC_WriteBuf(this, buf, len256);
1174
1175 DoC_Command(this, NAND_CMD_PAGEPROG, 0);
1176
1177 DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
1178 /* There's an implicit DoC_WaitReady() in DoC_Command */
1179
1180 dummy = ReadDOC(docptr, CDSNSlowIO);
1181 DoC_Delay(this, 2);
1182
1183 if (ReadDOC_(docptr, this->ioreg) & 1) {
1184 puts ("Error programming flash\n");
1185 /* Error in programming */
1186 *retlen = 0;
1187 return DOC_EIO;
1188 }
1189
1190 DoC_Command(this, NAND_CMD_SEQIN, 0);
1191 DoC_Address(this, ADDR_COLUMN_PAGE, to + len256, 0,
1192 CDSN_CTRL_ECC_IO);
1193 }
1194
1195 DoC_WriteBuf(this, &buf[len256], len - len256);
1196
1197 if (eccbuf) {
1198 WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_CE, docptr,
1199 CDSNControl);
1200
1201 if (DoC_is_Millennium(this)) {
1202 WriteDOC(0, docptr, NOP);
1203 WriteDOC(0, docptr, NOP);
1204 WriteDOC(0, docptr, NOP);
1205 } else {
1206 WriteDOC_(0, docptr, this->ioreg);
1207 WriteDOC_(0, docptr, this->ioreg);
1208 WriteDOC_(0, docptr, this->ioreg);
1209 }
1210
1211 /* Read the ECC data through the DiskOnChip ECC logic */
1212 for (di = 0; di < 6; di++) {
1213 eccbuf[di] = ReadDOC(docptr, ECCSyndrome0 + di);
1214 }
1215
1216 /* Reset the ECC engine */
1217 WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
1218
1219#ifdef PSYCHO_DEBUG
1220 printf
1221 ("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
1222 (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
1223 eccbuf[4], eccbuf[5]);
1224#endif
1225 }
1226
1227 DoC_Command(this, NAND_CMD_PAGEPROG, 0);
1228
1229 DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
1230 /* There's an implicit DoC_WaitReady() in DoC_Command */
1231
1232 dummy = ReadDOC(docptr, CDSNSlowIO);
1233 DoC_Delay(this, 2);
1234
1235 if (ReadDOC_(docptr, this->ioreg) & 1) {
1236 puts ("Error programming flash\n");
1237 /* Error in programming */
1238 *retlen = 0;
1239 return DOC_EIO;
1240 }
1241
1242 /* Let the caller know we completed it */
1243 *retlen = len;
1244
1245 if (eccbuf) {
1246 unsigned char x[8];
1247 size_t dummy;
1248 int ret;
1249
1250 /* Write the ECC data to flash */
1251 for (di=0; di<6; di++)
1252 x[di] = eccbuf[di];
1253
1254 x[6]=0x55;
1255 x[7]=0x55;
1256
1257 ret = doc_write_oob(this, to, 8, &dummy, x);
1258 return ret;
1259 }
1260 return 0;
1261}
1262
1263int doc_read_oob(struct DiskOnChip* this, loff_t ofs, size_t len,
1264 size_t * retlen, u_char * buf)
1265{
1266 int len256 = 0, ret;
1267 unsigned long docptr;
1268 struct Nand *mychip;
1269
1270 docptr = this->virtadr;
1271
1272 mychip = &this->chips[shr(ofs, this->chipshift)];
1273
1274 if (this->curfloor != mychip->floor) {
1275 DoC_SelectFloor(this, mychip->floor);
1276 DoC_SelectChip(this, mychip->chip);
1277 } else if (this->curchip != mychip->chip) {
1278 DoC_SelectChip(this, mychip->chip);
1279 }
1280 this->curfloor = mychip->floor;
1281 this->curchip = mychip->chip;
1282
1283 /* update address for 2M x 8bit devices. OOB starts on the second */
1284 /* page to maintain compatibility with doc_read_ecc. */
1285 if (this->page256) {
1286 if (!(ofs & 0x8))
1287 ofs += 0x100;
1288 else
1289 ofs -= 0x8;
1290 }
1291
1292 DoC_Command(this, NAND_CMD_READOOB, CDSN_CTRL_WP);
1293 DoC_Address(this, ADDR_COLUMN_PAGE, ofs, CDSN_CTRL_WP, 0);
1294
1295 /* treat crossing 8-byte OOB data for 2M x 8bit devices */
1296 /* Note: datasheet says it should automaticaly wrap to the */
1297 /* next OOB block, but it didn't work here. mf. */
1298 if (this->page256 && ofs + len > (ofs | 0x7) + 1) {
1299 len256 = (ofs | 0x7) + 1 - ofs;
1300 DoC_ReadBuf(this, buf, len256);
1301
1302 DoC_Command(this, NAND_CMD_READOOB, CDSN_CTRL_WP);
1303 DoC_Address(this, ADDR_COLUMN_PAGE, ofs & (~0x1ff),
1304 CDSN_CTRL_WP, 0);
1305 }
1306
1307 DoC_ReadBuf(this, &buf[len256], len - len256);
1308
1309 *retlen = len;
1310 /* Reading the full OOB data drops us off of the end of the page,
8bde7f77
WD
1311 * causing the flash device to go into busy mode, so we need
1312 * to wait until ready 11.4.1 and Toshiba TC58256FT docs */
c609719b
WD
1313
1314 ret = DoC_WaitReady(this);
1315
1316 return ret;
1317
1318}
1319
1320int doc_write_oob(struct DiskOnChip* this, loff_t ofs, size_t len,
1321 size_t * retlen, const u_char * buf)
1322{
1323 int len256 = 0;
1324 unsigned long docptr = this->virtadr;
1325 struct Nand *mychip = &this->chips[shr(ofs, this->chipshift)];
1326 volatile int dummy;
1327
1328#ifdef PSYCHO_DEBUG
1329 printf("doc_write_oob(%lx, %d): %2.2X %2.2X %2.2X %2.2X ... %2.2X %2.2X .. %2.2X %2.2X\n",
1330 (long)ofs, len, buf[0], buf[1], buf[2], buf[3],
1331 buf[8], buf[9], buf[14],buf[15]);
1332#endif
1333
1334 /* Find the chip which is to be used and select it */
1335 if (this->curfloor != mychip->floor) {
1336 DoC_SelectFloor(this, mychip->floor);
1337 DoC_SelectChip(this, mychip->chip);
1338 } else if (this->curchip != mychip->chip) {
1339 DoC_SelectChip(this, mychip->chip);
1340 }
1341 this->curfloor = mychip->floor;
1342 this->curchip = mychip->chip;
1343
1344 /* disable the ECC engine */
1345 WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
1346 WriteDOC (DOC_ECC_DIS, docptr, ECCConf);
1347
1348 /* Reset the chip, see Software Requirement 11.4 item 1. */
1349 DoC_Command(this, NAND_CMD_RESET, CDSN_CTRL_WP);
1350
1351 /* issue the Read2 command to set the pointer to the Spare Data Area. */
1352 DoC_Command(this, NAND_CMD_READOOB, CDSN_CTRL_WP);
1353
1354 /* update address for 2M x 8bit devices. OOB starts on the second */
1355 /* page to maintain compatibility with doc_read_ecc. */
1356 if (this->page256) {
1357 if (!(ofs & 0x8))
1358 ofs += 0x100;
1359 else
1360 ofs -= 0x8;
1361 }
1362
1363 /* issue the Serial Data In command to initial the Page Program process */
1364 DoC_Command(this, NAND_CMD_SEQIN, 0);
1365 DoC_Address(this, ADDR_COLUMN_PAGE, ofs, 0, 0);
1366
1367 /* treat crossing 8-byte OOB data for 2M x 8bit devices */
1368 /* Note: datasheet says it should automaticaly wrap to the */
1369 /* next OOB block, but it didn't work here. mf. */
1370 if (this->page256 && ofs + len > (ofs | 0x7) + 1) {
1371 len256 = (ofs | 0x7) + 1 - ofs;
1372 DoC_WriteBuf(this, buf, len256);
1373
1374 DoC_Command(this, NAND_CMD_PAGEPROG, 0);
1375 DoC_Command(this, NAND_CMD_STATUS, 0);
1376 /* DoC_WaitReady() is implicit in DoC_Command */
1377
1378 dummy = ReadDOC(docptr, CDSNSlowIO);
1379 DoC_Delay(this, 2);
1380
1381 if (ReadDOC_(docptr, this->ioreg) & 1) {
1382 puts ("Error programming oob data\n");
1383 /* There was an error */
1384 *retlen = 0;
1385 return DOC_EIO;
1386 }
1387 DoC_Command(this, NAND_CMD_SEQIN, 0);
1388 DoC_Address(this, ADDR_COLUMN_PAGE, ofs & (~0x1ff), 0, 0);
1389 }
1390
1391 DoC_WriteBuf(this, &buf[len256], len - len256);
1392
1393 DoC_Command(this, NAND_CMD_PAGEPROG, 0);
1394 DoC_Command(this, NAND_CMD_STATUS, 0);
1395 /* DoC_WaitReady() is implicit in DoC_Command */
1396
1397 dummy = ReadDOC(docptr, CDSNSlowIO);
1398 DoC_Delay(this, 2);
1399
1400 if (ReadDOC_(docptr, this->ioreg) & 1) {
1401 puts ("Error programming oob data\n");
1402 /* There was an error */
1403 *retlen = 0;
1404 return DOC_EIO;
1405 }
1406
1407 *retlen = len;
1408 return 0;
1409
1410}
1411
1412int doc_erase(struct DiskOnChip* this, loff_t ofs, size_t len)
1413{
1414 volatile int dummy;
1415 unsigned long docptr;
1416 struct Nand *mychip;
1417
1418 if (ofs & (this->erasesize-1) || len & (this->erasesize-1)) {
1419 puts ("Offset and size must be sector aligned\n");
1420 return DOC_EINVAL;
1421 }
1422
1423 docptr = this->virtadr;
1424
1425 /* FIXME: Do this in the background. Use timers or schedule_task() */
1426 while(len) {
1427 mychip = &this->chips[shr(ofs, this->chipshift)];
1428
1429 if (this->curfloor != mychip->floor) {
1430 DoC_SelectFloor(this, mychip->floor);
1431 DoC_SelectChip(this, mychip->chip);
1432 } else if (this->curchip != mychip->chip) {
1433 DoC_SelectChip(this, mychip->chip);
1434 }
1435 this->curfloor = mychip->floor;
1436 this->curchip = mychip->chip;
1437
1438 DoC_Command(this, NAND_CMD_ERASE1, 0);
1439 DoC_Address(this, ADDR_PAGE, ofs, 0, 0);
1440 DoC_Command(this, NAND_CMD_ERASE2, 0);
1441
1442 DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
1443
1444 dummy = ReadDOC(docptr, CDSNSlowIO);
1445 DoC_Delay(this, 2);
1446
1447 if (ReadDOC_(docptr, this->ioreg) & 1) {
1448 printf("Error erasing at 0x%lx\n", (long)ofs);
1449 /* There was an error */
1450 goto callback;
1451 }
1452 ofs += this->erasesize;
1453 len -= this->erasesize;
1454 }
1455
1456 callback:
1457 return 0;
1458}
1459
1460static inline int doccheck(unsigned long potential, unsigned long physadr)
1461{
1462 unsigned long window=potential;
1463 unsigned char tmp, ChipID;
1464#ifndef DOC_PASSIVE_PROBE
1465 unsigned char tmp2;
1466#endif
1467
1468 /* Routine copied from the Linux DOC driver */
1469
1470#ifdef CFG_DOCPROBE_55AA
1471 /* Check for 0x55 0xAA signature at beginning of window,
1472 this is no longer true once we remove the IPL (for Millennium */
1473 if (ReadDOC(window, Sig1) != 0x55 || ReadDOC(window, Sig2) != 0xaa)
1474 return 0;
1475#endif /* CFG_DOCPROBE_55AA */
1476
1477#ifndef DOC_PASSIVE_PROBE
1478 /* It's not possible to cleanly detect the DiskOnChip - the
1479 * bootup procedure will put the device into reset mode, and
1480 * it's not possible to talk to it without actually writing
1481 * to the DOCControl register. So we store the current contents
1482 * of the DOCControl register's location, in case we later decide
1483 * that it's not a DiskOnChip, and want to put it back how we
1484 * found it.
1485 */
1486 tmp2 = ReadDOC(window, DOCControl);
1487
1488 /* Reset the DiskOnChip ASIC */
1489 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
1490 window, DOCControl);
1491 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
1492 window, DOCControl);
1493
1494 /* Enable the DiskOnChip ASIC */
1495 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
1496 window, DOCControl);
1497 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
1498 window, DOCControl);
1499#endif /* !DOC_PASSIVE_PROBE */
1500
1501 ChipID = ReadDOC(window, ChipID);
1502
1503 switch (ChipID) {
1504 case DOC_ChipID_Doc2k:
1505 /* Check the TOGGLE bit in the ECC register */
1506 tmp = ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT;
1507 if ((ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT) != tmp)
1508 return ChipID;
1509 break;
1510
1511 case DOC_ChipID_DocMil:
1512 /* Check the TOGGLE bit in the ECC register */
1513 tmp = ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT;
1514 if ((ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT) != tmp)
1515 return ChipID;
1516 break;
1517
1518 default:
1519#ifndef CFG_DOCPROBE_55AA
1520/*
1521 * if the ID isn't the DoC2000 or DoCMillenium ID, so we can assume
1522 * the DOC is missing
1523 */
1524# if 0
1525 printf("Possible DiskOnChip with unknown ChipID %2.2X found at 0x%lx\n",
1526 ChipID, physadr);
1527# endif
1528#endif
1529#ifndef DOC_PASSIVE_PROBE
1530 /* Put back the contents of the DOCControl register, in case it's not
1531 * actually a DiskOnChip.
1532 */
1533 WriteDOC(tmp2, window, DOCControl);
1534#endif
1535 return 0;
1536 }
1537
1538 puts ("DiskOnChip failed TOGGLE test, dropping.\n");
1539
1540#ifndef DOC_PASSIVE_PROBE
1541 /* Put back the contents of the DOCControl register: it's not a DiskOnChip */
1542 WriteDOC(tmp2, window, DOCControl);
1543#endif
1544 return 0;
1545}
1546
1547void doc_probe(unsigned long physadr)
1548{
1549 struct DiskOnChip *this = NULL;
1550 int i=0, ChipID;
1551
1552 if ((ChipID = doccheck(physadr, physadr))) {
1553
1554 for (i=0; i<CFG_MAX_DOC_DEVICE; i++) {
1555 if (doc_dev_desc[i].ChipID == DOC_ChipID_UNKNOWN) {
1556 this = doc_dev_desc + i;
1557 break;
1558 }
1559 }
1560
1561 if (!this) {
1562 puts ("Cannot allocate memory for data structures.\n");
1563 return;
1564 }
1565
1566 if (curr_device == -1)
1567 curr_device = i;
1568
1569 memset((char *)this, 0, sizeof(struct DiskOnChip));
1570
1571 this->virtadr = physadr;
1572 this->physadr = physadr;
1573 this->ChipID = ChipID;
1574
1575 DoC2k_init(this);
1576 } else {
1577 puts ("No DiskOnChip found\n");
1578 }
1579}
1580
1581#endif /* (CONFIG_COMMANDS & CFG_CMD_DOC) */