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