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