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