* Patch by Stephen Williams, 01 Apr 2004:
[oweals/u-boot.git] / board / jse / flash.c
1 /*
2  * (C) Copyright 2000-2004
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 /*
25  * Modified 4/5/2001
26  * Wait for completion of each sector erase command issued
27  * 4/5/2001
28  * Chris Hallinan - DS4.COM, Inc. - clh@net1plus.com
29  */
30
31 #include <common.h>
32 #include <ppc4xx.h>
33 #include <asm/processor.h>
34
35 #if CFG_MAX_FLASH_BANKS != 1
36 #error "CFG_MAX_FLASH_BANKS must be 1"
37 #endif
38 flash_info_t flash_info[CFG_MAX_FLASH_BANKS];   /* info for FLASH chips        */
39
40 /*-----------------------------------------------------------------------
41  * Functions
42  */
43 static ulong flash_get_size (vu_long * addr, flash_info_t * info);
44 static int write_word (flash_info_t * info, ulong dest, ulong data);
45 static void flash_get_offsets (ulong base, flash_info_t * info);
46
47 #define ADDR0           0x5555
48 #define ADDR1           0x2aaa
49 #define FLASH_WORD_SIZE unsigned char
50
51 /*-----------------------------------------------------------------------
52  */
53
54 unsigned long flash_init (void)
55 {
56         unsigned long size_b0;
57         unsigned long base_b0;
58
59         /* Init: no FLASHes known */
60         flash_info[0].flash_id = FLASH_UNKNOWN;
61
62         /* Static FLASH Bank configuration here - FIXME XXX */
63
64         size_b0 =
65                 flash_get_size ((vu_long *) FLASH_BASE0_PRELIM,
66                                 &flash_info[0]);
67
68         if (flash_info[0].flash_id == FLASH_UNKNOWN) {
69                 printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n", size_b0, size_b0 << 20);
70         }
71
72         /* Only one bank */
73         /* Setup offsets */
74         flash_get_offsets (FLASH_BASE0_PRELIM, &flash_info[0]);
75
76         /* Monitor protection ON by default */
77         (void) flash_protect (FLAG_PROTECT_SET,
78                               FLASH_BASE0_PRELIM,
79                               FLASH_BASE0_PRELIM + monitor_flash_len - 1,
80                               &flash_info[0]);
81         flash_info[0].size = size_b0;
82
83         return size_b0;
84 }
85
86
87 /*-----------------------------------------------------------------------
88  */
89 static void flash_get_offsets (ulong base, flash_info_t * info)
90 {
91         int i;
92
93         /* set up sector start address table */
94         if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
95             (info->flash_id == FLASH_AM040)) {
96                 for (i = 0; i < info->sector_count; i++)
97                         info->start[i] = base + (i * 0x00010000);
98         } else {
99                 if (info->flash_id & FLASH_BTYPE) {
100                         /* set sector offsets for bottom boot block type        */
101                         info->start[0] = base + 0x00000000;
102                         info->start[1] = base + 0x00004000;
103                         info->start[2] = base + 0x00006000;
104                         info->start[3] = base + 0x00008000;
105                         for (i = 4; i < info->sector_count; i++) {
106                                 info->start[i] =
107                                         base + (i * 0x00010000) - 0x00030000;
108                         }
109                 } else {
110                         /* set sector offsets for top boot block type           */
111                         i = info->sector_count - 1;
112                         info->start[i--] = base + info->size - 0x00004000;
113                         info->start[i--] = base + info->size - 0x00006000;
114                         info->start[i--] = base + info->size - 0x00008000;
115                         for (; i >= 0; i--) {
116                                 info->start[i] = base + i * 0x00010000;
117                         }
118                 }
119         }
120 }
121
122 /*-----------------------------------------------------------------------
123  */
124 void flash_print_info (flash_info_t * info)
125 {
126         int i;
127         int k;
128         int size;
129         int erased;
130         volatile unsigned long *flash;
131
132         if (info->flash_id == FLASH_UNKNOWN) {
133                 printf ("missing or unknown FLASH type\n");
134                 return;
135         }
136
137         switch (info->flash_id & FLASH_VENDMASK) {
138         case FLASH_MAN_AMD:
139                 printf ("AMD ");
140                 break;
141         case FLASH_MAN_FUJ:
142                 printf ("FUJITSU ");
143                 break;
144         case FLASH_MAN_SST:
145                 printf ("SST ");
146                 break;
147         default:
148                 printf ("Unknown Vendor ");
149                 break;
150         }
151
152         switch (info->flash_id & FLASH_TYPEMASK) {
153         case FLASH_AM040:
154                 printf ("AM29F040 (512 Kbit, uniform sector size)\n");
155                 break;
156         case FLASH_AM400B:
157                 printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
158                 break;
159         case FLASH_AM400T:
160                 printf ("AM29LV400T (4 Mbit, top boot sector)\n");
161                 break;
162         case FLASH_AM800B:
163                 printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
164                 break;
165         case FLASH_AM800T:
166                 printf ("AM29LV800T (8 Mbit, top boot sector)\n");
167                 break;
168         case FLASH_AM160B:
169                 printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
170                 break;
171         case FLASH_AM160T:
172                 printf ("AM29LV160T (16 Mbit, top boot sector)\n");
173                 break;
174         case FLASH_AM320B:
175                 printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
176                 break;
177         case FLASH_AM320T:
178                 printf ("AM29LV320T (32 Mbit, top boot sector)\n");
179                 break;
180         case FLASH_SST800A:
181                 printf ("SST39LF/VF800 (8 Mbit, uniform sector size)\n");
182                 break;
183         case FLASH_SST160A:
184                 printf ("SST39LF/VF160 (16 Mbit, uniform sector size)\n");
185                 break;
186         default:
187                 printf ("Unknown Chip Type\n");
188                 break;
189         }
190
191         printf ("  Size: %ld KB in %d Sectors\n",
192                 info->size >> 10, info->sector_count);
193
194         printf ("  Sector Start Addresses:");
195         for (i = 0; i < info->sector_count; ++i) {
196                 /*
197                  * Check if whole sector is erased
198                  */
199                 if (i != (info->sector_count - 1))
200                         size = info->start[i + 1] - info->start[i];
201                 else
202                         size = info->start[0] + info->size - info->start[i];
203                 erased = 1;
204                 flash = (volatile unsigned long *) info->start[i];
205                 size = size >> 2;       /* divide by 4 for longword access */
206                 for (k = 0; k < size; k++) {
207                         if (*flash++ != 0xffffffff) {
208                                 erased = 0;
209                                 break;
210                         }
211                 }
212
213                 if ((i % 5) == 0)
214                         printf ("\n   ");
215 #if 0                           /* test-only */
216                 printf (" %08lX%s",
217                         info->start[i], info->protect[i] ? " (RO)" : "     "
218 #else
219                 printf (" %08lX%s%s",
220                         info->start[i],
221                         erased ? " E" : "  ", info->protect[i] ? "RO " : "   "
222 #endif
223                         );
224         }
225         printf ("\n");
226         return;
227 }
228
229 /*-----------------------------------------------------------------------
230  */
231
232
233 /*-----------------------------------------------------------------------
234  */
235
236 /*
237  * The following code cannot be run from FLASH!
238  */
239 static ulong flash_get_size (vu_long * addr, flash_info_t * info)
240 {
241         short i;
242         FLASH_WORD_SIZE value;
243         ulong base = (ulong) addr;
244         volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *) addr;
245
246         /* Write auto select command: read Manufacturer ID */
247         addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
248         addr2[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
249         addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00900090;
250
251 #ifdef CONFIG_ADCIOP
252         value = addr2[2];
253 #else
254         value = addr2[0];
255 #endif
256
257         switch (value) {
258         case (FLASH_WORD_SIZE) AMD_MANUFACT:
259                 info->flash_id = FLASH_MAN_AMD;
260                 break;
261         case (FLASH_WORD_SIZE) FUJ_MANUFACT:
262                 info->flash_id = FLASH_MAN_FUJ;
263                 break;
264         case (FLASH_WORD_SIZE) SST_MANUFACT:
265                 info->flash_id = FLASH_MAN_SST;
266                 break;
267         default:
268                 info->flash_id = FLASH_UNKNOWN;
269                 info->sector_count = 0;
270                 info->size = 0;
271                 return (0);     /* no or unknown flash  */
272         }
273
274 #ifdef CONFIG_ADCIOP
275         value = addr2[0];       /* device ID            */
276         /*        printf("\ndev_code=%x\n", value); */
277 #else
278         value = addr2[1];       /* device ID            */
279 #endif
280
281         switch (value) {
282         case (FLASH_WORD_SIZE) AMD_ID_F040B:
283                 info->flash_id += FLASH_AM040;
284                 info->sector_count = 8;
285                 info->size = 0x0080000; /* => 512 ko */
286                 break;
287         case (FLASH_WORD_SIZE) AMD_ID_LV040B:
288                 info->flash_id += FLASH_AM040;
289                 info->sector_count = 8;
290                 info->size = 0x0080000; /* => 512 ko */
291                 break;
292         case (FLASH_WORD_SIZE) AMD_ID_LV400T:
293                 info->flash_id += FLASH_AM400T;
294                 info->sector_count = 11;
295                 info->size = 0x00080000;
296                 break;          /* => 0.5 MB            */
297
298         case (FLASH_WORD_SIZE) AMD_ID_LV400B:
299                 info->flash_id += FLASH_AM400B;
300                 info->sector_count = 11;
301                 info->size = 0x00080000;
302                 break;          /* => 0.5 MB            */
303
304         case (FLASH_WORD_SIZE) AMD_ID_LV800T:
305                 info->flash_id += FLASH_AM800T;
306                 info->sector_count = 19;
307                 info->size = 0x00100000;
308                 break;          /* => 1 MB              */
309
310         case (FLASH_WORD_SIZE) AMD_ID_LV800B:
311                 info->flash_id += FLASH_AM800B;
312                 info->sector_count = 19;
313                 info->size = 0x00100000;
314                 break;          /* => 1 MB              */
315
316         case (FLASH_WORD_SIZE) AMD_ID_LV160T:
317                 info->flash_id += FLASH_AM160T;
318                 info->sector_count = 35;
319                 info->size = 0x00200000;
320                 break;          /* => 2 MB              */
321
322         case (FLASH_WORD_SIZE) AMD_ID_LV160B:
323                 info->flash_id += FLASH_AM160B;
324                 info->sector_count = 35;
325                 info->size = 0x00200000;
326                 break;          /* => 2 MB              */
327 #if 0                           /* enable when device IDs are available */
328         case (FLASH_WORD_SIZE) AMD_ID_LV320T:
329                 info->flash_id += FLASH_AM320T;
330                 info->sector_count = 67;
331                 info->size = 0x00400000;
332                 break;          /* => 4 MB              */
333
334         case (FLASH_WORD_SIZE) AMD_ID_LV320B:
335                 info->flash_id += FLASH_AM320B;
336                 info->sector_count = 67;
337                 info->size = 0x00400000;
338                 break;          /* => 4 MB              */
339 #endif
340         case (FLASH_WORD_SIZE) SST_ID_xF800A:
341                 info->flash_id += FLASH_SST800A;
342                 info->sector_count = 16;
343                 info->size = 0x00100000;
344                 break;          /* => 1 MB              */
345
346         case (FLASH_WORD_SIZE) SST_ID_xF160A:
347                 info->flash_id += FLASH_SST160A;
348                 info->sector_count = 32;
349                 info->size = 0x00200000;
350                 break;          /* => 2 MB              */
351
352         default:
353                 info->flash_id = FLASH_UNKNOWN;
354                 return (0);     /* => no or unknown flash */
355
356         }
357
358         /* set up sector start address table */
359         if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
360             (info->flash_id == FLASH_AM040)) {
361                 for (i = 0; i < info->sector_count; i++)
362                         info->start[i] = base + (i * 0x00010000);
363         } else {
364                 if (info->flash_id & FLASH_BTYPE) {
365                         /* set sector offsets for bottom boot block type        */
366                         info->start[0] = base + 0x00000000;
367                         info->start[1] = base + 0x00004000;
368                         info->start[2] = base + 0x00006000;
369                         info->start[3] = base + 0x00008000;
370                         for (i = 4; i < info->sector_count; i++) {
371                                 info->start[i] =
372                                         base + (i * 0x00010000) - 0x00030000;
373                         }
374                 } else {
375                         /* set sector offsets for top boot block type           */
376                         i = info->sector_count - 1;
377                         info->start[i--] = base + info->size - 0x00004000;
378                         info->start[i--] = base + info->size - 0x00006000;
379                         info->start[i--] = base + info->size - 0x00008000;
380                         for (; i >= 0; i--) {
381                                 info->start[i] = base + i * 0x00010000;
382                         }
383                 }
384         }
385
386         /* check for protected sectors */
387         for (i = 0; i < info->sector_count; i++) {
388                 /* read sector protection at sector address, (A7 .. A0) = 0x02 */
389                 /* D0 = 1 if protected */
390 #ifdef CONFIG_ADCIOP
391                 addr2 = (volatile FLASH_WORD_SIZE *) (info->start[i]);
392                 info->protect[i] = addr2[4] & 1;
393 #else
394                 addr2 = (volatile FLASH_WORD_SIZE *) (info->start[i]);
395                 if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST)
396                         info->protect[i] = 0;
397                 else
398                         info->protect[i] = addr2[2] & 1;
399 #endif
400         }
401
402         /*
403          * Prevent writes to uninitialized FLASH.
404          */
405         if (info->flash_id != FLASH_UNKNOWN) {
406 #if 0                           /* test-only */
407 #ifdef CONFIG_ADCIOP
408                 addr2 = (volatile unsigned char *) info->start[0];
409                 addr2[ADDR0] = 0xAA;
410                 addr2[ADDR1] = 0x55;
411                 addr2[ADDR0] = 0xF0;    /* reset bank */
412 #else
413                 addr2 = (FLASH_WORD_SIZE *) info->start[0];
414                 *addr2 = (FLASH_WORD_SIZE) 0x00F000F0;  /* reset bank */
415 #endif
416 #else  /* test-only */
417                 addr2 = (FLASH_WORD_SIZE *) info->start[0];
418                 *addr2 = (FLASH_WORD_SIZE) 0x00F000F0;  /* reset bank */
419 #endif /* test-only */
420         }
421
422         return (info->size);
423 }
424
425 int wait_for_DQ7 (flash_info_t * info, int sect)
426 {
427         ulong start, now, last;
428         volatile FLASH_WORD_SIZE *addr =
429                 (FLASH_WORD_SIZE *) (info->start[sect]);
430
431         start = get_timer (0);
432         last = start;
433         while ((addr[0] & (FLASH_WORD_SIZE) 0x00800080) !=
434                (FLASH_WORD_SIZE) 0x00800080) {
435                 if ((now = get_timer (start)) > CFG_FLASH_ERASE_TOUT) {
436                         printf ("Timeout\n");
437                         return -1;
438                 }
439                 /* show that we're waiting */
440                 if ((now - last) > 1000) {      /* every second */
441                         putc ('.');
442                         last = now;
443                 }
444         }
445         return 0;
446 }
447
448 /*-----------------------------------------------------------------------
449  */
450
451 int flash_erase (flash_info_t * info, int s_first, int s_last)
452 {
453         volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *) (info->start[0]);
454         volatile FLASH_WORD_SIZE *addr2;
455         int flag, prot, sect, l_sect;
456         int i;
457
458         if ((s_first < 0) || (s_first > s_last)) {
459                 if (info->flash_id == FLASH_UNKNOWN) {
460                         printf ("- missing\n");
461                 } else {
462                         printf ("- no sectors to erase\n");
463                 }
464                 return 1;
465         }
466
467         if (info->flash_id == FLASH_UNKNOWN) {
468                 printf ("Can't erase unknown flash type - aborted\n");
469                 return 1;
470         }
471
472         prot = 0;
473         for (sect = s_first; sect <= s_last; ++sect) {
474                 if (info->protect[sect]) {
475                         prot++;
476                 }
477         }
478
479         if (prot) {
480                 printf ("- Warning: %d protected sectors will not be erased!\n", prot);
481         } else {
482                 printf ("\n");
483         }
484
485         l_sect = -1;
486
487         /* Disable interrupts which might cause a timeout here */
488         flag = disable_interrupts ();
489
490         /* Start erase on unprotected sectors */
491         for (sect = s_first; sect <= s_last; sect++) {
492                 if (info->protect[sect] == 0) { /* not protected */
493                         addr2 = (FLASH_WORD_SIZE *) (info->start[sect]);
494                         printf ("Erasing sector %p\n", addr2);  /* CLH */
495
496                         if ((info->flash_id & FLASH_VENDMASK) ==
497                             FLASH_MAN_SST) {
498                                 addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
499                                 addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
500                                 addr[ADDR0] = (FLASH_WORD_SIZE) 0x00800080;
501                                 addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
502                                 addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
503                                 addr2[0] = (FLASH_WORD_SIZE) 0x00500050;        /* block erase */
504                                 for (i = 0; i < 50; i++)
505                                         udelay (1000);  /* wait 1 ms */
506                         } else {
507                                 addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
508                                 addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
509                                 addr[ADDR0] = (FLASH_WORD_SIZE) 0x00800080;
510                                 addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
511                                 addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
512                                 addr2[0] = (FLASH_WORD_SIZE) 0x00300030;        /* sector erase */
513                         }
514                         l_sect = sect;
515                         /*
516                          * Wait for each sector to complete, it's more
517                          * reliable.  According to AMD Spec, you must
518                          * issue all erase commands within a specified
519                          * timeout.  This has been seen to fail, especially
520                          * if printf()s are included (for debug)!!
521                          */
522                         wait_for_DQ7 (info, sect);
523                 }
524         }
525
526         /* re-enable interrupts if necessary */
527         if (flag)
528                 enable_interrupts ();
529
530         /* wait at least 80us - let's wait 1 ms */
531         udelay (1000);
532
533 #if 0
534         /*
535          * We wait for the last triggered sector
536          */
537         if (l_sect < 0)
538                 goto DONE;
539         wait_for_DQ7 (info, l_sect);
540
541       DONE:
542 #endif
543         /* reset to read mode */
544         addr = (FLASH_WORD_SIZE *) info->start[0];
545         addr[0] = (FLASH_WORD_SIZE) 0x00F000F0; /* reset bank */
546
547         printf (" done\n");
548         return 0;
549 }
550
551 /*-----------------------------------------------------------------------
552  * Copy memory to flash, returns:
553  * 0 - OK
554  * 1 - write timeout
555  * 2 - Flash not erased
556  */
557
558 int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
559 {
560         ulong cp, wp, data;
561         int i, l, rc;
562
563         wp = (addr & ~3);       /* get lower word aligned address */
564
565         /*
566          * handle unaligned start bytes
567          */
568         if ((l = addr - wp) != 0) {
569                 data = 0;
570                 for (i = 0, cp = wp; i < l; ++i, ++cp) {
571                         data = (data << 8) | (*(uchar *) cp);
572                 }
573                 for (; i < 4 && cnt > 0; ++i) {
574                         data = (data << 8) | *src++;
575                         --cnt;
576                         ++cp;
577                 }
578                 for (; cnt == 0 && i < 4; ++i, ++cp) {
579                         data = (data << 8) | (*(uchar *) cp);
580                 }
581
582                 if ((rc = write_word (info, wp, data)) != 0) {
583                         return (rc);
584                 }
585                 wp += 4;
586         }
587
588         /*
589          * handle word aligned part
590          */
591         while (cnt >= 4) {
592                 data = 0;
593                 for (i = 0; i < 4; ++i) {
594                         data = (data << 8) | *src++;
595                 }
596                 if ((rc = write_word (info, wp, data)) != 0) {
597                         return (rc);
598                 }
599                 wp += 4;
600                 cnt -= 4;
601         }
602
603         if (cnt == 0) {
604                 return (0);
605         }
606
607         /*
608          * handle unaligned tail bytes
609          */
610         data = 0;
611         for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
612                 data = (data << 8) | *src++;
613                 --cnt;
614         }
615         for (; i < 4; ++i, ++cp) {
616                 data = (data << 8) | (*(uchar *) cp);
617         }
618
619         return (write_word (info, wp, data));
620 }
621
622 /*-----------------------------------------------------------------------
623  * Write a word to Flash, returns:
624  * 0 - OK
625  * 1 - write timeout
626  * 2 - Flash not erased
627  */
628 static int write_word (flash_info_t * info, ulong dest, ulong data)
629 {
630         volatile FLASH_WORD_SIZE *addr2 =
631                 (FLASH_WORD_SIZE *) (info->start[0]);
632         volatile FLASH_WORD_SIZE *dest2 = (FLASH_WORD_SIZE *) dest;
633         volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *) & data;
634         ulong start;
635         int i;
636
637         /* Check if Flash is (sufficiently) erased */
638         if ((*((volatile FLASH_WORD_SIZE *) dest) &
639              (FLASH_WORD_SIZE) data) != (FLASH_WORD_SIZE) data) {
640                 return (2);
641         }
642
643         for (i = 0; i < 4 / sizeof (FLASH_WORD_SIZE); i++) {
644                 int flag;
645
646                 /* Disable interrupts which might cause a timeout here */
647                 flag = disable_interrupts ();
648
649                 addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
650                 addr2[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
651                 addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00A000A0;
652
653                 dest2[i] = data2[i];
654
655                 /* re-enable interrupts if necessary */
656                 if (flag)
657                         enable_interrupts ();
658
659                 /* data polling for D7 */
660                 start = get_timer (0);
661                 while ((dest2[i] & (FLASH_WORD_SIZE) 0x00800080) !=
662                        (data2[i] & (FLASH_WORD_SIZE) 0x00800080)) {
663
664                         if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
665                                 return (1);
666                         }
667                 }
668         }
669
670         return (0);
671 }