blob: 5e9bea30450683eea1d22c91d920676c3e5fe4e6 [file] [log] [blame]
wdenkc6097192002-11-03 00:24:07 +00001/*
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
wdenkac6dbb82003-03-26 11:42:53 +000024#include <linux/mtd/nftl.h>
wdenkc6097192002-11-03 00:24:07 +000025#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:
wdenk8bde7f72003-06-27 21:31:46 +000083 if (strcmp(argv[1],"info") == 0) {
wdenkc6097192002-11-03 00:24:07 +000084 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,
Wolfgang Denk77ddac92005-10-13 16:45:02 +0200146 (size_t *)&total, (u_char*)addr);
wdenkc6097192002-11-03 00:24:07 +0000147
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}
wdenk0d498392003-07-01 21:06:45 +0000173U_BOOT_CMD(
174 doc, 5, 1, do_doc,
wdenk8bde7f72003-06-27 21:31:46 +0000175 "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);
wdenkc6097192002-11-03 00:24:07 +0000184
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
wdenk0d498392003-07-01 21:06:45 +0000287U_BOOT_CMD(
288 docboot, 4, 1, do_docboot,
wdenk8bde7f72003-06-27 21:31:46 +0000289 "docboot - boot from DOC device\n",
290 "loadAddr dev\n"
291);
292
wdenkc6097192002-11-03 00:24:07 +0000293int 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,
Wolfgang Denk77ddac92005-10-13 16:45:02 +0200307 (size_t *)&n, (u_char*)buf,
308 noecc ? (uchar *)NULL : (uchar *)eccbuf);
wdenkc6097192002-11-03 00:24:07 +0000309 else
310 ret = doc_write_ecc(this, from, len,
Wolfgang Denk77ddac92005-10-13 16:45:02 +0200311 (size_t *)&n, (u_char*)buf,
312 noecc ? (uchar *)NULL : (uchar *)eccbuf);
wdenkc6097192002-11-03 00:24:07 +0000313
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);
wdenk8bde7f72003-06-27 21:31:46 +0000405 }
wdenkc6097192002-11-03 00:24:07 +0000406
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
wdenk7152b1d2003-09-05 23:19:14 +0000528/* Read a buffer from DoC, taking care of Millennium oddities */
wdenkc6097192002-11-03 00:24:07 +0000529static 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
wdenk7152b1d2003-09-05 23:19:14 +0000561/* Write a buffer to DoC, taking care of Millennium oddities */
wdenkc6097192002-11-03 00:24:07 +0000562static 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,
Wolfgang Denk77ddac92005-10-13 16:45:02 +0200807 (size_t *)&retlen, buf, NULL))) {
wdenkc6097192002-11-03 00:24:07 +0000808 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,
Wolfgang Denk77ddac92005-10-13 16:45:02 +0200832 8, (size_t *)&retlen, (uchar *)&h1) < 0)) {
wdenkc6097192002-11-03 00:24:07 +0000833#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 */
wdenk7205e402003-09-10 22:30:53 +0000864 if (mh->UnitSizeFactor == 0) {
865#ifdef NFTL_DEBUG
866 puts ("UnitSizeFactor 0x00 detected.\n"
867 "This violates the spec but we think we know what it means...\n");
868#endif
869 } else if (mh->UnitSizeFactor != 0xff) {
870 printf ("Sorry, we don't support UnitSizeFactor "
wdenkc6097192002-11-03 00:24:07 +0000871 "of != 1 yet.\n");
872 return -1;
873 }
874
875 nftl->nb_boot_blocks = le16_to_cpu(mh->FirstPhysicalEUN);
876 if ((nftl->nb_boot_blocks + 2) >= nftl->nb_blocks) {
877 printf ("NFTL Media Header sanity check failed:\n"
878 "nb_boot_blocks (%d) + 2 > nb_blocks (%d)\n",
879 nftl->nb_boot_blocks, nftl->nb_blocks);
880 return -1;
881 }
882
883 nftl->numvunits = le32_to_cpu(mh->FormattedSize) / nftl->EraseSize;
884 if (nftl->numvunits > (nftl->nb_blocks - nftl->nb_boot_blocks - 2)) {
885 printf ("NFTL Media Header sanity check failed:\n"
886 "numvunits (%d) > nb_blocks (%d) - nb_boot_blocks(%d) - 2\n",
887 nftl->numvunits,
888 nftl->nb_blocks,
889 nftl->nb_boot_blocks);
890 return -1;
891 }
892
893 nftl->nr_sects = nftl->numvunits * (nftl->EraseSize / SECTORSIZE);
894
895 /* If we're not using the last sectors in the device for some reason,
896 reduce nb_blocks accordingly so we forget they're there */
897 nftl->nb_blocks = le16_to_cpu(mh->NumEraseUnits) + le16_to_cpu(mh->FirstPhysicalEUN);
898
899 /* read the Bad Erase Unit Table and modify ReplUnitTable[] accordingly */
900 for (i = 0; i < nftl->nb_blocks; i++) {
901 if ((i & (SECTORSIZE - 1)) == 0) {
902 /* read one sector for every SECTORSIZE of blocks */
903 if ((ret = doc_read_ecc(nftl->mtd, block * nftl->EraseSize +
904 i + SECTORSIZE, SECTORSIZE,
Wolfgang Denk77ddac92005-10-13 16:45:02 +0200905 (size_t *)&retlen, buf, (uchar *)&oob)) < 0) {
wdenkc6097192002-11-03 00:24:07 +0000906 puts ("Read of bad sector table failed\n");
907 return -1;
908 }
909 }
910 /* mark the Bad Erase Unit as RESERVED in ReplUnitTable */
911 if (buf[i & (SECTORSIZE - 1)] != 0xff)
912 nftl->ReplUnitTable[i] = BLOCK_RESERVED;
913 }
914
915 nftl->MediaUnit = block;
916 boot_record_count++;
917
918 } /* foreach (block) */
919
920 return boot_record_count?0:-1;
921}
922
923/* This routine is made available to other mtd code via
924 * inter_module_register. It must only be accessed through
925 * inter_module_get which will bump the use count of this module. The
926 * addresses passed back in mtd are valid as long as the use count of
927 * this module is non-zero, i.e. between inter_module_get and
928 * inter_module_put. Keith Owens <kaos@ocs.com.au> 29 Oct 2000.
929 */
930static void DoC2k_init(struct DiskOnChip* this)
931{
932 struct NFTLrecord *nftl;
933
934 switch (this->ChipID) {
935 case DOC_ChipID_Doc2k:
936 this->name = "DiskOnChip 2000";
937 this->ioreg = DoC_2k_CDSN_IO;
938 break;
939 case DOC_ChipID_DocMil:
940 this->name = "DiskOnChip Millennium";
941 this->ioreg = DoC_Mil_CDSN_IO;
942 break;
943 }
944
945#ifdef DOC_DEBUG
946 printf("%s found at address 0x%lX\n", this->name,
947 this->physadr);
948#endif
949
950 this->totlen = 0;
951 this->numchips = 0;
952
953 this->curfloor = -1;
954 this->curchip = -1;
955
956 /* Ident all the chips present. */
957 DoC_ScanChips(this);
wdenk7205e402003-09-10 22:30:53 +0000958 if ((!this->numchips) || (!this->chips))
959 return;
wdenkc6097192002-11-03 00:24:07 +0000960
961 nftl = &this->nftl;
962
963 /* Get physical parameters */
964 nftl->EraseSize = this->erasesize;
wdenk8bde7f72003-06-27 21:31:46 +0000965 nftl->nb_blocks = this->totlen / this->erasesize;
wdenkc6097192002-11-03 00:24:07 +0000966 nftl->mtd = this;
967
968 if (find_boot_record(nftl) != 0)
969 this->nftl_found = 0;
970 else
971 this->nftl_found = 1;
972
973 printf("%s @ 0x%lX, %ld MB\n", this->name, this->physadr, this->totlen >> 20);
974}
975
976int doc_read_ecc(struct DiskOnChip* this, loff_t from, size_t len,
977 size_t * retlen, u_char * buf, u_char * eccbuf)
978{
979 unsigned long docptr;
980 struct Nand *mychip;
981 unsigned char syndrome[6];
982 volatile char dummy;
983 int i, len256 = 0, ret=0;
984
985 docptr = this->virtadr;
986
987 /* Don't allow read past end of device */
988 if (from >= this->totlen) {
989 puts ("Out of flash\n");
990 return DOC_EINVAL;
991 }
992
993 /* Don't allow a single read to cross a 512-byte block boundary */
994 if (from + len > ((from | 0x1ff) + 1))
995 len = ((from | 0x1ff) + 1) - from;
996
997 /* The ECC will not be calculated correctly if less than 512 is read */
998 if (len != 0x200 && eccbuf)
999 printf("ECC needs a full sector read (adr: %lx size %lx)\n",
1000 (long) from, (long) len);
1001
wdenk7152b1d2003-09-05 23:19:14 +00001002#ifdef PSYCHO_DEBUG
wdenkc6097192002-11-03 00:24:07 +00001003 printf("DoC_Read (adr: %lx size %lx)\n", (long) from, (long) len);
1004#endif
1005
1006 /* Find the chip which is to be used and select it */
1007 mychip = &this->chips[shr(from, this->chipshift)];
1008
1009 if (this->curfloor != mychip->floor) {
1010 DoC_SelectFloor(this, mychip->floor);
1011 DoC_SelectChip(this, mychip->chip);
1012 } else if (this->curchip != mychip->chip) {
1013 DoC_SelectChip(this, mychip->chip);
1014 }
1015
1016 this->curfloor = mychip->floor;
1017 this->curchip = mychip->chip;
1018
1019 DoC_Command(this,
1020 (!this->page256
1021 && (from & 0x100)) ? NAND_CMD_READ1 : NAND_CMD_READ0,
1022 CDSN_CTRL_WP);
1023 DoC_Address(this, ADDR_COLUMN_PAGE, from, CDSN_CTRL_WP,
1024 CDSN_CTRL_ECC_IO);
1025
1026 if (eccbuf) {
1027 /* Prime the ECC engine */
1028 WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
1029 WriteDOC(DOC_ECC_EN, docptr, ECCConf);
1030 } else {
1031 /* disable the ECC engine */
1032 WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
1033 WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
1034 }
1035
1036 /* treat crossing 256-byte sector for 2M x 8bits devices */
1037 if (this->page256 && from + len > (from | 0xff) + 1) {
1038 len256 = (from | 0xff) + 1 - from;
1039 DoC_ReadBuf(this, buf, len256);
1040
1041 DoC_Command(this, NAND_CMD_READ0, CDSN_CTRL_WP);
1042 DoC_Address(this, ADDR_COLUMN_PAGE, from + len256,
1043 CDSN_CTRL_WP, CDSN_CTRL_ECC_IO);
1044 }
1045
1046 DoC_ReadBuf(this, &buf[len256], len - len256);
1047
1048 /* Let the caller know we completed it */
1049 *retlen = len;
1050
1051 if (eccbuf) {
1052 /* Read the ECC data through the DiskOnChip ECC logic */
1053 /* Note: this will work even with 2M x 8bit devices as */
1054 /* they have 8 bytes of OOB per 256 page. mf. */
1055 DoC_ReadBuf(this, eccbuf, 6);
1056
1057 /* Flush the pipeline */
1058 if (DoC_is_Millennium(this)) {
1059 dummy = ReadDOC(docptr, ECCConf);
1060 dummy = ReadDOC(docptr, ECCConf);
1061 i = ReadDOC(docptr, ECCConf);
1062 } else {
1063 dummy = ReadDOC(docptr, 2k_ECCStatus);
1064 dummy = ReadDOC(docptr, 2k_ECCStatus);
1065 i = ReadDOC(docptr, 2k_ECCStatus);
1066 }
1067
1068 /* Check the ECC Status */
1069 if (i & 0x80) {
1070 int nb_errors;
1071 /* There was an ECC error */
1072#ifdef ECC_DEBUG
1073 printf("DiskOnChip ECC Error: Read at %lx\n", (long)from);
1074#endif
1075 /* Read the ECC syndrom through the DiskOnChip ECC logic.
1076 These syndrome will be all ZERO when there is no error */
1077 for (i = 0; i < 6; i++) {
1078 syndrome[i] =
1079 ReadDOC(docptr, ECCSyndrome0 + i);
1080 }
wdenk8bde7f72003-06-27 21:31:46 +00001081 nb_errors = doc_decode_ecc(buf, syndrome);
wdenkc6097192002-11-03 00:24:07 +00001082
1083#ifdef ECC_DEBUG
1084 printf("Errors corrected: %x\n", nb_errors);
1085#endif
wdenk8bde7f72003-06-27 21:31:46 +00001086 if (nb_errors < 0) {
wdenkc6097192002-11-03 00:24:07 +00001087 /* We return error, but have actually done the read. Not that
1088 this can be told to user-space, via sys_read(), but at least
1089 MTD-aware stuff can know about it by checking *retlen */
1090 printf("ECC Errors at %lx\n", (long)from);
1091 ret = DOC_EECC;
wdenk8bde7f72003-06-27 21:31:46 +00001092 }
wdenkc6097192002-11-03 00:24:07 +00001093 }
1094
1095#ifdef PSYCHO_DEBUG
1096 printf("ECC DATA at %lxB: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
1097 (long)from, eccbuf[0], eccbuf[1], eccbuf[2],
1098 eccbuf[3], eccbuf[4], eccbuf[5]);
1099#endif
1100
1101 /* disable the ECC engine */
1102 WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
1103 }
1104
1105 /* according to 11.4.1, we need to wait for the busy line
wdenk8bde7f72003-06-27 21:31:46 +00001106 * drop if we read to the end of the page. */
wdenkc6097192002-11-03 00:24:07 +00001107 if(0 == ((from + *retlen) & 0x1ff))
1108 {
1109 DoC_WaitReady(this);
1110 }
1111
1112 return ret;
1113}
1114
1115int doc_write_ecc(struct DiskOnChip* this, loff_t to, size_t len,
1116 size_t * retlen, const u_char * buf,
1117 u_char * eccbuf)
1118{
1119 int di; /* Yes, DI is a hangover from when I was disassembling the binary driver */
1120 unsigned long docptr;
1121 volatile char dummy;
1122 int len256 = 0;
1123 struct Nand *mychip;
1124
1125 docptr = this->virtadr;
1126
1127 /* Don't allow write past end of device */
1128 if (to >= this->totlen) {
1129 puts ("Out of flash\n");
1130 return DOC_EINVAL;
1131 }
1132
1133 /* Don't allow a single write to cross a 512-byte block boundary */
1134 if (to + len > ((to | 0x1ff) + 1))
1135 len = ((to | 0x1ff) + 1) - to;
1136
1137 /* The ECC will not be calculated correctly if less than 512 is written */
1138 if (len != 0x200 && eccbuf)
1139 printf("ECC needs a full sector write (adr: %lx size %lx)\n",
1140 (long) to, (long) len);
1141
1142 /* printf("DoC_Write (adr: %lx size %lx)\n", (long) to, (long) len); */
1143
1144 /* Find the chip which is to be used and select it */
1145 mychip = &this->chips[shr(to, this->chipshift)];
1146
1147 if (this->curfloor != mychip->floor) {
1148 DoC_SelectFloor(this, mychip->floor);
1149 DoC_SelectChip(this, mychip->chip);
1150 } else if (this->curchip != mychip->chip) {
1151 DoC_SelectChip(this, mychip->chip);
1152 }
1153
1154 this->curfloor = mychip->floor;
1155 this->curchip = mychip->chip;
1156
1157 /* Set device to main plane of flash */
1158 DoC_Command(this, NAND_CMD_RESET, CDSN_CTRL_WP);
1159 DoC_Command(this,
1160 (!this->page256
1161 && (to & 0x100)) ? NAND_CMD_READ1 : NAND_CMD_READ0,
1162 CDSN_CTRL_WP);
1163
1164 DoC_Command(this, NAND_CMD_SEQIN, 0);
1165 DoC_Address(this, ADDR_COLUMN_PAGE, to, 0, CDSN_CTRL_ECC_IO);
1166
1167 if (eccbuf) {
1168 /* Prime the ECC engine */
1169 WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
1170 WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf);
1171 } else {
1172 /* disable the ECC engine */
1173 WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
1174 WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
1175 }
1176
1177 /* treat crossing 256-byte sector for 2M x 8bits devices */
1178 if (this->page256 && to + len > (to | 0xff) + 1) {
1179 len256 = (to | 0xff) + 1 - to;
1180 DoC_WriteBuf(this, buf, len256);
1181
1182 DoC_Command(this, NAND_CMD_PAGEPROG, 0);
1183
1184 DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
1185 /* There's an implicit DoC_WaitReady() in DoC_Command */
1186
1187 dummy = ReadDOC(docptr, CDSNSlowIO);
1188 DoC_Delay(this, 2);
1189
1190 if (ReadDOC_(docptr, this->ioreg) & 1) {
1191 puts ("Error programming flash\n");
1192 /* Error in programming */
1193 *retlen = 0;
1194 return DOC_EIO;
1195 }
1196
1197 DoC_Command(this, NAND_CMD_SEQIN, 0);
1198 DoC_Address(this, ADDR_COLUMN_PAGE, to + len256, 0,
1199 CDSN_CTRL_ECC_IO);
1200 }
1201
1202 DoC_WriteBuf(this, &buf[len256], len - len256);
1203
1204 if (eccbuf) {
1205 WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_CE, docptr,
1206 CDSNControl);
1207
1208 if (DoC_is_Millennium(this)) {
1209 WriteDOC(0, docptr, NOP);
1210 WriteDOC(0, docptr, NOP);
1211 WriteDOC(0, docptr, NOP);
1212 } else {
1213 WriteDOC_(0, docptr, this->ioreg);
1214 WriteDOC_(0, docptr, this->ioreg);
1215 WriteDOC_(0, docptr, this->ioreg);
1216 }
1217
1218 /* Read the ECC data through the DiskOnChip ECC logic */
1219 for (di = 0; di < 6; di++) {
1220 eccbuf[di] = ReadDOC(docptr, ECCSyndrome0 + di);
1221 }
1222
1223 /* Reset the ECC engine */
1224 WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
1225
1226#ifdef PSYCHO_DEBUG
1227 printf
1228 ("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
1229 (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
1230 eccbuf[4], eccbuf[5]);
1231#endif
1232 }
1233
1234 DoC_Command(this, NAND_CMD_PAGEPROG, 0);
1235
1236 DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
1237 /* There's an implicit DoC_WaitReady() in DoC_Command */
1238
1239 dummy = ReadDOC(docptr, CDSNSlowIO);
1240 DoC_Delay(this, 2);
1241
1242 if (ReadDOC_(docptr, this->ioreg) & 1) {
1243 puts ("Error programming flash\n");
1244 /* Error in programming */
1245 *retlen = 0;
1246 return DOC_EIO;
1247 }
1248
1249 /* Let the caller know we completed it */
1250 *retlen = len;
1251
1252 if (eccbuf) {
1253 unsigned char x[8];
1254 size_t dummy;
1255 int ret;
1256
1257 /* Write the ECC data to flash */
1258 for (di=0; di<6; di++)
1259 x[di] = eccbuf[di];
1260
1261 x[6]=0x55;
1262 x[7]=0x55;
1263
1264 ret = doc_write_oob(this, to, 8, &dummy, x);
1265 return ret;
1266 }
1267 return 0;
1268}
1269
1270int doc_read_oob(struct DiskOnChip* this, loff_t ofs, size_t len,
1271 size_t * retlen, u_char * buf)
1272{
1273 int len256 = 0, ret;
1274 unsigned long docptr;
1275 struct Nand *mychip;
1276
1277 docptr = this->virtadr;
1278
1279 mychip = &this->chips[shr(ofs, this->chipshift)];
1280
1281 if (this->curfloor != mychip->floor) {
1282 DoC_SelectFloor(this, mychip->floor);
1283 DoC_SelectChip(this, mychip->chip);
1284 } else if (this->curchip != mychip->chip) {
1285 DoC_SelectChip(this, mychip->chip);
1286 }
1287 this->curfloor = mychip->floor;
1288 this->curchip = mychip->chip;
1289
1290 /* update address for 2M x 8bit devices. OOB starts on the second */
1291 /* page to maintain compatibility with doc_read_ecc. */
1292 if (this->page256) {
1293 if (!(ofs & 0x8))
1294 ofs += 0x100;
1295 else
1296 ofs -= 0x8;
1297 }
1298
1299 DoC_Command(this, NAND_CMD_READOOB, CDSN_CTRL_WP);
1300 DoC_Address(this, ADDR_COLUMN_PAGE, ofs, CDSN_CTRL_WP, 0);
1301
1302 /* treat crossing 8-byte OOB data for 2M x 8bit devices */
1303 /* Note: datasheet says it should automaticaly wrap to the */
1304 /* next OOB block, but it didn't work here. mf. */
1305 if (this->page256 && ofs + len > (ofs | 0x7) + 1) {
1306 len256 = (ofs | 0x7) + 1 - ofs;
1307 DoC_ReadBuf(this, buf, len256);
1308
1309 DoC_Command(this, NAND_CMD_READOOB, CDSN_CTRL_WP);
1310 DoC_Address(this, ADDR_COLUMN_PAGE, ofs & (~0x1ff),
1311 CDSN_CTRL_WP, 0);
1312 }
1313
1314 DoC_ReadBuf(this, &buf[len256], len - len256);
1315
1316 *retlen = len;
1317 /* Reading the full OOB data drops us off of the end of the page,
wdenk8bde7f72003-06-27 21:31:46 +00001318 * causing the flash device to go into busy mode, so we need
1319 * to wait until ready 11.4.1 and Toshiba TC58256FT docs */
wdenkc6097192002-11-03 00:24:07 +00001320
1321 ret = DoC_WaitReady(this);
1322
1323 return ret;
1324
1325}
1326
1327int doc_write_oob(struct DiskOnChip* this, loff_t ofs, size_t len,
1328 size_t * retlen, const u_char * buf)
1329{
1330 int len256 = 0;
1331 unsigned long docptr = this->virtadr;
1332 struct Nand *mychip = &this->chips[shr(ofs, this->chipshift)];
1333 volatile int dummy;
1334
1335#ifdef PSYCHO_DEBUG
1336 printf("doc_write_oob(%lx, %d): %2.2X %2.2X %2.2X %2.2X ... %2.2X %2.2X .. %2.2X %2.2X\n",
1337 (long)ofs, len, buf[0], buf[1], buf[2], buf[3],
1338 buf[8], buf[9], buf[14],buf[15]);
1339#endif
1340
1341 /* Find the chip which is to be used and select it */
1342 if (this->curfloor != mychip->floor) {
1343 DoC_SelectFloor(this, mychip->floor);
1344 DoC_SelectChip(this, mychip->chip);
1345 } else if (this->curchip != mychip->chip) {
1346 DoC_SelectChip(this, mychip->chip);
1347 }
1348 this->curfloor = mychip->floor;
1349 this->curchip = mychip->chip;
1350
1351 /* disable the ECC engine */
1352 WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
1353 WriteDOC (DOC_ECC_DIS, docptr, ECCConf);
1354
1355 /* Reset the chip, see Software Requirement 11.4 item 1. */
1356 DoC_Command(this, NAND_CMD_RESET, CDSN_CTRL_WP);
1357
1358 /* issue the Read2 command to set the pointer to the Spare Data Area. */
1359 DoC_Command(this, NAND_CMD_READOOB, CDSN_CTRL_WP);
1360
1361 /* update address for 2M x 8bit devices. OOB starts on the second */
1362 /* page to maintain compatibility with doc_read_ecc. */
1363 if (this->page256) {
1364 if (!(ofs & 0x8))
1365 ofs += 0x100;
1366 else
1367 ofs -= 0x8;
1368 }
1369
1370 /* issue the Serial Data In command to initial the Page Program process */
1371 DoC_Command(this, NAND_CMD_SEQIN, 0);
1372 DoC_Address(this, ADDR_COLUMN_PAGE, ofs, 0, 0);
1373
1374 /* treat crossing 8-byte OOB data for 2M x 8bit devices */
1375 /* Note: datasheet says it should automaticaly wrap to the */
1376 /* next OOB block, but it didn't work here. mf. */
1377 if (this->page256 && ofs + len > (ofs | 0x7) + 1) {
1378 len256 = (ofs | 0x7) + 1 - ofs;
1379 DoC_WriteBuf(this, buf, len256);
1380
1381 DoC_Command(this, NAND_CMD_PAGEPROG, 0);
1382 DoC_Command(this, NAND_CMD_STATUS, 0);
1383 /* DoC_WaitReady() is implicit in DoC_Command */
1384
1385 dummy = ReadDOC(docptr, CDSNSlowIO);
1386 DoC_Delay(this, 2);
1387
1388 if (ReadDOC_(docptr, this->ioreg) & 1) {
1389 puts ("Error programming oob data\n");
1390 /* There was an error */
1391 *retlen = 0;
1392 return DOC_EIO;
1393 }
1394 DoC_Command(this, NAND_CMD_SEQIN, 0);
1395 DoC_Address(this, ADDR_COLUMN_PAGE, ofs & (~0x1ff), 0, 0);
1396 }
1397
1398 DoC_WriteBuf(this, &buf[len256], len - len256);
1399
1400 DoC_Command(this, NAND_CMD_PAGEPROG, 0);
1401 DoC_Command(this, NAND_CMD_STATUS, 0);
1402 /* DoC_WaitReady() is implicit in DoC_Command */
1403
1404 dummy = ReadDOC(docptr, CDSNSlowIO);
1405 DoC_Delay(this, 2);
1406
1407 if (ReadDOC_(docptr, this->ioreg) & 1) {
1408 puts ("Error programming oob data\n");
1409 /* There was an error */
1410 *retlen = 0;
1411 return DOC_EIO;
1412 }
1413
1414 *retlen = len;
1415 return 0;
1416
1417}
1418
1419int doc_erase(struct DiskOnChip* this, loff_t ofs, size_t len)
1420{
1421 volatile int dummy;
1422 unsigned long docptr;
1423 struct Nand *mychip;
1424
1425 if (ofs & (this->erasesize-1) || len & (this->erasesize-1)) {
1426 puts ("Offset and size must be sector aligned\n");
1427 return DOC_EINVAL;
1428 }
1429
1430 docptr = this->virtadr;
1431
1432 /* FIXME: Do this in the background. Use timers or schedule_task() */
1433 while(len) {
1434 mychip = &this->chips[shr(ofs, this->chipshift)];
1435
1436 if (this->curfloor != mychip->floor) {
1437 DoC_SelectFloor(this, mychip->floor);
1438 DoC_SelectChip(this, mychip->chip);
1439 } else if (this->curchip != mychip->chip) {
1440 DoC_SelectChip(this, mychip->chip);
1441 }
1442 this->curfloor = mychip->floor;
1443 this->curchip = mychip->chip;
1444
1445 DoC_Command(this, NAND_CMD_ERASE1, 0);
1446 DoC_Address(this, ADDR_PAGE, ofs, 0, 0);
1447 DoC_Command(this, NAND_CMD_ERASE2, 0);
1448
1449 DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
1450
1451 dummy = ReadDOC(docptr, CDSNSlowIO);
1452 DoC_Delay(this, 2);
1453
1454 if (ReadDOC_(docptr, this->ioreg) & 1) {
1455 printf("Error erasing at 0x%lx\n", (long)ofs);
1456 /* There was an error */
1457 goto callback;
1458 }
1459 ofs += this->erasesize;
1460 len -= this->erasesize;
1461 }
1462
1463 callback:
1464 return 0;
1465}
1466
1467static inline int doccheck(unsigned long potential, unsigned long physadr)
1468{
1469 unsigned long window=potential;
1470 unsigned char tmp, ChipID;
1471#ifndef DOC_PASSIVE_PROBE
1472 unsigned char tmp2;
1473#endif
1474
1475 /* Routine copied from the Linux DOC driver */
1476
1477#ifdef CFG_DOCPROBE_55AA
1478 /* Check for 0x55 0xAA signature at beginning of window,
1479 this is no longer true once we remove the IPL (for Millennium */
1480 if (ReadDOC(window, Sig1) != 0x55 || ReadDOC(window, Sig2) != 0xaa)
1481 return 0;
1482#endif /* CFG_DOCPROBE_55AA */
1483
1484#ifndef DOC_PASSIVE_PROBE
1485 /* It's not possible to cleanly detect the DiskOnChip - the
1486 * bootup procedure will put the device into reset mode, and
1487 * it's not possible to talk to it without actually writing
1488 * to the DOCControl register. So we store the current contents
1489 * of the DOCControl register's location, in case we later decide
1490 * that it's not a DiskOnChip, and want to put it back how we
1491 * found it.
1492 */
1493 tmp2 = ReadDOC(window, DOCControl);
1494
1495 /* Reset the DiskOnChip ASIC */
1496 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
1497 window, DOCControl);
1498 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
1499 window, DOCControl);
1500
1501 /* Enable the DiskOnChip ASIC */
1502 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
1503 window, DOCControl);
1504 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
1505 window, DOCControl);
1506#endif /* !DOC_PASSIVE_PROBE */
1507
1508 ChipID = ReadDOC(window, ChipID);
1509
1510 switch (ChipID) {
1511 case DOC_ChipID_Doc2k:
1512 /* Check the TOGGLE bit in the ECC register */
1513 tmp = ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT;
1514 if ((ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT) != tmp)
1515 return ChipID;
1516 break;
1517
1518 case DOC_ChipID_DocMil:
1519 /* Check the TOGGLE bit in the ECC register */
1520 tmp = ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT;
1521 if ((ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT) != tmp)
1522 return ChipID;
1523 break;
1524
1525 default:
1526#ifndef CFG_DOCPROBE_55AA
1527/*
1528 * if the ID isn't the DoC2000 or DoCMillenium ID, so we can assume
1529 * the DOC is missing
1530 */
1531# if 0
1532 printf("Possible DiskOnChip with unknown ChipID %2.2X found at 0x%lx\n",
1533 ChipID, physadr);
1534# endif
1535#endif
1536#ifndef DOC_PASSIVE_PROBE
1537 /* Put back the contents of the DOCControl register, in case it's not
1538 * actually a DiskOnChip.
1539 */
1540 WriteDOC(tmp2, window, DOCControl);
1541#endif
1542 return 0;
1543 }
1544
1545 puts ("DiskOnChip failed TOGGLE test, dropping.\n");
1546
1547#ifndef DOC_PASSIVE_PROBE
1548 /* Put back the contents of the DOCControl register: it's not a DiskOnChip */
1549 WriteDOC(tmp2, window, DOCControl);
1550#endif
1551 return 0;
1552}
1553
1554void doc_probe(unsigned long physadr)
1555{
1556 struct DiskOnChip *this = NULL;
1557 int i=0, ChipID;
1558
1559 if ((ChipID = doccheck(physadr, physadr))) {
1560
1561 for (i=0; i<CFG_MAX_DOC_DEVICE; i++) {
1562 if (doc_dev_desc[i].ChipID == DOC_ChipID_UNKNOWN) {
1563 this = doc_dev_desc + i;
1564 break;
1565 }
1566 }
1567
1568 if (!this) {
1569 puts ("Cannot allocate memory for data structures.\n");
1570 return;
1571 }
1572
1573 if (curr_device == -1)
1574 curr_device = i;
1575
1576 memset((char *)this, 0, sizeof(struct DiskOnChip));
1577
1578 this->virtadr = physadr;
1579 this->physadr = physadr;
1580 this->ChipID = ChipID;
1581
1582 DoC2k_init(this);
1583 } else {
1584 puts ("No DiskOnChip found\n");
1585 }
1586}
1587
1588#endif /* (CONFIG_COMMANDS & CFG_CMD_DOC) */