board/w7o/flash.c: make (mostly) checkpatch clean
[oweals/u-boot.git] / board / w7o / flash.c
1 /*
2  * (C) Copyright 2001
3  * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com.
4  *  Based on code by:
5  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
6  *
7  * See file CREDITS for list of people who contributed to this
8  * project.
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License as
12  * published by the Free Software Foundation; either version 2 of
13  * the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
23  * MA 02111-1307 USA
24  */
25
26 #include <common.h>
27 #include <asm/ppc4xx.h>
28 #include <asm/processor.h>
29
30 #include <watchdog.h>
31
32 /* info for FLASH chips    */
33 flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
34
35 /*
36  * Functions
37  */
38 static ulong flash_get_size(vu_long *addr, flash_info_t *info);
39 static int write_word8(flash_info_t *info, ulong dest, ulong data);
40 static int write_word32(flash_info_t *info, ulong dest, ulong data);
41 static void flash_get_offsets(ulong base, flash_info_t *info);
42
43 unsigned long flash_init(void)
44 {
45         int i;
46         unsigned long size_b0, base_b0;
47         unsigned long size_b1, base_b1;
48
49         /* Init: no FLASHes known */
50         for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i)
51                 flash_info[i].flash_id = FLASH_UNKNOWN;
52
53         /* Get Size of Boot and Main Flashes */
54         size_b0 = flash_get_size((vu_long *) FLASH_BASE0_PRELIM,
55                                &flash_info[0]);
56         if (flash_info[0].flash_id == FLASH_UNKNOWN) {
57                 printf("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
58                         size_b0, size_b0 << 20);
59                 return 0;
60         }
61         size_b1 =
62                 flash_get_size((vu_long *) FLASH_BASE1_PRELIM,
63                                &flash_info[1]);
64         if (flash_info[1].flash_id == FLASH_UNKNOWN) {
65                 printf("## Unknown FLASH on Bank 1 - Size = 0x%08lx = %ld MB\n",
66                         size_b1, size_b1 << 20);
67                 return 0;
68         }
69
70         /* Calculate base addresses */
71         base_b0 = -size_b0;
72         base_b1 = -size_b1;
73
74         /* Setup offsets for Boot Flash */
75         flash_get_offsets(base_b0, &flash_info[0]);
76
77         /* Protect board level data */
78         (void) flash_protect(FLAG_PROTECT_SET,
79                              base_b0,
80                              flash_info[0].start[1] - 1, &flash_info[0]);
81
82         /* Monitor protection ON by default */
83         (void) flash_protect(FLAG_PROTECT_SET,
84                              base_b0 + size_b0 - monitor_flash_len,
85                              base_b0 + size_b0 - 1, &flash_info[0]);
86
87         /* Protect the FPGA image */
88         (void) flash_protect(FLAG_PROTECT_SET,
89                              FLASH_BASE1_PRELIM,
90                              FLASH_BASE1_PRELIM + CONFIG_SYS_FPGA_IMAGE_LEN -
91                              1, &flash_info[1]);
92
93         /* Protect the default boot image */
94         (void) flash_protect(FLAG_PROTECT_SET,
95                              FLASH_BASE1_PRELIM + CONFIG_SYS_FPGA_IMAGE_LEN,
96                              FLASH_BASE1_PRELIM + CONFIG_SYS_FPGA_IMAGE_LEN +
97                              0x600000 - 1, &flash_info[1]);
98
99         /* Setup offsets for Main Flash */
100         flash_get_offsets(FLASH_BASE1_PRELIM, &flash_info[1]);
101
102         return size_b0 + size_b1;
103 }
104
105 static void flash_get_offsets(ulong base, flash_info_t *info)
106 {
107         int i;
108
109         /* set up sector start address table - FOR BOOT ROM ONLY!!! */
110         if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040) {
111                 for (i = 0; i < info->sector_count; i++)
112                         info->start[i] = base + (i * 0x00010000);
113         }
114 }                               /* end flash_get_offsets() */
115
116 void flash_print_info(flash_info_t *info)
117 {
118         int i;
119         int k;
120         int size;
121         int erased;
122         volatile unsigned long *flash;
123
124         if (info->flash_id == FLASH_UNKNOWN) {
125                 printf("missing or unknown FLASH type\n");
126                 return;
127         }
128
129         switch (info->flash_id & FLASH_VENDMASK) {
130         case FLASH_MAN_AMD:
131                 printf("1 x AMD ");
132                 break;
133         case FLASH_MAN_STM:
134                 printf("1 x STM ");
135                 break;
136         case FLASH_MAN_INTEL:
137                 printf("2 x Intel ");
138                 break;
139         default:
140                 printf("Unknown Vendor ");
141         }
142
143         switch (info->flash_id & FLASH_TYPEMASK) {
144         case FLASH_AM040:
145                 if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD)
146                         printf("AM29LV040 (4096 Kbit, uniform sector size)\n");
147                 else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_STM)
148                         printf("M29W040B (4096 Kbit, uniform block size)\n");
149                 else
150                         printf("UNKNOWN 29x040x (4096 Kbit, uniform sector size)\n");
151                 break;
152         case FLASH_28F320J3A:
153                 printf("28F320J3A (32 Mbit = 128K x 32)\n");
154                 break;
155         case FLASH_28F640J3A:
156                 printf("28F640J3A (64 Mbit = 128K x 64)\n");
157                 break;
158         case FLASH_28F128J3A:
159                 printf("28F128J3A (128 Mbit = 128K x 128)\n");
160                 break;
161         default:
162                 printf("Unknown Chip Type\n");
163         }
164
165         if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_STM) {
166                 printf("  Size: %ld KB in %d Blocks\n",
167                        info->size >> 10, info->sector_count);
168         } else {
169                 printf("  Size: %ld KB in %d Sectors\n",
170                        info->size >> 10, info->sector_count);
171         }
172
173         printf("  Sector Start Addresses:");
174         for (i = 0; i < info->sector_count; ++i) {
175                 /*
176                  * Check if whole sector is erased
177                  */
178                 if (i != (info->sector_count - 1))
179                         size = info->start[i + 1] - info->start[i];
180                 else
181                         size = info->start[0] + info->size - info->start[i];
182                 erased = 1;
183                 flash = (volatile unsigned long *) info->start[i];
184                 size = size >> 2;       /* divide by 4 for longword access */
185                 for (k = 0; k < size; k++) {
186                         if (*flash++ != 0xffffffff) {
187                                 erased = 0;
188                                 break;
189                         }
190                 }
191
192                 if ((i % 5) == 0)
193                         printf("\n   ");
194                 printf(" %08lX%s%s",
195                        info->start[i],
196                        erased ? " E" : "  ",
197                        info->protect[i] ? "RO " : "   ");
198         }
199         printf("\n");
200 }                               /* end flash_print_info() */
201
202 /*
203  * The following code cannot be run from FLASH!
204  */
205 static ulong flash_get_size(vu_long *addr, flash_info_t *info)
206 {
207         short i;
208         ulong base = (ulong) addr;
209
210         /* Setup default type */
211         info->flash_id = FLASH_UNKNOWN;
212         info->sector_count = 0;
213         info->size = 0;
214
215         /* Test for Boot Flash */
216         if (base == FLASH_BASE0_PRELIM) {
217                 unsigned char value;
218                 volatile unsigned char *addr2 = (unsigned char *) addr;
219
220                 /* Write auto select command: read Manufacturer ID */
221                 *(addr2 + 0x555) = 0xaa;
222                 *(addr2 + 0x2aa) = 0x55;
223                 *(addr2 + 0x555) = 0x90;
224
225                 /* Manufacture ID */
226                 value = *addr2;
227                 switch (value) {
228                 case (unsigned char) AMD_MANUFACT:
229                         info->flash_id = FLASH_MAN_AMD;
230                         break;
231                 case (unsigned char) STM_MANUFACT:
232                         info->flash_id = FLASH_MAN_STM;
233                         break;
234                 default:
235                         *addr2 = 0xf0;  /* no or unknown flash  */
236                         return 0;
237                 }
238
239                 /* Device ID */
240                 value = *(addr2 + 1);
241                 switch (value) {
242                 case (unsigned char) AMD_ID_LV040B:
243                 case (unsigned char) STM_ID_29W040B:
244                         info->flash_id += FLASH_AM040;
245                         info->sector_count = 8;
246                         info->size = 0x00080000;
247                         break;  /* => 512Kb */
248                 default:
249                         *addr2 = 0xf0;  /* => no or unknown flash */
250                         return 0;
251                 }
252         } else {                /* MAIN Flash */
253                 unsigned long value;
254                 volatile unsigned long *addr2 = (unsigned long *) addr;
255
256                 /* Write auto select command: read Manufacturer ID */
257                 *addr2 = 0x90909090;
258
259                 /* Manufacture ID */
260                 value = *addr2;
261                 switch (value) {
262                 case (unsigned long) INTEL_MANUFACT:
263                         info->flash_id = FLASH_MAN_INTEL;
264                         break;
265                 default:
266                         *addr2 = 0xff;  /* no or unknown flash  */
267                         return 0;
268                 }
269
270                 /* Device ID - This shit is interleaved... */
271                 value = *(addr2 + 1);
272                 switch (value) {
273                 case (unsigned long) INTEL_ID_28F320J3A:
274                         info->flash_id += FLASH_28F320J3A;
275                         info->sector_count = 32;
276                         info->size = 0x00400000 * 2;
277                         break;  /* => 2 X 4 MB */
278                 case (unsigned long) INTEL_ID_28F640J3A:
279                         info->flash_id += FLASH_28F640J3A;
280                         info->sector_count = 64;
281                         info->size = 0x00800000 * 2;
282                         break;  /* => 2 X 8 MB */
283                 case (unsigned long) INTEL_ID_28F128J3A:
284                         info->flash_id += FLASH_28F128J3A;
285                         info->sector_count = 128;
286                         info->size = 0x01000000 * 2;
287                         break;  /* => 2 X 16 MB */
288                 default:
289                         *addr2 = 0xff;  /* => no or unknown flash */
290                 }
291         }
292
293         /* Make sure we don't exceed CONFIG_SYS_MAX_FLASH_SECT */
294         if (info->sector_count > CONFIG_SYS_MAX_FLASH_SECT) {
295                 printf("** ERROR: sector count %d > max (%d) **\n",
296                        info->sector_count, CONFIG_SYS_MAX_FLASH_SECT);
297                 info->sector_count = CONFIG_SYS_MAX_FLASH_SECT;
298         }
299
300         /* set up sector start address table */
301         switch (info->flash_id & FLASH_TYPEMASK) {
302         case FLASH_AM040:
303                 for (i = 0; i < info->sector_count; i++)
304                         info->start[i] = base + (i * 0x00010000);
305                 break;
306         case FLASH_28F320J3A:
307         case FLASH_28F640J3A:
308         case FLASH_28F128J3A:
309                 for (i = 0; i < info->sector_count; i++)
310                         info->start[i] = base +
311                                         (i * 0x00020000 * 2);   /* 2 Banks */
312                 break;
313         }
314
315         /* Test for Boot Flash */
316         if (base == FLASH_BASE0_PRELIM) {
317                 volatile unsigned char *addr2;
318
319                 /* check for protected sectors */
320                 for (i = 0; i < info->sector_count; i++) {
321                         /*
322                          * read sector protection at sector address,
323                          * (AX .. A0) = 0x02
324                          * D0 = 1 if protected
325                          */
326                         addr2 = (volatile unsigned char *) (info->start[i]);
327                         info->protect[i] = *(addr2 + 2) & 1;
328                 }
329
330                 /* Restore read mode */
331                 *(unsigned char *) base = 0xF0; /* Reset NORMAL Flash */
332         } else {                /* Main Flash */
333                 volatile unsigned long *addr2;
334
335                 /* check for protected sectors */
336                 for (i = 0; i < info->sector_count; i++) {
337                         /*
338                          * read sector protection at sector address,
339                          * (AX .. A0) = 0x02
340                          * D0 = 1 if protected
341                          */
342                         addr2 = (volatile unsigned long *) (info->start[i]);
343                         info->protect[i] = *(addr2 + 2) & 0x1;
344                 }
345
346                 /* Restore read mode */
347                 *(unsigned long *) base = 0xFFFFFFFF;   /* Reset  Flash */
348         }
349
350         return info->size;
351 }                               /* end flash_get_size() */
352
353 static int wait_for_DQ7(ulong addr, uchar cmp_val, ulong tout)
354 {
355         int i;
356
357         volatile uchar *vaddr = (uchar *) addr;
358
359         /* Loop X times */
360         for (i = 1; i <= (100 * tout); i++) {   /* Wait up to tout ms */
361                 udelay(10);
362                 /* Pause 10 us */
363
364                 /* Check for completion */
365                 if ((vaddr[0] & 0x80) == (cmp_val & 0x80))
366                         return 0;
367
368                 /* KEEP THE LUSER HAPPY - Print a dot every 1.1 seconds */
369                 if (!(i % 110000))
370                         putc('.');
371
372                 /* Kick the dog if needed */
373                 WATCHDOG_RESET();
374         }
375
376         return 1;
377 }                               /* wait_for_DQ7() */
378
379 static int flash_erase8(flash_info_t *info, int s_first, int s_last)
380 {
381         int tcode, rcode = 0;
382         volatile uchar *addr = (uchar *) (info->start[0]);
383         volatile uchar *sector_addr;
384         int flag, prot, sect;
385
386         /* Validate arguments */
387         if ((s_first < 0) || (s_first > s_last)) {
388                 if (info->flash_id == FLASH_UNKNOWN)
389                         printf("- missing\n");
390                 else
391                         printf("- no sectors to erase\n");
392                 return 1;
393         }
394
395         /* Check for KNOWN flash type */
396         if (info->flash_id == FLASH_UNKNOWN) {
397                 printf("Can't erase unknown flash type - aborted\n");
398                 return 1;
399         }
400
401         /* Check for protected sectors */
402         prot = 0;
403         for (sect = s_first; sect <= s_last; ++sect) {
404                 if (info->protect[sect])
405                         prot++;
406         }
407         if (prot) {
408                 printf("- Warning: %d protected sectors will not be erased!\n",
409                         prot);
410         } else {
411                 printf("\n");
412         }
413
414         /* Start erase on unprotected sectors */
415         for (sect = s_first; sect <= s_last; sect++) {
416                 if (info->protect[sect] == 0) { /* not protected */
417                         sector_addr = (uchar *) (info->start[sect]);
418
419                         if ((info->flash_id & FLASH_VENDMASK) ==
420                             FLASH_MAN_STM)
421                                 printf("Erasing block %p\n", sector_addr);
422                         else
423                                 printf("Erasing sector %p\n", sector_addr);
424
425                         /* Disable interrupts which might cause timeout */
426                         flag = disable_interrupts();
427
428                         *(addr + 0x555) = (uchar) 0xAA;
429                         *(addr + 0x2aa) = (uchar) 0x55;
430                         *(addr + 0x555) = (uchar) 0x80;
431                         *(addr + 0x555) = (uchar) 0xAA;
432                         *(addr + 0x2aa) = (uchar) 0x55;
433                         *sector_addr = (uchar) 0x30;    /* sector erase */
434
435                         /*
436                          * Wait for each sector to complete, it's more
437                          * reliable.  According to AMD Spec, you must
438                          * issue all erase commands within a specified
439                          * timeout.  This has been seen to fail, especially
440                          * if printf()s are included (for debug)!!
441                          * Takes up to 6 seconds.
442                          */
443                         tcode = wait_for_DQ7((ulong) sector_addr, 0x80, 6000);
444
445                         /* re-enable interrupts if necessary */
446                         if (flag)
447                                 enable_interrupts();
448
449                         /* Make sure we didn't timeout */
450                         if (tcode) {
451                                 printf("Timeout\n");
452                                 rcode = 1;
453                         }
454                 }
455         }
456
457         /* wait at least 80us - let's wait 1 ms */
458         udelay(1000);
459
460         /* reset to read mode */
461         addr = (uchar *) info->start[0];
462         *addr = (uchar) 0xF0;   /* reset bank */
463
464         printf(" done\n");
465         return rcode;
466 }                               /* end flash_erase8() */
467
468 static int flash_erase32(flash_info_t *info, int s_first, int s_last)
469 {
470         int flag, sect;
471         ulong start, now, last;
472         int prot = 0;
473
474         /* Validate arguments */
475         if ((s_first < 0) || (s_first > s_last)) {
476                 if (info->flash_id == FLASH_UNKNOWN)
477                         printf("- missing\n");
478                 else
479                         printf("- no sectors to erase\n");
480                 return 1;
481         }
482
483         /* Check for KNOWN flash type */
484         if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL) {
485                 printf("Can erase only Intel flash types - aborted\n");
486                 return 1;
487         }
488
489         /* Check for protected sectors */
490         for (sect = s_first; sect <= s_last; ++sect) {
491                 if (info->protect[sect])
492                         prot++;
493         }
494         if (prot) {
495                 printf("- Warning: %d protected sectors will not be erased!\n",
496                         prot);
497         } else {
498                 printf("\n");
499         }
500
501         start = get_timer(0);
502         last = start;
503         /* Start erase on unprotected sectors */
504         for (sect = s_first; sect <= s_last; sect++) {
505                 WATCHDOG_RESET();
506                 if (info->protect[sect] == 0) { /* not protected */
507                         vu_long *addr = (vu_long *) (info->start[sect]);
508                         unsigned long status;
509
510                         /* Disable interrupts which might cause a timeout */
511                         flag = disable_interrupts();
512
513                         *addr = 0x00500050;     /* clear status register */
514                         *addr = 0x00200020;     /* erase setup */
515                         *addr = 0x00D000D0;     /* erase confirm */
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                         while (((status = *addr) & 0x00800080) != 0x00800080) {
525                                 now = get_timer(start);
526                                 if (now > CONFIG_SYS_FLASH_ERASE_TOUT) {
527                                         printf("Timeout\n");
528                                         /* suspend erase      */
529                                         *addr = 0x00B000B0;
530                                         /* reset to read mode */
531                                         *addr = 0x00FF00FF;
532                                         return 1;
533                                 }
534
535                                 /*
536                                  * show that we're waiting
537                                  * every second (?)
538                                  */
539                                 if ((now - last) > 990) {
540                                         putc('.');
541                                         last = now;
542                                 }
543                         }
544                         *addr = 0x00FF00FF;     /* reset to read mode */
545                 }
546         }
547         printf(" done\n");
548         return 0;
549 }
550
551 int flash_erase(flash_info_t *info, int s_first, int s_last)
552 {
553         if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040)
554                 return flash_erase8(info, s_first, s_last);
555         else
556                 return flash_erase32(info, s_first, s_last);
557 }
558
559 /*
560  * Copy memory to flash, returns:
561  * 0 - OK
562  * 1 - write timeout
563  * 2 - Flash not erased
564  */
565 static int write_buff8(flash_info_t *info, uchar *src, ulong addr,
566                        ulong cnt)
567 {
568         ulong cp, wp, data;
569         ulong start;
570         int i, l, rc;
571
572         start = get_timer(0);
573
574         wp = (addr & ~3);       /* get lower word
575                                    aligned address */
576
577         /*
578          * handle unaligned start bytes
579          */
580         l = addr - wp;
581         if (l != 0) {
582                 data = 0;
583                 for (i = 0, cp = wp; i < l; ++i, ++cp)
584                         data = (data << 8) | (*(uchar *) cp);
585
586                 for (; i < 4 && cnt > 0; ++i) {
587                         data = (data << 8) | *src++;
588                         --cnt;
589                         ++cp;
590                 }
591
592                 for (; cnt == 0 && i < 4; ++i, ++cp)
593                         data = (data << 8) | (*(uchar *) cp);
594
595                 rc = write_word8(info, wp, data);
596                 if (rc != 0)
597                         return rc;
598
599                 wp += 4;
600         }
601
602         /*
603          * handle word aligned part
604          */
605         while (cnt >= 4) {
606                 data = 0;
607                 for (i = 0; i < 4; ++i)
608                         data = (data << 8) | *src++;
609
610                 rc = write_word8(info, wp, data);
611                 if (rc != 0)
612                         return rc;
613
614                 wp += 4;
615                 cnt -= 4;
616                 if (get_timer(start) > 1000) {  /* every second */
617                         WATCHDOG_RESET();
618                         putc('.');
619                         start = get_timer(0);
620                 }
621         }
622
623         if (cnt == 0)
624                 return 0;
625
626         /*
627          * handle unaligned tail bytes
628          */
629         data = 0;
630         for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
631                 data = (data << 8) | *src++;
632                 --cnt;
633         }
634
635         for (; i < 4; ++i, ++cp)
636                 data = (data << 8) | (*(uchar *) cp);
637
638         return write_word8(info, wp, data);
639 }
640
641 #define FLASH_WIDTH     4       /* flash bus width in bytes */
642 static int write_buff32(flash_info_t *info, uchar *src, ulong addr,
643                         ulong cnt)
644 {
645         ulong cp, wp, data;
646         int i, l, rc;
647         ulong start;
648
649         start = get_timer(0);
650
651         if (info->flash_id == FLASH_UNKNOWN)
652                 return 4;
653
654         /* get lower FLASH_WIDTH aligned address */
655         wp = (addr & ~(FLASH_WIDTH - 1));
656
657         /*
658          * handle unaligned start bytes
659          */
660         if ((l = addr - wp) != 0) {
661                 data = 0;
662                 for (i = 0, cp = wp; i < l; ++i, ++cp)
663                         data = (data << 8) | (*(uchar *) cp);
664
665                 for (; i < FLASH_WIDTH && cnt > 0; ++i) {
666                         data = (data << 8) | *src++;
667                         --cnt;
668                         ++cp;
669                 }
670
671                 for (; cnt == 0 && i < FLASH_WIDTH; ++i, ++cp)
672                         data = (data << 8) | (*(uchar *) cp);
673
674                 rc = write_word32(info, wp, data);
675                 if (rc != 0)
676                         return rc;
677
678                 wp += FLASH_WIDTH;
679         }
680
681         /*
682          * handle FLASH_WIDTH aligned part
683          */
684         while (cnt >= FLASH_WIDTH) {
685                 data = 0;
686                 for (i = 0; i < FLASH_WIDTH; ++i)
687                         data = (data << 8) | *src++;
688
689                 rc = write_word32(info, wp, data);
690                 if (rc != 0)
691                         return rc;
692
693                 wp += FLASH_WIDTH;
694                 cnt -= FLASH_WIDTH;
695                 if (get_timer(start) > 990) {   /* every second */
696                         putc('.');
697                         start = get_timer(0);
698                 }
699         }
700
701         if (cnt == 0)
702                 return 0;
703
704         /*
705          * handle unaligned tail bytes
706          */
707         data = 0;
708         for (i = 0, cp = wp; i < FLASH_WIDTH && cnt > 0; ++i, ++cp) {
709                 data = (data << 8) | *src++;
710                 --cnt;
711         }
712
713         for (; i < FLASH_WIDTH; ++i, ++cp)
714                 data = (data << 8) | (*(uchar *) cp);
715
716         return write_word32(info, wp, data);
717 }
718
719 int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
720 {
721         int retval;
722
723         if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040)
724                 retval = write_buff8(info, src, addr, cnt);
725         else
726                 retval = write_buff32(info, src, addr, cnt);
727
728         return retval;
729 }
730
731 /*
732  * Write a word to Flash, returns:
733  * 0 - OK
734  * 1 - write timeout
735  * 2 - Flash not erased
736  */
737
738 static int write_word8(flash_info_t *info, ulong dest, ulong data)
739 {
740         volatile uchar *addr2 = (uchar *) (info->start[0]);
741         volatile uchar *dest2 = (uchar *) dest;
742         volatile uchar *data2 = (uchar *) &data;
743         int flag;
744         int i, tcode, rcode = 0;
745
746         /* Check if Flash is (sufficently) erased */
747         if ((*((volatile uchar *)dest) & (uchar)data) != (uchar)data)
748                 return 2;
749
750         for (i = 0; i < (4 / sizeof(uchar)); i++) {
751                 /* Disable interrupts which might cause a timeout here */
752                 flag = disable_interrupts();
753
754                 *(addr2 + 0x555) = (uchar) 0xAA;
755                 *(addr2 + 0x2aa) = (uchar) 0x55;
756                 *(addr2 + 0x555) = (uchar) 0xA0;
757
758                 dest2[i] = data2[i];
759
760                 /* Wait for write to complete, up to 1ms */
761                 tcode = wait_for_DQ7((ulong) &dest2[i], data2[i], 1);
762
763                 /* re-enable interrupts if necessary */
764                 if (flag)
765                         enable_interrupts();
766
767                 /* Make sure we didn't timeout */
768                 if (tcode)
769                         rcode = 1;
770         }
771
772         return rcode;
773 }
774
775 static int write_word32(flash_info_t *info, ulong dest, ulong data)
776 {
777         vu_long *addr = (vu_long *) dest;
778         ulong status;
779         ulong start;
780         int flag;
781
782         /* Check if Flash is (sufficiently) erased */
783         if ((*addr & data) != data)
784                 return 2;
785
786         /* Disable interrupts which might cause a timeout here */
787         flag = disable_interrupts();
788
789         *addr = 0x00400040;     /* write setup */
790         *addr = data;
791
792         /* re-enable interrupts if necessary */
793         if (flag)
794                 enable_interrupts();
795
796         start = get_timer(0);
797
798         while (((status = *addr) & 0x00800080) != 0x00800080) {
799                 WATCHDOG_RESET();
800                 if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
801                         *addr = 0x00FF00FF;     /* restore read mode */
802                         return 1;
803                 }
804         }
805
806         *addr = 0x00FF00FF;     /* restore read mode */
807
808         return 0;
809 }
810
811 static int _flash_protect(flash_info_t *info, long sector)
812 {
813         int i;
814         int flag;
815         ulong status;
816         int rcode = 0;
817         volatile long *addr = (long *)sector;
818
819         switch (info->flash_id & FLASH_TYPEMASK) {
820         case FLASH_28F320J3A:
821         case FLASH_28F640J3A:
822         case FLASH_28F128J3A:
823                 /* Disable interrupts which might cause Flash to timeout */
824                 flag = disable_interrupts();
825
826                 /* Issue command */
827                 *addr = 0x00500050L;    /* Clear the status register */
828                 *addr = 0x00600060L;    /* Set lock bit setup */
829                 *addr = 0x00010001L;    /* Set lock bit confirm */
830
831                 /* Wait for command completion */
832                 for (i = 0; i < 10; i++) {      /* 75us timeout, wait 100us */
833                         udelay(10);
834                         if ((*addr & 0x00800080L) == 0x00800080L)
835                                 break;
836                 }
837
838                 /* Not successful? */
839                 status = *addr;
840                 if (status != 0x00800080L) {
841                         printf("Protect %x sector failed: %x\n",
842                                (uint) sector, (uint) status);
843                         rcode = 1;
844                 }
845
846                 /* Restore read mode */
847                 *addr = 0x00ff00ffL;
848
849                 /* re-enable interrupts if necessary */
850                 if (flag)
851                         enable_interrupts();
852
853                 break;
854         case FLASH_AM040:       /* No soft sector protection */
855                 break;
856         }
857
858         /* Turn protection on for this sector */
859         for (i = 0; i < info->sector_count; i++) {
860                 if (info->start[i] == sector) {
861                         info->protect[i] = 1;
862                         break;
863                 }
864         }
865
866         return rcode;
867 }
868
869 static int _flash_unprotect(flash_info_t *info, long sector)
870 {
871         int i;
872         int flag;
873         ulong status;
874         int rcode = 0;
875         volatile long *addr = (long *) sector;
876
877         switch (info->flash_id & FLASH_TYPEMASK) {
878         case FLASH_28F320J3A:
879         case FLASH_28F640J3A:
880         case FLASH_28F128J3A:
881                 /* Disable interrupts which might cause Flash to timeout */
882                 flag = disable_interrupts();
883
884                 *addr = 0x00500050L;    /* Clear the status register */
885                 *addr = 0x00600060L;    /* Clear lock bit setup */
886                 *addr = 0x00D000D0L;    /* Clear lock bit confirm */
887
888                 /* Wait for command completion */
889                 for (i = 0; i < 80; i++) {      /* 700ms timeout, wait 800 */
890                         udelay(10000);  /* Delay 10ms */
891                         if ((*addr & 0x00800080L) == 0x00800080L)
892                                 break;
893                 }
894
895                 /* Not successful? */
896                 status = *addr;
897                 if (status != 0x00800080L) {
898                         printf("Un-protect %x sector failed: %x\n",
899                                (uint) sector, (uint) status);
900                         *addr = 0x00ff00ffL;
901                         rcode = 1;
902                 }
903
904                 /* restore read mode */
905                 *addr = 0x00ff00ffL;
906
907                 /* re-enable interrupts if necessary */
908                 if (flag)
909                         enable_interrupts();
910
911                 break;
912         case FLASH_AM040:       /* No soft sector protection */
913                 break;
914         }
915
916         /*
917          * Fix Intel's little red wagon.  Reprotect
918          * sectors that were protected before we undid
919          * protection on a specific sector.
920          */
921         for (i = 0; i < info->sector_count; i++) {
922                 if (info->start[i] != sector) {
923                         if (info->protect[i]) {
924                                 if (_flash_protect(info, info->start[i]))
925                                         rcode = 1;
926                         }
927                 } else          /* Turn protection off for this sector */
928                         info->protect[i] = 0;
929         }
930
931         return rcode;
932 }
933
934 int flash_real_protect(flash_info_t *info, long sector, int prot)
935 {
936         int rcode;
937
938         if (prot)
939                 rcode = _flash_protect(info, info->start[sector]);
940         else
941                 rcode = _flash_unprotect(info, info->start[sector]);
942
943         return rcode;
944 }