add initial support for the crisarchitecture used on foxboards to openwrt
[oweals/openwrt.git] / target / linux / etrax-2.6 / image / e100boot / src / cbl / src / flash.c
1 /* $Id: flash.c,v 1.39 2004/04/20 07:57:57 jonashg Exp $
2  *
3  * Stolen from the eLinux kernel and stripped down.
4  *
5  * HISTORY:
6  *
7  * $Log: flash.c,v $
8  * Revision 1.39  2004/04/20 07:57:57  jonashg
9  * Clear flash_status fields to make it possible to flash several images
10  * sequentially.
11  *
12  * Revision 1.38  2003/12/16 09:04:07  magnusmn
13  * Removed FLASHFILL command
14  *
15  * Revision 1.37  2003/12/16 08:49:01  magnusmn
16  * Merging change_branch--fast_flash
17  *
18  * Revision 1.36.2.6  2003/12/15 17:21:27  magnusmn
19  * Reset counter when continuing with operations the next sector.
20  *
21  * Revision 1.36.2.5  2003/12/15 11:35:57  magnusmn
22  * Bail out if we try to erase the same sector more that 10 times
23  *
24  * Revision 1.36.2.4  2003/12/12 12:07:10  magnusmn
25  * FIX for ST M29W320DT
26  * Some chip need a reset to bring them back to read mode again.
27  *
28  * Revision 1.36.2.3  2003/11/10 16:38:04  orjanf
29  * Unified Erasing/Writing messages
30  *
31  * Revision 1.36.2.2  2003/11/10 15:52:34  magnusmn
32  * More info on a sector basis
33  *
34  * Revision 1.36.2.1  2003/11/07 16:23:20  magnusmn
35  * o Only erase a flash sector if we need to, that is if the source content isn't already is in place.
36  * o Don't erase a flash sector that already contain ones.
37  * o Don't write ones to a (d)word that already contain ones.
38  * o If there are two flashes, switch flash after an erase operation is started on one of them.
39  * o Flash fill doesn't work yet.
40  * o No timeout implemented, we will continue to erase/program until we succeed.
41  * o Interleave not tested.
42  *
43  * Revision 1.36  2003/10/16 17:08:51  jonashg
44  * Bugfix: reversed CFI-tables wasn't handled correctly since regions support was
45  * merged.
46  *
47  * Revision 1.35  2003/10/14 13:43:41  pkj
48  * Fixed compiler warnings.
49  *
50  * Revision 1.34  2003/10/14 10:48:13  magnusmn
51  * No need to write ones to a (d)word where there already are ones. This will save time during flash programming.
52  *
53  * Revision 1.33  2003/10/10 11:46:25  jonashg
54  * Merged change_branch--regions_support.
55  *
56  * Revision 1.32.2.3  2003/10/10 09:38:13  jonashg
57  * Corrected calculation of current region and sector before erase.
58  *
59  * Revision 1.32.2.2  2003/10/09 16:31:26  jonashg
60  * Regions support in JEDEC probe.
61  *
62  * Revision 1.32.2.1  2003/09/19 15:28:22  jonashg
63  * Support for unusual region layouts. It only works for CFI compliant chips (yet).
64  *
65  * Revision 1.32  2002/12/13 15:55:54  jonashg
66  * Fix for ST M29W160ET. It seems to need a reset before erase (even though the
67  * probe functions did reset it).
68  *
69  * Revision 1.31  2002/07/01 14:37:25  pkj
70  * Merged with the ASIC version of e100boot. Main difference is that
71  * information about the executed commands are sent back to e100boot
72  * instead of being sent to the debug port. This means there is no
73  * longer any need to use different boot loaders for different
74  * debug ports.
75  *
76  * Revision 1.30  2002/06/26 13:28:29  pkj
77  * flash_write() can now be used to erase an area (by specifying
78  * source as NULL), and to fill an area with the first udword of
79  * source by setting do_fill to TRUE).
80  *
81  * Revision 1.29  2002/06/26 13:19:37  pkj
82  * * flash_write() now returns a status code.
83  * * timeout is now decremented correctly in flash_write_part() to
84  *   actually be able to trigger the timeout message.
85  * * Fixed all compiler warnings.
86  *
87  * Revision 1.28  2002/06/20 12:58:18  pkj
88  * Changed svinto_boot.h to e100boot.h
89  *
90  * Revision 1.27  2002/06/19 14:00:29  pkj
91  * * Broke out the probing of the flash chips from  flash_write()
92  *   into flash_probe_chips().
93  * * flash_probe_chips() is not limited to two chips or that the
94  *   first chip exists.
95  *
96  * Revision 1.26  2002/02/21 14:37:52  jonashg
97  * Optimized away my sanity. It's back now I think.
98  *
99  * Revision 1.25  2002/02/21 14:28:24  jonashg
100  * Added support for Atmel AT49?V16?T (had to optimize a bit to make room).
101  *
102  * Revision 1.24  2002/01/31 14:36:14  jonashg
103  * * Added support for Atmel AT49[BL]V16[01] (the chip used in the ETRAX MCM).
104  * * Replaced concurrent sector erase with sequential (we have found three
105  *   different chips that cannot erase multiple sectors at the same time,
106  *   one of the is the chip in the MCM). I haven't noticed any performance
107  *   loss on chips (CFI and non-CFI) that can erase all sectors at the same
108  *   time either (maybe they don't really erase them at the same time in
109  *   hardware).
110  * * Added check for manufacturer id as well as device id (should have been
111  *   done a long time ago).
112  *
113  * Revision 1.23  2001/11/21 15:52:44  jonashg
114  * Almost readable.
115  *
116  * Revision 1.22  2001/11/21 15:24:38  jonashg
117  * Increased readability and decreased size some 40bytes.
118  *
119  * Revision 1.21  2001/11/20 13:40:12  starvik
120  * Corrected handling for CFI capable bottom boot flashes
121  * Shorted some strings to make more space available
122  *
123  * Revision 1.20  2001/08/08 17:51:28  pkj
124  * Made it possible to flash at a start offset other than zero when
125  * there are more than one physical flash chip available. Previously
126  * it always started flashing from the start of the first flash if
127  * there were more than one, even though the start offset was set to
128  * something else...
129  *
130  * Revision 1.19  2001/06/19 14:51:17  jonashg
131  * Added support for non-CFI flash Toshiba TC58FVT800.
132  *
133  * Revision 1.18  2001/04/05 06:32:39  starvik
134  * Works with flashes with multiple banks
135  *
136  * Revision 1.17  2001/03/06 15:21:16  jonashg
137  * More output to user.
138  *
139  * Revision 1.16  2001/03/06 14:11:16  jonashg
140  * * Switch to second device correctly when flashing images that extend past the
141  *   first device.
142  * * Only enter autoselect mode once saves a few bytes (not needed before reading
143  *   device id, since it was done before reading manufacturer id).
144  * * A few unnecessary resets removed to save another few bytes.
145  *
146  * Revision 1.15  2001/02/28 14:52:43  jonashg
147  * * Reverted to old sector erase sequence (that was correct).
148  * * A bit of executable size optimization (a few hundred bytes).
149  * * Cleanup.
150  *
151  * Revision 1.14  2001/02/27 14:18:59  jonashg
152  * * Write full erase command sequence to all sectors that should be erased.
153  * * Write 16bit erase command to non-interleaved chips.
154  *
155  * Revision 1.13  2001/02/23 11:03:41  jonashg
156  * Added support for 2 x 16Mb flashes (32-bits buswidth).
157  * The CFI probe does not detect two parallel flash devices, but the normal
158  * probe does (it should be easy to add that in the CFI-probe, but I didn't
159  * have any hardware to try it on and the size of the executable is getting
160  * pretty close to the size of the ETRAX cache).
161  *
162  * Revision 1.12  2001/02/12 13:59:00  jonashg
163  * Bugfix: pointer arithmetics made bootsector calculation go wrong.
164  *
165  * Revision 1.11  2000/11/10 08:02:23  starvik
166  * Added CFI support
167  *
168  * Revision 1.10  2000/10/26 13:47:32  johana
169  * Added support for Fujitsu flash 16MBit (2MByte) MBM29LV160BE and MBM29LV160TE.
170  * NOT VERIFIED YET!
171  *
172  * Revision 1.9  2000/06/28 13:02:50  bjornw
173  * * Added support for SST39LF800 and SST39LF160 flashes
174  * * Fixed some indentation issues
175  *
176  * Revision 1.8  2000/06/13 11:51:11  starvik
177  * Support for two flashes. Second flash is erased and programmed if program
178  * is larger than first flash.
179  *
180  * Revision 1.7  2000/04/13 16:06:15  macce
181  * See if flash is empty before erasing it. Might save some production time.
182  *
183  * Revision 1.6  2000/01/27 17:52:07  bjornw
184  * * Added Toshiba flashes
185  * * Added proper bootblock erase for the different flashes
186  *   (this caused the verify errors when trying to do ./flashitall before)
187  *
188  * Revision 1.5  2000/01/20 11:41:28  finn
189  * Improved the verify error printouts in flash_write.
190  *
191  * Revision 1.4  1999/12/21 19:32:53  bjornw
192  * Dont choke on full chip erases even though we dont implement it efficiently.
193  *
194  * Revision 1.3  1999/11/12 01:30:04  bjornw
195  * Added wait for busy to be ready. Removed some warnings.
196  *
197  * Revision 1.2  1999/10/27 07:42:42  johana
198  * Added support for ST M29W800T flash used in 5600
199  *
200  * Revision 1.1  1999/10/27 01:37:12  bjornw
201  * Wrote routines to erase and flash data into a flash ROM.
202  *
203  */
204
205 #include "e100boot.h"
206
207 //#define DEBUG
208
209 #ifdef DEBUG
210 #define FDEBUG(x) x
211 #else
212 #define FDEBUG(x)
213 #endif
214
215 /* Try turning of some of these if you run into space problems. */
216 #define CFI_PROBE
217 #define JEDEC_PROBE
218 #define INTERLEAVE
219
220 #define TYPE_X16        (16 / 8)
221
222 #define nop() __asm__("nop")
223
224 #define safe_printk send_string
225
226 static char *message_bottom_boot_8 = "8Mb BB";
227 static char *message_top_boot_8 = "8Mb TB";
228 static char *message_bottom_boot_16 = "16Mb BB";
229 static char *message_top_boot_16 = "16Mb TB";
230 static char *message_top_boot_32 = "32Mb TB";
231
232 enum {
233         /* Addresses */
234         ADDR_UNLOCK_1                   = 0x0555,
235         ADDR_UNLOCK_2                   = 0x02AA,
236         ADDR_MANUFACTURER               = 0x0000,
237         ADDR_DEVICE_ID                  = 0x0001,
238         ADDR_CFI_QUERY                  = 0x0055,
239
240         /* Commands */
241         CMD_UNLOCK_DATA_1               = 0x00AA,
242         CMD_UNLOCK_DATA_2               = 0x0055,
243         CMD_MANUFACTURER_UNLOCK_DATA    = 0x0090,
244         CMD_PROGRAM_UNLOCK_DATA         = 0x00A0,
245         CMD_RESET_DATA                  = 0x00F0,
246         CMD_SECTOR_ERASE_UNLOCK_DATA_1  = 0x0080,
247         CMD_SECTOR_ERASE_UNLOCK_DATA_2  = 0x0030,
248         CMD_CFI_QUERY_DATA              = 0x0098,
249
250         /* Offsets */
251         OFFSET_CFI_ID                   = 0x10,
252         OFFSET_CFI_SIZE                 = 0x27,
253         OFFSET_CFI_BLOCK_COUNT          = 0x2C,
254         OFFSET_CFI_BLOCK                = 0x2D,
255
256         /* Manufacturers */
257         MANUFACTURER_AMD                = 0x01,
258         MANUFACTURER_ATMEL              = 0x1F,
259         MANUFACTURER_FUJITSU            = 0x04,
260         MANUFACTURER_SST                = 0xBF,
261         MANUFACTURER_ST                 = 0x20,
262         MANUFACTURER_TOSHIBA            = 0x98,
263
264
265         /* To save precious space we store mfr and dev id together */
266
267         /* AMD devices */
268         AM29F800BB                      = 0x00012258,
269         AM29F800BT                      = 0x000122D6,
270         AM29LV800BB                     = 0x0001225B,
271         AM29LV800BT                     = 0x000122DA,
272         AM29LV160BT                     = 0x000122C4,
273
274         /* Atmel devices */
275         AT49xV16x                       = 0x001F00C0,
276         AT49xV16xT                      = 0x001F00C2,
277         AT49BV32xAT                     = 0x001F00C9,
278
279         /* Fujitsu devices */
280         MBM29LV160TE                    = 0x000422C4,
281         MBM29LV160BE                    = 0x00042249,
282
283         /* SST devices */
284         SST39LF800                      = 0x00BF2781,
285         SST39LF160                      = 0x00BF2782,
286
287         /* ST devices */
288         M29W800T                        = 0x002000D7, /* Used in 5600, similar
289                                                        * to AM29LV800, but no
290                                                        * unlock bypass
291                                                        */
292         /* Toshiba devices */
293         TC58FVT160                      = 0x009800C2,
294         TC58FVB160                      = 0x00980043,
295         TC58FVT800                      = 0x0098004F,
296
297         /* Toggle bit mask */
298         D6_MASK                         = 0x40
299 };
300
301 struct region {
302         unsigned long offset;
303         unsigned int sector_size;
304         unsigned int numsectors;
305 };
306
307 #define MAXREGIONS 8
308
309 struct chip {
310         volatile unsigned char *base;
311 #ifdef INTERLEAVE
312         byte interleave;
313         byte buswidth;
314 #endif
315         unsigned int size;
316         unsigned short numregions;
317         struct region regions[MAXREGIONS];
318 };
319
320 /* Allocate flash structures and initialize base. */
321 static struct chip chips[2] = {
322         { (unsigned char *)0x80000000,
323 #ifdef INTERLEAVE
324                 0, 0,
325 #endif
326                 0, 0, { } },
327         { (unsigned char *)0x84000000,
328 #ifdef INTERLEAVE
329                 0, 0,
330 #endif
331                 0, 0, { } }
332 };
333
334
335
336 static unsigned int
337 wide_read(struct chip *flash, unsigned long offset)
338 {
339 #ifdef INTERLEAVE
340         switch (flash->buswidth) {
341         case 2:
342 #endif
343                 return *((uword *)(flash->base + offset));
344
345 #ifdef INTERLEAVE
346         case 4:
347                 return *((udword *)(flash->base + offset));
348         }
349
350         return 0;
351 #endif
352 }
353
354 static int
355 wide_write_chunk(struct chip *flash, unsigned long offset, const void *chunk)
356 {
357 #ifdef INTERLEAVE
358         switch (flash->buswidth) {
359         case 2:
360 #endif
361                 *((uword *)(flash->base + offset)) = *((uword *)chunk);
362                 return 2;
363
364 #ifdef INTERLEAVE
365         case 4:
366                 *((udword *)(flash->base + offset)) = *((udword *)chunk);
367                 return 4;
368         }
369
370         return 0;
371 #endif
372 }
373
374 static void
375 wide_cmd(struct chip *flash, udword cmd, unsigned long offset)
376 {
377 #ifdef INTERLEAVE
378         if (flash->interleave == 1) {
379 #endif
380                 offset <<= 1;
381 #ifdef INTERLEAVE
382         } else if (flash->interleave == 2) {
383                 cmd |= (cmd << 16);
384                 offset <<= 2;
385         } else {
386                 safe_printk("Unsupported interleave!\n");
387                 return;
388         }
389 #endif
390
391         wide_write_chunk(flash, offset, &cmd);
392 }
393
394 static void
395 flash_unlock(struct chip *flash)
396 {
397         wide_cmd(flash, CMD_UNLOCK_DATA_1, ADDR_UNLOCK_1);
398         wide_cmd(flash, CMD_UNLOCK_DATA_2, ADDR_UNLOCK_2);
399 }
400
401 static int
402 flash_is_busy(struct chip *flash, unsigned long offset)
403 {
404 #ifdef INTERLEAVE
405         if (flash->interleave == 2) {
406                 udword read1, read2;
407
408                 read1 = wide_read(flash, offset);
409                 read2 = wide_read(flash, offset);
410                 return (((read1 >> 16) & D6_MASK) !=
411                         ((read2 >> 16) & D6_MASK)) ||
412                        (((read1 & 0xffff) & D6_MASK) !=
413                         ((read2 & 0xffff) & D6_MASK));
414         }
415 #endif
416
417         return ((wide_read(flash, offset) & D6_MASK) !=
418                 (wide_read(flash, offset) & D6_MASK));
419 }
420
421
422
423 #ifdef CFI_PROBE
424 static int
425 try_cfi(struct chip *flash)
426 {
427         int offset_shift = 1;
428
429 #ifdef INTERLEAVE
430         if (flash->interleave == 2) {
431                 offset_shift = 2;
432         }
433 #endif
434
435         /* Enter CFI mode */
436         wide_cmd(flash, CMD_CFI_QUERY_DATA, ADDR_CFI_QUERY);
437
438         /* Check if flash responds correctly */
439         if ((byte)wide_read(flash, (OFFSET_CFI_ID+0) << offset_shift) == 'Q' &&
440             (byte)wide_read(flash, (OFFSET_CFI_ID+1) << offset_shift) == 'R' &&
441             (byte)wide_read(flash, (OFFSET_CFI_ID+2) << offset_shift) == 'Y') {
442                 int block;               /* Current block */
443                 int block_count;         /* Number of blocks */
444                 unsigned int offset = 0; /* Offset into flash */
445                 int reverse = 0;         /* Reverse block table */
446                 int primary;             /* Offset to vendor specific table */
447
448                 safe_printk("Found 1 x CFI at ");
449                 send_hex((udword)flash->base, NL);
450
451                 flash->size =
452                         1 << wide_read(flash, OFFSET_CFI_SIZE << offset_shift);
453
454                 /* CFI stores flash organization in blocks. Each block contains
455                  * a number of sectors with the same size
456                  */
457                 block_count = wide_read(flash, OFFSET_CFI_BLOCK_COUNT <<
458                                                offset_shift);
459
460                 /* Check if table is reversed */
461                 primary = wide_read(flash, (OFFSET_CFI_ID+5) << offset_shift);
462                 /* For CFI version 1.0 we don't know. Assume that id & 0x80 */
463                 /* indicates top boot */
464                 if ((byte)wide_read(flash, (primary+4) << offset_shift) == 0x30)
465                 {
466                         /* read device id */
467                         wide_cmd(flash, CMD_RESET_DATA, ADDR_UNLOCK_1);
468                         flash_unlock(flash);
469                         wide_cmd(flash, CMD_MANUFACTURER_UNLOCK_DATA,
470                                  ADDR_UNLOCK_1);
471                         reverse = wide_read(flash, ADDR_DEVICE_ID * TYPE_X16
472 #ifdef INTERLEAVE
473                                             * flash->interleave
474 #endif
475                                            ) & 0x80;
476                         wide_cmd(flash, CMD_CFI_QUERY_DATA, ADDR_CFI_QUERY);
477                 } else {
478                         reverse = ((byte)wide_read(flash,
479                                         (primary+15) << offset_shift) == 3);
480                 }
481
482                 flash->numregions = block_count;
483                 if (block_count > MAXREGIONS) {
484                         safe_printk("Too many regions on chip!\n");
485                         return 0;
486                 }
487
488                 /* Blocks are stored backwards compared to flash organization */
489                 for (block = reverse ? block_count - 1 : 0;
490                      reverse ? block >= 0 : block < block_count;
491                      reverse ? block-- : block++) {
492                         int region;
493
494                         /* Size of each sector in block. Size is stored as
495                          * sector_size / 256.
496                          */
497                         int sector_size =
498                             (wide_read(flash, (OFFSET_CFI_BLOCK+block * 4+2) <<
499                                               offset_shift)
500                                 |
501                             (wide_read(flash, (OFFSET_CFI_BLOCK+block * 4+3) <<
502                                               offset_shift) << 8)
503                             ) << 8;
504
505                         /* Number of sectors */
506                         int sector_count =
507                             (wide_read(flash, (OFFSET_CFI_BLOCK+block * 4+0) <<
508                                               offset_shift)
509                                 |
510                             (wide_read(flash, (OFFSET_CFI_BLOCK+block * 4+1) <<
511                                               offset_shift) << 8)
512                             ) + 1;
513
514                         region = reverse? block_count - 1 - block : block;
515                         flash->regions[region].offset = offset;
516                         flash->regions[region].sector_size = sector_size;
517                         flash->regions[region].numsectors = sector_count;
518
519                         /* Can't use multiplication (we have no lib). */
520                         {
521                                 int temp;
522                                 for (temp = 0 ; temp < sector_count ; temp++) {
523                                         offset += sector_size;
524                                 }
525                         }
526
527 FDEBUG(
528         if (reverse) {
529                 safe_printk("NOTE! reversed table:\n");
530         }
531         safe_printk("region: ");
532         send_hex((udword)region, NL);
533         safe_printk("   offset: ");
534         send_hex((udword)flash->regions[region].offset, NL);
535         safe_printk("   sector_size: ");
536         send_hex((udword)flash->regions[region].sector_size, NL);
537         safe_printk("   numsectors: ");
538         send_hex((udword)flash->regions[region].numsectors, NL);
539 )
540
541                 /* Some flashes (SST) store information about alternate
542                          * block sizes. Ignore those by breaking when the sum
543                          * of the sector sizes == flash size.
544                          */
545                         if (offset == flash->size) {
546                                 break;
547                         }
548                 }
549
550                 /* reset */
551                 wide_cmd(flash, CMD_RESET_DATA, ADDR_UNLOCK_1);
552
553                 return 1;
554         }
555
556         /* reset */
557         wide_cmd(flash, CMD_RESET_DATA, ADDR_UNLOCK_1);
558
559         return 0;
560 }
561 #endif
562
563
564
565 static int
566 flash_probe(struct chip *flash)
567 {
568         char *message;
569         udword dev_id;
570         udword mfr_id;
571         udword id;
572
573         if (flash->size
574 #ifdef CFI_PROBE
575             || try_cfi(flash)
576 #endif
577            ) {
578                 return 1;
579         }
580
581 #ifdef JEDEC_PROBE
582         /* Read manufacturer ID. */
583         flash_unlock(flash);
584         wide_cmd(flash, CMD_MANUFACTURER_UNLOCK_DATA, ADDR_UNLOCK_1);
585         mfr_id = wide_read(flash, ADDR_MANUFACTURER * TYPE_X16
586 #ifdef INTERLEAVE
587                            * flash->interleave
588 #endif
589                           );
590         /* Read device ID. */
591         dev_id = wide_read(flash, ADDR_DEVICE_ID * TYPE_X16
592 #ifdef INTERLEAVE
593                            * flash->interleave
594 #endif
595                           );
596 FDEBUG(
597         safe_printk("mfr_id: ");
598         send_hex(mfr_id, NL);
599         safe_printk("dev_id: ");
600         send_hex(dev_id, NL);
601 )
602
603 #ifdef INTERLEAVE
604         if ((flash->interleave == 2) &&
605             ((mfr_id >> 16) == (mfr_id & 0xffff)) &&
606             ((dev_id >> 16) == (dev_id & 0xffff))) {
607                 mfr_id &= 0xffff;
608                 dev_id &= 0xffff;
609         }
610 #endif
611
612         id = (mfr_id << 16) | dev_id;
613
614         /* reset */
615         wide_cmd(flash, CMD_RESET_DATA, ADDR_UNLOCK_1);
616
617         /* Check device type and fill in correct sizes. */
618         switch (id) {
619                 case AM29LV160BT:
620                 case TC58FVT160:
621                 // case MBM29LV160TE: /* This is same id as AM29LV160BT */
622                         message = message_top_boot_16;
623
624                         flash->size = 0x00200000;
625
626                         flash->regions[0].offset = 0x00000000;
627                         flash->regions[0].sector_size = 0x10000;
628                         flash->regions[0].numsectors = 31;
629
630                         flash->regions[1].offset = 0x001F0000;
631                         flash->regions[1].sector_size = 0x08000;
632                         flash->regions[1].numsectors = 1;
633
634                         flash->regions[2].offset = 0x001F8000;
635                         flash->regions[2].sector_size = 0x02000;
636                         flash->regions[2].numsectors = 2;
637
638                         flash->regions[3].offset = 0x001FC000;
639                         flash->regions[3].sector_size = 0x04000;
640                         flash->regions[3].numsectors = 1;
641                                 break;
642
643                 // case AM29LV160BB:
644                 case TC58FVB160:
645                 case MBM29LV160BE:
646                         message = message_bottom_boot_16;
647
648                         flash->size = 0x00200000;
649
650                         flash->regions[0].offset = 0x00000000;
651                         flash->regions[0].sector_size = 0x04000;
652                         flash->regions[0].numsectors = 1;
653
654                         flash->regions[1].offset = 0x00004000;
655                         flash->regions[1].sector_size = 0x02000;
656                         flash->regions[1].numsectors = 2;
657
658                         flash->regions[2].offset = 0x00008000;
659                         flash->regions[2].sector_size = 0x08000;
660                         flash->regions[2].numsectors = 1;
661
662                         flash->regions[3].offset = 0x00010000;
663                         flash->regions[3].sector_size = 0x10000;
664                         flash->regions[3].numsectors = 31;
665                         break;
666
667                 case AM29LV800BB:
668                 case AM29F800BB:
669                         message = message_bottom_boot_8;
670
671                         flash->size = 0x00100000;
672
673                         flash->regions[0].offset = 0x00000000;
674                         flash->regions[0].sector_size = 0x04000;
675                         flash->regions[0].numsectors = 1;
676
677                         flash->regions[1].offset = 0x00004000;
678                         flash->regions[1].sector_size = 0x02000;
679                         flash->regions[1].numsectors = 2;
680
681                         flash->regions[2].offset = 0x00008000;
682                         flash->regions[2].sector_size = 0x08000;
683                         flash->regions[2].numsectors = 1;
684
685                         flash->regions[3].offset = 0x00010000;
686                         flash->regions[3].sector_size = 0x10000;
687                         flash->regions[3].numsectors = 15;
688                         break;
689
690                 case M29W800T:
691                 case AM29LV800BT:
692                 case AM29F800BT:
693                 case TC58FVT800:
694                         message = message_top_boot_8;
695
696                         flash->size = 0x00100000;
697
698                         flash->regions[0].offset = 0x00000000;
699                         flash->regions[0].sector_size = 0x10000;
700                         flash->regions[0].numsectors = 15;
701
702                         flash->regions[1].offset = 0x000F0000;
703                         flash->regions[1].sector_size = 0x08000;
704                         flash->regions[1].numsectors = 1;
705
706                         flash->regions[2].offset = 0x000F8000;
707                         flash->regions[2].sector_size = 0x02000;
708                         flash->regions[2].numsectors = 2;
709
710                         flash->regions[3].offset = 0x000FC000;
711                         flash->regions[3].sector_size = 0x04000;
712                         flash->regions[3].numsectors = 1;
713
714                         break;
715
716                 case AT49xV16x:
717                         message = message_bottom_boot_16;
718
719                         flash->size = 0x00200000;
720
721                         flash->regions[0].offset = 0x00000000;
722                         flash->regions[0].sector_size = 0x02000;
723                         flash->regions[0].numsectors = 8;
724
725                         flash->regions[1].offset = 0x00010000;
726                         flash->regions[1].sector_size = 0x10000;
727                         flash->regions[1].numsectors = 31;
728
729                         break;
730
731                 case AT49xV16xT:
732                         message = message_top_boot_16;
733
734                         flash->size = 0x00200000;
735
736                         flash->regions[0].offset = 0x00000000;
737                         flash->regions[0].sector_size = 0x10000;
738                         flash->regions[0].numsectors = 31;
739
740                         flash->regions[1].offset = 0x001F0000;
741                         flash->regions[1].sector_size = 0x02000;
742                         flash->regions[1].numsectors = 8;
743
744                         break;
745
746                 case AT49BV32xAT:
747                         message = message_top_boot_32;
748
749                         flash->size = 0x00400000;
750
751                         flash->regions[0].offset = 0x00000000;
752                         flash->regions[0].sector_size = 0x10000;
753                         flash->regions[0].numsectors = 63;
754
755                         flash->regions[1].offset = 0x001F0000;
756                         flash->regions[1].sector_size = 0x02000;
757                         flash->regions[1].numsectors = 8;
758
759                         break;
760
761                 default:
762 #endif
763 #ifdef INTERLEAVE
764                         if (flash->interleave == 1) {
765 #endif
766                                 safe_printk("No single x16 at ");
767 #ifdef INTERLEAVE
768                         } else {
769                                 safe_printk("No interleaved x16 at ");
770                         }
771 #endif
772                         send_hex((udword)flash->base, NL);
773
774                         return 0;
775 #ifdef JEDEC_PROBE
776         }
777
778         safe_printk("Found ");
779 #ifdef INTERLEAVE
780         if (flash->interleave == 1) {
781 #endif
782                 safe_printk("1");
783 #ifdef INTERLEAVE
784         }
785         if (flash->interleave == 2) {
786         int count = 0;
787
788                 flash->size <<= 1;
789         while (count < MAXREGIONS) {
790                 flash->regions[count].offset <<= 1;
791                 flash->regions[count].sector_size <<= 1;
792                 count++;
793         }
794                 safe_printk("2");
795         }
796 #endif
797         safe_printk(" x ");
798         safe_printk(message);
799         safe_printk(" at ");
800         send_hex((udword)flash->base, NL);
801
802         return 1;
803 #endif
804 }
805
806 /* Start erase of a sector but do no wait for completion */
807 static void
808 start_sector_erase(struct chip *flash, unsigned long offset)
809 {
810         flash_unlock(flash);
811         wide_cmd(flash, CMD_SECTOR_ERASE_UNLOCK_DATA_1, ADDR_UNLOCK_1);
812         flash_unlock(flash);
813
814 #ifdef INTERLEAVE
815         if (flash->interleave == 2) {
816                 *(udword *)(flash->base+offset) = (CMD_SECTOR_ERASE_UNLOCK_DATA_2 << 16) |
817                                                    CMD_SECTOR_ERASE_UNLOCK_DATA_2;
818         } else {
819 #endif
820                 *(uword *)(flash->base+offset) = CMD_SECTOR_ERASE_UNLOCK_DATA_2;
821 #ifdef INTERLEAVE
822         }
823 #endif
824 }
825
826 /* Return the size of the sector at the given offset */
827 static int
828 find_sector_size(struct chip *flash, unsigned long offset)
829 {
830         unsigned int i, j;
831         int region_size;
832         /* Sanity check */
833         if (offset >= flash->size)
834                 return 0;
835
836         for(i=0; i < MAXREGIONS; i++) 
837                 if (offset >= flash->regions[i].offset) {
838                         region_size=0;
839                         for (j=0; j < flash->regions[i].numsectors; j++)
840                                 region_size += flash->regions[i].sector_size;
841                         if (offset < flash->regions[i].offset + region_size)
842                                 return flash->regions[i].sector_size;
843                 }
844
845         /* Should not happen */
846         return 0;
847 }
848
849 /* Check and see if we need to erase the sector  */
850 /* The return values mean */
851 /* 0: The source and destination are the same. */
852 /* 1: The source and destination are not the same, but flash sector already contains only ones. */
853 /* 2: The source and destination are not the same and the flash sector is tainted by some zeroes. */
854 static char
855 need_to_erase(struct chip *flash, unsigned long offset, const unsigned char *source, int size)
856 {
857         int i;
858         unsigned long j;
859                 
860         for (i = 0; i < size; i+=2)
861                 if (*(uword*)(flash->base + i + offset) != *(uword*)(source + i)) {
862                         /* Check if the sector only contain zeroes */
863                         for (j = offset; j < (size + offset); j+=2) {
864                                 if (*(uword*)(flash->base + j) != 0xffff)
865                                         return 2;
866                         }
867                         return 1;
868                 }
869                         
870         /* The source is equal to the destination */
871         return 0;
872 }
873
874 static unsigned int
875 flash_probe_chips(void)
876 {
877         unsigned int tot_size = 0;
878         unsigned int i = 0;
879
880         for (; i < sizeof chips/sizeof *chips; i++) {
881 #ifdef INTERLEAVE
882                 byte interleave;
883
884                 for (interleave = 1; interleave < 4; interleave *= 2) {
885                         chips[i].interleave = interleave;
886                         if (interleave == 1) {
887                                 chips[i].buswidth = sizeof(uword);
888                         } else {
889                                 chips[i].buswidth = sizeof(udword);
890                         }
891
892                         if (flash_probe(&chips[i])) {
893                                 break;
894                         }
895                 }
896 #else
897                 flash_probe(&chips[i]);
898 #endif
899
900                 tot_size += chips[i].size;
901         }
902
903         return tot_size;
904 }
905
906 /* Program a sector (given by size) at the given offset. Do not write only ones. */
907 static void
908 program_sector(struct chip *flash, unsigned long offset, const unsigned char *source, int size)
909 {
910         int chunk_size = 0;
911         int bytes_written = 0;
912
913         
914         while (bytes_written < size) {
915                 if (
916 #ifdef INTERLEAVE
917                     (flash->buswidth == 2) && 
918 #endif
919                     *(uword*)(source + bytes_written) == 0xffff) {
920                         chunk_size=2;   
921                 }
922 #ifdef INTERLEAVE
923                 else if ((flash->buswidth == 4) && *(udword*)(source + bytes_written) == 0xffffffff) {
924                         chunk_size=4;   
925                 }
926 #endif
927                 else {
928                         flash_unlock(flash);
929                         wide_cmd(flash, CMD_PROGRAM_UNLOCK_DATA, ADDR_UNLOCK_1);
930                         chunk_size = wide_write_chunk(flash, offset + bytes_written, source + bytes_written);
931                         while(flash_is_busy(flash, offset + bytes_written))
932                         /* Nothing */  
933                         ;
934                 }
935                 
936                 bytes_written += chunk_size;
937         }
938 }
939
940 int
941 flash_write(const unsigned char *source, unsigned int offset, unsigned int size)
942 {
943         struct flash_status {
944                 unsigned char busy;             /* Indicates if the flash is busy */
945                 const unsigned char *src;       /* From where to get the source info */
946                 unsigned long offset;           /* Start operations in flash at this offset */
947                 unsigned int size;              /* Size to erase/program (if needed) */
948                 unsigned int bytes_done;        /* Bytes written (if needed) */
949                 unsigned int erase_attempts;    /* Keep track how many times we try to erase the same sector */
950         };
951         
952         unsigned int tot_size = flash_probe_chips();
953         unsigned int i, j;
954         unsigned int current_sector_size;
955         unsigned long current_offset;
956         const unsigned char *current_src;
957         char need_erase;
958         struct flash_status *current_flash = NULL;
959         
960         static struct flash_status flash_status[2] = {
961                 { 0, NULL, 0, 0, 0, 0 },
962                 { 0, NULL, 0, 0, 0, 0 }
963         };
964
965         if (!tot_size) {
966                 /* No chips found, bail out. */
967                 return ERR_FLASH_NONE;
968         }
969
970         if (offset + size > tot_size) {
971                 safe_printk("Fatal: flash is too small.\n");
972                 return ERR_FLASH_TOO_SMALL;
973         }
974
975         /* Initiate the flash_status structs so that we can keep track of what needs to be done
976            on the different flash chips */
977         
978         /* Operations only on flash chip 1 */
979         if (offset >= (&chips[0])->size) {
980                 flash_status[0].size = 0;
981                 flash_status[1].src = source;
982                 flash_status[1].offset = offset - (&chips[0])->size;
983                 flash_status[1].size = size;
984         }
985         /* Operations on both flash chips */
986         else if ((offset < (&chips[0])->size) && ((offset+size) > (&chips[0])->size)) {
987                 flash_status[0].src = source;
988                 flash_status[0].offset = offset;
989                 flash_status[0].size = (&chips[0])->size - offset;
990                 flash_status[1].src = source + flash_status[0].size;
991                 flash_status[1].offset = 0;
992                 flash_status[1].size = size - flash_status[0].size;
993         } 
994         /* Operations only on flash chip 0 */
995         else {
996                 flash_status[0].src = source;
997                 flash_status[0].offset = offset;
998                 flash_status[0].size = size;
999                 flash_status[1].size = 0;
1000         }
1001         flash_status[0].busy = 0;
1002         flash_status[0].bytes_done = 0;
1003         flash_status[0].erase_attempts = 0;
1004         flash_status[1].busy = 0;
1005         flash_status[1].bytes_done = 0;
1006         flash_status[1].erase_attempts = 0;
1007 #if 0
1008         for (i = 0; i < 2; i++) { 
1009                 safe_printk("\nFlash ");
1010                 send_hex(i, NL);
1011                 safe_printk("src:\t");
1012                 send_hex((int)flash_status[i].src, NL);
1013                 safe_printk("offset:\t");
1014                 send_hex(flash_status[i].offset, NL);
1015                 safe_printk("size:\t");
1016                 send_hex(flash_status[i].size, NL);
1017                 safe_printk("\n");
1018         }
1019 #endif
1020
1021         /* Erase and write */
1022
1023         i = 0;  /* Start operations on flash 0 */       
1024
1025 #define CHANGE_FLASH
1026
1027         while (((&flash_status[0])->bytes_done + (&flash_status[1])->bytes_done) < size) {
1028         
1029                 struct flash_status *previous_flash = &flash_status[i ? 0 : 1];
1030                 current_flash = &flash_status[i];
1031
1032 #ifdef CHANGE_FLASH
1033                 /* Change flash only if:
1034                    - There is a flash to change to and operations should be made on that flash *AND*
1035                    - There is more to write to the previous flash *AND*
1036                    - Operations should be made on the current flash *OR*
1037                    - The current flash is busy *OR*
1038                    - All has been written to the current flash */
1039         
1040                 if (previous_flash->size && (previous_flash->bytes_done < previous_flash->size) &&
1041                         (!current_flash->size || current_flash->busy || 
1042                           current_flash->bytes_done == current_flash->size))    
1043                                 i = i ? 0 : 1;  /* Change flash chip */ 
1044 #else
1045                 /* Finish one flash chip before continuing on the next one */
1046                 
1047                 if ((&flash_status[i])->bytes_done == (&flash_status[i])->size)
1048                         i = i ? 0 : 1;  /* Change flash chip */ 
1049 #endif
1050                 /* Bail out if we have tried to erase the same sector more that 10 times. */
1051                 if(current_flash->erase_attempts > 10) {
1052                         safe_printk("Sector erase error\n");
1053                         return ERR_FLASH_ERASE;
1054                 }
1055
1056                 /* Get the current status from the chip we are about to access */
1057                 current_flash = &flash_status[i];
1058                 current_offset = current_flash->offset + current_flash->bytes_done;
1059                 current_src = current_flash->src + current_flash->bytes_done;
1060                 current_sector_size = find_sector_size(&chips[i], current_offset);
1061         
1062                 /* Make sure that the chip we are about to access has finished erasing */
1063                 if (current_flash->busy) {
1064                         while (flash_is_busy(&chips[i], current_offset))
1065                                 /* nothing */
1066                                 ;
1067                         current_flash->busy = 0;
1068                 }
1069                 
1070                 /* Some flash chip need a reset to bring them back to read mode again. */
1071                 wide_cmd(&chips[i], CMD_RESET_DATA, ADDR_UNLOCK_1);
1072         
1073                 /* Find out if we need to erase the sector or not */
1074                 need_erase = need_to_erase(&chips[i], current_offset, current_src, current_sector_size);
1075                 
1076                 if (need_erase == 0) {
1077                         current_flash->bytes_done += current_sector_size;
1078                         current_flash->erase_attempts = 0;
1079                         send_hex((int)(&chips[i])->base + current_offset, 0);
1080                         safe_printk(": No need to write\n");
1081                         continue;
1082                 } else if (need_erase == 1) {
1083                         /* Erased, not worth printing. */
1084                 }
1085                 else if (need_erase == 2) {
1086                         send_hex((int)(&chips[i])->base + current_offset, 0);
1087                         safe_printk(": Erasing ");
1088                         send_hex(current_sector_size, 0);
1089                         safe_printk(" bytes\n");
1090                         start_sector_erase(&chips[i], current_offset);          
1091                         current_flash->busy=1;
1092                         current_flash->erase_attempts++;
1093                         continue;
1094                 }
1095                         
1096                 /* The sector is ready to be programmed */      
1097                 send_hex((int)(&chips[i])->base + current_offset, 0);
1098                 safe_printk(": Writing ");
1099                 send_hex(current_sector_size, 0);
1100                 safe_printk(" bytes\n");
1101                 program_sector(&chips[i], current_offset, current_src, current_sector_size);
1102                 current_flash->bytes_done += current_sector_size;
1103                 current_flash->erase_attempts = 0;
1104         }
1105         
1106         /* Verify that the flash chip(s) have the correct content */
1107         for (i = 0; i < 2; i++) {
1108                 current_flash = &flash_status[i]; 
1109                 if (!current_flash->size)
1110                         continue;
1111                 send_hex((int)(&chips[i])->base, 0);
1112                 safe_printk(": Verifying...");
1113                 for (j = 0; j < current_flash->size; j+=2) {
1114                         if (*(uword*)(current_flash->offset + j + (&chips[i])->base) != 
1115                             *(uword*)(current_flash->src + j)) {
1116                                 safe_printk("Error at ");
1117                                 send_hex(j, NL);
1118                                 return ERR_FLASH_VERIFY;
1119                         }
1120                 }
1121                 safe_printk("OK\n");
1122         }
1123
1124         return ERR_FLASH_OK;
1125 }