]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/esd/common/flash.c
imported Freescale specific U-Boot additions for i.MX28,... release L2.6.31_10.08.01
[karo-tx-uboot.git] / board / esd / common / flash.c
1 /*
2  * (C) Copyright 2001
3  * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
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 #ifdef __PPC__
26 #include <ppc4xx.h>
27 #endif
28 #include <asm/processor.h>
29
30 flash_info_t    flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */
31
32 /*-----------------------------------------------------------------------
33  * Functions
34  */
35 static int write_word (flash_info_t *info, ulong dest, ulong data);
36
37 /*-----------------------------------------------------------------------
38  */
39 static void flash_get_offsets (ulong base, flash_info_t *info)
40 {
41         int i;
42         short n;
43
44         /* set up sector start address table */
45         if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
46             ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM640U)) {
47             for (i = 0; i < info->sector_count; i++)
48                 info->start[i] = base + (i * 0x00010000);
49         } else if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL322B) ||
50                    ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL323B) ||
51                    ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B) ||
52                    ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL324B)) {
53                 /* set sector offsets for bottom boot block type        */
54                 for (i=0; i<8; ++i) {           /*  8 x 8k boot sectors */
55                         info->start[i] = base;
56                         base += 8 << 10;
57                 }
58                 while (i < info->sector_count) {        /* 64k regular sectors  */
59                         info->start[i] = base;
60                         base += 64 << 10;
61                         ++i;
62                 }
63         } else if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL322T) ||
64                    ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL323T) ||
65                    ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320T) ||
66                    ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL324T)) {
67                 /* set sector offsets for top boot block type           */
68                 base += info->size;
69                 i = info->sector_count;
70                 for (n=0; n<8; ++n) {           /*  8 x 8k boot sectors */
71                         base -= 8 << 10;
72                         --i;
73                         info->start[i] = base;
74                 }
75                 while (i > 0) {                 /* 64k regular sectors  */
76                         base -= 64 << 10;
77                         --i;
78                         info->start[i] = base;
79                 }
80         } else {
81             if (info->flash_id & FLASH_BTYPE) {
82                 /* set sector offsets for bottom boot block type        */
83                 info->start[0] = base + 0x00000000;
84                 info->start[1] = base + 0x00004000;
85                 info->start[2] = base + 0x00006000;
86                 info->start[3] = base + 0x00008000;
87                 for (i = 4; i < info->sector_count; i++) {
88                         info->start[i] = base + (i * 0x00010000) - 0x00030000;
89                 }
90             } else {
91                 /* set sector offsets for top boot block type           */
92                 i = info->sector_count - 1;
93                 info->start[i--] = base + info->size - 0x00004000;
94                 info->start[i--] = base + info->size - 0x00006000;
95                 info->start[i--] = base + info->size - 0x00008000;
96                 for (; i >= 0; i--) {
97                         info->start[i] = base + i * 0x00010000;
98                 }
99             }
100         }
101 }
102
103 /*-----------------------------------------------------------------------
104  */
105 void flash_print_info  (flash_info_t *info)
106 {
107         int i;
108         int k;
109         int size;
110         int erased;
111         volatile unsigned long *flash;
112
113         if (info->flash_id == FLASH_UNKNOWN) {
114                 printf ("missing or unknown FLASH type\n");
115                 return;
116         }
117
118         switch (info->flash_id & FLASH_VENDMASK) {
119         case FLASH_MAN_AMD:     printf ("AMD ");                break;
120         case FLASH_MAN_FUJ:     printf ("FUJITSU ");            break;
121         case FLASH_MAN_SST:     printf ("SST ");                break;
122         case FLASH_MAN_EXCEL:   printf ("Excel Semiconductor "); break;
123         default:                printf ("Unknown Vendor ");     break;
124         }
125
126         switch (info->flash_id & FLASH_TYPEMASK) {
127         case FLASH_AM400B:      printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
128                                 break;
129         case FLASH_AM400T:      printf ("AM29LV400T (4 Mbit, top boot sector)\n");
130                                 break;
131         case FLASH_AM800B:      printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
132                                 break;
133         case FLASH_AM800T:      printf ("AM29LV800T (8 Mbit, top boot sector)\n");
134                                 break;
135         case FLASH_AM160B:      printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
136                                 break;
137         case FLASH_AM160T:      printf ("AM29LV160T (16 Mbit, top boot sector)\n");
138                                 break;
139         case FLASH_AM320T:      printf ("AM29LV320T (32 M, top sector)\n");
140                                 break;
141         case FLASH_AM320B:      printf ("AM29LV320B (32 M, bottom sector)\n");
142                                 break;
143         case FLASH_AMDL322T:    printf ("AM29DL322T (32 M, top sector)\n");
144                                 break;
145         case FLASH_AMDL322B:    printf ("AM29DL322B (32 M, bottom sector)\n");
146                                 break;
147         case FLASH_AMDL323T:    printf ("AM29DL323T (32 M, top sector)\n");
148                                 break;
149         case FLASH_AMDL323B:    printf ("AM29DL323B (32 M, bottom sector)\n");
150                                 break;
151         case FLASH_AM640U:      printf ("AM29LV640D (64 M, uniform sector)\n");
152                                 break;
153         case FLASH_SST800A:     printf ("SST39LF/VF800 (8 Mbit, uniform sector size)\n");
154                                 break;
155         case FLASH_SST160A:     printf ("SST39LF/VF160 (16 Mbit, uniform sector size)\n");
156                                 break;
157         case FLASH_SST320:      printf ("SST39LF/VF320 (32 Mbit, uniform sector size)\n");
158                                 break;
159         case FLASH_SST640:      printf ("SST39LF/VF640 (64 Mbit, uniform sector size)\n");
160                                 break;
161         default:                printf ("Unknown Chip Type\n");
162                                 break;
163         }
164
165         printf ("  Size: %ld MB in %d Sectors\n",
166                 info->size >> 20, info->sector_count);
167
168         printf ("  Sector Start Addresses:");
169         for (i=0; i<info->sector_count; ++i) {
170 #ifdef CONFIG_SYS_FLASH_EMPTY_INFO
171                 /*
172                  * Check if whole sector is erased
173                  */
174                 if (i != (info->sector_count-1))
175                   size = info->start[i+1] - info->start[i];
176                 else
177                   size = info->start[0] + info->size - info->start[i];
178                 erased = 1;
179                 flash = (volatile unsigned long *)info->start[i];
180                 size = size >> 2;        /* divide by 4 for longword access */
181                 for (k=0; k<size; k++)
182                   {
183                     if (*flash++ != 0xffffffff)
184                       {
185                         erased = 0;
186                         break;
187                       }
188                   }
189
190                 if ((i % 5) == 0)
191                         printf ("\n   ");
192                 /* print empty and read-only info */
193                 printf (" %08lX%s%s",
194                         info->start[i],
195                         erased ? " E" : "  ",
196                         info->protect[i] ? "RO " : "   ");
197 #else
198                 if ((i % 5) == 0)
199                         printf ("\n   ");
200                 printf (" %08lX%s",
201                         info->start[i],
202                         info->protect[i] ? " (RO)" : "     ");
203 #endif
204
205         }
206         printf ("\n");
207         return;
208 }
209
210 /*-----------------------------------------------------------------------
211  */
212
213
214 /*-----------------------------------------------------------------------
215  */
216
217 /*
218  * The following code cannot be run from FLASH!
219  */
220 static ulong flash_get_size (vu_long *addr, flash_info_t *info)
221 {
222         short i;
223         short n;
224         CONFIG_SYS_FLASH_WORD_SIZE value;
225         ulong base = (ulong)addr;
226         volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *)addr;
227
228         /* Write auto select command: read Manufacturer ID */
229         addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA;
230         addr2[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055;
231         addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00900090;
232
233         value = addr2[CONFIG_SYS_FLASH_READ0];
234
235         switch (value) {
236         case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_MANUFACT:
237                 info->flash_id = FLASH_MAN_AMD;
238                 break;
239         case (CONFIG_SYS_FLASH_WORD_SIZE)FUJ_MANUFACT:
240                 info->flash_id = FLASH_MAN_FUJ;
241                 break;
242         case (CONFIG_SYS_FLASH_WORD_SIZE)SST_MANUFACT:
243                 info->flash_id = FLASH_MAN_SST;
244                 break;
245         case (CONFIG_SYS_FLASH_WORD_SIZE)EXCEL_MANUFACT:
246                 info->flash_id = FLASH_MAN_EXCEL;
247                 break;
248         default:
249                 info->flash_id = FLASH_UNKNOWN;
250                 info->sector_count = 0;
251                 info->size = 0;
252                 return (0);                     /* no or unknown flash  */
253         }
254
255         value = addr2[CONFIG_SYS_FLASH_READ1];          /* device ID            */
256
257         switch (value) {
258         case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV400T:
259                 info->flash_id += FLASH_AM400T;
260                 info->sector_count = 11;
261                 info->size = 0x00080000;
262                 break;                          /* => 0.5 MB            */
263
264         case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV400B:
265                 info->flash_id += FLASH_AM400B;
266                 info->sector_count = 11;
267                 info->size = 0x00080000;
268                 break;                          /* => 0.5 MB            */
269
270         case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV800T:
271                 info->flash_id += FLASH_AM800T;
272                 info->sector_count = 19;
273                 info->size = 0x00100000;
274                 break;                          /* => 1 MB              */
275
276         case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV800B:
277                 info->flash_id += FLASH_AM800B;
278                 info->sector_count = 19;
279                 info->size = 0x00100000;
280                 break;                          /* => 1 MB              */
281
282         case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV160T:
283                 info->flash_id += FLASH_AM160T;
284                 info->sector_count = 35;
285                 info->size = 0x00200000;
286                 break;                          /* => 2 MB              */
287
288         case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV160B:
289                 info->flash_id += FLASH_AM160B;
290                 info->sector_count = 35;
291                 info->size = 0x00200000;
292                 break;                          /* => 2 MB              */
293
294         case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV320T:
295                 info->flash_id += FLASH_AM320T;
296                 info->sector_count = 71;
297                 info->size = 0x00400000;  break;        /* => 4 MB      */
298
299         case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV320B:
300                 info->flash_id += FLASH_AM320B;
301                 info->sector_count = 71;
302                 info->size = 0x00400000;  break;        /* => 4 MB      */
303
304         case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_DL322T:
305                 info->flash_id += FLASH_AMDL322T;
306                 info->sector_count = 71;
307                 info->size = 0x00400000;  break;        /* => 4 MB      */
308
309         case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_DL322B:
310                 info->flash_id += FLASH_AMDL322B;
311                 info->sector_count = 71;
312                 info->size = 0x00400000;  break;        /* => 4 MB      */
313
314         case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_DL323T:
315                 info->flash_id += FLASH_AMDL323T;
316                 info->sector_count = 71;
317                 info->size = 0x00400000;  break;        /* => 4 MB      */
318
319         case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_DL323B:
320                 info->flash_id += FLASH_AMDL323B;
321                 info->sector_count = 71;
322                 info->size = 0x00400000;  break;        /* => 4 MB      */
323
324         case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV640U:
325                 info->flash_id += FLASH_AM640U;
326                 info->sector_count = 128;
327                 info->size = 0x00800000;  break;        /* => 8 MB      */
328
329 #if !(defined(CONFIG_ADCIOP) || defined(CONFIG_DASA_SIM))
330         case (CONFIG_SYS_FLASH_WORD_SIZE)SST_ID_xF800A:
331                 info->flash_id += FLASH_SST800A;
332                 info->sector_count = 16;
333                 info->size = 0x00100000;
334                 break;                          /* => 1 MB              */
335
336         case (CONFIG_SYS_FLASH_WORD_SIZE)SST_ID_xF160A:
337         case (CONFIG_SYS_FLASH_WORD_SIZE)SST_ID_xF1601:
338         case (CONFIG_SYS_FLASH_WORD_SIZE)SST_ID_xF1602:
339                 info->flash_id += FLASH_SST160A;
340                 info->sector_count = 32;
341                 info->size = 0x00200000;
342                 break;                          /* => 2 MB              */
343
344         case (CONFIG_SYS_FLASH_WORD_SIZE)SST_ID_xF3201:
345         case (CONFIG_SYS_FLASH_WORD_SIZE)SST_ID_xF3202:
346                 info->flash_id += FLASH_SST320;
347                 info->sector_count = 64;
348                 info->size = 0x00400000;
349                 break;                          /* => 4 MB              */
350
351         case (CONFIG_SYS_FLASH_WORD_SIZE)SST_ID_xF6401:
352         case (CONFIG_SYS_FLASH_WORD_SIZE)SST_ID_xF6402:
353                 info->flash_id += FLASH_SST640;
354                 info->sector_count = 128;
355                 info->size = 0x00800000;
356                 break;                          /* => 8 MB              */
357 #endif
358
359         default:
360                 info->flash_id = FLASH_UNKNOWN;
361                 return (0);                     /* => no or unknown flash */
362
363         }
364
365         /* set up sector start address table */
366         if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
367             ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM640U)) {
368             for (i = 0; i < info->sector_count; i++)
369                 info->start[i] = base + (i * 0x00010000);
370         } else if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL322B) ||
371                    ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL323B) ||
372                    ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B) ||
373                    ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL324B)) {
374                 /* set sector offsets for bottom boot block type        */
375                 for (i=0; i<8; ++i) {           /*  8 x 8k boot sectors */
376                         info->start[i] = base;
377                         base += 8 << 10;
378                 }
379                 while (i < info->sector_count) {        /* 64k regular sectors  */
380                         info->start[i] = base;
381                         base += 64 << 10;
382                         ++i;
383                 }
384         } else if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL322T) ||
385                    ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL323T) ||
386                    ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320T) ||
387                    ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL324T)) {
388                 /* set sector offsets for top boot block type           */
389                 base += info->size;
390                 i = info->sector_count;
391                 for (n=0; n<8; ++n) {           /*  8 x 8k boot sectors */
392                         base -= 8 << 10;
393                         --i;
394                         info->start[i] = base;
395                 }
396                 while (i > 0) {                 /* 64k regular sectors  */
397                         base -= 64 << 10;
398                         --i;
399                         info->start[i] = base;
400                 }
401         } else {
402             if (info->flash_id & FLASH_BTYPE) {
403                 /* set sector offsets for bottom boot block type        */
404                 info->start[0] = base + 0x00000000;
405                 info->start[1] = base + 0x00004000;
406                 info->start[2] = base + 0x00006000;
407                 info->start[3] = base + 0x00008000;
408                 for (i = 4; i < info->sector_count; i++) {
409                         info->start[i] = base + (i * 0x00010000) - 0x00030000;
410                 }
411             } else {
412                 /* set sector offsets for top boot block type           */
413                 i = info->sector_count - 1;
414                 info->start[i--] = base + info->size - 0x00004000;
415                 info->start[i--] = base + info->size - 0x00006000;
416                 info->start[i--] = base + info->size - 0x00008000;
417                 for (; i >= 0; i--) {
418                         info->start[i] = base + i * 0x00010000;
419                 }
420             }
421         }
422
423         /* check for protected sectors */
424         for (i = 0; i < info->sector_count; i++) {
425                 /* read sector protection at sector address, (A7 .. A0) = 0x02 */
426                 /* D0 = 1 if protected */
427                 addr2 = (volatile CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[i]);
428                 if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_AMD)
429                   info->protect[i] = 0;
430                 else
431                   info->protect[i] = addr2[CONFIG_SYS_FLASH_READ2] & 1;
432         }
433
434         /*
435          * Prevent writes to uninitialized FLASH.
436          */
437         if (info->flash_id != FLASH_UNKNOWN) {
438                 addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *)info->start[0];
439                 *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE)0x00F000F0;        /* reset bank */
440         }
441
442         return (info->size);
443 }
444
445
446 /*-----------------------------------------------------------------------
447  */
448
449 int     flash_erase (flash_info_t *info, int s_first, int s_last)
450 {
451         volatile CONFIG_SYS_FLASH_WORD_SIZE *addr = (CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[0]);
452         volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2;
453         int flag, prot, sect, l_sect;
454         ulong start, now, last;
455         int i;
456
457         if ((s_first < 0) || (s_first > s_last)) {
458                 if (info->flash_id == FLASH_UNKNOWN) {
459                         printf ("- missing\n");
460                 } else {
461                         printf ("- no sectors to erase\n");
462                 }
463                 return 1;
464         }
465
466         if (info->flash_id == FLASH_UNKNOWN) {
467                 printf ("Can't erase unknown flash type - aborted\n");
468                 return 1;
469         }
470
471         prot = 0;
472         for (sect=s_first; sect<=s_last; ++sect) {
473                 if (info->protect[sect]) {
474                         prot++;
475                 }
476         }
477
478         if (prot) {
479                 printf ("- Warning: %d protected sectors will not be erased!\n",
480                         prot);
481         } else {
482                 printf ("\n");
483         }
484
485         l_sect = -1;
486
487         /* Disable interrupts which might cause a timeout here */
488         flag = disable_interrupts();
489
490         /* Start erase on unprotected sectors */
491         for (sect = s_first; sect<=s_last; sect++) {
492                 if (info->protect[sect] == 0) { /* not protected */
493                     addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[sect]);
494                     if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) {
495                         addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA;
496                         addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055;
497                         addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080;
498                         addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA;
499                         addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055;
500                         addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00500050;  /* block erase */
501                         for (i=0; i<50; i++)
502                           udelay(1000);  /* wait 1 ms */
503                     } else {
504                         if (sect == s_first) {
505                             addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA;
506                             addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055;
507                             addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080;
508                             addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA;
509                             addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055;
510                         }
511                         addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00300030;  /* sector erase */
512                     }
513                     l_sect = sect;
514                 }
515         }
516
517         /* re-enable interrupts if necessary */
518         if (flag)
519                 enable_interrupts();
520
521         /* wait at least 80us - let's wait 1 ms */
522         udelay (1000);
523
524         /*
525          * We wait for the last triggered sector
526          */
527         if (l_sect < 0)
528                 goto DONE;
529
530         start = get_timer (0);
531         last  = start;
532         addr = (CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[l_sect]);
533         while ((addr[0] & (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080) != (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080) {
534                 if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
535                         printf ("Timeout\n");
536                         return 1;
537                 }
538                 /* show that we're waiting */
539                 if ((now - last) > 1000) {      /* every second */
540                         putc ('.');
541                         last = now;
542                 }
543         }
544
545 DONE:
546         /* reset to read mode */
547         addr = (CONFIG_SYS_FLASH_WORD_SIZE *)info->start[0];
548         addr[0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00F000F0;       /* reset bank */
549
550         printf (" done\n");
551         return 0;
552 }
553
554 /*-----------------------------------------------------------------------
555  * Copy memory to flash, returns:
556  * 0 - OK
557  * 1 - write timeout
558  * 2 - Flash not erased
559  */
560
561 int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
562 {
563         ulong cp, wp, data;
564         int i, l, rc;
565
566         wp = (addr & ~3);       /* get lower word aligned address */
567
568         /*
569          * handle unaligned start bytes
570          */
571         if ((l = addr - wp) != 0) {
572                 data = 0;
573                 for (i=0, cp=wp; i<l; ++i, ++cp) {
574                         data = (data << 8) | (*(uchar *)cp);
575                 }
576                 for (; i<4 && cnt>0; ++i) {
577                         data = (data << 8) | *src++;
578                         --cnt;
579                         ++cp;
580                 }
581                 for (; cnt==0 && i<4; ++i, ++cp) {
582                         data = (data << 8) | (*(uchar *)cp);
583                 }
584
585                 if ((rc = write_word(info, wp, data)) != 0) {
586                         return (rc);
587                 }
588                 wp += 4;
589         }
590
591         /*
592          * handle word aligned part
593          */
594         while (cnt >= 4) {
595                 data = 0;
596                 for (i=0; i<4; ++i) {
597                         data = (data << 8) | *src++;
598                 }
599                 if ((rc = write_word(info, wp, data)) != 0) {
600                         return (rc);
601                 }
602                 wp  += 4;
603                 cnt -= 4;
604         }
605
606         if (cnt == 0) {
607                 return (0);
608         }
609
610         /*
611          * handle unaligned tail bytes
612          */
613         data = 0;
614         for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
615                 data = (data << 8) | *src++;
616                 --cnt;
617         }
618         for (; i<4; ++i, ++cp) {
619                 data = (data << 8) | (*(uchar *)cp);
620         }
621
622         return (write_word(info, wp, data));
623 }
624
625 /*-----------------------------------------------------------------------
626  * Write a word to Flash, returns:
627  * 0 - OK
628  * 1 - write timeout
629  * 2 - Flash not erased
630  */
631 static int write_word (flash_info_t *info, ulong dest, ulong data)
632 {
633         volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[0]);
634         volatile CONFIG_SYS_FLASH_WORD_SIZE *dest2 = (CONFIG_SYS_FLASH_WORD_SIZE *)dest;
635         volatile CONFIG_SYS_FLASH_WORD_SIZE *data2 = (CONFIG_SYS_FLASH_WORD_SIZE *)&data;
636         ulong start;
637         int flag;
638         int i;
639
640         /* Check if Flash is (sufficiently) erased */
641         if ((*((vu_long *)dest) & data) != data) {
642                 return (2);
643         }
644
645         /* Disable interrupts which might cause a timeout here */
646         flag = disable_interrupts();
647
648         for (i=0; i<4/sizeof(CONFIG_SYS_FLASH_WORD_SIZE); i++)
649           {
650             addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA;
651             addr2[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055;
652             addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00A000A0;
653
654             dest2[i] = data2[i];
655
656             /* re-enable interrupts if necessary */
657             if (flag)
658               enable_interrupts();
659
660             /* data polling for D7 */
661             start = get_timer (0);
662             while ((dest2[i] & (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080) !=
663                    (data2[i] & (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080)) {
664               if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
665                 return (1);
666               }
667             }
668           }
669
670         return (0);
671 }
672
673 /*-----------------------------------------------------------------------
674  */