]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/mousse/flash.c
Merge branch 'u-boot-imx/master' into 'u-boot-arm/master'
[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[CONFIG_SYS_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
199 #if 0
200         PRINTF ("flashWait: dev=%d addr=0x%x expect=0x%x erase=%d\n",
201                 DEV_NO (dev), addr, expect, erase);
202 #endif
203
204         if (dev->bank != FLASH0_BANK) {
205                 rv = ERROR;
206                 goto done;
207         }
208
209         if (erase)
210                 polls = FLASH_ERASE_SECTOR_TIMEOUT;     /* Ticks */
211         else
212                 polls = FLASH_PROGRAM_POLLS;    /* Loops */
213
214         for (i = 0; i < polls; i++) {
215                 if (erase)
216                         udelay (SLEEP_DELAY);
217
218                 data = FLASH0_READ (dev, addr);
219
220                 if (((data ^ expect) & 0x80) == 0) {
221                         rv = OK;
222                         goto done;
223                 }
224
225                 if (data & 0x20) {
226                         /*
227                          * If the 0x20 bit has come on, it could actually be because
228                          * the operation succeeded, so check the done bit again.
229                          */
230
231                         data = FLASH0_READ (dev, addr);
232
233                         if (((data ^ expect) & 0x80) == 0) {
234                                 rv = OK;
235                                 goto done;
236                         }
237
238                         printf ("flashWait: Program error (dev: %d, addr: 0x%x)\n",
239                                         DEV_NO (dev), addr);
240
241                         flashReset (dev);
242                         rv = ERROR;
243                         goto done;
244                 }
245         }
246
247         printf ("flashWait: Timeout %s (dev: %d, addr: 0x%x)\n",
248                 erase ? "erasing sector" : "programming byte",
249                 DEV_NO (dev), addr);
250
251   done:
252
253 #if 0
254         PRINTF ("flashWait: rv=%d\n", rv);
255 #endif
256
257         return rv;
258 }
259
260 /***********************************************************************
261  *
262  * Public Flash Routines
263  *
264  ***********************************************************************/
265
266 STATUS flashLibInit (void)
267 {
268         int i;
269
270         PRINTF ("flashLibInit: devices=%d\n", flashDevCount);
271
272         for (i = 0; i < flashDevCount; i++) {
273                 flash_dev_t *dev = &flashDev[i];
274
275                 /*
276                  * For bank 1, probe both without and with byte swappage,
277                  * so that this module works on both old and new Mousse boards.
278                  */
279
280                 flashReset (dev);
281
282                 if (flashProbe (dev) != ERROR)
283                         dev->found = 1;
284
285                 flashReset (dev);
286
287                 if (flashProbe (dev) != ERROR)
288                         dev->found = 1;
289
290                 dev->swap = 0;
291
292                 if (dev->found) {
293                         PRINTF ("\n  FLASH %s[%d]: iobase=0x%x - %d sectors %d KB",
294                                 flashDev[i].name, i, flashDev[i].base,
295                                 flashDev[i].sectors,
296                                 (flashDev[i].sectors * FLASH_SECTOR_SIZE) / 1024);
297
298                 }
299         }
300
301         flashLibInited = 1;
302
303         PRINTF ("flashLibInit: done\n");
304
305         return OK;
306 }
307
308 STATUS flashEraseSector (flash_dev_t * dev, int sector)
309 {
310         int pos, addr;
311
312         PRINTF ("flashErasesector: dev=%d sector=%d\n", DEV_NO (dev), sector);
313
314         if (flashCheck (dev) == ERROR)
315                 return ERROR;
316
317         if (sector < 0 || sector >= dev->sectors) {
318                 printf ("flashEraseSector: Sector out of range (dev: %d, sector: %d)\n", DEV_NO (dev), sector);
319                 return ERROR;
320         }
321
322         pos = FLASH_SECTOR_POS (dev, sector);
323
324         if (dev->bank != FLASH0_BANK) {
325                 return ERROR;
326         }
327
328         addr = pos;
329
330         FLASH0_WRITE (dev, 0xaaa, 0xaa);
331         FLASH0_WRITE (dev, 0x555, 0x55);
332         FLASH0_WRITE (dev, 0xaaa, 0x80);
333         FLASH0_WRITE (dev, 0xaaa, 0xaa);
334         FLASH0_WRITE (dev, 0x555, 0x55);
335         FLASH0_WRITE (dev, addr, 0x30);
336
337         return flashWait (dev, addr, 0xff, 1);
338 }
339
340 /*
341  * Note: it takes about as long to flash all sectors together with Chip
342  * Erase as it does to flash them one at a time (about 30 seconds for 2
343  * MB).  Also since we want to be able to treat subsets of sectors as if
344  * they were complete devices, we don't use Chip Erase.
345  */
346
347 STATUS flashErase (flash_dev_t * dev)
348 {
349         int sector;
350
351         PRINTF ("flashErase: dev=%d sectors=%d\n", DEV_NO (dev), dev->sectors);
352
353         if (flashCheck (dev) == ERROR)
354                 return ERROR;
355
356         for (sector = 0; sector < dev->sectors; sector++) {
357                 if (flashEraseSector (dev, sector) == ERROR)
358                         return ERROR;
359         }
360         return OK;
361 }
362
363 /*
364  * Read and write bytes
365  */
366
367 STATUS flashRead (flash_dev_t * dev, int pos, char *buf, int len)
368 {
369         int addr, words;
370
371         PRINTF ("flashRead: dev=%d pos=0x%x buf=0x%x len=0x%x\n",
372                 DEV_NO (dev), pos, (int) buf, len);
373
374         if (flashCheck (dev) == ERROR)
375                 return ERROR;
376
377         if (pos < 0 || len < 0 || pos + len > FLASH_MAX_POS (dev)) {
378                 printf ("flashRead: Position out of range "
379                         "(dev: %d, pos: 0x%x, len: 0x%x)\n",
380                         DEV_NO (dev), pos, len);
381                 return ERROR;
382         }
383
384         if (len == 0)
385                 return OK;
386
387         if (dev->bank == FLASH0_BANK) {
388                 addr = pos;
389                 words = len;
390
391                 PRINTF ("flashRead: memcpy(0x%x, 0x%x, 0x%x)\n",
392                         (int) buf, (int) FLASH0_ADDR (dev, pos), len);
393
394                 memcpy (buf, FLASH0_ADDR (dev, addr), words);
395
396         }
397         PRINTF ("flashRead: rv=OK\n");
398
399         return OK;
400 }
401
402 STATUS flashWrite (flash_dev_t * dev, int pos, char *buf, int len)
403 {
404         int addr, words;
405
406         PRINTF ("flashWrite: dev=%d pos=0x%x buf=0x%x len=0x%x\n",
407                 DEV_NO (dev), pos, (int) buf, len);
408
409         if (flashCheck (dev) == ERROR)
410                 return ERROR;
411
412         if (pos < 0 || len < 0 || pos + len > FLASH_MAX_POS (dev)) {
413                 printf ("flashWrite: Position out of range "
414                         "(dev: %d, pos: 0x%x, len: 0x%x)\n",
415                         DEV_NO (dev), pos, len);
416                 return ERROR;
417         }
418
419         if (len == 0)
420                 return OK;
421
422         if (dev->bank == FLASH0_BANK) {
423                 unsigned char tmp;
424
425                 addr = pos;
426                 words = len;
427
428                 while (words--) {
429                         tmp = *buf;
430                         if (~FLASH0_READ (dev, addr) & tmp) {
431                                 printf ("flashWrite: Attempt to program 0 to 1 "
432                                         "(dev: %d, addr: 0x%x, data: 0x%x)\n",
433                                         DEV_NO (dev), addr, tmp);
434                                 return ERROR;
435                         }
436                         FLASH0_WRITE (dev, 0xaaa, 0xaa);
437                         FLASH0_WRITE (dev, 0x555, 0x55);
438                         FLASH0_WRITE (dev, 0xaaa, 0xa0);
439                         FLASH0_WRITE (dev, addr, tmp);
440                         if (flashWait (dev, addr, tmp, 0) < 0)
441                                 return ERROR;
442                         buf++;
443                         addr++;
444                 }
445         }
446
447         PRINTF ("flashWrite: rv=OK\n");
448
449         return OK;
450 }
451
452 /*
453  * flashWritable returns true if a range contains all F's.
454  */
455
456 STATUS flashWritable (flash_dev_t * dev, int pos, int len)
457 {
458         int addr, words;
459         int rv = ERROR;
460
461         PRINTF ("flashWritable: dev=%d pos=0x%x len=0x%x\n",
462                         DEV_NO (dev), pos, len);
463
464         if (flashCheck (dev) == ERROR)
465                 goto done;
466
467         if (pos < 0 || len < 0 || pos + len > FLASH_MAX_POS (dev)) {
468                 printf ("flashWritable: Position out of range "
469                         "(dev: %d, pos: 0x%x, len: 0x%x)\n",
470                         DEV_NO (dev), pos, len);
471                 goto done;
472         }
473
474         if (len == 0) {
475                 rv = 1;
476                 goto done;
477         }
478
479         if (dev->bank == FLASH0_BANK) {
480                 addr = pos;
481                 words = len;
482
483                 while (words--) {
484                         if (FLASH0_READ (dev, addr) != 0xff) {
485                                 rv = 0;
486                                 goto done;
487                         }
488                         addr++;
489                 }
490         }
491
492         rv = 1;
493
494   done:
495         PRINTF ("flashWrite: rv=%d\n", rv);
496         return rv;
497 }
498
499
500 /*
501  * NOTE: the below code cannot run from FLASH!!!
502  */
503 /***********************************************************************
504  *
505  * Flash Diagnostics
506  *
507  ***********************************************************************/
508
509 STATUS flashDiag (flash_dev_t * dev)
510 {
511         unsigned int *buf = 0;
512         int i, len, sector;
513         int rv = ERROR;
514
515         if (flashCheck (dev) == ERROR)
516                 return ERROR;
517
518         printf ("flashDiag: Testing device %d, "
519                 "base: 0x%x, %d sectors @ %d kB = %d kB\n",
520                 DEV_NO (dev), dev->base,
521                 dev->sectors,
522                 1 << (dev->lgSectorSize - 10),
523                 dev->sectors << (dev->lgSectorSize - 10));
524
525         len = 1 << dev->lgSectorSize;
526
527         printf ("flashDiag: Erasing\n");
528
529         if (flashErase (dev) == ERROR) {
530                 printf ("flashDiag: Erase failed\n");
531                 goto done;
532         }
533         printf ("%d bytes requested ...\n", len);
534         buf = malloc (len);
535         printf ("allocated %d bytes ...\n", len);
536         if (buf == 0) {
537                 printf ("flashDiag: Out of memory\n");
538                 goto done;
539         }
540
541         /*
542          * Write unique counting pattern to each sector
543          */
544
545         for (sector = 0; sector < dev->sectors; sector++) {
546                 printf ("flashDiag: Write sector %d\n", sector);
547
548                 for (i = 0; i < len / 4; i++)
549                         buf[i] = sector << 24 | i;
550
551                 if (flashWrite (dev,
552                                 sector << dev->lgSectorSize,
553                                 (char *) buf, len) == ERROR) {
554                         printf ("flashDiag: Write failed (dev: %d, sector: %d)\n",
555                                 DEV_NO (dev), sector);
556                         goto done;
557                 }
558         }
559
560         /*
561          * Verify
562          */
563
564         for (sector = 0; sector < dev->sectors; sector++) {
565                 printf ("flashDiag: Verify sector %d\n", sector);
566
567                 if (flashRead (dev,
568                                    sector << dev->lgSectorSize,
569                                    (char *) buf, 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
639         flashLibInit ();
640
641         /*
642          * Provide info for FLASH (up to 960K) of Kernel Image data.
643          */
644         dev = FLASH_DEV_BANK0_LOW;
645         flash_info[FLASH_BANK_KERNEL].flash_id =
646                         (dev->vendorID << 16) | dev->deviceID;
647         flash_info[FLASH_BANK_KERNEL].sector_count = dev->sectors;
648         flash_info[FLASH_BANK_KERNEL].size =
649                         flash_info[FLASH_BANK_KERNEL].sector_count * FLASH_SECTOR_SIZE;
650         flash_info[FLASH_BANK_KERNEL].start[FIRST_SECTOR] = dev->base;
651         size += flash_info[FLASH_BANK_KERNEL].size;
652
653         /*
654          * Provide info for 512K PLCC FLASH ROM (U-Boot)
655          */
656         dev = FLASH_DEV_BANK0_BOOT;
657         flash_info[FLASH_BANK_BOOT].flash_id =
658                         (dev->vendorID << 16) | dev->deviceID;
659         flash_info[FLASH_BANK_BOOT].sector_count = dev->sectors;
660         flash_info[FLASH_BANK_BOOT].size =
661                         flash_info[FLASH_BANK_BOOT].sector_count * FLASH_SECTOR_SIZE;
662         flash_info[FLASH_BANK_BOOT].start[FIRST_SECTOR] = dev->base;
663         size += flash_info[FLASH_BANK_BOOT].size;
664
665
666         /*
667          * Provide info for 512K FLASH0 segment (U-Boot)
668          */
669         dev = FLASH_DEV_BANK0_HIGH;
670         flash_info[FLASH_BANK_AUX].flash_id =
671                         (dev->vendorID << 16) | dev->deviceID;
672         flash_info[FLASH_BANK_AUX].sector_count = dev->sectors;
673         flash_info[FLASH_BANK_AUX].size =
674                         flash_info[FLASH_BANK_AUX].sector_count * FLASH_SECTOR_SIZE;
675         flash_info[FLASH_BANK_AUX].start[FIRST_SECTOR] = dev->base;
676         size += flash_info[FLASH_BANK_AUX].size;
677
678
679         return size;
680 }
681
682 /*
683  * Get flash device from U-Boot flash info.
684  */
685 flash_dev_t *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
695                 if (dev->found && (dev->base == info->start[0]))
696                         return dev;
697         }
698         printf ("ERROR: notice, no FLASH mapped at address 0x%x\n",
699                         (unsigned int) info->start[0]);
700         return NULL;
701 }
702
703 ulong flash_get_size (vu_long * addr, flash_info_t * info)
704 {
705         int i;
706
707         for (i = 0; i < flashDevCount; i++) {
708                 flash_dev_t *dev = &flashDev[i];
709
710                 if (dev->found) {
711                         if (dev->base == (unsigned int) addr) {
712                                 info->flash_id = (dev->vendorID << 16) | dev->deviceID;
713                                 info->sector_count = dev->sectors;
714                                 info->size = info->sector_count * FLASH_SECTOR_SIZE;
715                                 return dev->sectors * FLASH_SECTOR_SIZE;
716                         }
717                 }
718         }
719         return 0;
720 }
721
722 void flash_print_info (flash_info_t * info)
723 {
724         int i;
725         unsigned int chip;
726
727         if (info->flash_id == FLASH_UNKNOWN) {
728                 printf ("missing or unknown FLASH type\n");
729                 return;
730         }
731
732         switch ((info->flash_id >> 16) & 0xff) {
733         case 0x1:
734                 printf ("AMD ");
735                 break;
736         default:
737                 printf ("Unknown Vendor ");
738                 break;
739         }
740         chip = (unsigned int) info->flash_id & 0x000000ff;
741
742         switch (chip) {
743
744         case AMD_ID_F040B:
745                 printf ("AM29F040B (4 Mbit)\n");
746                 break;
747
748         case AMD_ID_LV160B:
749         case FLASH_AM160LV:
750         case 0x49:
751                 printf ("AM29LV160B (16 Mbit / 2M x 8bit)\n");
752                 break;
753
754         default:
755                 printf ("Unknown Chip Type:0x%x\n", chip);
756                 break;
757         }
758
759         printf ("  Size: %ld bytes in %d Sectors\n",
760                 info->size, info->sector_count);
761
762         printf ("  Sector Start Addresses:");
763         for (i = 0; i < info->sector_count; ++i) {
764                 if ((i % 5) == 0)
765                         printf ("\n   ");
766                 printf (" %08lX%s",
767                         info->start[FIRST_SECTOR] + i * FLASH_SECTOR_SIZE,
768                         info->protect[i] ? " (RO)" : "     ");
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         int prot, sect;
780         flash_dev_t *dev = NULL;
781
782         if ((s_first < 0) || (s_first > s_last)) {
783                 if (info->flash_id == FLASH_UNKNOWN) {
784                         printf ("- missing\n");
785                 } else {
786                         printf ("- no sectors to erase\n");
787                 }
788                 return 1;
789         }
790
791         prot = 0;
792         for (sect = s_first; sect <= s_last; sect++) {
793                 if (info->protect[sect]) {
794                         prot++;
795                 }
796         }
797
798         if (prot) {
799                 printf ("- Warning: %d protected sectors will not be erased!\n",
800                         prot);
801         } else {
802                 printf ("\n");
803         }
804
805         /* Start erase on unprotected sectors */
806         dev = getFlashDevFromInfo (info);
807         if (dev) {
808                 printf ("Erase FLASH[%s] -%d sectors:", dev->name, dev->sectors);
809                 for (sect = s_first; sect <= s_last; sect++) {
810                         if (info->protect[sect] == 0) { /* not protected */
811                                 printf (".");
812                                 if (ERROR == flashEraseSector (dev, sect)) {
813                                         printf ("ERROR: could not erase sector %d on FLASH[%s]\n", sect, dev->name);
814                                         return 1;
815                                 }
816                         }
817                 }
818         }
819         printf (" done\n");
820         return 0;
821 }
822
823 /*-----------------------------------------------------------------------
824  * Write a word to Flash, returns:
825  * 0 - OK
826  * 1 - write timeout
827  * 2 - Flash not erased
828  */
829 static int write_word (flash_info_t * info, ulong dest, ulong data)
830 {
831
832         flash_dev_t *dev = getFlashDevFromInfo (info);
833         int addr = dest - info->start[0];
834
835         if (!dev)
836                 return 1;
837
838         if (OK != flashWrite (dev, addr, (char *) &data, sizeof (ulong))) {
839                 printf ("ERROR: could not write to addr=0x%x, data=0x%x\n",
840                         (unsigned int) addr, (unsigned) data);
841                 return 1;
842         }
843
844         if ((addr % FLASH_SECTOR_SIZE) == 0)
845                 printf (".");
846
847
848         PRINTF ("write_word:0x%x, base=0x%x, addr=0x%x, data=0x%x\n",
849                 (unsigned) info->start[0],
850                 (unsigned) dest,
851                 (unsigned) (dest - info->start[0]), (unsigned) data);
852
853         return (0);
854 }
855
856
857 /*-----------------------------------------------------------------------
858  * Copy memory to flash, returns:
859  * 0 - OK
860  * 1 - write timeout
861  * 2 - Flash not erased
862  */
863
864 int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
865 {
866         ulong cp, wp, data;
867         int i, l, rc;
868         flash_dev_t *dev = getFlashDevFromInfo (info);
869
870         if (dev) {
871                 printf ("FLASH[%s]:", dev->name);
872                 wp = (addr & ~3);       /* get lower word aligned address */
873
874                 /*
875                  * handle unaligned start bytes
876                  */
877                 if ((l = addr - wp) != 0) {
878                         data = 0;
879                         for (i = 0, cp = wp; i < l; ++i, ++cp) {
880                                 data = (data << 8) | (*(uchar *) cp);
881                         }
882                         for (; i < 4 && cnt > 0; ++i) {
883                                 data = (data << 8) | *src++;
884                                 --cnt;
885                                 ++cp;
886                         }
887                         for (; cnt == 0 && i < 4; ++i, ++cp) {
888                                 data = (data << 8) | (*(uchar *) cp);
889                         }
890                         if ((rc = write_word (info, wp, data)) != 0) {
891                                 return (rc);
892                         }
893                         wp += 4;
894                 }
895
896                 /*
897                  * handle word aligned part
898                  */
899                 while (cnt >= 4) {
900                         data = 0;
901                         for (i = 0; i < 4; ++i) {
902                                 data = (data << 8) | *src++;
903                         }
904                         if ((rc = write_word (info, wp, data)) != 0) {
905                                 return (rc);
906                         }
907                         wp += 4;
908                         cnt -= 4;
909                 }
910
911                 if (cnt == 0) {
912                         return (0);
913                 }
914
915                 /*
916                  * handle unaligned tail bytes
917                  */
918                 data = 0;
919                 for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
920                         data = (data << 8) | *src++;
921                         --cnt;
922                 }
923                 for (; i < 4; ++i, ++cp) {
924                         data = (data << 8) | (*(uchar *) cp);
925                 }
926
927                 return (write_word (info, wp, data));
928         }
929         return 1;
930 }
931
932 /*-----------------------------------------------------------------------
933  */