Merge with /home/wd/git/u-boot/custodian/u-boot-ppc4xx
[oweals/u-boot.git] / board / amcc / taihu / flash.c
1 /*
2  * (C) Copyright 2000
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 /*
25  * Modified 4/5/2001
26  * Wait for completion of each sector erase command issued
27  * 4/5/2001
28  * Chris Hallinan - DS4.COM, Inc. - clh@net1plus.com
29  */
30
31 #include <common.h>
32 #include <ppc4xx.h>
33 #include <asm/processor.h>
34
35 flash_info_t flash_info[CFG_MAX_FLASH_BANKS];   /* info for FLASH chips        */
36
37 #undef DEBUG
38 #ifdef DEBUG
39 #define DEBUGF(x...) printf(x)
40 #else
41 #define DEBUGF(x...)
42 #endif                          /* DEBUG */
43
44 #define CFG_FLASH_CHAR_SIZE unsigned char
45 #define CFG_FLASH_CHAR_ADDR0 (0x0aaa)
46 #define CFG_FLASH_CHAR_ADDR1 (0x0555)
47 /*-----------------------------------------------------------------------
48  * Functions
49  */
50 static ulong flash_get_size(vu_long * addr, flash_info_t * info);
51 static void flash_get_offsets(ulong base, flash_info_t * info);
52 static int write_word(flash_info_t * info, ulong dest, ulong data);
53 #ifdef FLASH_BASE1_PRELIM
54 static int write_word_1(flash_info_t * info, ulong dest, ulong data);
55 static int write_word_2(flash_info_t * info, ulong dest, ulong data);
56 static int flash_erase_1(flash_info_t * info, int s_first, int s_last);
57 static int flash_erase_2(flash_info_t * info, int s_first, int s_last);
58 static ulong flash_get_size_1(vu_long * addr, flash_info_t * info);
59 static ulong flash_get_size_2(vu_long * addr, flash_info_t * info);
60 #endif
61
62 unsigned long flash_init(void)
63 {
64         unsigned long size_b0, size_b1=0;
65         int i;
66
67         /* Init: no FLASHes known */
68         for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
69                 flash_info[i].flash_id = FLASH_UNKNOWN;
70         }
71
72         /* Static FLASH Bank configuration here - FIXME XXX */
73
74         size_b0 =
75             flash_get_size((vu_long *) FLASH_BASE0_PRELIM, &flash_info[0]);
76
77         if (flash_info[0].flash_id == FLASH_UNKNOWN) {
78                 printf("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
79                        size_b0, size_b0 << 20);
80         }
81
82         if (size_b0) {
83                 /* Setup offsets */
84                 flash_get_offsets(FLASH_BASE0_PRELIM, &flash_info[0]);
85                 /* Monitor protection ON by default */
86                 (void)flash_protect(FLAG_PROTECT_SET,
87                                     CFG_MONITOR_BASE,
88                                     CFG_MONITOR_BASE + CFG_MONITOR_LEN - 1,
89                                     &flash_info[0]);
90 #ifdef CFG_ENV_IS_IN_FLASH
91                 (void)flash_protect(FLAG_PROTECT_SET, CFG_ENV_ADDR,
92                                     CFG_ENV_ADDR + CFG_ENV_SECT_SIZE - 1,
93                                     &flash_info[0]);
94                 (void)flash_protect(FLAG_PROTECT_SET, CFG_ENV_ADDR_REDUND,
95                                     CFG_ENV_ADDR_REDUND + CFG_ENV_SECT_SIZE - 1,
96                                     &flash_info[0]);
97 #endif
98                 /* Also protect sector containing initial power-up instruction */
99                 /* (flash_protect() checks address range - other call ignored) */
100                 (void)flash_protect(FLAG_PROTECT_SET,
101                                     0xFFFFFFFC, 0xFFFFFFFF, &flash_info[0]);
102
103                 flash_info[0].size = size_b0;
104         }
105 #ifdef FLASH_BASE1_PRELIM
106         size_b1 =
107             flash_get_size((vu_long *) FLASH_BASE1_PRELIM, &flash_info[1])*2;
108
109         if (flash_info[1].flash_id == FLASH_UNKNOWN) {
110                 printf("## Unknown FLASH on Bank 1 - Size = 0x%08lx = %ld MB\n",
111                        size_b1, size_b1 << 20);
112         }
113
114         if (size_b1) {
115                 /* Setup offsets */
116                 flash_get_offsets(FLASH_BASE1_PRELIM, &flash_info[1]);
117                 flash_info[1].size = size_b1;
118         }
119 #endif
120         return (size_b0 + size_b1);
121 }
122
123 static void flash_get_offsets(ulong base, flash_info_t * info)
124 {
125         int i;
126
127         /* set up sector start address table */
128         if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
129             (info->flash_id == FLASH_AM040)) {
130                 for (i = 0; i < info->sector_count; i++)
131                         info->start[i] = base + (i * 0x00010000);
132         } else if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMLV128U) {
133                 for (i = 0; i < info->sector_count; i++) {
134                         info->start[i] = base + (i * 0x00010000*2);
135                 }
136         } else if ((info->flash_id & FLASH_TYPEMASK) == FLASH_S29GL128N ) {
137                 for (i = 0; i < info->sector_count; i++) {
138                         info->start[i] = base + (i * 0x00020000*2);
139                 }
140         } else {
141                 if (info->flash_id & FLASH_BTYPE) {
142                         /* set sector offsets for bottom boot block type        */
143                         info->start[0] = base + 0x00000000;
144                         info->start[1] = base + 0x00004000;
145                         info->start[2] = base + 0x00006000;
146                         info->start[3] = base + 0x00008000;
147                         for (i = 4; i < info->sector_count; i++) {
148                                 info->start[i] =
149                                     base + (i * 0x00010000) - 0x00030000;
150                         }
151                 } else {
152                         /* set sector offsets for top boot block type           */
153                         i = info->sector_count - 1;
154                         info->start[i--] = base + info->size - 0x00004000;
155                         info->start[i--] = base + info->size - 0x00006000;
156                         info->start[i--] = base + info->size - 0x00008000;
157                         for (; i >= 0; i--) {
158                                 info->start[i] = base + i * 0x00010000;
159                         }
160                 }
161         }
162 }
163
164
165 void flash_print_info(flash_info_t * info)
166 {
167         int i;
168         int k;
169         int size;
170         int erased;
171         volatile unsigned long *flash;
172
173         if (info->flash_id == FLASH_UNKNOWN) {
174                 printf("missing or unknown FLASH type\n");
175                 return;
176         }
177
178         switch (info->flash_id & FLASH_VENDMASK) {
179         case FLASH_MAN_AMD:
180                 printf("AMD ");
181                 break;
182         case FLASH_MAN_STM:
183                 printf("STM ");
184                 break;
185         case FLASH_MAN_FUJ:
186                 printf("FUJITSU ");
187                 break;
188         case FLASH_MAN_SST:
189                 printf("SST ");
190                 break;
191         default:
192                 printf("Unknown Vendor ");
193                 break;
194         }
195
196         switch (info->flash_id & FLASH_TYPEMASK) {
197         case FLASH_AM040:
198                 printf("AM29F040 (512 Kbit, uniform sector size)\n");
199                 break;
200         case FLASH_AM400B:
201                 printf("AM29LV400B (4 Mbit, bottom boot sect)\n");
202                 break;
203         case FLASH_AM400T:
204                 printf("AM29LV400T (4 Mbit, top boot sector)\n");
205                 break;
206         case FLASH_AM800B:
207                 printf("AM29LV800B (8 Mbit, bottom boot sect)\n");
208                 break;
209         case FLASH_AM800T:
210                 printf("AM29LV800T (8 Mbit, top boot sector)\n");
211                 break;
212         case FLASH_AMD016:
213                 printf("AM29F016D (16 Mbit, uniform sector size)\n");
214                 break;
215         case FLASH_AM160B:
216                 printf("AM29LV160B (16 Mbit, bottom boot sect)\n");
217                 break;
218         case FLASH_AM160T:
219                 printf("AM29LV160T (16 Mbit, top boot sector)\n");
220                 break;
221         case FLASH_AM320B:
222                 printf("AM29LV320B (32 Mbit, bottom boot sect)\n");
223                 break;
224         case FLASH_AM320T:
225                 printf("AM29LV320T (32 Mbit, top boot sector)\n");
226                 break;
227         case FLASH_AM033C:
228                 printf("AM29LV033C (32 Mbit, top boot sector)\n");
229                 break;
230         case FLASH_AMLV128U:
231                 printf("AM29LV128U (128 Mbit * 2, top boot sector)\n");
232                 break;
233         case FLASH_SST800A:
234                 printf("SST39LF/VF800 (8 Mbit, uniform sector size)\n");
235                 break;
236         case FLASH_SST160A:
237                 printf("SST39LF/VF160 (16 Mbit, uniform sector size)\n");
238                 break;
239         case FLASH_STMW320DT:
240                 printf ("M29W320DT (32 M, top sector)\n");
241                 break;
242         case FLASH_S29GL128N:
243                 printf ("S29GL128N (256 Mbit, uniform sector size)\n");
244                 break;
245         default:
246                 printf("Unknown Chip Type\n");
247                 break;
248         }
249
250         printf("  Size: %ld KB in %d Sectors\n",
251                info->size >> 10, info->sector_count);
252
253         printf("  Sector Start Addresses:");
254         for (i = 0; i < info->sector_count; ++i) {
255                 /*
256                  * Check if whole sector is erased
257                  */
258                 if (i != (info->sector_count - 1))
259                         size = info->start[i + 1] - info->start[i];
260                 else
261                         size = info->start[0] + info->size - info->start[i];
262                 erased = 1;
263                 flash = (volatile unsigned long *)info->start[i];
264                 size = size >> 2;       /* divide by 4 for longword access */
265                 for (k = 0; k < size; k++) {
266                         if (*flash++ != 0xffffffff) {
267                                 erased = 0;
268                                 break;
269                         }
270                 }
271
272                 if ((i % 5) == 0)
273                         printf("\n   ");
274                 printf(" %08lX%s%s",
275                        info->start[i],
276                        erased ? " E" : "  ", info->protect[i] ? "RO " : "   ");
277         }
278         printf("\n");
279         return;
280 }
281
282
283 /*
284  * The following code cannot be run from FLASH!
285  */
286 #ifdef FLASH_BASE1_PRELIM
287 static ulong flash_get_size(vu_long * addr, flash_info_t * info)
288 {
289         if ((ulong)addr == FLASH_BASE1_PRELIM) {
290                 return flash_get_size_2(addr, info);
291         } else {
292                 return flash_get_size_1(addr, info);
293         }
294 }
295
296 static ulong flash_get_size_1(vu_long * addr, flash_info_t * info)
297 #else
298 static ulong flash_get_size(vu_long * addr, flash_info_t * info)
299 #endif
300 {
301         short i;
302         CFG_FLASH_WORD_SIZE value;
303         ulong base = (ulong) addr;
304         volatile CFG_FLASH_WORD_SIZE *addr2 = (CFG_FLASH_WORD_SIZE *) addr;
305
306         DEBUGF("FLASH ADDR: %08x\n", (unsigned)addr);
307
308         /* Write auto select command: read Manufacturer ID */
309         addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00AA00AA;
310         addr2[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x00550055;
311         addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00900090;
312         udelay(1000);
313
314         value = addr2[0];
315         DEBUGF("FLASH MANUFACT: %x\n", value);
316
317         switch (value) {
318         case (CFG_FLASH_WORD_SIZE) AMD_MANUFACT:
319                 info->flash_id = FLASH_MAN_AMD;
320                 break;
321         case (CFG_FLASH_WORD_SIZE) FUJ_MANUFACT:
322                 info->flash_id = FLASH_MAN_FUJ;
323                 break;
324         case (CFG_FLASH_WORD_SIZE) SST_MANUFACT:
325                 info->flash_id = FLASH_MAN_SST;
326                 break;
327         case (CFG_FLASH_WORD_SIZE) STM_MANUFACT:
328                 info->flash_id = FLASH_MAN_STM;
329                 break;
330         default:
331                 info->flash_id = FLASH_UNKNOWN;
332                 info->sector_count = 0;
333                 info->size = 0;
334                 return 0;       /* no or unknown flash  */
335         }
336
337         value = addr2[1];       /* device ID            */
338         DEBUGF("\nFLASH DEVICEID: %x\n", value);
339
340         switch (value) {
341         case (CFG_FLASH_WORD_SIZE) AMD_ID_LV040B:
342                 info->flash_id += FLASH_AM040;
343                 info->sector_count = 8;
344                 info->size = 0x0080000; /* => 512 ko */
345                 break;
346
347         case (CFG_FLASH_WORD_SIZE) AMD_ID_F040B:
348                 info->flash_id += FLASH_AM040;
349                 info->sector_count = 8;
350                 info->size = 0x0080000; /* => 512 ko */
351                 break;
352
353         case (CFG_FLASH_WORD_SIZE) STM_ID_M29W040B:
354                 info->flash_id += FLASH_AM040;
355                 info->sector_count = 8;
356                 info->size = 0x0080000; /* => 512 ko */
357                 break;
358
359         case (CFG_FLASH_WORD_SIZE) AMD_ID_F016D:
360                 info->flash_id += FLASH_AMD016;
361                 info->sector_count = 32;
362                 info->size = 0x00200000;
363                 break;          /* => 2 MB              */
364
365         case (CFG_FLASH_WORD_SIZE) AMD_ID_LV033C:
366                 info->flash_id += FLASH_AMDLV033C;
367                 info->sector_count = 64;
368                 info->size = 0x00400000;
369                 break;          /* => 4 MB              */
370
371         case (CFG_FLASH_WORD_SIZE) AMD_ID_LV400T:
372                 info->flash_id += FLASH_AM400T;
373                 info->sector_count = 11;
374                 info->size = 0x00080000;
375                 break;          /* => 0.5 MB            */
376
377         case (CFG_FLASH_WORD_SIZE) AMD_ID_LV400B:
378                 info->flash_id += FLASH_AM400B;
379                 info->sector_count = 11;
380                 info->size = 0x00080000;
381                 break;          /* => 0.5 MB            */
382
383         case (CFG_FLASH_WORD_SIZE) AMD_ID_LV800T:
384                 info->flash_id += FLASH_AM800T;
385                 info->sector_count = 19;
386                 info->size = 0x00100000;
387                 break;          /* => 1 MB              */
388
389         case (CFG_FLASH_WORD_SIZE) AMD_ID_LV800B:
390                 info->flash_id += FLASH_AM800B;
391                 info->sector_count = 19;
392                 info->size = 0x00100000;
393                 break;          /* => 1 MB              */
394
395         case (CFG_FLASH_WORD_SIZE) AMD_ID_LV160T:
396                 info->flash_id += FLASH_AM160T;
397                 info->sector_count = 35;
398                 info->size = 0x00200000;
399                 break;          /* => 2 MB              */
400
401         case (CFG_FLASH_WORD_SIZE) AMD_ID_LV160B:
402                 info->flash_id += FLASH_AM160B;
403                 info->sector_count = 35;
404                 info->size = 0x00200000;
405                 break;          /* => 2 MB              */
406         default:
407                 info->flash_id = FLASH_UNKNOWN;
408                 return 0;       /* => no or unknown flash */
409         }
410
411         /* set up sector start address table */
412         if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
413             ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040) ||
414             ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMD016)) {
415                 for (i = 0; i < info->sector_count; i++)
416                         info->start[i] = base + (i * 0x00010000);
417         }
418         else if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMLV128U) {
419                 for (i = 0; i < info->sector_count; i++)
420                         info->start[i] = base + (i * 0x00010000 * 2);
421         } else {
422                 if (info->flash_id & FLASH_BTYPE) {
423                         /* set sector offsets for bottom boot block type        */
424                         info->start[0] = base + 0x00000000;
425                         info->start[1] = base + 0x00004000;
426                         info->start[2] = base + 0x00006000;
427                         info->start[3] = base + 0x00008000;
428                         for (i = 4; i < info->sector_count; i++) {
429                                 info->start[i] =
430                                     base + (i * 0x00010000) - 0x00030000;
431                         }
432                 } else {
433                         /* set sector offsets for top boot block type           */
434                         i = info->sector_count - 1;
435                         info->start[i--] = base + info->size - 0x00004000;
436                         info->start[i--] = base + info->size - 0x00006000;
437                         info->start[i--] = base + info->size - 0x00008000;
438                         for (; i >= 0; i--) {
439                                 info->start[i] = base + i * 0x00010000;
440                         }
441                 }
442         }
443
444         /* check for protected sectors */
445         for (i = 0; i < info->sector_count; i++) {
446                 /* read sector protection at sector address, (A7 .. A0) = 0x02 */
447                 /* D0 = 1 if protected */
448                 addr2 = (volatile CFG_FLASH_WORD_SIZE *)(info->start[i]);
449
450                 /* For AMD29033C flash we need to resend the command of *
451                  * reading flash protection for upper 8 Mb of flash     */
452                 if (i == 32) {
453                         addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0xAAAAAAAA;
454                         addr2[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x55555555;
455                         addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x90909090;
456                 }
457
458                 if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST)
459                         info->protect[i] = 0;
460                 else
461                         info->protect[i] = addr2[2] & 1;
462         }
463
464         /* issue bank reset to return to read mode */
465         addr2[0] = (CFG_FLASH_WORD_SIZE) 0x00F000F0;
466
467         return info->size;
468 }
469
470 static int wait_for_DQ7_1(flash_info_t * info, int sect)
471 {
472         ulong start, now, last;
473         volatile CFG_FLASH_WORD_SIZE *addr =
474             (CFG_FLASH_WORD_SIZE *) (info->start[sect]);
475
476         start = get_timer(0);
477         last = start;
478         while ((addr[0] & (CFG_FLASH_WORD_SIZE) 0x00800080) !=
479                (CFG_FLASH_WORD_SIZE) 0x00800080) {
480                 if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
481                         printf("Timeout\n");
482                         return -1;
483                 }
484                 /* show that we're waiting */
485                 if ((now - last) > 1000) {      /* every second */
486                         putc('.');
487                         last = now;
488                 }
489         }
490         return 0;
491 }
492
493 #ifdef FLASH_BASE1_PRELIM
494 int flash_erase(flash_info_t * info, int s_first, int s_last)
495 {
496         if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B) ||
497             ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320T) ||
498             ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMLV128U) ||
499             ((info->flash_id & FLASH_TYPEMASK) == FLASH_S29GL128N) ||
500             ((info->flash_id & FLASH_TYPEMASK) == FLASH_STMW320DT)) {
501                 return flash_erase_2(info, s_first, s_last);
502         } else {
503                 return flash_erase_1(info, s_first, s_last);
504         }
505 }
506
507 static int flash_erase_1(flash_info_t * info, int s_first, int s_last)
508 #else
509 int flash_erase(flash_info_t * info, int s_first, int s_last)
510 #endif
511 {
512         volatile CFG_FLASH_WORD_SIZE *addr = (CFG_FLASH_WORD_SIZE *) (info->start[0]);
513         volatile CFG_FLASH_WORD_SIZE *addr2;
514         int flag, prot, sect, l_sect;
515         int i;
516
517         if ((s_first < 0) || (s_first > s_last)) {
518                 if (info->flash_id == FLASH_UNKNOWN) {
519                         printf("- missing\n");
520                 } else {
521                         printf("- no sectors to erase\n");
522                 }
523                 return 1;
524         }
525
526         if (info->flash_id == FLASH_UNKNOWN) {
527                 printf("Can't erase unknown flash type - aborted\n");
528                 return 1;
529         }
530
531         prot = 0;
532         for (sect = s_first; sect <= s_last; ++sect) {
533                 if (info->protect[sect]) {
534                         prot++;
535                 }
536         }
537
538         if (prot) {
539                 printf("- Warning: %d protected sectors will not be erased!\n",
540                        prot);
541         } else {
542                 printf("\n");
543         }
544
545         l_sect = -1;
546
547         /* Disable interrupts which might cause a timeout here */
548         flag = disable_interrupts();
549
550         /* Start erase on unprotected sectors */
551         for (sect = s_first; sect <= s_last; sect++) {
552                 if (info->protect[sect] == 0) { /* not protected */
553                         addr2 = (CFG_FLASH_WORD_SIZE *) (info->start[sect]);
554
555                         if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) {
556                                 addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00AA00AA;
557                                 addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x00550055;
558                                 addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00800080;
559                                 addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00AA00AA;
560                                 addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x00550055;
561                                 addr2[0] = (CFG_FLASH_WORD_SIZE) 0x00500050;    /* block erase */
562                                 for (i = 0; i < 50; i++)
563                                         udelay(1000);   /* wait 1 ms */
564                         } else {
565                                 addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00AA00AA;
566                                 addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x00550055;
567                                 addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00800080;
568                                 addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00AA00AA;
569                                 addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x00550055;
570                                 addr2[0] = (CFG_FLASH_WORD_SIZE) 0x00300030;    /* sector erase */
571                         }
572                         l_sect = sect;
573                         /*
574                          * Wait for each sector to complete, it's more
575                          * reliable.  According to AMD Spec, you must
576                          * issue all erase commands within a specified
577                          * timeout.  This has been seen to fail, especially
578                          * if printf()s are included (for debug)!!
579                          */
580                         wait_for_DQ7_1(info, sect);
581                 }
582         }
583
584         /* re-enable interrupts if necessary */
585         if (flag)
586                 enable_interrupts();
587
588         /* wait at least 80us - let's wait 1 ms */
589         udelay(1000);
590
591         /* reset to read mode */
592         addr = (CFG_FLASH_WORD_SIZE *) info->start[0];
593         addr[0] = (CFG_FLASH_WORD_SIZE) 0x00F000F0;     /* reset bank */
594
595         printf(" done\n");
596         return 0;
597 }
598
599 /*-----------------------------------------------------------------------
600  * Copy memory to flash, returns:
601  * 0 - OK
602  * 1 - write timeout
603  * 2 - Flash not erased
604  */
605 int write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt)
606 {
607         ulong cp, wp, data;
608         int i, l, rc;
609
610         wp = (addr & ~3);       /* get lower word aligned address */
611
612         /*
613          * handle unaligned start bytes
614          */
615         if ((l = addr - wp) != 0) {
616                 data = 0;
617                 for (i = 0, cp = wp; i < l; ++i, ++cp) {
618                         data = (data << 8) | (*(uchar *) cp);
619                 }
620                 for (; i < 4 && cnt > 0; ++i) {
621                         data = (data << 8) | *src++;
622                         --cnt;
623                         ++cp;
624                 }
625                 for (; cnt == 0 && i < 4; ++i, ++cp) {
626                         data = (data << 8) | (*(uchar *) cp);
627                 }
628
629                 if ((rc = write_word(info, wp, data)) != 0) {
630                         return rc;
631                 }
632                 wp += 4;
633         }
634
635         /*
636          * handle word aligned part
637          */
638         while (cnt >= 4) {
639                 data = 0;
640                 for (i = 0; i < 4; ++i) {
641                         data = (data << 8) | *src++;
642                 }
643                 if ((rc = write_word(info, wp, data)) != 0) {
644                         return rc;
645                 }
646                 wp += 4;
647                 cnt -= 4;
648         }
649
650         if (cnt == 0) {
651                 return 0;
652         }
653
654         /*
655          * handle unaligned tail bytes
656          */
657         data = 0;
658         for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
659                 data = (data << 8) | *src++;
660                 --cnt;
661         }
662         for (; i < 4; ++i, ++cp) {
663                 data = (data << 8) | (*(uchar *) cp);
664         }
665
666         return (write_word(info, wp, data));
667 }
668
669 /*-----------------------------------------------------------------------
670  * Copy memory to flash, returns:
671  * 0 - OK
672  * 1 - write timeout
673  * 2 - Flash not erased
674  */
675 #ifdef FLASH_BASE1_PRELIM
676 static int write_word(flash_info_t * info, ulong dest, ulong data)
677 {
678         if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B) ||
679             ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320T) ||
680             ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMLV128U) ||
681             ((info->flash_id & FLASH_TYPEMASK) == FLASH_S29GL128N) ||
682             ((info->flash_id & FLASH_TYPEMASK) == FLASH_STMW320DT)) {
683                 return write_word_2(info, dest, data);
684         } else {
685                 return write_word_1(info, dest, data);
686         }
687 }
688
689 static int write_word_1(flash_info_t * info, ulong dest, ulong data)
690 #else
691 static int write_word(flash_info_t * info, ulong dest, ulong data)
692 #endif
693 {
694         volatile CFG_FLASH_WORD_SIZE *addr2 = (CFG_FLASH_WORD_SIZE *) (info->start[0]);
695         volatile CFG_FLASH_WORD_SIZE *dest2 = (CFG_FLASH_WORD_SIZE *) dest;
696         volatile CFG_FLASH_WORD_SIZE *data2 = (CFG_FLASH_WORD_SIZE *) & data;
697         ulong start;
698         int i;
699
700         /* Check if Flash is (sufficiently) erased */
701         if ((*((vu_long *)dest) & data) != data) {
702                 return 2;
703         }
704
705         for (i = 0; i < 4 / sizeof(CFG_FLASH_WORD_SIZE); i++) {
706                 int flag;
707
708                 /* Disable interrupts which might cause a timeout here */
709                 flag = disable_interrupts();
710
711                 addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00AA00AA;
712                 addr2[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x00550055;
713                 addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00A000A0;
714
715                 dest2[i] = data2[i];
716
717                 /* re-enable interrupts if necessary */
718                 if (flag)
719                         enable_interrupts();
720
721                 /* data polling for D7 */
722                 start = get_timer(0);
723                 while ((dest2[i] & (CFG_FLASH_WORD_SIZE) 0x00800080) !=
724                        (data2[i] & (CFG_FLASH_WORD_SIZE) 0x00800080)) {
725
726                         if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
727                                 return 1;
728                         }
729                 }
730         }
731
732         return 0;
733 }
734
735 #ifdef FLASH_BASE1_PRELIM
736
737 /*
738  * The following code cannot be run from FLASH!
739  */
740 static ulong flash_get_size_2(vu_long * addr, flash_info_t * info)
741 {
742         short i;
743         CFG_FLASH_CHAR_SIZE value;
744         ulong base = (ulong) addr;
745         volatile CFG_FLASH_WORD_SIZE *addr2 = (CFG_FLASH_WORD_SIZE *) addr;
746
747         DEBUGF("FLASH ADDR: %08x\n", (unsigned)addr);
748
749         /* Write auto select command: read Manufacturer ID */
750         addr2[CFG_FLASH_CHAR_ADDR0] = (CFG_FLASH_WORD_SIZE) 0xAAAAAAAA;
751         addr2[CFG_FLASH_CHAR_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x55555555;
752         addr2[CFG_FLASH_CHAR_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x90909090;
753         udelay(1000);
754
755         value = (CFG_FLASH_CHAR_SIZE)addr2[0];
756         DEBUGF("FLASH MANUFACT: %x\n", value);
757
758         switch (value) {
759         case (CFG_FLASH_CHAR_SIZE) AMD_MANUFACT:
760                 info->flash_id = FLASH_MAN_AMD;
761                 break;
762         case (CFG_FLASH_CHAR_SIZE) FUJ_MANUFACT:
763                 info->flash_id = FLASH_MAN_FUJ;
764                 break;
765         case (CFG_FLASH_CHAR_SIZE) SST_MANUFACT:
766                 info->flash_id = FLASH_MAN_SST;
767                 break;
768         case (CFG_FLASH_CHAR_SIZE) STM_MANUFACT:
769                 info->flash_id = FLASH_MAN_STM;
770                 break;
771         default:
772                 info->flash_id = FLASH_UNKNOWN;
773                 info->sector_count = 0;
774                 info->size = 0;
775                 return 0;               /* no or unknown flash */
776         }
777
778         value = (CFG_FLASH_CHAR_SIZE)addr2[2];  /* device ID */
779         DEBUGF("\nFLASH DEVICEID: %x\n", value);
780
781         switch (value) {
782         case (CFG_FLASH_CHAR_SIZE) AMD_ID_LV040B:
783                 info->flash_id += FLASH_AM040;
784                 info->sector_count = 8;
785                 info->size = 0x0080000; /* => 512 ko */
786                 break;
787
788         case (CFG_FLASH_CHAR_SIZE) AMD_ID_F040B:
789                 info->flash_id += FLASH_AM040;
790                 info->sector_count = 8;
791                 info->size = 0x0080000; /* => 512 ko */
792                 break;
793
794         case (CFG_FLASH_CHAR_SIZE) STM_ID_M29W040B:
795                 info->flash_id += FLASH_AM040;
796                 info->sector_count = 8;
797                 info->size = 0x0080000; /* => 512 ko */
798                 break;
799
800         case (CFG_FLASH_CHAR_SIZE) AMD_ID_F016D:
801                 info->flash_id += FLASH_AMD016;
802                 info->sector_count = 32;
803                 info->size = 0x00200000;
804                 break;                  /* => 2 MB */
805
806         case (CFG_FLASH_CHAR_SIZE) AMD_ID_LV033C:
807                 info->flash_id += FLASH_AMDLV033C;
808                 info->sector_count = 64;
809                 info->size = 0x00400000;
810                 break;                  /* => 4 MB */
811
812         case (CFG_FLASH_CHAR_SIZE) AMD_ID_LV400T:
813                 info->flash_id += FLASH_AM400T;
814                 info->sector_count = 11;
815                 info->size = 0x00080000;
816                 break;                  /* => 0.5 MB */
817
818         case (CFG_FLASH_CHAR_SIZE) AMD_ID_LV400B:
819                 info->flash_id += FLASH_AM400B;
820                 info->sector_count = 11;
821                 info->size = 0x00080000;
822                 break;                  /* => 0.5 MB */
823
824         case (CFG_FLASH_CHAR_SIZE) AMD_ID_LV800T:
825                 info->flash_id += FLASH_AM800T;
826                 info->sector_count = 19;
827                 info->size = 0x00100000;
828                 break;                  /* => 1 MB */
829
830         case (CFG_FLASH_CHAR_SIZE) AMD_ID_LV800B:
831                 info->flash_id += FLASH_AM800B;
832                 info->sector_count = 19;
833                 info->size = 0x00100000;
834                 break;                  /* => 1 MB */
835
836         case (CFG_FLASH_CHAR_SIZE) AMD_ID_LV160T:
837                 info->flash_id += FLASH_AM160T;
838                 info->sector_count = 35;
839                 info->size = 0x00200000;
840                 break;                  /* => 2 MB */
841
842         case (CFG_FLASH_CHAR_SIZE) AMD_ID_LV160B:
843                 info->flash_id += FLASH_AM160B;
844                 info->sector_count = 35;
845                 info->size = 0x00200000;
846                 break;                  /* => 2 MB */
847         case (CFG_FLASH_CHAR_SIZE) AMD_ID_MIRROR:
848                 if ((CFG_FLASH_CHAR_SIZE)addr2[0x1c] == (CFG_FLASH_CHAR_SIZE)AMD_ID_LV128U_2
849                                 && (CFG_FLASH_CHAR_SIZE)addr2[0x1e] ==  (CFG_FLASH_CHAR_SIZE)AMD_ID_LV128U_3) {
850                         info->flash_id += FLASH_AMLV128U;
851                         info->sector_count = 256;
852                         info->size = 0x01000000;
853                 } else if ((CFG_FLASH_CHAR_SIZE)addr2[0x1c] == (CFG_FLASH_CHAR_SIZE)AMD_ID_GL128N_2
854                                 && (CFG_FLASH_CHAR_SIZE)addr2[0x1e] ==  (CFG_FLASH_CHAR_SIZE)AMD_ID_GL128N_3 ) {
855                         info->flash_id += FLASH_S29GL128N;
856                         info->sector_count = 128;
857                         info->size = 0x01000000;
858                 }
859                 else
860                         info->flash_id = FLASH_UNKNOWN;
861                 break;                  /* => 2 MB */
862
863         default:
864                 info->flash_id = FLASH_UNKNOWN;
865                 return 0;               /* => no or unknown flash */
866         }
867
868         /* set up sector start address table */
869         if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
870             ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040) ||
871             ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMD016)) {
872                 for (i = 0; i < info->sector_count; i++)
873                         info->start[i] = base + (i * 0x00010000);
874         } else if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMLV128U) {
875                 for (i = 0; i < info->sector_count; i++)
876                         info->start[i] = base + (i * 0x00010000);
877         } else if ((info->flash_id & FLASH_TYPEMASK) == FLASH_S29GL128N ) {
878                 for (i = 0; i < info->sector_count; i++)
879                         info->start[i] = base + (i * 0x00020000);
880         } else {
881                 if (info->flash_id & FLASH_BTYPE) {
882                         /* set sector offsets for bottom boot block type */
883                         info->start[0] = base + 0x00000000;
884                         info->start[1] = base + 0x00004000;
885                         info->start[2] = base + 0x00006000;
886                         info->start[3] = base + 0x00008000;
887                         for (i = 4; i < info->sector_count; i++) {
888                                 info->start[i] =
889                                     base + (i * 0x00010000) - 0x00030000;
890                         }
891                 } else {
892                         /* set sector offsets for top boot block type */
893                         i = info->sector_count - 1;
894                         info->start[i--] = base + info->size - 0x00004000;
895                         info->start[i--] = base + info->size - 0x00006000;
896                         info->start[i--] = base + info->size - 0x00008000;
897                         for (; i >= 0; i--) {
898                                 info->start[i] = base + i * 0x00010000;
899                         }
900                 }
901         }
902
903         /* check for protected sectors */
904         for (i = 0; i < info->sector_count; i++) {
905                 /* read sector protection at sector address, (A7 .. A0) = 0x02 */
906                 /* D0 = 1 if protected */
907                 addr2 = (volatile CFG_FLASH_WORD_SIZE *)(info->start[i]);
908
909                 /* For AMD29033C flash we need to resend the command of *
910                  * reading flash protection for upper 8 Mb of flash     */
911                 if (i == 32) {
912                         addr2[CFG_FLASH_CHAR_ADDR0] = (CFG_FLASH_WORD_SIZE) 0xAAAAAAAA;
913                         addr2[CFG_FLASH_CHAR_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x55555555;
914                         addr2[CFG_FLASH_CHAR_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x90909090;
915                 }
916
917                 if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST)
918                         info->protect[i] = 0;
919                 else
920                         info->protect[i] = (CFG_FLASH_CHAR_SIZE)addr2[4] & 1;
921         }
922
923         /* issue bank reset to return to read mode */
924         addr2[0] = (CFG_FLASH_WORD_SIZE) 0xF0F0F0F0;
925         return info->size;
926 }
927
928 static int wait_for_DQ7_2(flash_info_t * info, int sect)
929 {
930         ulong start, now, last;
931         volatile CFG_FLASH_WORD_SIZE *addr =
932             (CFG_FLASH_WORD_SIZE *) (info->start[sect]);
933
934         start = get_timer(0);
935         last = start;
936         while (((CFG_FLASH_WORD_SIZE)addr[0] & (CFG_FLASH_WORD_SIZE) 0x80808080) !=
937                (CFG_FLASH_WORD_SIZE) 0x80808080) {
938                 if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
939                         printf("Timeout\n");
940                         return -1;
941                 }
942                 /* show that we're waiting */
943                 if ((now - last) > 1000) { /* every second */
944                         putc('.');
945                         last = now;
946                 }
947         }
948         return 0;
949 }
950
951 static int flash_erase_2(flash_info_t * info, int s_first, int s_last)
952 {
953         volatile CFG_FLASH_WORD_SIZE *addr = (CFG_FLASH_WORD_SIZE *) (info->start[0]);
954         volatile CFG_FLASH_WORD_SIZE *addr2;
955         int flag, prot, sect, l_sect;
956         int i;
957
958         if ((s_first < 0) || (s_first > s_last)) {
959                 if (info->flash_id == FLASH_UNKNOWN) {
960                         printf("- missing\n");
961                 } else {
962                         printf("- no sectors to erase\n");
963                 }
964                 return 1;
965         }
966
967         if (info->flash_id == FLASH_UNKNOWN) {
968                 printf("Can't erase unknown flash type - aborted\n");
969                 return 1;
970         }
971
972         prot = 0;
973         for (sect = s_first; sect <= s_last; ++sect) {
974                 if (info->protect[sect]) {
975                         prot++;
976                 }
977         }
978
979         if (prot) {
980                 printf("- Warning: %d protected sectors will not be erased!\n",
981                        prot);
982         } else {
983                 printf("\n");
984         }
985
986         l_sect = -1;
987
988         /* Disable interrupts which might cause a timeout here */
989         flag = disable_interrupts();
990
991         /* Start erase on unprotected sectors */
992         for (sect = s_first; sect <= s_last; sect++) {
993                 if (info->protect[sect] == 0) { /* not protected */
994                         addr2 = (CFG_FLASH_WORD_SIZE *) (info->start[sect]);
995
996                         if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) {
997                                 addr[CFG_FLASH_CHAR_ADDR0] = (CFG_FLASH_WORD_SIZE) 0xAAAAAAAA;
998                                 addr[CFG_FLASH_CHAR_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x55555555;
999                                 addr[CFG_FLASH_CHAR_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x80808080;
1000                                 addr[CFG_FLASH_CHAR_ADDR0] = (CFG_FLASH_WORD_SIZE) 0xAAAAAAAA;
1001                                 addr[CFG_FLASH_CHAR_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x55555555;
1002                                 addr2[0] = (CFG_FLASH_WORD_SIZE) 0x50505050;    /* block erase */
1003                                 for (i = 0; i < 50; i++)
1004                                         udelay(1000);   /* wait 1 ms */
1005                         } else {
1006                                 addr[CFG_FLASH_CHAR_ADDR0] = (CFG_FLASH_WORD_SIZE) 0xAAAAAAAA;
1007                                 addr[CFG_FLASH_CHAR_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x55555555;
1008                                 addr[CFG_FLASH_CHAR_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x80808080;
1009                                 addr[CFG_FLASH_CHAR_ADDR0] = (CFG_FLASH_WORD_SIZE) 0xAAAAAAAA;
1010                                 addr[CFG_FLASH_CHAR_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x55555555;
1011                                 addr2[0] = (CFG_FLASH_WORD_SIZE) 0x30303030;    /* sector erase */
1012                         }
1013                         l_sect = sect;
1014                         /*
1015                          * Wait for each sector to complete, it's more
1016                          * reliable.  According to AMD Spec, you must
1017                          * issue all erase commands within a specified
1018                          * timeout.  This has been seen to fail, especially
1019                          * if printf()s are included (for debug)!!
1020                          */
1021                         wait_for_DQ7_2(info, sect);
1022                 }
1023         }
1024
1025         /* re-enable interrupts if necessary */
1026         if (flag)
1027                 enable_interrupts();
1028
1029         /* wait at least 80us - let's wait 1 ms */
1030         udelay(1000);
1031
1032         /* reset to read mode */
1033         addr = (CFG_FLASH_WORD_SIZE *) info->start[0];
1034         addr[0] = (CFG_FLASH_WORD_SIZE) 0xF0F0F0F0; /* reset bank */
1035
1036         printf(" done\n");
1037         return 0;
1038 }
1039
1040 static int write_word_2(flash_info_t * info, ulong dest, ulong data)
1041 {
1042         volatile CFG_FLASH_WORD_SIZE *addr2 = (CFG_FLASH_WORD_SIZE *) (info->start[0]);
1043         volatile CFG_FLASH_WORD_SIZE *dest2 = (CFG_FLASH_WORD_SIZE *) dest;
1044         volatile CFG_FLASH_WORD_SIZE *data2 = (CFG_FLASH_WORD_SIZE *) & data;
1045         ulong start;
1046         int i;
1047
1048         /* Check if Flash is (sufficiently) erased */
1049         if ((*((vu_long *)dest) & data) != data) {
1050                 return 2;
1051         }
1052
1053         for (i = 0; i < 4 / sizeof(CFG_FLASH_WORD_SIZE); i++) {
1054                 int flag;
1055
1056                 /* Disable interrupts which might cause a timeout here */
1057                 flag = disable_interrupts();
1058
1059                 addr2[CFG_FLASH_CHAR_ADDR0] = (CFG_FLASH_WORD_SIZE) 0xAAAAAAAA;
1060                 addr2[CFG_FLASH_CHAR_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x55555555;
1061                 addr2[CFG_FLASH_CHAR_ADDR0] = (CFG_FLASH_WORD_SIZE) 0xA0A0A0A0;
1062
1063                 dest2[i] = data2[i];
1064
1065                 /* re-enable interrupts if necessary */
1066                 if (flag)
1067                         enable_interrupts();
1068
1069                 /* data polling for D7 */
1070                 start = get_timer(0);
1071                 while ((dest2[i] & (CFG_FLASH_WORD_SIZE) 0x80808080) !=
1072                        (data2[i] & (CFG_FLASH_WORD_SIZE) 0x80808080)) {
1073
1074                         if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
1075                                 return 1;
1076                         }
1077                 }
1078         }
1079
1080         return 0;
1081 }
1082
1083 #endif /* FLASH_BASE1_PRELIM */