]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/eric/flash.c
* Get (mostly) rid of CFG_MONITOR_LEN definition; compute real length
[karo-tx-uboot.git] / board / eric / flash.c
1 /*
2  * (C) Copyright 2001
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 #include <common.h>
25 #include <ppc4xx.h>
26 #include <asm/processor.h>
27
28 flash_info_t    flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips        */
29
30
31 #ifdef CFG_FLASH_16BIT
32 #define FLASH_WORD_SIZE unsigned short
33 #define FLASH_ID_MASK   0xFFFF
34 #else
35 #define FLASH_WORD_SIZE unsigned long
36 #define FLASH_ID_MASK   0xFFFFFFFF
37 #endif
38
39 /*-----------------------------------------------------------------------
40  * Functions
41  */
42 /* stolen from esteem192e/flash.c */
43 ulong flash_get_size (volatile FLASH_WORD_SIZE *addr, flash_info_t *info);
44
45 #ifndef CFG_FLASH_16BIT
46 static int write_word (flash_info_t *info, ulong dest, ulong data);
47 #else
48 static int write_short (flash_info_t *info, ulong dest, ushort data);
49 #endif
50 static void flash_get_offsets (ulong base, flash_info_t *info);
51
52
53 /*-----------------------------------------------------------------------
54  */
55
56 unsigned long flash_init (void)
57 {
58         unsigned long size_b0, size_b1;
59         int i;
60         uint pbcr;
61         unsigned long base_b0, base_b1;
62
63         /* Init: no FLASHes known */
64         for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
65                 flash_info[i].flash_id = FLASH_UNKNOWN;
66         }
67
68         /* Static FLASH Bank configuration here - FIXME XXX */
69
70         size_b0 = flash_get_size((volatile FLASH_WORD_SIZE *)FLASH_BASE0_PRELIM, &flash_info[0]);
71
72         if (flash_info[0].flash_id == FLASH_UNKNOWN) {
73                 printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
74                         size_b0, size_b0<<20);
75         }
76
77         /* Only one bank */
78         if (CFG_MAX_FLASH_BANKS == 1)
79           {
80             /* Setup offsets */
81             flash_get_offsets (FLASH_BASE0_PRELIM, &flash_info[0]);
82
83             /* Monitor protection ON by default */
84 #if 0       /* sand: */
85             (void)flash_protect(FLAG_PROTECT_SET,
86                                 FLASH_BASE0_PRELIM-monitor_flash_len+size_b0,
87                                 FLASH_BASE0_PRELIM-1+size_b0,
88                                 &flash_info[0]);
89 #else
90             (void)flash_protect(FLAG_PROTECT_SET,
91                                 CFG_MONITOR_BASE,
92                                 CFG_MONITOR_BASE+monitor_flash_len-1,
93                                 &flash_info[0]);
94 #endif
95             size_b1 = 0 ;
96             flash_info[0].size = size_b0;
97           }
98
99         /* 2 banks */
100         else
101           {
102             size_b1 = flash_get_size((volatile FLASH_WORD_SIZE *)FLASH_BASE1_PRELIM, &flash_info[1]);
103
104             /* Re-do sizing to get full correct info */
105
106             if (size_b1)
107               {
108                 mtdcr(ebccfga, pb0cr);
109                 pbcr = mfdcr(ebccfgd);
110                 mtdcr(ebccfga, pb0cr);
111                 base_b1 = -size_b1;
112                 pbcr = (pbcr & 0x0001ffff) | base_b1 | (((size_b1/1024/1024)-1)<<17);
113                 mtdcr(ebccfgd, pbcr);
114                 /*          printf("pb1cr = %x\n", pbcr); */
115               }
116
117             if (size_b0)
118               {
119                 mtdcr(ebccfga, pb1cr);
120                 pbcr = mfdcr(ebccfgd);
121                 mtdcr(ebccfga, pb1cr);
122                 base_b0 = base_b1 - size_b0;
123                 pbcr = (pbcr & 0x0001ffff) | base_b0 | (((size_b0/1024/1024)-1)<<17);
124                 mtdcr(ebccfgd, pbcr);
125                 /*            printf("pb0cr = %x\n", pbcr); */
126               }
127
128             size_b0 = flash_get_size((volatile FLASH_WORD_SIZE *)base_b0, &flash_info[0]);
129
130             flash_get_offsets (base_b0, &flash_info[0]);
131
132             /* monitor protection ON by default */
133 #if 0       /* sand: */
134             (void)flash_protect(FLAG_PROTECT_SET,
135                                 FLASH_BASE0_PRELIM-monitor_flash_len+size_b0,
136                                 FLASH_BASE0_PRELIM-1+size_b0,
137                                 &flash_info[0]);
138 #else
139             (void)flash_protect(FLAG_PROTECT_SET,
140                                 CFG_MONITOR_BASE,
141                                 CFG_MONITOR_BASE+monitor_flash_len-1,
142                                 &flash_info[0]);
143 #endif
144
145             if (size_b1) {
146               /* Re-do sizing to get full correct info */
147               size_b1 = flash_get_size((volatile FLASH_WORD_SIZE *)base_b1, &flash_info[1]);
148
149               flash_get_offsets (base_b1, &flash_info[1]);
150
151               /* monitor protection ON by default */
152               (void)flash_protect(FLAG_PROTECT_SET,
153                                   base_b1+size_b1-monitor_flash_len,
154                                   base_b1+size_b1-1,
155                                   &flash_info[1]);
156               /* monitor protection OFF by default (one is enough) */
157               (void)flash_protect(FLAG_PROTECT_CLEAR,
158                                   base_b0+size_b0-monitor_flash_len,
159                                   base_b0+size_b0-1,
160                                   &flash_info[0]);
161             } else {
162               flash_info[1].flash_id = FLASH_UNKNOWN;
163               flash_info[1].sector_count = -1;
164             }
165
166             flash_info[0].size = size_b0;
167             flash_info[1].size = size_b1;
168           }/* else 2 banks */
169         return (size_b0 + size_b1);
170 }
171
172
173
174 /*-----------------------------------------------------------------------
175  */
176
177 static void flash_get_offsets (ulong base, flash_info_t *info)
178 {
179         int i;
180
181         /* set up sector start adress table */
182         if ((info->flash_id & FLASH_TYPEMASK) == FLASH_28F320J3A ||
183             (info->flash_id & FLASH_TYPEMASK) == FLASH_28F640J3A ||
184             (info->flash_id & FLASH_TYPEMASK) == FLASH_28F128J3A) {
185             for (i = 0; i < info->sector_count; i++) {
186                 info->start[i] = base + (i * info->size/info->sector_count);
187             }
188         } else if (info->flash_id & FLASH_BTYPE) {
189              if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
190
191 #ifndef CFG_FLASH_16BIT
192                 /* set sector offsets for bottom boot block type        */
193                 info->start[0] = base + 0x00000000;
194                 info->start[1] = base + 0x00004000;
195                 info->start[2] = base + 0x00008000;
196                 info->start[3] = base + 0x0000C000;
197                 info->start[4] = base + 0x00010000;
198                 info->start[5] = base + 0x00014000;
199                 info->start[6] = base + 0x00018000;
200                 info->start[7] = base + 0x0001C000;
201                 for (i = 8; i < info->sector_count; i++) {
202                         info->start[i] = base + (i * 0x00020000) - 0x000E0000;
203                 }
204                }
205              else {
206                 /* set sector offsets for bottom boot block type        */
207                 info->start[0] = base + 0x00000000;
208                 info->start[1] = base + 0x00008000;
209                 info->start[2] = base + 0x0000C000;
210                 info->start[3] = base + 0x00010000;
211                 for (i = 4; i < info->sector_count; i++) {
212                         info->start[i] = base + (i * 0x00020000) - 0x00060000;
213                 }
214                }
215 #else
216                 /* set sector offsets for bottom boot block type        */
217                 info->start[0] = base + 0x00000000;
218                 info->start[1] = base + 0x00002000;
219                 info->start[2] = base + 0x00004000;
220                 info->start[3] = base + 0x00006000;
221                 info->start[4] = base + 0x00008000;
222                 info->start[5] = base + 0x0000A000;
223                 info->start[6] = base + 0x0000C000;
224                 info->start[7] = base + 0x0000E000;
225                 for (i = 8; i < info->sector_count; i++) {
226                         info->start[i] = base + (i * 0x00010000) - 0x00070000;
227                 }
228                }
229              else {
230                 /* set sector offsets for bottom boot block type        */
231                 info->start[0] = base + 0x00000000;
232                 info->start[1] = base + 0x00004000;
233                 info->start[2] = base + 0x00006000;
234                 info->start[3] = base + 0x00008000;
235                 for (i = 4; i < info->sector_count; i++) {
236                         info->start[i] = base + (i * 0x00010000) - 0x00030000;
237                 }
238                }
239 #endif
240         } else {
241                 /* set sector offsets for top boot block type           */
242                 i = info->sector_count - 1;
243              if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
244
245 #ifndef CFG_FLASH_16BIT
246                 info->start[i--] = base + info->size - 0x00004000;
247                 info->start[i--] = base + info->size - 0x00008000;
248                 info->start[i--] = base + info->size - 0x0000C000;
249                 info->start[i--] = base + info->size - 0x00010000;
250                 info->start[i--] = base + info->size - 0x00014000;
251                 info->start[i--] = base + info->size - 0x00018000;
252                 info->start[i--] = base + info->size - 0x0001C000;
253                 for (; i >= 0; i--) {
254                         info->start[i] = base + i * 0x00020000;
255                 }
256
257                } else {
258
259                 info->start[i--] = base + info->size - 0x00008000;
260                 info->start[i--] = base + info->size - 0x0000C000;
261                 info->start[i--] = base + info->size - 0x00010000;
262                 for (; i >= 0; i--) {
263                         info->start[i] = base + i * 0x00020000;
264                 }
265                }
266 #else
267                 info->start[i--] = base + info->size - 0x00002000;
268                 info->start[i--] = base + info->size - 0x00004000;
269                 info->start[i--] = base + info->size - 0x00006000;
270                 info->start[i--] = base + info->size - 0x00008000;
271                 info->start[i--] = base + info->size - 0x0000A000;
272                 info->start[i--] = base + info->size - 0x0000C000;
273                 info->start[i--] = base + info->size - 0x0000E000;
274                 for (; i >= 0; i--) {
275                         info->start[i] = base + i * 0x00010000;
276                 }
277
278                } else {
279
280                 info->start[i--] = base + info->size - 0x00004000;
281                 info->start[i--] = base + info->size - 0x00006000;
282                 info->start[i--] = base + info->size - 0x00008000;
283                 for (; i >= 0; i--) {
284                         info->start[i] = base + i * 0x00010000;
285                 }
286                }
287 #endif
288         }
289
290
291 }
292
293 /*-----------------------------------------------------------------------
294  */
295
296 void flash_print_info  (flash_info_t *info)
297 {
298         int i;
299         uchar *boottype;
300         uchar botboot[]=", bottom boot sect)\n";
301         uchar topboot[]=", top boot sector)\n";
302
303         if (info->flash_id == FLASH_UNKNOWN) {
304                 printf ("missing or unknown FLASH type\n");
305                 return;
306         }
307
308         switch (info->flash_id & FLASH_VENDMASK) {
309         case FLASH_MAN_AMD:     printf ("AMD ");                break;
310         case FLASH_MAN_FUJ:     printf ("FUJITSU ");            break;
311         case FLASH_MAN_SST:     printf ("SST ");                break;
312         case FLASH_MAN_STM:     printf ("STM ");                break;
313         case FLASH_MAN_INTEL:   printf ("INTEL ");              break;
314         default:                printf ("Unknown Vendor ");     break;
315         }
316
317         if (info->flash_id & 0x0001 ) {
318         boottype = botboot;
319         } else {
320         boottype = topboot;
321         }
322
323         switch (info->flash_id & FLASH_TYPEMASK) {
324         case FLASH_AM400B:      printf ("AM29LV400B (4 Mbit%s",boottype);
325                                 break;
326         case FLASH_AM400T:      printf ("AM29LV400T (4 Mbit%s",boottype);
327                                 break;
328         case FLASH_AM800B:      printf ("AM29LV800B (8 Mbit%s",boottype);
329                                 break;
330         case FLASH_AM800T:      printf ("AM29LV800T (8 Mbit%s",boottype);
331                                 break;
332         case FLASH_AM160B:      printf ("AM29LV160B (16 Mbit%s",boottype);
333                                 break;
334         case FLASH_AM160T:      printf ("AM29LV160T (16 Mbit%s",boottype);
335                                 break;
336         case FLASH_AM320B:      printf ("AM29LV320B (32 Mbit%s",boottype);
337                                 break;
338         case FLASH_AM320T:      printf ("AM29LV320T (32 Mbit%s",boottype);
339                                 break;
340         case FLASH_INTEL800B:   printf ("INTEL28F800B (8 Mbit%s",boottype);
341                                 break;
342         case FLASH_INTEL800T:   printf ("INTEL28F800T (8 Mbit%s",boottype);
343                                 break;
344         case FLASH_INTEL160B:   printf ("INTEL28F160B (16 Mbit%s",boottype);
345                                 break;
346         case FLASH_INTEL160T:   printf ("INTEL28F160T (16 Mbit%s",boottype);
347                                 break;
348         case FLASH_INTEL320B:   printf ("INTEL28F320B (32 Mbit%s",boottype);
349                                 break;
350         case FLASH_INTEL320T:   printf ("INTEL28F320T (32 Mbit%s",boottype);
351                                 break;
352
353 #if 0 /* enable when devices are available */
354
355         case FLASH_INTEL640B:   printf ("INTEL28F640B (64 Mbit%s",boottype);
356                                 break;
357         case FLASH_INTEL640T:   printf ("INTEL28F640T (64 Mbit%s",boottype);
358                                 break;
359 #endif
360         case FLASH_28F320J3A:   printf ("INTEL28F320J3A (32 Mbit%s",boottype);
361                                 break;
362         case FLASH_28F640J3A:   printf ("INTEL28F640J3A (64 Mbit%s",boottype);
363                                 break;
364         case FLASH_28F128J3A:   printf ("INTEL28F128J3A (128 Mbit%s",boottype);
365                                 break;
366
367         default:                printf ("Unknown Chip Type\n");
368                                 break;
369         }
370
371         printf ("  Size: %ld MB in %d Sectors\n",
372                 info->size >> 20, info->sector_count);
373
374         printf ("  Sector Start Addresses:");
375         for (i=0; i<info->sector_count; ++i) {
376                 if ((i % 5) == 0)
377                         printf ("\n   ");
378                 printf (" %08lX%s",
379                         info->start[i],
380                         info->protect[i] ? " (RO)" : "     "
381                 );
382         }
383         printf ("\n");
384         return;
385 }
386
387
388 /*-----------------------------------------------------------------------
389  */
390
391
392 /*-----------------------------------------------------------------------
393  */
394
395 /*
396  * The following code cannot be run from FLASH!
397  */
398 ulong flash_get_size (volatile FLASH_WORD_SIZE *addr, flash_info_t *info)
399 {
400         short i;
401         ulong base = (ulong)addr;
402         FLASH_WORD_SIZE value;
403
404         /* Write auto select command: read Manufacturer ID */
405
406
407 #ifndef CFG_FLASH_16BIT
408
409         /*
410          * Note: if it is an AMD flash and the word at addr[0000]
411          * is 0x00890089 this routine will think it is an Intel
412          * flash device and may(most likely) cause trouble.
413          */
414
415         addr[0x0000] = 0x00900090;
416         if(addr[0x0000] != 0x00890089){
417                 addr[0x0555] = 0x00AA00AA;
418                 addr[0x02AA] = 0x00550055;
419                 addr[0x0555] = 0x00900090;
420 #else
421
422         /*
423          * Note: if it is an AMD flash and the word at addr[0000]
424          * is 0x0089 this routine will think it is an Intel
425          * flash device and may(most likely) cause trouble.
426          */
427
428         addr[0x0000] = 0x0090;
429
430         if(addr[0x0000] != 0x0089){
431                 addr[0x0555] = 0x00AA;
432                 addr[0x02AA] = 0x0055;
433                 addr[0x0555] = 0x0090;
434 #endif
435         }
436         value = addr[0];
437
438         switch (value) {
439         case (AMD_MANUFACT & FLASH_ID_MASK):
440                 info->flash_id = FLASH_MAN_AMD;
441                 break;
442         case (FUJ_MANUFACT & FLASH_ID_MASK):
443                 info->flash_id = FLASH_MAN_FUJ;
444                 break;
445         case (STM_MANUFACT & FLASH_ID_MASK):
446                 info->flash_id = FLASH_MAN_STM;
447                 break;
448         case (SST_MANUFACT & FLASH_ID_MASK):
449                 info->flash_id = FLASH_MAN_SST;
450                 break;
451         case (INTEL_MANUFACT & FLASH_ID_MASK):
452                 info->flash_id = FLASH_MAN_INTEL;
453                 break;
454         default:
455                 info->flash_id = FLASH_UNKNOWN;
456                 info->sector_count = 0;
457                 info->size = 0;
458                 return (0);                     /* no or unknown flash  */
459
460         }
461
462         value = addr[1];                        /* device ID            */
463
464         switch (value) {
465
466         case (AMD_ID_LV400T & FLASH_ID_MASK):
467                 info->flash_id += FLASH_AM400T;
468                 info->sector_count = 11;
469                 info->size = 0x00100000;
470                 break;                          /* => 1 MB              */
471
472         case (AMD_ID_LV400B & FLASH_ID_MASK):
473                 info->flash_id += FLASH_AM400B;
474                 info->sector_count = 11;
475                 info->size = 0x00100000;
476                 break;                          /* => 1 MB              */
477
478         case (AMD_ID_LV800T & FLASH_ID_MASK):
479                 info->flash_id += FLASH_AM800T;
480                 info->sector_count = 19;
481                 info->size = 0x00200000;
482                 break;                          /* => 2 MB              */
483
484         case (AMD_ID_LV800B & FLASH_ID_MASK):
485                 info->flash_id += FLASH_AM800B;
486                 info->sector_count = 19;
487                 info->size = 0x00200000;
488                 break;                          /* => 2 MB              */
489
490         case (AMD_ID_LV160T & FLASH_ID_MASK):
491                 info->flash_id += FLASH_AM160T;
492                 info->sector_count = 35;
493                 info->size = 0x00400000;
494                 break;                          /* => 4 MB              */
495
496         case (AMD_ID_LV160B & FLASH_ID_MASK):
497                 info->flash_id += FLASH_AM160B;
498                 info->sector_count = 35;
499                 info->size = 0x00400000;
500                 break;                          /* => 4 MB              */
501 #if 0   /* enable when device IDs are available */
502         case (AMD_ID_LV320T & FLASH_ID_MASK):
503                 info->flash_id += FLASH_AM320T;
504                 info->sector_count = 67;
505                 info->size = 0x00800000;
506                 break;                          /* => 8 MB              */
507
508         case (AMD_ID_LV320B & FLASH_ID_MASK):
509                 info->flash_id += FLASH_AM320B;
510                 info->sector_count = 67;
511                 info->size = 0x00800000;
512                 break;                          /* => 8 MB              */
513 #endif
514
515         case (INTEL_ID_28F800B3T & FLASH_ID_MASK):
516                 info->flash_id += FLASH_INTEL800T;
517                 info->sector_count = 23;
518                 info->size = 0x00200000;
519                 break;                          /* => 2 MB              */
520
521         case (INTEL_ID_28F800B3B & FLASH_ID_MASK):
522                 info->flash_id += FLASH_INTEL800B;
523                 info->sector_count = 23;
524                 info->size = 0x00200000;
525                 break;                          /* => 2 MB              */
526
527         case (INTEL_ID_28F160B3T & FLASH_ID_MASK):
528                 info->flash_id += FLASH_INTEL160T;
529                 info->sector_count = 39;
530                 info->size = 0x00400000;
531                 break;                          /* => 4 MB              */
532
533         case (INTEL_ID_28F160B3B & FLASH_ID_MASK):
534                 info->flash_id += FLASH_INTEL160B;
535                 info->sector_count = 39;
536                 info->size = 0x00400000;
537                 break;                          /* => 4 MB              */
538
539         case (INTEL_ID_28F320B3T & FLASH_ID_MASK):
540                 info->flash_id += FLASH_INTEL320T;
541                 info->sector_count = 71;
542                 info->size = 0x00800000;
543                 break;                          /* => 8 MB              */
544
545         case (INTEL_ID_28F320B3B & FLASH_ID_MASK):
546                 info->flash_id += FLASH_AM320B;
547                 info->sector_count = 71;
548                 info->size = 0x00800000;
549                 break;                          /* => 8 MB              */
550
551 #if 0 /* enable when devices are available */
552         case (INTEL_ID_28F320B3T & FLASH_ID_MASK):
553                 info->flash_id += FLASH_INTEL320T;
554                 info->sector_count = 135;
555                 info->size = 0x01000000;
556                 break;                          /* => 16 MB             */
557
558         case (INTEL_ID_28F320B3B & FLASH_ID_MASK):
559                 info->flash_id += FLASH_AM320B;
560                 info->sector_count = 135;
561                 info->size = 0x01000000;
562                 break;                          /* => 16 MB             */
563 #endif
564         case (INTEL_ID_28F320J3A & FLASH_ID_MASK):
565                 info->flash_id += FLASH_28F320J3A;
566                 info->sector_count = 32;
567                 info->size = 0x00400000;
568                 break;                          /* => 32 MBit   */
569         case (INTEL_ID_28F640J3A & FLASH_ID_MASK):
570                 info->flash_id += FLASH_28F640J3A;
571                 info->sector_count = 64;
572                 info->size = 0x00800000;
573                 break;                          /* => 64 MBit   */
574         case (INTEL_ID_28F128J3A & FLASH_ID_MASK):
575                 info->flash_id += FLASH_28F128J3A;
576                 info->sector_count = 128;
577                 info->size = 0x01000000;
578                 break;                          /* => 128 MBit          */
579
580         default:
581                 /* FIXME*/
582                 info->flash_id = FLASH_UNKNOWN;
583                 return (0);                     /* => no or unknown flash */
584         }
585
586         flash_get_offsets(base, info);
587
588         /* check for protected sectors */
589         for (i = 0; i < info->sector_count; i++) {
590                 /* read sector protection at sector address, (A7 .. A0) = 0x02 */
591                 /* D0 = 1 if protected */
592                 addr = (volatile FLASH_WORD_SIZE *)(info->start[i]);
593                 info->protect[i] = addr[2] & 1;
594         }
595
596         /*
597          * Prevent writes to uninitialized FLASH.
598          */
599         if (info->flash_id != FLASH_UNKNOWN) {
600                 addr = (volatile FLASH_WORD_SIZE *)info->start[0];
601                 if( (info->flash_id & 0xFF00) == FLASH_MAN_INTEL){
602                    *addr = (0x00F000F0 & FLASH_ID_MASK);        /* reset bank */
603                 } else {
604                    *addr = (0x00FF00FF & FLASH_ID_MASK);        /* reset bank */
605                 }
606         }
607
608         return (info->size);
609 }
610
611
612 /*-----------------------------------------------------------------------
613  */
614
615 int     flash_erase (flash_info_t *info, int s_first, int s_last)
616 {
617
618         volatile FLASH_WORD_SIZE *addr=(volatile FLASH_WORD_SIZE*)(info->start[0]);
619         int flag, prot, sect, l_sect, barf;
620         ulong start, now, last;
621         int rcode = 0;
622
623         if ((s_first < 0) || (s_first > s_last)) {
624                 if (info->flash_id == FLASH_UNKNOWN) {
625                         printf ("- missing\n");
626                 } else {
627                         printf ("- no sectors to erase\n");
628                 }
629                 return 1;
630         }
631
632         if ((info->flash_id == FLASH_UNKNOWN) ||
633             ((info->flash_id > FLASH_AMD_COMP) &&
634              ( (info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL ) ) ){
635                 printf ("Can't erase unknown flash type - aborted\n");
636                 return 1;
637         }
638
639         prot = 0;
640         for (sect=s_first; sect<=s_last; ++sect) {
641                 if (info->protect[sect]) {
642                         prot++;
643                 }
644         }
645
646         if (prot) {
647                 printf ("- Warning: %d protected sectors will not be erased!\n",
648                         prot);
649         } else {
650                 printf ("\n");
651         }
652
653         l_sect = -1;
654
655         /* Disable interrupts which might cause a timeout here */
656         flag = disable_interrupts();
657     if(info->flash_id < FLASH_AMD_COMP) {
658 #ifndef CFG_FLASH_16BIT
659         addr[0x0555] = 0x00AA00AA;
660         addr[0x02AA] = 0x00550055;
661         addr[0x0555] = 0x00800080;
662         addr[0x0555] = 0x00AA00AA;
663         addr[0x02AA] = 0x00550055;
664 #else
665         addr[0x0555] = 0x00AA;
666         addr[0x02AA] = 0x0055;
667         addr[0x0555] = 0x0080;
668         addr[0x0555] = 0x00AA;
669         addr[0x02AA] = 0x0055;
670 #endif
671         /* Start erase on unprotected sectors */
672         for (sect = s_first; sect<=s_last; sect++) {
673                 if (info->protect[sect] == 0) { /* not protected */
674                         addr = (volatile FLASH_WORD_SIZE *)(info->start[sect]);
675                         addr[0] = (0x00300030 & FLASH_ID_MASK);
676                         l_sect = sect;
677                 }
678         }
679
680         /* re-enable interrupts if necessary */
681         if (flag)
682                 enable_interrupts();
683
684         /* wait at least 80us - let's wait 1 ms */
685         udelay (1000);
686
687         /*
688          * We wait for the last triggered sector
689          */
690         if (l_sect < 0)
691                 goto DONE;
692
693         start = get_timer (0);
694         last  = start;
695         addr = (volatile FLASH_WORD_SIZE*)(info->start[l_sect]);
696         while ((addr[0] & (0x00800080&FLASH_ID_MASK)) !=
697                           (0x00800080&FLASH_ID_MASK)  )
698         {
699                 if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
700                         printf ("Timeout\n");
701                         return 1;
702                 }
703                 /* show that we're waiting */
704                 if ((now - last) > 1000) {      /* every second */
705                         serial_putc ('.');
706                         last = now;
707                 }
708         }
709
710 DONE:
711         /* reset to read mode */
712         addr = (volatile FLASH_WORD_SIZE *)info->start[0];
713         addr[0] = (0x00F000F0 & FLASH_ID_MASK); /* reset bank */
714     } else {
715
716
717         for (sect = s_first; sect<=s_last; sect++) {
718                 if (info->protect[sect] == 0) { /* not protected */
719                         barf = 0;
720 #ifndef CFG_FLASH_16BIT
721                         addr = (vu_long*)(info->start[sect]);
722                         addr[0] = 0x00200020;
723                         addr[0] = 0x00D000D0;
724                         while(!(addr[0] & 0x00800080)); /* wait for error or finish */
725                         if( addr[0] & 0x003A003A) {     /* check for error */
726                                 barf = addr[0] & 0x003A0000;
727                                 if( barf ) {
728                                         barf >>=16;
729                                 } else {
730                                         barf = addr[0] & 0x0000003A;
731                                 }
732                         }
733 #else
734                         addr = (vu_short*)(info->start[sect]);
735                         addr[0] = 0x0020;
736                         addr[0] = 0x00D0;
737                         while(!(addr[0] & 0x0080));     /* wait for error or finish */
738                         if( addr[0] & 0x003A)   /* check for error */
739                                 barf = addr[0] & 0x003A;
740 #endif
741                         if(barf) {
742                                 printf("\nFlash error in sector at %lx\n",(unsigned long)addr);
743                                 if(barf & 0x0002) printf("Block locked, not erased.\n");
744                                 if((barf & 0x0030) == 0x0030)
745                                         printf("Command Sequence error.\n");
746                                 if((barf & 0x0030) == 0x0020)
747                                         printf("Block Erase error.\n");
748                                 if(barf & 0x0008) printf("Vpp Low error.\n");
749                                 rcode = 1;
750                         } else printf(".");
751                         l_sect = sect;
752                 }
753         addr = (volatile FLASH_WORD_SIZE *)info->start[0];
754         addr[0] = (0x00FF00FF & FLASH_ID_MASK); /* reset bank */
755
756         }
757
758     }
759         printf (" done\n");
760         return rcode;
761 }
762
763 /*-----------------------------------------------------------------------
764  */
765
766 /*flash_info_t *addr2info (ulong addr)
767 {
768         flash_info_t *info;
769         int i;
770
771         for (i=0, info=&flash_info[0]; i<CFG_MAX_FLASH_BANKS; ++i, ++info) {
772                 if ((addr >= info->start[0]) &&
773                     (addr < (info->start[0] + info->size)) ) {
774                         return (info);
775                 }
776         }
777
778         return (NULL);
779 }
780 */
781 /*-----------------------------------------------------------------------
782  * Copy memory to flash.
783  * Make sure all target addresses are within Flash bounds,
784  * and no protected sectors are hit.
785  * Returns:
786  * 0 - OK
787  * 1 - write timeout
788  * 2 - Flash not erased
789  * 4 - target range includes protected sectors
790  * 8 - target address not in Flash memory
791  */
792
793 /*int flash_write (uchar *src, ulong addr, ulong cnt)
794 {
795         int i;
796         ulong         end        = addr + cnt - 1;
797         flash_info_t *info_first = addr2info (addr);
798         flash_info_t *info_last  = addr2info (end );
799         flash_info_t *info;
800
801         if (cnt == 0) {
802                 return (0);
803         }
804
805         if (!info_first || !info_last) {
806                 return (8);
807         }
808
809         for (info = info_first; info <= info_last; ++info) {
810                 ulong b_end = info->start[0] + info->size;*/    /* bank end addr */
811 /*              short s_end = info->sector_count - 1;
812                 for (i=0; i<info->sector_count; ++i) {
813                         ulong e_addr = (i == s_end) ? b_end : info->start[i + 1];
814
815                         if ((end >= info->start[i]) && (addr < e_addr) &&
816                             (info->protect[i] != 0) ) {
817                                 return (4);
818                         }
819                 }
820         }
821
822 */      /* finally write data to flash */
823 /*      for (info = info_first; info <= info_last && cnt>0; ++info) {
824                 ulong len;
825
826                 len = info->start[0] + info->size - addr;
827                 if (len > cnt)
828                         len = cnt;
829                 if ((i = write_buff(info, src, addr, len)) != 0) {
830                         return (i);
831                 }
832                 cnt  -= len;
833                 addr += len;
834                 src  += len;
835         }
836         return (0);
837 }
838 */
839 /*-----------------------------------------------------------------------
840  * Copy memory to flash, returns:
841  * 0 - OK
842  * 1 - write timeout
843  * 2 - Flash not erased
844  */
845
846 int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
847 {
848 #ifndef CFG_FLASH_16BIT
849         ulong cp, wp, data;
850         int l;
851 #else
852         ulong cp, wp;
853         ushort data;
854 #endif
855         int i, rc;
856
857 #ifndef CFG_FLASH_16BIT
858
859
860         wp = (addr & ~3);       /* get lower word aligned address */
861
862         /*
863          * handle unaligned start bytes
864          */
865         if ((l = addr - wp) != 0) {
866                 data = 0;
867                 for (i=0, cp=wp; i<l; ++i, ++cp) {
868                         data = (data << 8) | (*(uchar *)cp);
869                 }
870                 for (; i<4 && cnt>0; ++i) {
871                         data = (data << 8) | *src++;
872                         --cnt;
873                         ++cp;
874                 }
875                 for (; cnt==0 && i<4; ++i, ++cp) {
876                         data = (data << 8) | (*(uchar *)cp);
877                 }
878
879                 if ((rc = write_word(info, wp, data)) != 0) {
880                         return (rc);
881                 }
882                 wp += 4;
883         }
884
885         /*
886          * handle word aligned part
887          */
888         while (cnt >= 4) {
889                 data = 0;
890                 for (i=0; i<4; ++i) {
891                         data = (data << 8) | *src++;
892                 }
893                 if ((rc = write_word(info, wp, data)) != 0) {
894                         return (rc);
895                 }
896                 wp  += 4;
897                 cnt -= 4;
898         }
899
900         if (cnt == 0) {
901                 return (0);
902         }
903
904         /*
905          * handle unaligned tail bytes
906          */
907         data = 0;
908         for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
909                 data = (data << 8) | *src++;
910                 --cnt;
911         }
912         for (; i<4; ++i, ++cp) {
913                 data = (data << 8) | (*(uchar *)cp);
914         }
915
916         return (write_word(info, wp, data));
917
918 #else
919         wp = (addr & ~1);       /* get lower word aligned address */
920
921         /*
922          * handle unaligned start byte
923          */
924         if (addr - wp) {
925                 data = 0;
926                 data = (data << 8) | *src++;
927                 --cnt;
928                 if ((rc = write_short(info, wp, data)) != 0) {
929                         return (rc);
930                 }
931                 wp += 2;
932         }
933
934         /*
935          * handle word aligned part
936          */
937 /*      l = 0; used for debuging  */
938         while (cnt >= 2) {
939                 data = 0;
940                 for (i=0; i<2; ++i) {
941                         data = (data << 8) | *src++;
942                 }
943
944 /*              if(!l){
945                         printf("%x",data);
946                         l = 1;
947                 }  used for debuging */
948
949                 if ((rc = write_short(info, wp, data)) != 0) {
950                         return (rc);
951                 }
952                 wp  += 2;
953                 cnt -= 2;
954         }
955
956         if (cnt == 0) {
957                 return (0);
958         }
959
960         /*
961          * handle unaligned tail bytes
962          */
963         data = 0;
964         for (i=0, cp=wp; i<2 && cnt>0; ++i, ++cp) {
965                 data = (data << 8) | *src++;
966                 --cnt;
967         }
968         for (; i<2; ++i, ++cp) {
969                 data = (data << 8) | (*(uchar *)cp);
970         }
971
972         return (write_short(info, wp, data));
973
974
975 #endif
976 }
977
978 /*-----------------------------------------------------------------------
979  * Write a word to Flash, returns:
980  * 0 - OK
981  * 1 - write timeout
982  * 2 - Flash not erased
983  */
984 #ifndef CFG_FLASH_16BIT
985 static int write_word (flash_info_t *info, ulong dest, ulong data)
986 {
987         vu_long *addr = (vu_long*)(info->start[0]);
988         ulong start,barf;
989         int flag;
990
991
992         /* Check if Flash is (sufficiently) erased */
993         if ((*((vu_long *)dest) & data) != data) {
994                 return (2);
995         }
996
997         /* Disable interrupts which might cause a timeout here */
998         flag = disable_interrupts();
999
1000      if(info->flash_id > FLASH_AMD_COMP) {
1001         /* AMD stuff */
1002         addr[0x0555] = 0x00AA00AA;
1003         addr[0x02AA] = 0x00550055;
1004         addr[0x0555] = 0x00A000A0;
1005      } else {
1006         /* intel stuff */
1007         *addr = 0x00400040;
1008      }
1009         *((vu_long *)dest) = data;
1010
1011         /* re-enable interrupts if necessary */
1012         if (flag)
1013                 enable_interrupts();
1014
1015         /* data polling for D7 */
1016         start = get_timer (0);
1017
1018      if(info->flash_id > FLASH_AMD_COMP) {
1019
1020         while ((*((vu_long *)dest) & 0x00800080) != (data & 0x00800080)) {
1021                 if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
1022                         return (1);
1023                 }
1024         }
1025
1026      } else {
1027
1028         while(!(addr[0] & 0x00800080)){         /* wait for error or finish */
1029                 if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
1030                         return (1);
1031         }
1032
1033         if( addr[0] & 0x003A003A) {     /* check for error */
1034                 barf = addr[0] & 0x003A0000;
1035                 if( barf ) {
1036                         barf >>=16;
1037                 } else {
1038                         barf = addr[0] & 0x0000003A;
1039                 }
1040                 printf("\nFlash write error at address %lx\n",(unsigned long)dest);
1041                 if(barf & 0x0002) printf("Block locked, not erased.\n");
1042                 if(barf & 0x0010) printf("Programming error.\n");
1043                 if(barf & 0x0008) printf("Vpp Low error.\n");
1044                 return(2);
1045         }
1046
1047
1048      }
1049
1050         return (0);
1051
1052 }
1053
1054 #else
1055
1056 static int write_short (flash_info_t *info, ulong dest, ushort data)
1057 {
1058         vu_short *addr = (vu_short*)(info->start[0]);
1059         ulong start,barf;
1060         int flag;
1061
1062         /* Check if Flash is (sufficiently) erased */
1063         if ((*((vu_short *)dest) & data) != data) {
1064                 return (2);
1065         }
1066
1067         /* Disable interrupts which might cause a timeout here */
1068         flag = disable_interrupts();
1069
1070      if(info->flash_id < FLASH_AMD_COMP) {
1071         /* AMD stuff */
1072         addr[0x0555] = 0x00AA;
1073         addr[0x02AA] = 0x0055;
1074         addr[0x0555] = 0x00A0;
1075      } else {
1076         /* intel stuff */
1077         *addr = 0x00D0;
1078         *addr = 0x0040;
1079      }
1080         *((vu_short *)dest) = data;
1081
1082         /* re-enable interrupts if necessary */
1083         if (flag)
1084                 enable_interrupts();
1085
1086         /* data polling for D7 */
1087         start = get_timer (0);
1088
1089      if(info->flash_id < FLASH_AMD_COMP) {
1090           /* AMD stuff */
1091         while ((*((vu_short *)dest) & 0x0080) != (data & 0x0080)) {
1092                 if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
1093                         return (1);
1094                 }
1095         }
1096
1097      } else {
1098         /* intel stuff */
1099         while(!(addr[0] & 0x0080)){     /* wait for error or finish */
1100                 if (get_timer(start) > CFG_FLASH_WRITE_TOUT) return (1);
1101         }
1102
1103         if( addr[0] & 0x003A) { /* check for error */
1104                 barf = addr[0] & 0x003A;
1105                 printf("\nFlash write error at address %lx\n",(unsigned long)dest);
1106                 if(barf & 0x0002) printf("Block locked, not erased.\n");
1107                 if(barf & 0x0010) printf("Programming error.\n");
1108                 if(barf & 0x0008) printf("Vpp Low error.\n");
1109                 return(2);
1110         }
1111         *addr = 0x00B0;
1112         *addr = 0x0070;
1113         while(!(addr[0] & 0x0080)){     /* wait for error or finish */
1114                 if (get_timer(start) > CFG_FLASH_WRITE_TOUT) return (1);
1115         }
1116
1117         *addr = 0x00FF;
1118
1119      }
1120
1121         return (0);
1122
1123 }
1124
1125
1126 #endif
1127
1128 /*-----------------------------------------------------------------------
1129  */
1130