]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/mousse/flash.c
Initial revision
[karo-tx-uboot.git] / board / mousse / flash.c
1 /*
2  * MOUSSE/MPC8240 Board definitions.
3  * Flash Routines for MOUSSE onboard AMD29LV106DB devices
4  *
5  * (C) Copyright 2000
6  * Marius Groeger <mgroeger@sysgo.de>
7  * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
8  *
9  * (C) Copyright 2000
10  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
11  *
12  * (C) Copyright 1999, by Curt McDowell, 08-06-99, Broadcom Corp.
13  * (C) Copyright 2001, James Dougherty, 07/18/01, Broadcom Corp.
14  *
15  * See file CREDITS for list of people who contributed to this
16  * project.
17  *
18  * This program is free software; you can redistribute it and/or
19  * modify it under the terms of the GNU General Public License as
20  * published by the Free Software Foundation; either version 2 of
21  * the License, or (at your option) any later version.
22  *
23  * This program is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26  * GNU General Public License for more details.
27  *
28  * You should have received a copy of the GNU General Public License
29  * along with this program; if not, write to the Free Software
30  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
31  * MA 02111-1307 USA
32  */
33
34 #include <common.h>
35 #include <mpc8xx.h>
36 #include <malloc.h>
37 #include "mousse.h"
38 #include "flash.h"
39
40 int flashLibDebug = 0;
41 int flashLibInited = 0;
42
43 #define OK  0
44 #define ERROR -1
45 #define STATUS int
46 #define PRINTF                  if (flashLibDebug) printf
47 #if 0
48 #define PRIVATE                 static
49 #else
50 #define PRIVATE
51 #endif
52
53 flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
54
55 #define SLEEP_DELAY    166
56 #define FLASH_SECTOR_SIZE   (64*1024)
57 /***********************************************************************
58  *
59  * Virtual Flash Devices on Mousse board
60  *
61  * These must be kept in sync with the definitions in flashLib.h.
62  *
63  ***********************************************************************/
64
65 PRIVATE flash_dev_t flashDev[] = {
66     /* Bank 0 sector SA0 (16 kB) */
67     {   "SA0",FLASH0_BANK, FLASH0_SEG0_START, 1, 14,
68         FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
69     },
70     /* Bank 0 sector SA1 (8 kB) */
71     {   "SA1", FLASH0_BANK, FLASH0_SEG0_START + 0x4000, 1, 13,
72         FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
73     },
74     /* Bank 0 sector SA2 (8 kB) */
75     {   "SA2", FLASH0_BANK, FLASH0_SEG0_START + 0x6000, 1, 13,
76         FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
77     },
78     /* Bank 0 sector SA3 is occluded by Mousse I/O devices */
79     /* Bank 0 sectors SA4-SA18, after Mousse devices up to PLCC (960 kB)  */
80     {   "KERNEL", FLASH0_BANK, FLASH0_SEG1_START, 15, 16,
81         FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
82     },
83     /* Bank 0 sectors SA19-SA26, jumper can occlude this by PLCC (512 kB) */
84     /* This is where the Kahlua boot vector and boot ROM code resides. */
85     {   "BOOT",FLASH0_BANK, FLASH0_SEG2_START, 8, 16,
86         FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
87     },
88     /* Bank 0 sectors SA27-SA34 (512 kB) */
89     {   "RAMDISK",FLASH0_BANK, FLASH0_SEG3_START, 8, 16,
90         FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
91     },
92 };
93
94 int flashDevCount = (sizeof (flashDev) / sizeof (flashDev[0]));
95
96 #define DEV(no)                 (&flashDev[no])
97 #define DEV_NO(dev)             ((dev) - flashDev)
98
99 /***********************************************************************
100  *
101  * Private Flash Routines
102  *
103  ***********************************************************************/
104
105 /*
106  * The convention is:
107  *
108  * "addr" is always the PROM raw address, which is the address of an
109  * 8-bit quantity for flash 0 and 16-bit quantity for flash 1.
110  *
111  * "pos" is always a logical byte position from the PROM beginning.
112  */
113
114 #define FLASH0_ADDR(dev, addr) \
115         ((unsigned char *) ((dev)->base + (addr)))
116
117 #define FLASH0_WRITE(dev, addr, value) \
118         (*FLASH0_ADDR(dev, addr) = (value))
119
120 #define FLASH0_READ(dev, addr) \
121         (*FLASH0_ADDR(dev, addr))
122
123 PRIVATE int flashCheck(flash_dev_t *dev)
124 {
125     if (! flashLibInited) {
126         printf("flashCheck: flashLib not initialized\n");
127         return ERROR;
128     }
129
130     if (dev < &flashDev[0] || dev >= &flashDev[flashDevCount]) {
131         printf("flashCheck: Bad dev parameter\n");
132         return ERROR;
133     }
134
135     if (! dev->found) {
136         printf("flashCheck: Device %d not available\n", DEV_NO(dev));
137         return ERROR;
138     }
139
140     return OK;
141 }
142
143 PRIVATE void flashReset(flash_dev_t *dev)
144 {
145     PRINTF("flashReset: dev=%d\n", DEV_NO(dev));
146
147     if (dev->bank == FLASH0_BANK) {
148         FLASH0_WRITE(dev, 0x555, 0xaa);
149         FLASH0_WRITE(dev, 0xaaa, 0x55);
150         FLASH0_WRITE(dev, 0x555, 0xf0);
151     }
152
153     udelay(SLEEP_DELAY);
154
155     PRINTF("flashReset: done\n");
156 }
157
158 PRIVATE int flashProbe(flash_dev_t *dev)
159 {
160     int                 rv, deviceID, vendorID;
161
162     PRINTF("flashProbe: dev=%d\n", DEV_NO(dev));
163
164     if (dev->bank != FLASH0_BANK) {
165         rv = ERROR;
166         goto DONE;
167     }
168
169     FLASH0_WRITE(dev, 0xaaa, 0xaa);
170     FLASH0_WRITE(dev, 0x555, 0x55);
171     FLASH0_WRITE(dev, 0xaaa, 0x90);
172
173     udelay(SLEEP_DELAY);
174
175     vendorID = FLASH0_READ(dev, 0);
176     deviceID = FLASH0_READ(dev, 2);
177
178     FLASH0_WRITE(dev, 0, 0xf0);
179
180     PRINTF("flashProbe: vendor=0x%x device=0x%x\n", vendorID, deviceID);
181
182     if (vendorID == dev->vendorID && deviceID == dev->deviceID)
183         rv = OK;
184     else
185         rv = ERROR;
186
187 DONE:
188     PRINTF("flashProbe: rv=%d\n", rv);
189
190     return rv;
191 }
192
193 PRIVATE int flashWait(flash_dev_t *dev, int addr, int expect, int erase)
194 {
195     int                 rv = ERROR;
196     int                 i, data;
197     int                 polls;
198 #if 0
199     PRINTF("flashWait: dev=%d addr=0x%x expect=0x%x erase=%d\n",
200            DEV_NO(dev), addr, expect, erase);
201 #endif
202
203     if (dev->bank != FLASH0_BANK) {
204         rv = ERROR;
205         goto done;
206     }
207
208     if (erase)
209         polls = FLASH_ERASE_SECTOR_TIMEOUT;     /* Ticks */
210     else
211         polls = FLASH_PROGRAM_POLLS;            /* Loops */
212
213     for (i = 0; i < polls; i++) {
214         if (erase)
215             udelay(SLEEP_DELAY);
216
217         data = FLASH0_READ(dev, addr);
218
219         if (((data ^ expect) & 0x80) == 0) {
220             rv = OK;
221             goto done;
222         }
223
224         if (data & 0x20) {
225             /*
226              * If the 0x20 bit has come on, it could actually be because
227              * the operation succeeded, so check the done bit again.
228              */
229
230             data = FLASH0_READ(dev, addr);
231
232             if (((data ^ expect) & 0x80) == 0) {
233                 rv = OK;
234                 goto done;
235             }
236
237             printf("flashWait: Program error (dev: %d, addr: 0x%x)\n",
238                    DEV_NO(dev), addr);
239
240             flashReset(dev);
241             rv = ERROR;
242             goto done;
243         }
244     }
245
246     printf("flashWait: Timeout %s (dev: %d, addr: 0x%x)\n",
247            erase ? "erasing sector" : "programming byte",
248            DEV_NO(dev), addr);
249
250 done:
251
252 #if 0
253     PRINTF("flashWait: rv=%d\n", rv);
254 #endif
255
256     return rv;
257 }
258
259 /***********************************************************************
260  *
261  * Public Flash Routines
262  *
263  ***********************************************************************/
264
265 STATUS flashLibInit(void)
266 {
267     int                 i;
268
269     PRINTF("flashLibInit: devices=%d\n", flashDevCount);
270
271     for (i = 0; i < flashDevCount; i++) {
272         flash_dev_t     *dev = &flashDev[i];
273         /*
274          * For bank 1, probe both without and with byte swappage,
275          * so that this module works on both old and new Mousse boards.
276          */
277
278         flashReset(dev);
279
280         if (flashProbe(dev) != ERROR)
281             dev->found = 1;
282
283             flashReset(dev);
284
285             if (flashProbe(dev) != ERROR)
286                 dev->found = 1;
287
288             dev->swap = 0;
289
290             if(dev->found){
291               PRINTF("\n  FLASH %s[%d]: iobase=0x%x - %d sectors %d KB",
292                      flashDev[i].name,i,flashDev[i].base, flashDev[i].sectors,
293                      (flashDev[i].sectors * FLASH_SECTOR_SIZE)/1024);
294
295             }
296     }
297
298     flashLibInited = 1;
299
300     PRINTF("flashLibInit: done\n");
301
302     return OK;
303 }
304
305 STATUS flashEraseSector(flash_dev_t *dev, int sector)
306 {
307     int                 pos, addr;
308
309     PRINTF("flashErasesector: dev=%d sector=%d\n", DEV_NO(dev), sector);
310
311     if (flashCheck(dev) == ERROR)
312         return ERROR;
313
314     if (sector < 0 || sector >= dev->sectors) {
315         printf("flashEraseSector: Sector out of range (dev: %d, sector: %d)\n",
316                DEV_NO(dev), sector);
317         return ERROR;
318     }
319
320     pos = FLASH_SECTOR_POS(dev, sector);
321
322     if (dev->bank != FLASH0_BANK) {
323         return ERROR;
324     }
325
326     addr = pos;
327
328     FLASH0_WRITE(dev, 0xaaa, 0xaa);
329     FLASH0_WRITE(dev, 0x555, 0x55);
330     FLASH0_WRITE(dev, 0xaaa, 0x80);
331     FLASH0_WRITE(dev, 0xaaa, 0xaa);
332     FLASH0_WRITE(dev, 0x555, 0x55);
333     FLASH0_WRITE(dev, addr, 0x30);
334
335     return flashWait(dev, addr, 0xff, 1);
336 }
337
338 /*
339  * Note: it takes about as long to flash all sectors together with Chip
340  * Erase as it does to flash them one at a time (about 30 seconds for 2
341  * MB).  Also since we want to be able to treat subsets of sectors as if
342  * they were complete devices, we don't use Chip Erase.
343  */
344
345 STATUS flashErase(flash_dev_t *dev)
346 {
347     int                 sector;
348
349     PRINTF("flashErase: dev=%d sectors=%d\n", DEV_NO(dev), dev->sectors);
350
351     if (flashCheck(dev) == ERROR)
352         return ERROR;
353
354     for (sector = 0; sector < dev->sectors; sector++) {
355       if (flashEraseSector(dev, sector) == ERROR)
356             return ERROR;
357     }
358     return OK;
359 }
360
361 /*
362  * Read and write bytes
363  */
364
365 STATUS flashRead(flash_dev_t *dev, int pos, char *buf, int len)
366 {
367     int                 addr, words;
368
369     PRINTF("flashRead: dev=%d pos=0x%x buf=0x%x len=0x%x\n",
370            DEV_NO(dev), pos, (int) buf, len);
371
372     if (flashCheck(dev) == ERROR)
373         return ERROR;
374
375     if (pos < 0 || len < 0 || pos + len > FLASH_MAX_POS(dev)) {
376         printf("flashRead: Position out of range "
377                "(dev: %d, pos: 0x%x, len: 0x%x)\n",
378                DEV_NO(dev), pos, len);
379         return ERROR;
380     }
381
382     if (len == 0)
383         return OK;
384
385     if (dev->bank == FLASH0_BANK) {
386         addr = pos;
387         words = len;
388
389         PRINTF("flashRead: memcpy(0x%x, 0x%x, 0x%x)\n",
390                (int) buf, (int) FLASH0_ADDR(dev, pos), len);
391
392         memcpy(buf, FLASH0_ADDR(dev, addr), words);
393
394     }
395     PRINTF("flashRead: rv=OK\n");
396
397     return OK;
398 }
399
400 STATUS flashWrite(flash_dev_t *dev, int pos, char *buf, int len)
401 {
402     int                 addr, words;
403
404     PRINTF("flashWrite: dev=%d pos=0x%x buf=0x%x len=0x%x\n",
405            DEV_NO(dev), pos, (int) buf, len);
406
407     if (flashCheck(dev) == ERROR)
408         return ERROR;
409
410     if (pos < 0 || len < 0 || pos + len > FLASH_MAX_POS(dev)) {
411         printf("flashWrite: Position out of range "
412                "(dev: %d, pos: 0x%x, len: 0x%x)\n",
413                DEV_NO(dev), pos, len);
414         return ERROR;
415     }
416
417     if (len == 0)
418         return OK;
419
420     if (dev->bank == FLASH0_BANK) {
421         unsigned char tmp;
422
423         addr = pos;
424         words = len;
425
426         while (words--) {
427             tmp = *buf;
428             if (~FLASH0_READ(dev, addr) & tmp) {
429                 printf("flashWrite: Attempt to program 0 to 1 "
430                        "(dev: %d, addr: 0x%x, data: 0x%x)\n",
431                        DEV_NO(dev), addr, tmp);
432                 return ERROR;
433             }
434             FLASH0_WRITE(dev, 0xaaa, 0xaa);
435             FLASH0_WRITE(dev, 0x555, 0x55);
436             FLASH0_WRITE(dev, 0xaaa, 0xa0);
437             FLASH0_WRITE(dev, addr, tmp);
438             if (flashWait(dev, addr, tmp, 0) < 0)
439                 return ERROR;
440             buf++;
441             addr++;
442         }
443     }
444
445     PRINTF("flashWrite: rv=OK\n");
446
447     return OK;
448 }
449
450 /*
451  * flashWritable returns TRUE if a range contains all F's.
452  */
453
454 STATUS flashWritable(flash_dev_t *dev, int pos, int len)
455 {
456     int                 addr, words;
457     int                 rv = ERROR;
458
459     PRINTF("flashWritable: dev=%d pos=0x%x len=0x%x\n",
460            DEV_NO(dev), pos, len);
461
462     if (flashCheck(dev) == ERROR)
463         goto done;
464
465     if (pos < 0 || len < 0 || pos + len > FLASH_MAX_POS(dev)) {
466         printf("flashWritable: Position out of range "
467                "(dev: %d, pos: 0x%x, len: 0x%x)\n",
468                DEV_NO(dev), pos, len);
469         goto done;
470     }
471
472     if (len == 0) {
473         rv = 1;
474         goto done;
475     }
476
477     if (dev->bank == FLASH0_BANK) {
478         addr = pos;
479         words = len;
480
481         while (words--) {
482             if (FLASH0_READ(dev, addr) != 0xff) {
483                 rv = 0;
484                 goto done;
485             }
486             addr++;
487         }
488     }
489
490     rv = 1;
491
492  done:
493     PRINTF("flashWrite: rv=%d\n", rv);
494     return rv;
495 }
496
497
498 /*
499  * NOTE: the below code cannot run from FLASH!!!
500  */
501 /***********************************************************************
502  *
503  * Flash Diagnostics
504  *
505  ***********************************************************************/
506
507 STATUS flashDiag(flash_dev_t *dev)
508 {
509     unsigned int        *buf = 0;
510     int                 i, len, sector;
511     int                 rv = ERROR;
512
513     if (flashCheck(dev) == ERROR)
514         return ERROR;
515
516     printf("flashDiag: Testing device %d, "
517            "base: 0x%x, %d sectors @ %d kB = %d kB\n",
518            DEV_NO(dev), dev->base,
519            dev->sectors,
520            1 << (dev->lgSectorSize - 10),
521            dev->sectors << (dev->lgSectorSize - 10));
522
523     len = 1 << dev->lgSectorSize;
524
525     printf("flashDiag: Erasing\n");
526
527     if (flashErase(dev) == ERROR) {
528         printf("flashDiag: Erase failed\n");
529         goto done;
530     }
531     printf("%d bytes requested ...\n", len);
532     buf = malloc(len);
533     printf("allocated %d bytes ...\n", len);
534     if (buf == 0) {
535         printf("flashDiag: Out of memory\n");
536         goto done;
537     }
538
539     /*
540      * Write unique counting pattern to each sector
541      */
542
543     for (sector = 0; sector < dev->sectors; sector++) {
544         printf("flashDiag: Write sector %d\n", sector);
545
546         for (i = 0; i < len / 4; i++)
547             buf[i] = sector << 24 | i;
548
549         if (flashWrite(dev,
550                        sector << dev->lgSectorSize,
551                        (char *) buf,
552                        len) == ERROR) {
553             printf("flashDiag: Write failed (dev: %d, sector: %d)\n",
554                    DEV_NO(dev), sector);
555             goto done;
556         }
557     }
558
559     /*
560      * Verify
561      */
562
563     for (sector = 0; sector < dev->sectors; sector++) {
564         printf("flashDiag: Verify sector %d\n", sector);
565
566         if (flashRead(dev,
567                       sector << dev->lgSectorSize,
568                       (char *) buf,
569                       len) == ERROR) {
570             printf("flashDiag: Read failed (dev: %d, sector: %d)\n",
571                    DEV_NO(dev), sector);
572             goto done;
573         }
574
575         for (i = 0; i < len / 4; i++) {
576             if (buf[i] != (sector << 24 | i)) {
577                 printf("flashDiag: Verify error "
578                        "(dev: %d, sector: %d, offset: 0x%x)\n",
579                        DEV_NO(dev), sector, i);
580                 printf("flashDiag: Expected 0x%08x, got 0x%08x\n",
581                        sector << 24 | i, buf[i]);
582
583                 goto done;
584             }
585         }
586     }
587
588     printf("flashDiag: Erasing\n");
589
590     if (flashErase(dev) == ERROR) {
591         printf("flashDiag: Final erase failed\n");
592         goto done;
593     }
594
595     rv = OK;
596
597  done:
598     if (buf)
599         free(buf);
600
601     if (rv == OK)
602         printf("flashDiag: Device %d passed\n", DEV_NO(dev));
603     else
604         printf("flashDiag: Device %d failed\n", DEV_NO(dev));
605
606     return rv;
607 }
608
609 STATUS flashDiagAll(void)
610 {
611     int                 i;
612     int                 rv = OK;
613
614     PRINTF("flashDiagAll: devices=%d\n", flashDevCount);
615
616     for (i = 0; i < flashDevCount; i++) {
617         flash_dev_t     *dev = &flashDev[i];
618
619         if (dev->found && flashDiag(dev) == ERROR)
620             rv = ERROR;
621     }
622
623     if (rv == OK)
624         printf("flashDiagAll: Passed\n");
625     else
626         printf("flashDiagAll: Failed because of earlier errors\n");
627
628     return OK;
629 }
630
631
632 /*-----------------------------------------------------------------------
633  */
634 unsigned long flash_init (void)
635 {
636     unsigned long size = 0;
637     flash_dev_t *dev = NULL;
638     flashLibInit();
639
640     /*
641      * Provide info for FLASH (up to 960K) of Kernel Image data.
642      */
643     dev = FLASH_DEV_BANK0_LOW;
644     flash_info[FLASH_BANK_KERNEL].flash_id =
645       (dev->vendorID << 16) | dev->deviceID;
646     flash_info[FLASH_BANK_KERNEL].sector_count = dev->sectors;
647     flash_info[FLASH_BANK_KERNEL].size =
648       flash_info[FLASH_BANK_KERNEL].sector_count * FLASH_SECTOR_SIZE;
649     flash_info[FLASH_BANK_KERNEL].start[FIRST_SECTOR] = dev->base;
650     size += flash_info[FLASH_BANK_KERNEL].size;
651
652     /*
653      * Provide info for 512K PLCC FLASH ROM (U-Boot)
654      */
655     dev = FLASH_DEV_BANK0_BOOT;
656     flash_info[FLASH_BANK_BOOT].flash_id =
657       (dev->vendorID << 16) | dev->deviceID;
658     flash_info[FLASH_BANK_BOOT].sector_count = dev->sectors;
659     flash_info[FLASH_BANK_BOOT].size =
660       flash_info[FLASH_BANK_BOOT].sector_count * FLASH_SECTOR_SIZE;
661     flash_info[FLASH_BANK_BOOT].start[FIRST_SECTOR] = dev->base;
662     size += flash_info[FLASH_BANK_BOOT].size;
663
664
665     /*
666      * Provide info for 512K FLASH0 segment (U-Boot)
667      */
668     dev = FLASH_DEV_BANK0_HIGH;
669     flash_info[FLASH_BANK_AUX].flash_id =
670       (dev->vendorID << 16) | dev->deviceID;
671     flash_info[FLASH_BANK_AUX].sector_count = dev->sectors;
672     flash_info[FLASH_BANK_AUX].size =
673       flash_info[FLASH_BANK_AUX].sector_count * FLASH_SECTOR_SIZE;
674     flash_info[FLASH_BANK_AUX].start[FIRST_SECTOR] = dev->base;
675     size += flash_info[FLASH_BANK_AUX].size;
676
677
678     return  size;
679 }
680
681 /*
682  * Get flash device from U-Boot flash info.
683  */
684 flash_dev_t*
685 getFlashDevFromInfo(flash_info_t* info)
686 {
687   int i;
688
689   if(!info)
690     return NULL;
691
692   for (i = 0; i < flashDevCount; i++) {
693     flash_dev_t *dev = &flashDev[i];
694     if(dev->found && (dev->base == info->start[0]))
695       return dev;
696   }
697   printf("ERROR: notice, no FLASH mapped at address 0x%x\n",
698          (unsigned int)info->start[0]);
699   return NULL;
700 }
701
702 ulong
703 flash_get_size (vu_long *addr, flash_info_t *info)
704 {
705     int i;
706     for(i = 0; i < flashDevCount; i++) {
707       flash_dev_t       *dev = &flashDev[i];
708       if(dev->found){
709         if(dev->base == (unsigned int)addr){
710           info->flash_id = (dev->vendorID << 16) | dev->deviceID;
711           info->sector_count = dev->sectors;
712           info->size = info->sector_count * FLASH_SECTOR_SIZE;
713           return dev->sectors * FLASH_SECTOR_SIZE;
714         }
715       }
716     }
717     return 0;
718 }
719
720 void
721 flash_print_info  (flash_info_t *info)
722 {
723   int i;
724   unsigned int chip;
725
726     if (info->flash_id == FLASH_UNKNOWN) {
727         printf ("missing or unknown FLASH type\n");
728         return;
729     }
730
731     switch ((info->flash_id >> 16) & 0xff) {
732     case 0x1:
733         printf ("AMD ");
734         break;
735     default:
736         printf ("Unknown Vendor ");
737         break;
738     }
739     chip = (unsigned int) info->flash_id & 0x000000ff;
740
741     switch (chip) {
742
743     case AMD_ID_F040B:
744         printf ("AM29F040B (4 Mbit)\n");
745         break;
746
747     case AMD_ID_LV160B:
748     case FLASH_AM160LV:
749     case 0x49:
750         printf ("AM29LV160B (16 Mbit / 2M x 8bit)\n");
751         break;
752
753     default:
754       printf ("Unknown Chip Type:0x%x\n", chip);
755         break;
756     }
757
758     printf ("  Size: %ld bytes in %d Sectors\n",
759             info->size, info->sector_count);
760
761     printf ("  Sector Start Addresses:");
762     for (i=0; i<info->sector_count; ++i) {
763       if ((i % 5) == 0)
764           printf ("\n   ");
765         printf (" %08lX%s",
766                 info->start[FIRST_SECTOR] + i*FLASH_SECTOR_SIZE,
767                 info->protect[i] ? " (RO)" : "     "
768                 );
769     }
770     printf ("\n");
771 }
772
773
774 /*
775  * Erase a range of flash sectors.
776  */
777 int flash_erase (flash_info_t *info, int s_first, int s_last)
778 {
779     vu_long *addr = (vu_long*)(info->start[0]);
780     int prot, sect, l_sect;
781     flash_dev_t* dev = NULL;
782
783     if ((s_first < 0) || (s_first > s_last)) {
784         if (info->flash_id == FLASH_UNKNOWN) {
785             printf ("- missing\n");
786         } else {
787             printf ("- no sectors to erase\n");
788         }
789         return 1;
790     }
791
792     prot = 0;
793     for (sect = s_first; sect <= s_last; sect++) {
794         if (info->protect[sect]) {
795             prot++;
796         }
797     }
798
799     if (prot) {
800         printf ("- Warning: %d protected sectors will not be erased!\n",
801                 prot);
802     } else {
803         printf ("\n");
804     }
805
806     l_sect = -1;
807
808     /* Start erase on unprotected sectors */
809     dev = getFlashDevFromInfo(info);
810     if(dev){
811       printf("Erase FLASH[%s] -%d sectors:", dev->name, dev->sectors);
812       for (sect = s_first; sect<=s_last; sect++) {
813         if (info->protect[sect] == 0) { /* not protected */
814           addr = (vu_long*)(dev->base);
815           /*   printf("erase_sector: sector=%d, addr=0x%x\n",
816                sect, addr); */
817           printf(".");
818           if(ERROR == flashEraseSector(dev, sect)){
819             printf("ERROR: could not erase sector %d on FLASH[%s]\n",
820                    sect, dev->name);
821             return 1;
822           }
823         }
824       }
825     }
826     printf (" done\n");
827     return 0;
828 }
829
830 /*-----------------------------------------------------------------------
831  * Write a word to Flash, returns:
832  * 0 - OK
833  * 1 - write timeout
834  * 2 - Flash not erased
835  */
836 static int
837 write_word (flash_info_t *info, ulong dest, ulong data)
838 {
839
840   flash_dev_t* dev = getFlashDevFromInfo(info);
841   int addr = dest - info->start[0];
842
843   if (! dev)
844     return 1;
845
846   if(OK != flashWrite(dev, addr, (char*)&data, sizeof(ulong))){
847     printf("ERROR: could not write to addr=0x%x, data=0x%x\n",
848            (unsigned int)addr, (unsigned)data);
849     return 1;
850   }
851
852   if((addr % FLASH_SECTOR_SIZE) == 0)
853     printf(".");
854
855
856   PRINTF("write_word:0x%x, base=0x%x, addr=0x%x, data=0x%x\n",
857          (unsigned)info->start[0],
858          (unsigned)dest,
859          (unsigned)(dest - info->start[0]),
860          (unsigned)data);
861
862
863
864     return (0);
865 }
866
867
868 /*-----------------------------------------------------------------------
869  * Copy memory to flash, returns:
870  * 0 - OK
871  * 1 - write timeout
872  * 2 - Flash not erased
873  */
874
875 int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
876 {
877     ulong cp, wp, data;
878     int i, l, rc;
879     flash_dev_t* dev = getFlashDevFromInfo(info);
880
881     if( dev ) {
882       printf("FLASH[%s]:", dev->name);
883       wp = (addr & ~3); /* get lower word aligned address */
884
885       /*
886        * handle unaligned start bytes
887        */
888       if ((l = addr - wp) != 0) {
889         data = 0;
890         for (i=0, cp=wp; i<l; ++i, ++cp) {
891           data = (data << 8) | (*(uchar *)cp);
892         }
893         for (; i<4 && cnt>0; ++i) {
894           data = (data << 8) | *src++;
895           --cnt;
896           ++cp;
897         }
898         for (; cnt==0 && i<4; ++i, ++cp) {
899           data = (data << 8) | (*(uchar *)cp);
900         }
901         if ((rc = write_word(info, wp, data)) != 0) {
902           return (rc);
903         }
904         wp += 4;
905       }
906
907       /*
908        * handle word aligned part
909        */
910       while (cnt >= 4) {
911         data = 0;
912         for (i=0; i<4; ++i) {
913           data = (data << 8) | *src++;
914         }
915         if ((rc = write_word(info, wp, data)) != 0) {
916           return (rc);
917         }
918         wp  += 4;
919         cnt -= 4;
920       }
921
922       if (cnt == 0) {
923         return (0);
924       }
925
926       /*
927        * handle unaligned tail bytes
928        */
929       data = 0;
930       for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
931         data = (data << 8) | *src++;
932         --cnt;
933       }
934       for (; i<4; ++i, ++cp) {
935         data = (data << 8) | (*(uchar *)cp);
936       }
937
938       return (write_word(info, wp, data));
939     }
940     return 1;
941 }
942
943 /*-----------------------------------------------------------------------
944  */