]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/alaska/flash.c
977822ac51e10b562d9af76f54bbf6bb66a2bea4
[karo-tx-uboot.git] / board / alaska / flash.c
1 /*
2  * (C) Copyright 2001
3  * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
4  *
5  * (C) Copyright 2001-2004
6  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
7  *
8  * See file CREDITS for list of people who contributed to this
9  * project.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License as
13  * published by the Free Software Foundation; either version 2 of
14  * the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
24  * MA 02111-1307 USA
25  */
26
27 #include <common.h>
28 #include <linux/byteorder/swab.h>
29
30
31 flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];    /* info for FLASH chips    */
32
33 /* Board support for 1 or 2 flash devices */
34 #define FLASH_PORT_WIDTH8
35
36 typedef unsigned char FLASH_PORT_WIDTH;
37 typedef volatile unsigned char FLASH_PORT_WIDTHV;
38
39 #define SWAP(x)         (x)
40
41 /* Intel-compatible flash ID */
42 #define INTEL_COMPAT    0x89
43 #define INTEL_ALT       0xB0
44
45 /* Intel-compatible flash commands */
46 #define INTEL_PROGRAM   0x10
47 #define INTEL_ERASE     0x20
48 #define INTEL_CLEAR     0x50
49 #define INTEL_LOCKBIT   0x60
50 #define INTEL_PROTECT   0x01
51 #define INTEL_STATUS    0x70
52 #define INTEL_READID    0x90
53 #define INTEL_CONFIRM   0xD0
54 #define INTEL_RESET     0xFF
55
56 /* Intel-compatible flash status bits */
57 #define INTEL_FINISHED  0x80
58 #define INTEL_OK        0x80
59
60 #define FPW             FLASH_PORT_WIDTH
61 #define FPWV            FLASH_PORT_WIDTHV
62
63 #define FLASH_CYCLE1    0x0555
64 #define FLASH_CYCLE2    0x02aa
65
66 #define WR_BLOCK        0x20
67 /*-----------------------------------------------------------------------
68  * Functions
69  */
70 static ulong flash_get_size (FPW * addr, flash_info_t * info);
71 static int write_data (flash_info_t * info, ulong dest, FPW data);
72 static int write_data_block (flash_info_t * info, ulong src, ulong dest);
73 static int write_word_amd (flash_info_t * info, FPWV * dest, FPW data);
74 static void flash_get_offsets (ulong base, flash_info_t * info);
75 void inline spin_wheel (void);
76 static void flash_sync_real_protect (flash_info_t * info);
77 static unsigned char intel_sector_protected (flash_info_t *info, ushort sector);
78 static unsigned char same_chip_banks (int bank1, int bank2);
79
80 /*-----------------------------------------------------------------------
81  */
82
83 unsigned long flash_init (void)
84 {
85         int i;
86         ulong size = 0;
87         ulong fsize = 0;
88
89         for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
90                 memset (&flash_info[i], 0, sizeof (flash_info_t));
91
92                 switch (i) {
93                 case 0:
94                         flash_get_size ((FPW *) CONFIG_SYS_FLASH1_BASE,
95                                         &flash_info[i]);
96                         flash_get_offsets (CONFIG_SYS_FLASH1_BASE, &flash_info[i]);
97                         break;
98                 case 1:
99                         flash_get_size ((FPW *) CONFIG_SYS_FLASH1_BASE,
100                                         &flash_info[i]);
101                         fsize = CONFIG_SYS_FLASH1_BASE + flash_info[i - 1].size;
102                         flash_get_offsets (fsize, &flash_info[i]);
103                         break;
104                 case 2:
105                         flash_get_size ((FPW *) CONFIG_SYS_FLASH0_BASE,
106                                         &flash_info[i]);
107                         flash_get_offsets (CONFIG_SYS_FLASH0_BASE, &flash_info[i]);
108                         break;
109                 case 3:
110                         flash_get_size ((FPW *) CONFIG_SYS_FLASH0_BASE,
111                                         &flash_info[i]);
112                         fsize = CONFIG_SYS_FLASH0_BASE + flash_info[i - 1].size;
113                         flash_get_offsets (fsize, &flash_info[i]);
114                         break;
115                 default:
116                         panic ("configured to many flash banks!\n");
117                         break;
118                 }
119                 size += flash_info[i].size;
120
121                 /* get the h/w and s/w protection status in sync */
122                 flash_sync_real_protect(&flash_info[i]);
123         }
124
125         /* Protect monitor and environment sectors
126          */
127 #if defined (CONFIG_SYS_AMD_BOOT)
128         flash_protect (FLAG_PROTECT_SET,
129                        CONFIG_SYS_MONITOR_BASE,
130                        CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1,
131                        &flash_info[2]);
132         flash_protect (FLAG_PROTECT_SET,
133                        CONFIG_SYS_INTEL_BASE,
134                        CONFIG_SYS_INTEL_BASE + monitor_flash_len - 1,
135                        &flash_info[1]);
136 #else
137         flash_protect (FLAG_PROTECT_SET,
138                        CONFIG_SYS_MONITOR_BASE,
139                        CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1,
140                        &flash_info[3]);
141         flash_protect (FLAG_PROTECT_SET,
142                        CONFIG_SYS_AMD_BASE,
143                        CONFIG_SYS_AMD_BASE + monitor_flash_len - 1, &flash_info[0]);
144 #endif
145
146         flash_protect (FLAG_PROTECT_SET,
147                        CONFIG_ENV1_ADDR,
148                        CONFIG_ENV1_ADDR + CONFIG_ENV1_SIZE - 1, &flash_info[1]);
149         flash_protect (FLAG_PROTECT_SET,
150                        CONFIG_ENV_ADDR,
151                        CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, &flash_info[3]);
152
153         return size;
154 }
155
156 /*-----------------------------------------------------------------------
157  */
158 static void flash_get_offsets (ulong base, flash_info_t * info)
159 {
160         int i;
161
162         if (info->flash_id == FLASH_UNKNOWN)
163                 return;
164
165         if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD) {
166                 for (i = 0; i < info->sector_count; i++) {
167                         info->start[i] = base + (i * PHYS_AMD_SECT_SIZE);
168                         info->protect[i] = 0;
169                 }
170         }
171
172         if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
173                 for (i = 0; i < info->sector_count; i++) {
174                         info->start[i] = base + (i * PHYS_INTEL_SECT_SIZE);
175                 }
176         }
177 }
178
179 /*-----------------------------------------------------------------------
180  */
181 void flash_print_info (flash_info_t * info)
182 {
183         int i;
184
185         if (info->flash_id == FLASH_UNKNOWN) {
186                 printf ("missing or unknown FLASH type\n");
187                 return;
188         }
189
190         switch (info->flash_id & FLASH_VENDMASK) {
191         case FLASH_MAN_INTEL:
192                 printf ("INTEL ");
193                 break;
194         case FLASH_MAN_AMD:
195                 printf ("AMD ");
196                 break;
197         default:
198                 printf ("Unknown Vendor ");
199                 break;
200         }
201
202         switch (info->flash_id & FLASH_TYPEMASK) {
203         case FLASH_28F128J3A:
204                 printf ("28F128J3A\n");
205                 break;
206
207         case FLASH_AM040:
208                 printf ("AMD29F040B\n");
209                 break;
210
211         default:
212                 printf ("Unknown Chip Type\n");
213                 break;
214         }
215
216         printf ("  Size: %ld MB in %d Sectors\n",
217                 info->size >> 20, info->sector_count);
218
219         printf ("  Sector Start Addresses:");
220         for (i = 0; i < info->sector_count; ++i) {
221                 if ((i % 5) == 0)
222                         printf ("\n   ");
223                 printf (" %08lX%s",
224                         info->start[i], info->protect[i] ? " (RO)" : "     ");
225         }
226         printf ("\n");
227         return;
228 }
229
230 /*
231  * The following code cannot be run from FLASH!
232  */
233 static ulong flash_get_size (FPW * addr, flash_info_t * info)
234 {
235         FPWV value;
236         static int amd = 0;
237
238         /* Write auto select command: read Manufacturer ID */
239         /* Write auto select command sequence and test FLASH answer */
240         addr[FLASH_CYCLE1] = (FPW) 0x00AA00AA;  /* for AMD, Intel ignores this */
241         __asm__ ("sync");
242         addr[FLASH_CYCLE2] = (FPW) 0x00550055;  /* for AMD, Intel ignores this */
243         __asm__ ("sync");
244         addr[FLASH_CYCLE1] = (FPW) 0x00900090;  /* selects Intel or AMD */
245         __asm__ ("sync");
246
247         udelay (100);
248
249         switch (addr[0] & 0xff) {
250
251         case (uchar) AMD_MANUFACT:
252                 info->flash_id = FLASH_MAN_AMD;
253                 value = addr[1];
254                 break;
255
256         case (uchar) INTEL_MANUFACT:
257                 info->flash_id = FLASH_MAN_INTEL;
258                 value = addr[2];
259                 break;
260
261         default:
262                 printf ("unknown\n");
263                 info->flash_id = FLASH_UNKNOWN;
264                 info->sector_count = 0;
265                 info->size = 0;
266                 addr[0] = (FPW) 0x00FF00FF;     /* restore read mode */
267                 return (0);     /* no or unknown flash  */
268         }
269
270         switch (value) {
271
272         case (FPW) INTEL_ID_28F128J3A:
273                 info->flash_id += FLASH_28F128J3A;
274                 info->sector_count = 64;
275                 info->size = 0x00800000;        /* => 16 MB     */
276                 break;
277
278         case (FPW) AMD_ID_LV040B:
279                 info->flash_id += FLASH_AM040;
280                 if (amd == 0) {
281                         info->sector_count = 7;
282                         info->size = 0x00070000;        /* => 448 KB     */
283                         amd = 1;
284                 } else {
285                         /* for Environment settings */
286                         info->sector_count = 1;
287                         info->size = PHYS_AMD_SECT_SIZE;        /* => 64 KB     */
288                         amd = 0;
289                 }
290                 break;
291
292         default:
293                 info->flash_id = FLASH_UNKNOWN;
294                 break;
295         }
296
297         if (info->sector_count > CONFIG_SYS_MAX_FLASH_SECT) {
298                 printf ("** ERROR: sector count %d > max (%d) **\n",
299                         info->sector_count, CONFIG_SYS_MAX_FLASH_SECT);
300                 info->sector_count = CONFIG_SYS_MAX_FLASH_SECT;
301         }
302
303         if (value == (FPW) INTEL_ID_28F128J3A)
304                 addr[0] = (FPW) 0x00FF00FF;     /* restore read mode */
305         else
306                 addr[0] = (FPW) 0x00F000F0;     /* restore read mode */
307
308         return (info->size);
309 }
310
311
312 /*
313  * This function gets the u-boot flash sector protection status
314  * (flash_info_t.protect[]) in sync with the sector protection
315  * status stored in hardware.
316  */
317 static void flash_sync_real_protect (flash_info_t * info)
318 {
319         int i;
320
321         switch (info->flash_id & FLASH_TYPEMASK) {
322         case FLASH_28F128J3A:
323                 for (i = 0; i < info->sector_count; ++i) {
324                         info->protect[i] = intel_sector_protected(info, i);
325                 }
326                 break;
327         case FLASH_AM040:
328         default:
329                 /* no h/w protect support */
330                 break;
331         }
332 }
333
334
335 /*
336  * checks if "sector" in bank "info" is protected. Should work on intel
337  * strata flash chips 28FxxxJ3x in 8-bit mode.
338  * Returns 1 if sector is protected (or timed-out while trying to read
339  * protection status), 0 if it is not.
340  */
341 static unsigned char intel_sector_protected (flash_info_t *info, ushort sector)
342 {
343         FPWV *addr;
344         FPWV *lock_conf_addr;
345         ulong start;
346         unsigned char ret;
347
348         /*
349          * first, wait for the WSM to be finished. The rationale for
350          * waiting for the WSM to become idle for at most
351          * CONFIG_SYS_FLASH_ERASE_TOUT is as follows. The WSM can be busy
352          * because of: (1) erase, (2) program or (3) lock bit
353          * configuration. So we just wait for the longest timeout of
354          * the (1)-(3), i.e. the erase timeout.
355          */
356
357         /* wait at least 35ns (W12) before issuing Read Status Register */
358         udelay(1);
359         addr = (FPWV *) info->start[sector];
360         *addr = (FPW) INTEL_STATUS;
361
362         start = get_timer (0);
363         while ((*addr & (FPW) INTEL_FINISHED) != (FPW) INTEL_FINISHED) {
364                 if (get_timer (start) > CONFIG_SYS_FLASH_ERASE_TOUT) {
365                         *addr = (FPW) INTEL_RESET; /* restore read mode */
366                         printf("WSM busy too long, can't get prot status\n");
367                         return 1;
368                 }
369         }
370
371         /* issue the Read Identifier Codes command */
372         *addr = (FPW) INTEL_READID;
373
374         /* wait at least 35ns (W12) before reading */
375         udelay(1);
376
377         /* Intel example code uses offset of 4 for 8-bit flash */
378         lock_conf_addr = (FPWV *) info->start[sector] + 4;
379         ret = (*lock_conf_addr & (FPW) INTEL_PROTECT) ? 1 : 0;
380
381         /* put flash back in read mode */
382         *addr = (FPW) INTEL_RESET;
383
384         return ret;
385 }
386
387
388 /*
389  * Checks if "bank1" and "bank2" are on the same chip.  Returns 1 if they
390  * are and 0 otherwise.
391  */
392 static unsigned char same_chip_banks (int bank1, int bank2)
393 {
394         unsigned char same_chip[CONFIG_SYS_MAX_FLASH_BANKS][CONFIG_SYS_MAX_FLASH_BANKS] = {
395                 {1, 1, 0, 0},
396                 {1, 1, 0, 0},
397                 {0, 0, 1, 1},
398                 {0, 0, 1, 1}
399         };
400         return same_chip[bank1][bank2];
401 }
402
403
404 /*-----------------------------------------------------------------------
405  */
406 int flash_erase (flash_info_t * info, int s_first, int s_last)
407 {
408         int flag, prot, sect;
409         ulong type, start;
410         int rcode = 0, intel = 0;
411
412         if ((s_first < 0) || (s_first > s_last)) {
413                 if (info->flash_id == FLASH_UNKNOWN)
414                         printf ("- missing\n");
415                 else
416                         printf ("- no sectors to erase\n");
417                 return 1;
418         }
419
420         type = (info->flash_id & FLASH_VENDMASK);
421         if ((type != FLASH_MAN_INTEL)) {
422                 type = (info->flash_id & FLASH_VENDMASK);
423                 if ((type != FLASH_MAN_AMD)) {
424                         printf ("Can't erase unknown flash type %08lx - aborted\n",
425                                 info->flash_id);
426                         return 1;
427                 }
428         }
429
430         if (type == FLASH_MAN_INTEL)
431                 intel = 1;
432
433         prot = 0;
434         for (sect = s_first; sect <= s_last; ++sect) {
435                 if (info->protect[sect]) {
436                         prot++;
437                 }
438         }
439
440         if (prot) {
441                 printf ("- Warning: %d protected sectors will not be erased!\n", prot);
442         } else {
443                 printf ("\n");
444         }
445
446         start = get_timer (0);
447
448         /* Disable interrupts which might cause a timeout here */
449         flag = disable_interrupts ();
450
451         /* Start erase on unprotected sectors */
452         for (sect = s_first; sect <= s_last; sect++) {
453                 if (info->protect[sect] == 0) { /* not protected */
454                         FPWV *addr = (FPWV *) (info->start[sect]);
455                         FPW status;
456
457                         printf ("Erasing sector %2d ... ", sect);
458
459                         /* arm simple, non interrupt dependent timer */
460                         start = get_timer (0);
461
462                         if (intel) {
463                                 *addr = (FPW) 0x00500050;       /* clear status register */
464                                 *addr = (FPW) 0x00200020;       /* erase setup */
465                                 *addr = (FPW) 0x00D000D0;       /* erase confirm */
466                         } else {
467                                 FPWV *base;     /* first address in bank */
468
469                                 base = (FPWV *) (CONFIG_SYS_AMD_BASE);
470                                 base[FLASH_CYCLE1] = (FPW) 0x00AA00AA;  /* unlock */
471                                 base[FLASH_CYCLE2] = (FPW) 0x00550055;  /* unlock */
472                                 base[FLASH_CYCLE1] = (FPW) 0x00800080;  /* erase mode */
473                                 base[FLASH_CYCLE1] = (FPW) 0x00AA00AA;  /* unlock */
474                                 base[FLASH_CYCLE2] = (FPW) 0x00550055;  /* unlock */
475                                 *addr = (FPW) 0x00300030;       /* erase sector */
476                         }
477
478                         while (((status =
479                                  *addr) & (FPW) 0x00800080) !=
480                                (FPW) 0x00800080) {
481                                 if (get_timer (start) > CONFIG_SYS_FLASH_ERASE_TOUT) {
482                                         printf ("Timeout\n");
483                                         if (intel) {
484                                                 *addr = (FPW) 0x00B000B0;       /* suspend erase     */
485                                                 *addr = (FPW) 0x00FF00FF;       /* reset to read mode */
486                                         } else
487                                                 *addr = (FPW) 0x00F000F0;       /* reset to read mode */
488
489                                         rcode = 1;
490                                         break;
491                                 }
492                         }
493
494                         if (intel) {
495                                 *addr = (FPW) 0x00500050;       /* clear status register cmd.   */
496                                 *addr = (FPW) 0x00FF00FF;       /* resest to read mode          */
497                         } else
498                                 *addr = (FPW) 0x00F000F0;       /* reset to read mode */
499
500                         printf (" done\n");
501                 }
502         }
503         if (flag)
504                 enable_interrupts();
505
506         return rcode;
507 }
508
509 /*-----------------------------------------------------------------------
510  * Copy memory to flash, returns:
511  * 0 - OK
512  * 1 - write timeout
513  * 2 - Flash not erased
514  * 4 - Flash not identified
515  */
516
517 int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
518 {
519         if (info->flash_id == FLASH_UNKNOWN) {
520                 return 4;
521         }
522
523         switch (info->flash_id & FLASH_VENDMASK) {
524         case FLASH_MAN_AMD:
525             {
526                 FPW data = 0;   /* 16 or 32 bit word, matches flash bus width */
527                 int bytes;      /* number of bytes to program in current word */
528                 int left;       /* number of bytes left to program */
529                 int i, res;
530
531                 for (left = cnt, res = 0;
532                      left > 0 && res == 0;
533                      addr += sizeof (data), left -=
534                      sizeof (data) - bytes) {
535
536                         bytes = addr & (sizeof (data) - 1);
537                         addr &= ~(sizeof (data) - 1);
538
539                         /* combine source and destination data so can program
540                          * an entire word of 16 or 32 bits
541                          */
542                         for (i = 0; i < sizeof (data); i++) {
543                                 data <<= 8;
544                                 if (i < bytes || i - bytes >= left)
545                                         data += *((uchar *) addr + i);
546                                 else
547                                         data += *src++;
548                         }
549
550                         res = write_word_amd (info, (FPWV *) addr,
551                                               data);
552                 }
553                 return res;
554             }           /* case FLASH_MAN_AMD */
555
556         case FLASH_MAN_INTEL:
557             {
558                 ulong cp, wp;
559                 FPW data;
560                 int count, i, l, rc, port_width;
561
562                 /* get lower word aligned address */
563                 wp = addr;
564                 port_width = 1;
565
566                 /*
567                  * handle unaligned start bytes
568                  */
569                 if ((l = addr - wp) != 0) {
570                         data = 0;
571                         for (i = 0, cp = wp; i < l; ++i, ++cp) {
572                                 data = (data << 8) | (*(uchar *) cp);
573                         }
574
575                         for (; i < port_width && cnt > 0; ++i) {
576                                 data = (data << 8) | *src++;
577                                 --cnt;
578                                 ++cp;
579                         }
580
581                         for (; cnt == 0 && i < port_width; ++i, ++cp)
582                                 data = (data << 8) | (*(uchar *) cp);
583
584                         if ((rc =
585                              write_data (info, wp, SWAP (data))) != 0)
586                                 return (rc);
587                         wp += port_width;
588                 }
589
590                 if (cnt > WR_BLOCK) {
591                         /*
592                          * handle word aligned part
593                          */
594                         count = 0;
595                         while (cnt >= WR_BLOCK) {
596
597                                 if ((rc =
598                                      write_data_block (info,
599                                                        (ulong) src,
600                                                        wp)) != 0)
601                                         return (rc);
602
603                                 wp += WR_BLOCK;
604                                 src += WR_BLOCK;
605                                 cnt -= WR_BLOCK;
606
607                                 if (count++ > 0x800) {
608                                         spin_wheel ();
609                                         count = 0;
610                                 }
611                         }
612                 }
613
614                 if (cnt < WR_BLOCK) {
615                         /*
616                          * handle word aligned part
617                          */
618                         count = 0;
619                         while (cnt >= port_width) {
620                                 data = 0;
621                                 for (i = 0; i < port_width; ++i)
622                                         data = (data << 8) | *src++;
623
624                                 if ((rc =
625                                      write_data (info, wp,
626                                                  SWAP (data))) != 0)
627                                         return (rc);
628
629                                 wp += port_width;
630                                 cnt -= port_width;
631                                 if (count++ > 0x800) {
632                                         spin_wheel ();
633                                         count = 0;
634                                 }
635                         }
636                 }
637
638                 if (cnt == 0)
639                         return (0);
640
641                 /*
642                  * handle unaligned tail bytes
643                  */
644                 data = 0;
645                 for (i = 0, cp = wp; i < port_width && cnt > 0;
646                      ++i, ++cp) {
647                         data = (data << 8) | *src++;
648                         --cnt;
649                 }
650
651                 for (; i < port_width; ++i, ++cp)
652                         data = (data << 8) | (*(uchar *) cp);
653
654                 return (write_data (info, wp, SWAP (data)));
655             }           /* case FLASH_MAN_INTEL */
656
657         }                       /* switch */
658         return (0);
659 }
660
661 /*-----------------------------------------------------------------------
662  * Write a word or halfword to Flash, returns:
663  * 0 - OK
664  * 1 - write timeout
665  * 2 - Flash not erased
666  */
667 static int write_data (flash_info_t * info, ulong dest, FPW data)
668 {
669         FPWV *addr = (FPWV *) dest;
670         ulong start;
671         int flag, rc = 0;
672
673         /* Check if Flash is (sufficiently) erased */
674         if ((*addr & data) != data) {
675                 printf ("not erased at %08lx (%lx)\n", (ulong)addr, (ulong)*addr);
676                 return (2);
677         }
678         /* Disable interrupts which might cause a timeout here */
679         flag = disable_interrupts ();
680
681         *addr = (FPW) 0x00400040;       /* write setup */
682         *addr = data;
683
684         /* arm simple, non interrupt dependent timer */
685         start = get_timer (0);
686
687         /* wait while polling the status register */
688         while ((*addr & (FPW) 0x00800080) != (FPW) 0x00800080) {
689                 if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
690                         rc = 1;
691                         goto OUT;
692                 }
693         }
694
695 OUT:
696         *addr = (FPW)0x00FF00FF;        /* restore read mode */
697
698         if (flag)
699                 enable_interrupts();
700
701         return rc;
702 }
703
704 /*-----------------------------------------------------------------------
705  * Write a word or halfword to Flash, returns:
706  * 0 - OK
707  * 1 - write timeout
708  * 2 - Flash not erased
709  */
710 static int write_data_block (flash_info_t * info, ulong src, ulong dest)
711 {
712         FPWV *srcaddr = (FPWV *) src;
713         FPWV *dstaddr = (FPWV *) dest;
714         ulong start;
715         int flag, i, rc = 0;
716
717         /* Check if Flash is (sufficiently) erased */
718         for (i = 0; i < WR_BLOCK; i++)
719                 if ((*dstaddr++ & 0xff) != 0xff) {
720                         printf ("not erased at %08lx (%lx)\n",
721                                 (ulong)dstaddr, (ulong)*dstaddr);
722                         return (2);
723                 }
724
725         dstaddr = (FPWV *) dest;
726
727         /* Disable interrupts which might cause a timeout here */
728         flag = disable_interrupts ();
729
730         *dstaddr = (FPW) 0x00e800e8;    /* write block setup */
731
732         /* arm simple, non interrupt dependent timer */
733         start = get_timer (0);
734
735         /* wait while polling the status register */
736         while ((*dstaddr & (FPW)0x00800080) != (FPW)0x00800080) {
737                 if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
738                         rc = 1;
739                         goto OUT;
740                 }
741         }
742
743         *dstaddr = (FPW) 0x001f001f;    /* write 32 to buffer */
744         for (i = 0; i < WR_BLOCK; i++)
745                 *dstaddr++ = *srcaddr++;
746
747         dstaddr -= 1;
748         *dstaddr = (FPW) 0x00d000d0;    /* write 32 to buffer */
749
750         /* arm simple, non interrupt dependent timer */
751         start = get_timer (0);
752
753         /* wait while polling the status register */
754         while ((*dstaddr & (FPW) 0x00800080) != (FPW) 0x00800080) {
755                 if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
756                         *dstaddr = (FPW) 0x00FF00FF;    /* restore read mode */
757                         return (1);
758                 }
759         }
760
761 OUT:
762         *dstaddr = (FPW)0x00FF00FF;     /* restore read mode */
763         if (flag)
764                 enable_interrupts();
765
766         return rc;
767 }
768
769 /*-----------------------------------------------------------------------
770  * Write a word to Flash for AMD FLASH
771  * A word is 16 or 32 bits, whichever the bus width of the flash bank
772  * (not an individual chip) is.
773  *
774  * returns:
775  * 0 - OK
776  * 1 - write timeout
777  * 2 - Flash not erased
778  */
779 static int write_word_amd (flash_info_t * info, FPWV * dest, FPW data)
780 {
781         ulong start;
782         int flag;
783         int res = 0;            /* result, assume success */
784         FPWV *base;             /* first address in flash bank */
785
786         /* Check if Flash is (sufficiently) erased */
787         if ((*dest & data) != data) {
788                 return (2);
789         }
790
791         base = (FPWV *) (CONFIG_SYS_AMD_BASE);
792
793         /* Disable interrupts which might cause a timeout here */
794         flag = disable_interrupts ();
795
796         base[FLASH_CYCLE1] = (FPW) 0x00AA00AA;  /* unlock */
797         base[FLASH_CYCLE2] = (FPW) 0x00550055;  /* unlock */
798         base[FLASH_CYCLE1] = (FPW) 0x00A000A0;  /* selects program mode */
799
800         *dest = data;           /* start programming the data */
801
802         /* re-enable interrupts if necessary */
803         if (flag)
804                 enable_interrupts ();
805
806         start = get_timer (0);
807
808         /* data polling for D7 */
809         while (res == 0
810                && (*dest & (FPW) 0x00800080) != (data & (FPW) 0x00800080)) {
811                 if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
812                         *dest = (FPW) 0x00F000F0;       /* reset bank */
813                         res = 1;
814                 }
815         }
816
817         return (res);
818 }
819
820 void inline spin_wheel (void)
821 {
822         static int p = 0;
823         static char w[] = "\\/-";
824
825         printf ("\010%c", w[p]);
826         (++p == 3) ? (p = 0) : 0;
827 }
828
829 /*-----------------------------------------------------------------------
830  * Set/Clear sector's lock bit, returns:
831  * 0 - OK
832  * 1 - Error (timeout, voltage problems, etc.)
833  */
834 int flash_real_protect (flash_info_t * info, long sector, int prot)
835 {
836         ulong start;
837         int i, j;
838         int curr_bank;
839         int bank;
840         int rc = 0;
841         FPWV *addr = (FPWV *) (info->start[sector]);
842         int flag = disable_interrupts ();
843
844         /*
845          * 29F040B AMD flash does not support software protection/unprotection,
846          * the only way to protect the AMD flash is marked it as prot bit.
847          * This flash only support hardware protection, by supply or not supply
848          * 12vpp to the flash
849          */
850         if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD) {
851                 info->protect[sector] = prot;
852
853                 return 0;
854         }
855
856         *addr = INTEL_CLEAR;    /* Clear status register    */
857         if (prot) {             /* Set sector lock bit      */
858                 *addr = INTEL_LOCKBIT;  /* Sector lock bit          */
859                 *addr = INTEL_PROTECT;  /* set                      */
860         } else {                /* Clear sector lock bit    */
861                 *addr = INTEL_LOCKBIT;  /* All sectors lock bits    */
862                 *addr = INTEL_CONFIRM;  /* clear                    */
863         }
864
865         start = get_timer (0);
866
867         while ((*addr & INTEL_FINISHED) != INTEL_FINISHED) {
868                 if (get_timer (start) > CONFIG_SYS_FLASH_UNLOCK_TOUT) {
869                         printf ("Flash lock bit operation timed out\n");
870                         rc = 1;
871                         break;
872                 }
873         }
874
875         if (*addr != INTEL_OK) {
876                 printf ("Flash lock bit operation failed at %08X, CSR=%08X\n",
877                         (uint) addr, (uint) * addr);
878                 rc = 1;
879         }
880
881         if (!rc)
882                 info->protect[sector] = prot;
883
884         /*
885          * Clear lock bit command clears all sectors lock bits, so
886          * we have to restore lock bits of protected sectors.
887          */
888         if (!prot) {
889                 /*
890                  * re-locking must be done for all banks that belong on one
891                  * FLASH chip, as all the sectors on the chip were unlocked
892                  * by INTEL_LOCKBIT/INTEL_CONFIRM commands. (let's hope
893                  * that banks never span chips, in particular chips which
894                  * support h/w protection differently).
895                  */
896
897                 /* find the current bank number */
898                 curr_bank = CONFIG_SYS_MAX_FLASH_BANKS + 1;
899                 for (j = 0; j < CONFIG_SYS_MAX_FLASH_BANKS; ++j) {
900                         if (&flash_info[j] == info) {
901                                 curr_bank = j;
902                         }
903                 }
904                 if (curr_bank == CONFIG_SYS_MAX_FLASH_BANKS + 1) {
905                         printf("Error: can't determine bank number!\n");
906                 }
907
908                 for (bank = 0; bank < CONFIG_SYS_MAX_FLASH_BANKS; ++bank) {
909                         if (!same_chip_banks(curr_bank, bank)) {
910                                 continue;
911                         }
912                         info = &flash_info[bank];
913                         for (i = 0; i < info->sector_count; i++) {
914                                 if (info->protect[i]) {
915                                         start = get_timer (0);
916                                         addr = (FPWV *) (info->start[i]);
917                                         *addr = INTEL_LOCKBIT;  /* Sector lock bit  */
918                                         *addr = INTEL_PROTECT;  /* set              */
919                                         while ((*addr & INTEL_FINISHED) !=
920                                                INTEL_FINISHED) {
921                                                 if (get_timer (start) >
922                                                     CONFIG_SYS_FLASH_UNLOCK_TOUT) {
923                                                         printf ("Flash lock bit operation timed out\n");
924                                                         rc = 1;
925                                                         break;
926                                                 }
927                                         }
928                                 }
929                         }
930                 }
931
932                 /*
933                  * get the s/w sector protection status in sync with the h/w,
934                  * in case something went wrong during the re-locking.
935                  */
936                 flash_sync_real_protect(info); /* resets flash to read  mode */
937         }
938
939         if (flag)
940                 enable_interrupts ();
941
942         *addr = INTEL_RESET;    /* Reset to read array mode */
943
944         return rc;
945 }