* Patch by Dave Peverley, 30 Apr 2004:
[platform/kernel/u-boot.git] / board / ocotea / flash.c
1 /*
2  * (C) Copyright 2004
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * (C) Copyright 2002 Jun Gu <jung@artesyncp.com>
6  * Add support for Am29F016D and dynamic switch setting.
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 /*
28  * Modified 4/5/2001
29  * Wait for completion of each sector erase command issued
30  * 4/5/2001
31  * Chris Hallinan - DS4.COM, Inc. - clh@net1plus.com
32  */
33
34 #include <common.h>
35 #include <ppc4xx.h>
36 #include <asm/processor.h>
37
38 #undef DEBUG
39
40 #ifdef DEBUG
41 #define DEBUGF(x...) printf(x)
42 #else
43 #define DEBUGF(x...)
44 #endif                          /* DEBUG */
45
46 #define     BOOT_SMALL_FLASH        32  /* 00100000 */
47 #define     FLASH_ONBD_N            2   /* 00000010 */
48 #define     FLASH_SRAM_SEL          1   /* 00000001 */
49
50 #define     BOOT_SMALL_FLASH_VAL    4
51 #define     FLASH_ONBD_N_VAL        2
52 #define     FLASH_SRAM_SEL_VAL      1
53
54
55 flash_info_t flash_info[CFG_MAX_FLASH_BANKS];   /* info for FLASH chips        */
56
57 static unsigned long flash_addr_table[8][CFG_MAX_FLASH_BANKS] = {
58         {0xFF800000, 0xFF900000, 0xFFC00000},   /* 0:000: configuraton 4 */
59         {0xFF900000, 0xFF800000, 0xFFC00000},   /* 1:001: configuraton 3 */
60         {0x00000000, 0x00000000, 0x00000000},   /* 2:010: configuraton 8 */
61         {0x00000000, 0x00000000, 0x00000000},   /* 3:011: configuraton 7 */
62         {0xFFE00000, 0xFFF00000, 0xFF800000},   /* 4:100: configuraton 2 */
63         {0xFFF00000, 0xFFF80000, 0xFF800000},   /* 5:101: configuraton 1 */
64         {0x00000000, 0x00000000, 0x00000000},   /* 6:110: configuraton 6 */
65         {0x00000000, 0x00000000, 0x00000000}    /* 7:111: configuraton 5 */
66 };
67
68 /*-----------------------------------------------------------------------
69  * Functions
70  */
71 static ulong flash_get_size(vu_long * addr, flash_info_t * info);
72 static int write_word(flash_info_t * info, ulong dest, ulong data);
73
74
75 #ifdef CONFIG_OCOTEA
76 #define ADDR0           0x5555
77 #define ADDR1           0x2aaa
78 #define FLASH_WORD_SIZE unsigned char
79 #endif
80
81 /*-----------------------------------------------------------------------
82  */
83
84 unsigned long flash_init(void)
85 {
86         unsigned long total_b = 0;
87         unsigned long size_b[CFG_MAX_FLASH_BANKS];
88         unsigned char *fpga_base = (unsigned char *) CFG_FPGA_BASE;
89         unsigned char switch_status;
90         unsigned short index = 0;
91         int i;
92
93         /* read FPGA base register FPGA_REG0 */
94         switch_status = *fpga_base;
95
96         /* check the bitmap of switch status */
97         if (switch_status & BOOT_SMALL_FLASH) {
98                 index += BOOT_SMALL_FLASH_VAL;
99         }
100         if (switch_status & FLASH_ONBD_N) {
101                 index += FLASH_ONBD_N_VAL;
102         }
103         if (switch_status & FLASH_SRAM_SEL) {
104                 index += FLASH_SRAM_SEL_VAL;
105         }
106
107         DEBUGF("\n");
108         DEBUGF("FLASH: Index: %d\n", index);
109
110         /* Init: no FLASHes known */
111         for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
112                 flash_info[i].flash_id = FLASH_UNKNOWN;
113                 flash_info[i].sector_count = -1;
114                 flash_info[i].size = 0;
115
116                 /* check whether the address is 0 */
117                 if (flash_addr_table[index][i] == 0) {
118                         continue;
119                 }
120
121                 /* call flash_get_size() to initialize sector address */
122                 size_b[i] = flash_get_size((vu_long *) flash_addr_table[index][i], &flash_info[i]);
123                 flash_info[i].size = size_b[i];
124                 if (flash_info[i].flash_id == FLASH_UNKNOWN) {
125                         printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n",
126                                 i, size_b[i], size_b[i] << 20);
127                         flash_info[i].sector_count = -1;
128                         flash_info[i].size = 0;
129                 }
130
131                 total_b += flash_info[i].size;
132         }
133
134         return total_b;
135 }
136
137 /*-----------------------------------------------------------------------
138  */
139 void flash_print_info(flash_info_t * info)
140 {
141         int i;
142         int k;
143         int size;
144         int erased;
145         volatile unsigned long *flash;
146
147         if (info->flash_id == FLASH_UNKNOWN) {
148                 printf("missing or unknown FLASH type\n");
149                 return;
150         }
151
152         switch (info->flash_id & FLASH_VENDMASK) {
153         case FLASH_MAN_AMD:
154                 printf("AMD ");
155                 break;
156         case FLASH_MAN_FUJ:
157                 printf("FUJITSU ");
158                 break;
159         case FLASH_MAN_SST:
160                 printf("SST ");
161                 break;
162         default:
163                 printf("Unknown Vendor ");
164                 break;
165         }
166
167         switch (info->flash_id & FLASH_TYPEMASK) {
168         case FLASH_AM040:
169                 printf("AM29F040 (512 Kbit, uniform sector size)\n");
170                 break;
171         case FLASH_AM400B:
172                 printf("AM29LV400B (4 Mbit, bottom boot sect)\n");
173                 break;
174         case FLASH_AM400T:
175                 printf("AM29LV400T (4 Mbit, top boot sector)\n");
176                 break;
177         case FLASH_AM800B:
178                 printf("AM29LV800B (8 Mbit, bottom boot sect)\n");
179                 break;
180         case FLASH_AM800T:
181                 printf("AM29LV800T (8 Mbit, top boot sector)\n");
182                 break;
183         case FLASH_AM160B:
184                 printf("AM29LV160B (16 Mbit, bottom boot sect)\n");
185                 break;
186         case FLASH_AM160T:
187                 printf("AM29LV160T (16 Mbit, top boot sector)\n");
188                 break;
189         case FLASH_AM320B:
190                 printf("AM29LV320B (32 Mbit, bottom boot sect)\n");
191                 break;
192         case FLASH_AM320T:
193                 printf("AM29LV320T (32 Mbit, top boot sector)\n");
194                 break;
195         case FLASH_AMDLV033C:
196                 printf("AM29LV033C (32 Mbit, top boot sector)\n");
197                 break;
198         case FLASH_SST800A:
199                 printf("SST39LF/VF800 (8 Mbit, uniform sector size)\n");
200                 break;
201         case FLASH_SST160A:
202                 printf("SST39LF/VF160 (16 Mbit, uniform sector size)\n");
203                 break;
204         default:
205                 printf("Unknown Chip Type\n");
206                 break;
207         }
208
209         printf("  Size: %ld KB in %d Sectors\n",
210                info->size >> 10, info->sector_count);
211
212         printf("  Sector Start Addresses:");
213         for (i = 0; i < info->sector_count; ++i) {
214                 /*
215                  * Check if whole sector is erased
216                  */
217                 if (i != (info->sector_count - 1))
218                         size = info->start[i + 1] - info->start[i];
219                 else
220                         size = info->start[0] + info->size - info->start[i];
221                 erased = 1;
222                 flash = (volatile unsigned long *) info->start[i];
223                 size = size >> 2;       /* divide by 4 for longword access */
224                 for (k = 0; k < size; k++) {
225                         if (*flash++ != 0xffffffff) {
226                                 erased = 0;
227                                 break;
228                         }
229                 }
230
231                 if ((i % 5) == 0)
232                         printf("\n   ");
233                 printf(" %08lX%s%s",
234                        info->start[i],
235                        erased ? " E" : "  ", info->protect[i] ? "RO " : "   ");
236         }
237         printf("\n");
238         return;
239 }
240
241 /*-----------------------------------------------------------------------
242  */
243
244 /*
245  * The following code cannot be run from FLASH!
246  */
247 static ulong flash_get_size(vu_long * addr, flash_info_t * info)
248 {
249         short i;
250         FLASH_WORD_SIZE value;
251         ulong base = (ulong) addr;
252         volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *) addr;
253
254         DEBUGF("FLASH ADDR: %08x\n", (unsigned) addr);
255
256         /* Write auto select command: read Manufacturer ID */
257         udelay(10000);
258         addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
259         udelay(1000);
260         addr2[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
261         udelay(1000);
262         addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00900090;
263         udelay(1000);
264
265         value = addr2[0];
266         DEBUGF("FLASH MANUFACT: %x\n", value);
267
268         switch (value) {
269         case (FLASH_WORD_SIZE) AMD_MANUFACT:
270                 info->flash_id = FLASH_MAN_AMD;
271                 break;
272         case (FLASH_WORD_SIZE) FUJ_MANUFACT:
273                 info->flash_id = FLASH_MAN_FUJ;
274                 break;
275         case (FLASH_WORD_SIZE) SST_MANUFACT:
276                 info->flash_id = FLASH_MAN_SST;
277                 break;
278         case (FLASH_WORD_SIZE) STM_MANUFACT:
279                 info->flash_id = FLASH_MAN_STM;
280                 break;
281         default:
282                 info->flash_id = FLASH_UNKNOWN;
283                 info->sector_count = 0;
284                 info->size = 0;
285                 return (0);             /* no or unknown flash  */
286         }
287
288         value = addr2[1];               /* device ID            */
289
290         DEBUGF("\nFLASH DEVICEID: %x\n", value);
291
292         switch (value) {
293         case (FLASH_WORD_SIZE) AMD_ID_LV040B:
294                 info->flash_id += FLASH_AM040;
295                 info->sector_count = 8;
296                 info->size = 0x0080000; /* => 512 ko */
297                 break;
298         case (FLASH_WORD_SIZE) AMD_ID_F040B:
299                 info->flash_id += FLASH_AM040;
300                 info->sector_count = 8;
301                 info->size = 0x0080000; /* => 512 ko */
302                 break;
303         case (FLASH_WORD_SIZE) AMD_ID_LV033C:
304                 info->flash_id += FLASH_AMDLV033C;
305                 info->sector_count = 64;
306                 info->size = 0x00400000;
307                 break;                  /* => 4 MB              */
308         default:
309                 info->flash_id = FLASH_UNKNOWN;
310                 return (0);             /* => no or unknown flash */
311         }
312
313         /* set up sector start address table */
314         if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
315             (info->flash_id == FLASH_AM040) ||
316             (info->flash_id == FLASH_AMD016)) {
317                 for (i = 0; i < info->sector_count; i++)
318                         info->start[i] = base + (i * 0x00010000);
319         } else {
320                 if (info->flash_id & FLASH_BTYPE) {
321                         /* set sector offsets for bottom boot block type        */
322                         info->start[0] = base + 0x00000000;
323                         info->start[1] = base + 0x00004000;
324                         info->start[2] = base + 0x00006000;
325                         info->start[3] = base + 0x00008000;
326                         for (i = 4; i < info->sector_count; i++) {
327                                 info->start[i] = base + (i * 0x00010000) - 0x00030000;
328                         }
329                 } else {
330                         /* set sector offsets for top boot block type           */
331                         i = info->sector_count - 1;
332                         info->start[i--] = base + info->size - 0x00004000;
333                         info->start[i--] = base + info->size - 0x00006000;
334                         info->start[i--] = base + info->size - 0x00008000;
335                         for (; i >= 0; i--) {
336                                 info->start[i] = base + i * 0x00010000;
337                         }
338                 }
339         }
340
341         /* check for protected sectors */
342         for (i = 0; i < info->sector_count; i++) {
343                 /* read sector protection at sector address, (A7 .. A0) = 0x02 */
344                 /* D0 = 1 if protected */
345                 addr2 = (volatile FLASH_WORD_SIZE *) (info->start[i]);
346                 if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST)
347                         info->protect[i] = 0;
348                 else
349                         info->protect[i] = addr2[2] & 1;
350         }
351
352         /* issue bank reset to return to read mode */
353         addr2[0] = (FLASH_WORD_SIZE) 0x00F000F0;
354
355         /*
356          * Prevent writes to uninitialized FLASH.
357          */
358         if (info->flash_id != FLASH_UNKNOWN) {
359                 /* ? ? ? */
360         }
361
362         return (info->size);
363 }
364
365 int wait_for_DQ7(flash_info_t * info, int sect)
366 {
367         ulong start, now, last;
368         volatile FLASH_WORD_SIZE *addr =
369                 (FLASH_WORD_SIZE *) (info->start[sect]);
370
371         start = get_timer(0);
372         last = start;
373         while ((addr[0] & (FLASH_WORD_SIZE) 0x00800080) !=
374                (FLASH_WORD_SIZE) 0x00800080) {
375                 if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
376                         printf("Timeout\n");
377                         return -1;
378                 }
379                 /* show that we're waiting */
380                 if ((now - last) > 1000) {      /* every second */
381                         putc('.');
382                         last = now;
383                 }
384         }
385         return 0;
386 }
387
388 /*-----------------------------------------------------------------------
389  */
390
391 int flash_erase(flash_info_t * info, int s_first, int s_last)
392 {
393         volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *) (info->start[0]);
394         volatile FLASH_WORD_SIZE *addr2;
395         int flag, prot, sect, l_sect;
396         int i;
397
398         if ((s_first < 0) || (s_first > s_last)) {
399                 if (info->flash_id == FLASH_UNKNOWN) {
400                         printf("- missing\n");
401                 } else {
402                         printf("- no sectors to erase\n");
403                 }
404                 return 1;
405         }
406
407         if (info->flash_id == FLASH_UNKNOWN) {
408                 printf("Can't erase unknown flash type - aborted\n");
409                 return 1;
410         }
411
412         prot = 0;
413         for (sect = s_first; sect <= s_last; ++sect) {
414                 if (info->protect[sect]) {
415                         prot++;
416                 }
417         }
418
419         if (prot) {
420                 printf("- Warning: %d protected sectors will not be erased!\n",
421                        prot);
422         } else {
423                 printf("\n");
424         }
425
426         l_sect = -1;
427
428         /* Disable interrupts which might cause a timeout here */
429         flag = disable_interrupts();
430
431         /* Start erase on unprotected sectors */
432         for (sect = s_first; sect <= s_last; sect++) {
433                 if (info->protect[sect] == 0) { /* not protected */
434                         addr2 = (FLASH_WORD_SIZE *) (info->start[sect]);
435                         printf("Erasing sector %p\n", addr2);
436
437                         if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) {
438                                 addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
439                                 addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
440                                 addr[ADDR0] = (FLASH_WORD_SIZE) 0x00800080;
441                                 addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
442                                 addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
443                                 addr2[0] = (FLASH_WORD_SIZE) 0x00500050;        /* block erase */
444                                 for (i = 0; i < 50; i++)
445                                         udelay(1000);   /* wait 1 ms */
446                         } else {
447                                 addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
448                                 addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
449                                 addr[ADDR0] = (FLASH_WORD_SIZE) 0x00800080;
450                                 addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
451                                 addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
452                                 addr2[0] = (FLASH_WORD_SIZE) 0x00300030;        /* sector erase */
453                         }
454                         l_sect = sect;
455                         /*
456                          * Wait for each sector to complete, it's more
457                          * reliable.  According to AMD Spec, you must
458                          * issue all erase commands within a specified
459                          * timeout.  This has been seen to fail, especially
460                          * if printf()s are included (for debug)!!
461                          */
462                         wait_for_DQ7(info, sect);
463                 }
464         }
465
466         /* re-enable interrupts if necessary */
467         if (flag)
468                 enable_interrupts();
469
470         /* wait at least 80us - let's wait 1 ms */
471         udelay(1000);
472
473         /* reset to read mode */
474         addr = (FLASH_WORD_SIZE *) info->start[0];
475         addr[0] = (FLASH_WORD_SIZE) 0x00F000F0; /* reset bank */
476
477         printf(" done\n");
478         return 0;
479 }
480
481 /*-----------------------------------------------------------------------
482  * Copy memory to flash, returns:
483  * 0 - OK
484  * 1 - write timeout
485  * 2 - Flash not erased
486  */
487 int write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt)
488 {
489         ulong cp, wp, data;
490         int i, l, rc;
491
492         wp = (addr & ~3);               /* get lower word aligned address */
493
494         /*
495          * handle unaligned start bytes
496          */
497         if ((l = addr - wp) != 0) {
498                 data = 0;
499             for (i = 0, cp = wp; i < l; ++i, ++cp) {
500                     data = (data << 8) | (*(uchar *) cp);
501             }
502             for (; i < 4 && cnt > 0; ++i) {
503                     data = (data << 8) | *src++;
504                     --cnt;
505                     ++cp;
506             }
507             for (; cnt == 0 && i < 4; ++i, ++cp) {
508                     data = (data << 8) | (*(uchar *) cp);
509             }
510
511             if ((rc = write_word(info, wp, data)) != 0) {
512                     return (rc);
513             }
514             wp += 4;
515         }
516
517         /*
518          * handle word aligned part
519          */
520         while (cnt >= 4) {
521                 data = 0;
522                 for (i = 0; i < 4; ++i) {
523                         data = (data << 8) | *src++;
524                 }
525                 if ((rc = write_word(info, wp, data)) != 0) {
526                         return (rc);
527                 }
528                 wp += 4;
529                 cnt -= 4;
530         }
531
532         if (cnt == 0) {
533                 return (0);
534         }
535
536         /*
537          * handle unaligned tail bytes
538          */
539         data = 0;
540         for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
541                 data = (data << 8) | *src++;
542                 --cnt;
543         }
544         for (; i < 4; ++i, ++cp) {
545                 data = (data << 8) | (*(uchar *) cp);
546         }
547
548         return (write_word(info, wp, data));
549 }
550
551 /*-----------------------------------------------------------------------
552  * Write a word to Flash, returns:
553  * 0 - OK
554  * 1 - write timeout
555  * 2 - Flash not erased
556  */
557 static int write_word(flash_info_t * info, ulong dest, ulong data)
558 {
559         volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *) (info->start[0]);
560         volatile FLASH_WORD_SIZE *dest2 = (FLASH_WORD_SIZE *) dest;
561         volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *) & data;
562         ulong start;
563         int i;
564
565         /* Check if Flash is (sufficiently) erased */
566         if ((*((volatile FLASH_WORD_SIZE *) dest) &
567              (FLASH_WORD_SIZE) data) != (FLASH_WORD_SIZE) data) {
568                 return (2);
569         }
570
571         for (i = 0; i < 4 / sizeof(FLASH_WORD_SIZE); i++) {
572                 int flag;
573
574                 /* Disable interrupts which might cause a timeout here */
575                 flag = disable_interrupts();
576
577                 addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
578                 addr2[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
579                 addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00A000A0;
580
581                 dest2[i] = data2[i];
582
583                 /* re-enable interrupts if necessary */
584                 if (flag)
585                         enable_interrupts();
586
587                 /* data polling for D7 */
588                 start = get_timer(0);
589                 while ((dest2[i] & (FLASH_WORD_SIZE) 0x00800080) !=
590                        (data2[i] & (FLASH_WORD_SIZE) 0x00800080)) {
591
592                         if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
593                                 return (1);
594                         }
595                 }
596         }
597
598         return (0);
599 }