]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/tqc/tqm5200/cam5200_flash.c
Merge branch 'u-boot/master' into u-boot-arm/master
[karo-tx-uboot.git] / board / tqc / tqm5200 / cam5200_flash.c
1 /*
2  * (C) Copyright 2006
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 #include <common.h>
9 #include <mpc5xxx.h>
10 #include <asm/processor.h>
11
12 #if defined(CONFIG_CAM5200) && defined(CONFIG_CAM5200_NIOSFLASH)
13
14 #if 0
15 #define DEBUGF(x...) printf(x)
16 #else
17 #define DEBUGF(x...)
18 #endif
19
20 #define swap16(x) __swab16(x)
21
22 flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];    /* info for FLASH chips */
23
24 /*
25  * CAM5200 is a TQM5200B based board. Additionally it also features
26  * a NIOS cpu. The NIOS CPU peripherals are accessible through MPC5xxx
27  * Local Bus on CS5. This includes 32 bit wide RAM and SRAM as well as
28  * 16 bit wide flash device. Big Endian order on a 32 bit CS5 makes
29  * access to flash chip slightly more complicated as additional byte
30  * swapping is necessary within each 16 bit wide flash 'word'.
31  *
32  * This driver's task is to handle both flash devices: 32 bit TQM5200B
33  * flash chip and 16 bit NIOS cpu flash chip. In the below
34  * flash_addr_table table we use least significant address bit to mark
35  * 16 bit flash bank and two sets of routines *_32 and *_16 to handle
36  * specifics of both flashes.
37  */
38 static unsigned long flash_addr_table[][CONFIG_SYS_MAX_FLASH_BANKS] = {
39         {CONFIG_SYS_BOOTCS_START, CONFIG_SYS_CS5_START | 1}
40 };
41
42 /*-----------------------------------------------------------------------
43  * Functions
44  */
45 static int write_word(flash_info_t * info, ulong dest, ulong data);
46 #ifdef CONFIG_SYS_FLASH_2ND_16BIT_DEV
47 static int write_word_32(flash_info_t * info, ulong dest, ulong data);
48 static int write_word_16(flash_info_t * info, ulong dest, ulong data);
49 static int flash_erase_32(flash_info_t * info, int s_first, int s_last);
50 static int flash_erase_16(flash_info_t * info, int s_first, int s_last);
51 static ulong flash_get_size_32(vu_long * addr, flash_info_t * info);
52 static ulong flash_get_size_16(vu_long * addr, flash_info_t * info);
53 #endif
54
55 void flash_print_info(flash_info_t * info)
56 {
57         int i, k;
58         int size, erased;
59         volatile unsigned long *flash;
60
61         if (info->flash_id == FLASH_UNKNOWN) {
62                 printf("missing or unknown FLASH type\n");
63                 return;
64         }
65
66         switch (info->flash_id & FLASH_VENDMASK) {
67                 case FLASH_MAN_AMD:
68                         printf("AMD ");
69                         break;
70                 case FLASH_MAN_FUJ:
71                         printf("FUJITSU ");
72                         break;
73                 default:
74                         printf("Unknown Vendor ");
75                         break;
76         }
77
78         switch (info->flash_id & FLASH_TYPEMASK) {
79                 case FLASH_S29GL128N:
80                         printf ("S29GL128N (256 Mbit, uniform sector size)\n");
81                         break;
82                 case FLASH_AM320B:
83                         printf ("29LV320B (32 Mbit, bottom boot sect)\n");
84                         break;
85                 case FLASH_AM320T:
86                         printf ("29LV320T (32 Mbit, top boot sect)\n");
87                         break;
88                 default:
89                         printf("Unknown Chip Type\n");
90                         break;
91         }
92
93         printf("  Size: %ld KB in %d Sectors\n",
94                         info->size >> 10, info->sector_count);
95
96         printf("  Sector Start Addresses:");
97         for (i = 0; i < info->sector_count; ++i) {
98                 /*
99                  * Check if whole sector is erased
100                  */
101                 if (i != (info->sector_count - 1))
102                         size = info->start[i + 1] - info->start[i];
103                 else
104                         size = info->start[0] + info->size - info->start[i];
105
106                 erased = 1;
107                 flash = (volatile unsigned long *)info->start[i];
108                 size = size >> 2;       /* divide by 4 for longword access */
109
110                 for (k = 0; k < size; k++) {
111                         if (*flash++ != 0xffffffff) {
112                                 erased = 0;
113                                 break;
114                         }
115                 }
116
117                 if ((i % 5) == 0)
118                         printf("\n   ");
119
120                 printf(" %08lX%s%s", info->start[i],
121                                 erased ? " E" : "  ",
122                                 info->protect[i] ? "RO " : "   ");
123         }
124         printf("\n");
125         return;
126 }
127
128
129 /*
130  * The following code cannot be run from FLASH!
131  */
132 #ifdef CONFIG_SYS_FLASH_2ND_16BIT_DEV
133 static ulong flash_get_size(vu_long * addr, flash_info_t * info)
134 {
135
136         DEBUGF("get_size: FLASH ADDR %08lx\n", addr);
137
138         /* bit 0 used for big flash marking */
139         if ((ulong)addr & 0x1)
140                 return flash_get_size_16((vu_long *)((ulong)addr & 0xfffffffe), info);
141         else
142                 return flash_get_size_32(addr, info);
143 }
144
145 static ulong flash_get_size_32(vu_long * addr, flash_info_t * info)
146 #else
147 static ulong flash_get_size(vu_long * addr, flash_info_t * info)
148 #endif
149 {
150         short i;
151         CONFIG_SYS_FLASH_WORD_SIZE value;
152         ulong base = (ulong) addr;
153         volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *) addr;
154
155         DEBUGF("get_size32: FLASH ADDR: %08x\n", (unsigned)addr);
156
157         /* Write auto select command: read Manufacturer ID */
158         addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00AA00AA;
159         addr2[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00550055;
160         addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00900090;
161         udelay(1000);
162
163         value = addr2[0];
164         DEBUGF("FLASH MANUFACT: %x\n", value);
165
166         switch (value) {
167                 case (CONFIG_SYS_FLASH_WORD_SIZE) AMD_MANUFACT:
168                         info->flash_id = FLASH_MAN_AMD;
169                         break;
170                 default:
171                         info->flash_id = FLASH_UNKNOWN;
172                         info->sector_count = 0;
173                         info->size = 0;
174                         return (0);     /* no or unknown flash  */
175         }
176
177         value = addr2[1];       /* device ID            */
178         DEBUGF("\nFLASH DEVICEID: %x\n", value);
179
180         switch (value) {
181                 case AMD_ID_MIRROR:
182                         DEBUGF("Mirror Bit flash: addr[14] = %08lX  addr[15] = %08lX\n",
183                                         addr[14], addr[15]);
184                         switch(addr[14]) {
185                                 case AMD_ID_GL128N_2:
186                                         if (addr[15] != AMD_ID_GL128N_3) {
187                                                 DEBUGF("Chip: S29GL128N -> unknown\n");
188                                                 info->flash_id = FLASH_UNKNOWN;
189                                         } else {
190                                                 DEBUGF("Chip: S29GL128N\n");
191                                                 info->flash_id += FLASH_S29GL128N;
192                                                 info->sector_count = 128;
193                                                 info->size = 0x02000000;
194                                         }
195                                         break;
196                                 default:
197                                         info->flash_id = FLASH_UNKNOWN;
198                                         return(0);
199                         }
200                         break;
201
202                 default:
203                         info->flash_id = FLASH_UNKNOWN;
204                         return (0);     /* => no or unknown flash */
205         }
206
207         /* set up sector start address table */
208         for (i = 0; i < info->sector_count; i++)
209                 info->start[i] = base + (i * 0x00040000);
210
211         /* check for protected sectors */
212         for (i = 0; i < info->sector_count; i++) {
213                 /* read sector protection at sector address, (A7 .. A0) = 0x02 */
214                 /* D0 = 1 if protected */
215                 addr2 = (volatile CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[i]);
216
217                 info->protect[i] = addr2[2] & 1;
218         }
219
220         /* issue bank reset to return to read mode */
221         addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00F000F0;
222
223         return (info->size);
224 }
225
226 static int wait_for_DQ7_32(flash_info_t * info, int sect)
227 {
228         ulong start, now, last;
229         volatile CONFIG_SYS_FLASH_WORD_SIZE *addr =
230                 (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[sect]);
231
232         start = get_timer(0);
233         last = start;
234         while ((addr[0] & (CONFIG_SYS_FLASH_WORD_SIZE) 0x00800080) !=
235                         (CONFIG_SYS_FLASH_WORD_SIZE) 0x00800080) {
236                 if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
237                         printf("Timeout\n");
238                         return -1;
239                 }
240                 /* show that we're waiting */
241                 if ((now - last) > 1000) {      /* every second */
242                         putc('.');
243                         last = now;
244                 }
245         }
246         return 0;
247 }
248
249 #ifdef CONFIG_SYS_FLASH_2ND_16BIT_DEV
250 int flash_erase(flash_info_t * info, int s_first, int s_last)
251 {
252         if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B) {
253                 return flash_erase_16(info, s_first, s_last);
254         } else {
255                 return flash_erase_32(info, s_first, s_last);
256         }
257 }
258
259 static int flash_erase_32(flash_info_t * info, int s_first, int s_last)
260 #else
261 int flash_erase(flash_info_t * info, int s_first, int s_last)
262 #endif
263 {
264         volatile CONFIG_SYS_FLASH_WORD_SIZE *addr = (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[0]);
265         volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2;
266         int flag, prot, sect;
267
268         if ((s_first < 0) || (s_first > s_last)) {
269                 if (info->flash_id == FLASH_UNKNOWN)
270                         printf("- missing\n");
271                 else
272                         printf("- no sectors to erase\n");
273                 return 1;
274         }
275
276         if (info->flash_id == FLASH_UNKNOWN) {
277                 printf("Can't erase unknown flash type - aborted\n");
278                 return 1;
279         }
280
281         prot = 0;
282         for (sect = s_first; sect <= s_last; ++sect) {
283                 if (info->protect[sect])
284                         prot++;
285         }
286
287         if (prot)
288                 printf("- Warning: %d protected sectors will not be erased!", prot);
289
290         printf("\n");
291
292         /* Disable interrupts which might cause a timeout here */
293         flag = disable_interrupts();
294
295         /* Start erase on unprotected sectors */
296         for (sect = s_first; sect <= s_last; sect++) {
297                 if (info->protect[sect] == 0) { /* not protected */
298                         addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[sect]);
299
300                         addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00AA00AA;
301                         addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00550055;
302                         addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00800080;
303                         addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00AA00AA;
304                         addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00550055;
305                         addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00300030;     /* sector erase */
306
307                         /*
308                          * Wait for each sector to complete, it's more
309                          * reliable.  According to AMD Spec, you must
310                          * issue all erase commands within a specified
311                          * timeout.  This has been seen to fail, especially
312                          * if printf()s are included (for debug)!!
313                          */
314                         wait_for_DQ7_32(info, sect);
315                 }
316         }
317
318         /* re-enable interrupts if necessary */
319         if (flag)
320                 enable_interrupts();
321
322         /* wait at least 80us - let's wait 1 ms */
323         udelay(1000);
324
325         /* reset to read mode */
326         addr = (CONFIG_SYS_FLASH_WORD_SIZE *) info->start[0];
327         addr[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00F000F0;      /* reset bank */
328
329         printf(" done\n");
330         return 0;
331 }
332
333 /*-----------------------------------------------------------------------
334  * Copy memory to flash, returns:
335  * 0 - OK
336  * 1 - write timeout
337  * 2 - Flash not erased
338  */
339 int write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt)
340 {
341         ulong cp, wp, data;
342         int i, l, rc;
343
344         wp = (addr & ~3);       /* get lower word aligned address */
345
346         /*
347          * handle unaligned start bytes
348          */
349         if ((l = addr - wp) != 0) {
350                 data = 0;
351                 for (i = 0, cp = wp; i < l; ++i, ++cp)
352                         data = (data << 8) | (*(uchar *) cp);
353
354                 for (; i < 4 && cnt > 0; ++i) {
355                         data = (data << 8) | *src++;
356                         --cnt;
357                         ++cp;
358                 }
359
360                 for (; cnt == 0 && i < 4; ++i, ++cp)
361                         data = (data << 8) | (*(uchar *) cp);
362
363                 if ((rc = write_word(info, wp, data)) != 0)
364                         return (rc);
365
366                 wp += 4;
367         }
368
369         /*
370          * handle word aligned part
371          */
372         while (cnt >= 4) {
373                 data = 0;
374                 for (i = 0; i < 4; ++i)
375                         data = (data << 8) | *src++;
376
377                 if ((rc = write_word(info, wp, data)) != 0)
378                         return (rc);
379
380                 wp += 4;
381                 cnt -= 4;
382         }
383
384         if (cnt == 0)
385                 return (0);
386
387         /*
388          * handle unaligned tail bytes
389          */
390         data = 0;
391         for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
392                 data = (data << 8) | *src++;
393                 --cnt;
394         }
395         for (; i < 4; ++i, ++cp)
396                 data = (data << 8) | (*(uchar *) cp);
397
398         return (write_word(info, wp, data));
399 }
400
401 /*-----------------------------------------------------------------------
402  * Copy memory to flash, returns:
403  * 0 - OK
404  * 1 - write timeout
405  * 2 - Flash not erased
406  */
407 #ifdef CONFIG_SYS_FLASH_2ND_16BIT_DEV
408 static int write_word(flash_info_t * info, ulong dest, ulong data)
409 {
410         if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B) {
411                 return write_word_16(info, dest, data);
412         } else {
413                 return write_word_32(info, dest, data);
414         }
415 }
416
417 static int write_word_32(flash_info_t * info, ulong dest, ulong data)
418 #else
419 static int write_word(flash_info_t * info, ulong dest, ulong data)
420 #endif
421 {
422         volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[0]);
423         volatile CONFIG_SYS_FLASH_WORD_SIZE *dest2 = (CONFIG_SYS_FLASH_WORD_SIZE *) dest;
424         ulong *datap = &data;
425         volatile CONFIG_SYS_FLASH_WORD_SIZE *data2 =
426                         (volatile CONFIG_SYS_FLASH_WORD_SIZE *)datap;
427         ulong start;
428         int i, flag;
429
430         /* Check if Flash is (sufficiently) erased */
431         if ((*((vu_long *)dest) & data) != data)
432                 return (2);
433
434         for (i = 0; i < 4 / sizeof(CONFIG_SYS_FLASH_WORD_SIZE); i++) {
435                 /* Disable interrupts which might cause a timeout here */
436                 flag = disable_interrupts();
437
438                 addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00AA00AA;
439                 addr2[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00550055;
440                 addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00A000A0;
441
442                 dest2[i] = data2[i];
443
444                 /* re-enable interrupts if necessary */
445                 if (flag)
446                         enable_interrupts();
447
448                 /* data polling for D7 */
449                 start = get_timer(0);
450                 while ((dest2[i] & (CONFIG_SYS_FLASH_WORD_SIZE) 0x00800080) !=
451                                 (data2[i] & (CONFIG_SYS_FLASH_WORD_SIZE) 0x00800080)) {
452
453                         if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT)
454                                 return (1);
455                 }
456         }
457
458         return (0);
459 }
460
461 #ifdef CONFIG_SYS_FLASH_2ND_16BIT_DEV
462
463 #undef  CONFIG_SYS_FLASH_WORD_SIZE
464 #define CONFIG_SYS_FLASH_WORD_SIZE unsigned short
465
466 /*
467  * The following code cannot be run from FLASH!
468  */
469 static ulong flash_get_size_16(vu_long * addr, flash_info_t * info)
470 {
471         short i;
472         CONFIG_SYS_FLASH_WORD_SIZE value;
473         ulong base = (ulong) addr;
474         volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *) addr;
475
476         DEBUGF("get_size16: FLASH ADDR: %08x\n", (unsigned)addr);
477
478         /* issue bank reset to return to read mode */
479         addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0xF000F000;
480
481         /* Write auto select command: read Manufacturer ID */
482         addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0xAA00AA00;
483         addr2[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x55005500;
484         addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x90009000;
485         udelay(1000);
486
487         value = swap16(addr2[0]);
488         DEBUGF("FLASH MANUFACT: %x\n", value);
489
490         switch (value) {
491                 case (CONFIG_SYS_FLASH_WORD_SIZE) AMD_MANUFACT:
492                         info->flash_id = FLASH_MAN_AMD;
493                         break;
494                 case (CONFIG_SYS_FLASH_WORD_SIZE) FUJ_MANUFACT:
495                         info->flash_id = FLASH_MAN_FUJ;
496                         break;
497                 default:
498                         info->flash_id = FLASH_UNKNOWN;
499                         info->sector_count = 0;
500                         info->size = 0;
501                         return (0);     /* no or unknown flash  */
502         }
503
504         value = swap16(addr2[1]);       /* device ID            */
505         DEBUGF("\nFLASH DEVICEID: %x\n", value);
506
507         switch (value) {
508                 case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV320B:
509                         info->flash_id += FLASH_AM320B;
510                         info->sector_count = 71;
511                         info->size = 0x00400000;
512                         break;  /* => 4 MB      */
513                 case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV320T:
514                         info->flash_id += FLASH_AM320T;
515                         info->sector_count = 71;
516                         info->size = 0x00400000;
517                         break;  /* => 4 MB      */
518                 default:
519                         info->flash_id = FLASH_UNKNOWN;
520                         return (0);     /* => no or unknown flash */
521         }
522
523         if (info->flash_id & FLASH_BTYPE) {
524                 /* set sector offsets for bottom boot block type        */
525                 info->start[0] = base + 0x00000000;
526                 info->start[1] = base + 0x00002000;
527                 info->start[2] = base + 0x00004000;
528                 info->start[3] = base + 0x00006000;
529                 info->start[4] = base + 0x00008000;
530                 info->start[5] = base + 0x0000a000;
531                 info->start[6] = base + 0x0000c000;
532                 info->start[7] = base + 0x0000e000;
533
534                 for (i = 8; i < info->sector_count; i++)
535                         info->start[i] = base + (i * 0x00010000) - 0x00070000;
536         } else {
537                 /* set sector offsets for top boot block type           */
538                 i = info->sector_count - 1;
539                 info->start[i--] = base + info->size - 0x00002000;
540                 info->start[i--] = base + info->size - 0x00004000;
541                 info->start[i--] = base + info->size - 0x00006000;
542                 info->start[i--] = base + info->size - 0x00008000;
543                 info->start[i--] = base + info->size - 0x0000a000;
544                 info->start[i--] = base + info->size - 0x0000c000;
545                 info->start[i--] = base + info->size - 0x0000e000;
546
547                 for (; i >= 0; i--)
548                         info->start[i] = base + i * 0x00010000;
549         }
550
551         /* check for protected sectors */
552         for (i = 0; i < info->sector_count; i++) {
553                 /* read sector protection at sector address, (A7 .. A0) = 0x02 */
554                 /* D0 = 1 if protected */
555                 addr2 = (volatile CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[i]);
556
557                 info->protect[i] = addr2[2] & 1;
558         }
559
560         /* issue bank reset to return to read mode */
561         addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0xF000F000;
562
563         return (info->size);
564 }
565
566 static int wait_for_DQ7_16(flash_info_t * info, int sect)
567 {
568         ulong start, now, last;
569         volatile CONFIG_SYS_FLASH_WORD_SIZE *addr =
570                 (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[sect]);
571
572         start = get_timer(0);
573         last = start;
574         while ((addr[0] & (CONFIG_SYS_FLASH_WORD_SIZE) 0x80008000) !=
575                         (CONFIG_SYS_FLASH_WORD_SIZE) 0x80008000) {
576                 if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
577                         printf("Timeout\n");
578                         return -1;
579                 }
580                 /* show that we're waiting */
581                 if ((now - last) > 1000) {      /* every second */
582                         putc('.');
583                         last = now;
584                 }
585         }
586         return 0;
587 }
588
589 static int flash_erase_16(flash_info_t * info, int s_first, int s_last)
590 {
591         volatile CONFIG_SYS_FLASH_WORD_SIZE *addr = (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[0]);
592         volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2;
593         int flag, prot, sect;
594
595         if ((s_first < 0) || (s_first > s_last)) {
596                 if (info->flash_id == FLASH_UNKNOWN)
597                         printf("- missing\n");
598                 else
599                         printf("- no sectors to erase\n");
600                 return 1;
601         }
602
603         if (info->flash_id == FLASH_UNKNOWN) {
604                 printf("Can't erase unknown flash type - aborted\n");
605                 return 1;
606         }
607
608         prot = 0;
609         for (sect = s_first; sect <= s_last; ++sect) {
610                 if (info->protect[sect])
611                         prot++;
612         }
613
614         if (prot)
615                 printf("- Warning: %d protected sectors will not be erased!",   prot);
616
617         printf("\n");
618
619         /* Disable interrupts which might cause a timeout here */
620         flag = disable_interrupts();
621
622         /* Start erase on unprotected sectors */
623         for (sect = s_first; sect <= s_last; sect++) {
624                 if (info->protect[sect] == 0) { /* not protected */
625                         addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[sect]);
626
627                         addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0xAA00AA00;
628                         addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x55005500;
629                         addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x80008000;
630                         addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0xAA00AA00;
631                         addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x55005500;
632                         addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x30003000;     /* sector erase */
633
634                         /*
635                          * Wait for each sector to complete, it's more
636                          * reliable.  According to AMD Spec, you must
637                          * issue all erase commands within a specified
638                          * timeout.  This has been seen to fail, especially
639                          * if printf()s are included (for debug)!!
640                          */
641                         wait_for_DQ7_16(info, sect);
642                 }
643         }
644
645         /* re-enable interrupts if necessary */
646         if (flag)
647                 enable_interrupts();
648
649         /* wait at least 80us - let's wait 1 ms */
650         udelay(1000);
651
652         /* reset to read mode */
653         addr = (CONFIG_SYS_FLASH_WORD_SIZE *) info->start[0];
654         addr[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0xF000F000;      /* reset bank */
655
656         printf(" done\n");
657         return 0;
658 }
659
660 static int write_word_16(flash_info_t * info, ulong dest, ulong data)
661 {
662         volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[0]);
663         volatile CONFIG_SYS_FLASH_WORD_SIZE *dest2 = (CONFIG_SYS_FLASH_WORD_SIZE *) dest;
664         ulong *datap = &data;
665         volatile CONFIG_SYS_FLASH_WORD_SIZE *data2 =
666                         (volatile CONFIG_SYS_FLASH_WORD_SIZE *)datap;
667         ulong start;
668         int i;
669
670         /* Check if Flash is (sufficiently) erased */
671         for (i = 0; i < 4 / sizeof(CONFIG_SYS_FLASH_WORD_SIZE); i++) {
672                 if ((dest2[i] & swap16(data2[i])) != swap16(data2[i]))
673                         return (2);
674         }
675
676         for (i = 0; i < 4 / sizeof(CONFIG_SYS_FLASH_WORD_SIZE); i++) {
677                 int flag;
678
679                 /* Disable interrupts which might cause a timeout here */
680                 flag = disable_interrupts();
681
682                 addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0xAA00AA00;
683                 addr2[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x55005500;
684                 addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0xA000A000;
685
686                 dest2[i] = swap16(data2[i]);
687
688                 /* re-enable interrupts if necessary */
689                 if (flag)
690                         enable_interrupts();
691
692                 /* data polling for D7 */
693                 start = get_timer(0);
694                 while ((dest2[i] & (CONFIG_SYS_FLASH_WORD_SIZE) 0x80008000) !=
695                                 (swap16(data2[i]) & (CONFIG_SYS_FLASH_WORD_SIZE) 0x80008000)) {
696
697                         if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
698                                 return (1);
699                         }
700                 }
701         }
702
703         return (0);
704 }
705 #endif /* CONFIG_SYS_FLASH_2ND_16BIT_DEV */
706
707 /*-----------------------------------------------------------------------
708  * Functions
709  */
710 static ulong flash_get_size(vu_long * addr, flash_info_t * info);
711 static int write_word(flash_info_t * info, ulong dest, ulong data);
712
713 /*-----------------------------------------------------------------------
714  */
715
716 unsigned long flash_init(void)
717 {
718         unsigned long total_b = 0;
719         unsigned long size_b[CONFIG_SYS_MAX_FLASH_BANKS];
720         unsigned short index = 0;
721         int i;
722
723         DEBUGF("\n");
724         DEBUGF("FLASH: Index: %d\n", index);
725
726         /* Init: no FLASHes known */
727         for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
728                 flash_info[i].flash_id = FLASH_UNKNOWN;
729                 flash_info[i].sector_count = -1;
730                 flash_info[i].size = 0;
731
732                 /* check whether the address is 0 */
733                 if (flash_addr_table[index][i] == 0)
734                         continue;
735
736                 /* call flash_get_size() to initialize sector address */
737                 size_b[i] = flash_get_size((vu_long *) flash_addr_table[index][i],
738                                 &flash_info[i]);
739
740                 flash_info[i].size = size_b[i];
741
742                 if (flash_info[i].flash_id == FLASH_UNKNOWN) {
743                         printf("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n",
744                                         i+1, size_b[i], size_b[i] << 20);
745                         flash_info[i].sector_count = -1;
746                         flash_info[i].size = 0;
747                 }
748
749                 /* Monitor protection ON by default */
750                 (void)flash_protect(FLAG_PROTECT_SET, CONFIG_SYS_MONITOR_BASE,
751                                     CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN - 1,
752                                     &flash_info[i]);
753 #if defined(CONFIG_ENV_IS_IN_FLASH)
754                 (void)flash_protect(FLAG_PROTECT_SET, CONFIG_ENV_ADDR,
755                                     CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE - 1,
756                                     &flash_info[i]);
757 #if defined(CONFIG_ENV_ADDR_REDUND)
758                 (void)flash_protect(FLAG_PROTECT_SET, CONFIG_ENV_ADDR_REDUND,
759                                     CONFIG_ENV_ADDR_REDUND + CONFIG_ENV_SECT_SIZE - 1,
760                                     &flash_info[i]);
761 #endif
762 #endif
763                 total_b += flash_info[i].size;
764         }
765
766         return total_b;
767 }
768 #endif /* if defined(CONFIG_CAM5200) && defined(CONFIG_CAM5200_NIOSFLASH) */