]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/atc/flash.c
* Add support for Promess ATC board
[karo-tx-uboot.git] / board / atc / flash.c
1 /*
2  * (C) Copyright 2003
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 #include <common.h>
25
26 flash_info_t    flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips        */
27
28 /* NOTE - CONFIG_FLASH_16BIT means the CPU interface is 16-bit, it
29  *        has nothing to do with the flash chip being 8-bit or 16-bit.
30  */
31 #ifdef CONFIG_FLASH_16BIT
32 typedef unsigned short FLASH_PORT_WIDTH;
33 typedef volatile unsigned short FLASH_PORT_WIDTHV;
34 #define FLASH_ID_MASK   0xFFFF
35 #else
36 typedef unsigned long FLASH_PORT_WIDTH;
37 typedef volatile unsigned long FLASH_PORT_WIDTHV;
38 #define FLASH_ID_MASK   0xFFFFFFFF
39 #endif
40
41 #define FPW     FLASH_PORT_WIDTH
42 #define FPWV    FLASH_PORT_WIDTHV
43
44 #define ORMASK(size) ((-size) & OR_AM_MSK)
45
46 #define FLASH_CYCLE1    0x0555
47 #define FLASH_CYCLE2    0x02aa
48
49 /*-----------------------------------------------------------------------
50  * Functions
51  */
52 static ulong flash_get_size(FPWV *addr, flash_info_t *info);
53 static void flash_reset(flash_info_t *info);
54 static int write_word_intel(flash_info_t *info, FPWV *dest, FPW data);
55 static int write_word_amd(flash_info_t *info, FPWV *dest, FPW data);
56 static void flash_get_offsets(ulong base, flash_info_t *info);
57 static flash_info_t *flash_get_info(ulong base);
58
59 /*-----------------------------------------------------------------------
60  * flash_init()
61  *
62  * sets up flash_info and returns size of FLASH (bytes)
63  */
64 unsigned long flash_init (void)
65 {
66         unsigned long size = 0;
67         int i;
68
69         /* Init: no FLASHes known */
70         for (i=0; i < CFG_MAX_FLASH_BANKS; ++i) {
71 #if 0
72                 ulong flashbase = (i == 0) ? PHYS_FLASH_1 : PHYS_FLASH_2;
73 #else
74                 ulong flashbase = CFG_FLASH_BASE;
75 #endif
76
77                 memset(&flash_info[i], 0, sizeof(flash_info_t));
78
79                 flash_info[i].size = 
80                         flash_get_size((FPW *)flashbase, &flash_info[i]);
81
82                 if (flash_info[i].flash_id == FLASH_UNKNOWN) {
83                         printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx\n",
84                         i, flash_info[i].size);
85                 }
86                 
87                 size += flash_info[i].size;
88         }
89
90 #if CFG_MONITOR_BASE >= CFG_FLASH_BASE
91         /* monitor protection ON by default */
92         flash_protect(FLAG_PROTECT_SET,
93                       CFG_MONITOR_BASE,
94                       CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
95                       flash_get_info(CFG_MONITOR_BASE));
96 #endif
97
98 #ifdef  CFG_ENV_IS_IN_FLASH
99         /* ENV protection ON by default */
100         flash_protect(FLAG_PROTECT_SET,
101                       CFG_ENV_ADDR,
102                       CFG_ENV_ADDR+CFG_ENV_SIZE-1,
103                       flash_get_info(CFG_ENV_ADDR));
104 #endif
105
106
107         return size ? size : 1;
108 }
109
110 /*-----------------------------------------------------------------------
111  */
112 static void flash_reset(flash_info_t *info)
113 {
114         FPWV *base = (FPWV *)(info->start[0]);
115
116         /* Put FLASH back in read mode */
117         if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL)
118                 *base = (FPW)0x00FF00FF;        /* Intel Read Mode */
119         else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD)
120                 *base = (FPW)0x00F000F0;        /* AMD Read Mode */
121 }
122
123 /*-----------------------------------------------------------------------
124  */
125 static void flash_get_offsets (ulong base, flash_info_t *info)
126 {
127         int i;
128
129         /* set up sector start address table */
130         if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL
131             && (info->flash_id & FLASH_BTYPE)) {
132                 int bootsect_size;      /* number of bytes/boot sector  */
133                 int sect_size;          /* number of bytes/regular sector */
134
135                 bootsect_size = 0x00002000 * (sizeof(FPW)/2);
136                 sect_size =     0x00010000 * (sizeof(FPW)/2);
137
138                 /* set sector offsets for bottom boot block type        */
139                 for (i = 0; i < 8; ++i) {
140                         info->start[i] = base + (i * bootsect_size);
141                 }
142                 for (i = 8; i < info->sector_count; i++) {
143                         info->start[i] = base + ((i - 7) * sect_size);
144                 }
145         }
146         else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD
147                  && (info->flash_id & FLASH_TYPEMASK) == FLASH_AM640U) {
148
149                 int sect_size;          /* number of bytes/sector */
150
151                 sect_size = 0x00010000 * (sizeof(FPW)/2);
152
153                 /* set up sector start address table (uniform sector type) */
154                 for( i = 0; i < info->sector_count; i++ )
155                         info->start[i] = base + (i * sect_size);
156         }
157 }
158
159 /*-----------------------------------------------------------------------
160  */
161
162 static flash_info_t *flash_get_info(ulong base)
163 {
164         int i;
165         flash_info_t * info;
166         
167         for (i = 0; i < CFG_MAX_FLASH_BANKS; i ++) {
168                 info = & flash_info[i];
169                 if (info->start[0] <= base && base < info->start[0] + info->size)
170                         break;
171         }
172         
173         return i == CFG_MAX_FLASH_BANKS ? 0 : info;
174 }
175
176 /*-----------------------------------------------------------------------
177  */
178
179 void flash_print_info (flash_info_t *info)
180 {
181         int i;
182         uchar *boottype;
183         uchar *bootletter;
184         uchar *fmt;
185         uchar botbootletter[] = "B";
186         uchar topbootletter[] = "T";
187         uchar botboottype[] = "bottom boot sector";
188         uchar topboottype[] = "top boot sector";
189
190         if (info->flash_id == FLASH_UNKNOWN) {
191                 printf ("missing or unknown FLASH type\n");
192                 return;
193         }
194
195         switch (info->flash_id & FLASH_VENDMASK) {
196         case FLASH_MAN_AMD:     printf ("AMD ");                break;
197         case FLASH_MAN_BM:      printf ("BRIGHT MICRO ");       break;
198         case FLASH_MAN_FUJ:     printf ("FUJITSU ");            break;
199         case FLASH_MAN_SST:     printf ("SST ");                break;
200         case FLASH_MAN_STM:     printf ("STM ");                break;
201         case FLASH_MAN_INTEL:   printf ("INTEL ");              break;
202         default:                printf ("Unknown Vendor ");     break;
203         }
204
205         /* check for top or bottom boot, if it applies */
206         if (info->flash_id & FLASH_BTYPE) {
207                 boottype = botboottype;
208                 bootletter = botbootletter;
209         }
210         else {
211                 boottype = topboottype;
212                 bootletter = topbootletter;
213         }
214
215         switch (info->flash_id & FLASH_TYPEMASK) {
216         case FLASH_AM640U:
217                 fmt = "29LV641D (64 Mbit, uniform sectors)\n";
218                 break;
219         case FLASH_28F800C3B:
220         case FLASH_28F800C3T:
221                 fmt = "28F800C3%s (8 Mbit, %s)\n";
222                 break;
223         case FLASH_INTEL800B:
224         case FLASH_INTEL800T:
225                 fmt = "28F800B3%s (8 Mbit, %s)\n";
226                 break;
227         case FLASH_28F160C3B:
228         case FLASH_28F160C3T:
229                 fmt = "28F160C3%s (16 Mbit, %s)\n";
230                 break;
231         case FLASH_INTEL160B:
232         case FLASH_INTEL160T:
233                 fmt = "28F160B3%s (16 Mbit, %s)\n";
234                 break;
235         case FLASH_28F320C3B:
236         case FLASH_28F320C3T:
237                 fmt = "28F320C3%s (32 Mbit, %s)\n";
238                 break;
239         case FLASH_INTEL320B:
240         case FLASH_INTEL320T:
241                 fmt = "28F320B3%s (32 Mbit, %s)\n";
242                 break;
243         case FLASH_28F640C3B:
244         case FLASH_28F640C3T:
245                 fmt = "28F640C3%s (64 Mbit, %s)\n";
246                 break;
247         case FLASH_INTEL640B:
248         case FLASH_INTEL640T:
249                 fmt = "28F640B3%s (64 Mbit, %s)\n";
250                 break;
251         default:
252                 fmt = "Unknown Chip Type\n";
253                 break;
254         }
255
256         printf (fmt, bootletter, boottype);
257
258         printf ("  Size: %ld MB in %d Sectors\n",
259                 info->size >> 20,
260                 info->sector_count);
261
262         printf ("  Sector Start Addresses:");
263
264         for (i=0; i<info->sector_count; ++i) {
265                 if ((i % 5) == 0) {
266                         printf ("\n   ");
267                 }
268
269                 printf (" %08lX%s", info->start[i],
270                         info->protect[i] ? " (RO)" : "     ");
271         }
272
273         printf ("\n");
274 }
275
276 /*-----------------------------------------------------------------------
277  */
278
279 /*
280  * The following code cannot be run from FLASH!
281  */
282
283 ulong flash_get_size (FPWV *addr, flash_info_t *info)
284 {
285         /* Write auto select command: read Manufacturer ID */
286
287         /* Write auto select command sequence and test FLASH answer */
288         addr[FLASH_CYCLE1] = (FPW)0x00AA00AA;   /* for AMD, Intel ignores this */
289         addr[FLASH_CYCLE2] = (FPW)0x00550055;   /* for AMD, Intel ignores this */
290         addr[FLASH_CYCLE1] = (FPW)0x00900090;   /* selects Intel or AMD */
291
292         /* The manufacturer codes are only 1 byte, so just use 1 byte.
293          * This works for any bus width and any FLASH device width.
294          */
295         udelay(1000000);//psl
296         //psl   switch (addr[1] & 0xff) {
297         switch (addr[0] & 0xff) {//psl
298
299         case (uchar)AMD_MANUFACT:
300                 info->flash_id = FLASH_MAN_AMD;
301                 break;
302
303         case (uchar)INTEL_MANUFACT:
304                 info->flash_id = FLASH_MAN_INTEL;
305                 break;
306
307         default:
308                 info->flash_id = FLASH_UNKNOWN;
309                 info->sector_count = 0;
310                 info->size = 0;
311                 break;
312         }
313
314         /* Check 16 bits or 32 bits of ID so work on 32 or 16 bit bus. */
315         //psl   if (info->flash_id != FLASH_UNKNOWN) switch (addr[0]) {
316         if (info->flash_id != FLASH_UNKNOWN) switch (addr[1]) {
317
318         case (FPW)AMD_ID_LV640U:        /* 29LV640 and 29LV641 have same ID */
319                 info->flash_id += FLASH_AM640U;
320                 info->sector_count = 128;
321                 info->size = 0x00800000 * (sizeof(FPW)/2);
322                 break;                          /* => 8 or 16 MB        */
323
324         case (FPW)INTEL_ID_28F800C3B:
325                 info->flash_id += FLASH_28F800C3B;
326                 info->sector_count = 23;
327                 info->size = 0x00100000 * (sizeof(FPW)/2);
328                 break;                          /* => 1 or 2 MB         */
329
330         case (FPW)INTEL_ID_28F800B3B:
331                 info->flash_id += FLASH_INTEL800B;
332                 info->sector_count = 23;
333                 info->size = 0x00100000 * (sizeof(FPW)/2);
334                 break;                          /* => 1 or 2 MB         */
335
336         case (FPW)INTEL_ID_28F160C3B:
337                 info->flash_id += FLASH_28F160C3B;
338                 info->sector_count = 39;
339                 info->size = 0x00200000 * (sizeof(FPW)/2);
340                 break;                          /* => 2 or 4 MB         */
341
342         case (FPW)INTEL_ID_28F160B3B:
343                 info->flash_id += FLASH_INTEL160B;
344                 info->sector_count = 39;
345                 info->size = 0x00200000 * (sizeof(FPW)/2);
346                 break;                          /* => 2 or 4 MB         */
347
348         case (FPW)INTEL_ID_28F320C3B:
349                 info->flash_id += FLASH_28F320C3B;
350                 info->sector_count = 71;
351                 info->size = 0x00400000 * (sizeof(FPW)/2);
352                 break;                          /* => 4 or 8 MB         */
353
354         case (FPW)INTEL_ID_28F320B3B:
355                 info->flash_id += FLASH_INTEL320B;
356                 info->sector_count = 71;
357                 info->size = 0x00400000 * (sizeof(FPW)/2);
358                 break;                          /* => 4 or 8 MB         */
359
360         case (FPW)INTEL_ID_28F640C3B:
361                 info->flash_id += FLASH_28F640C3B;
362                 info->sector_count = 135;
363                 info->size = 0x00800000 * (sizeof(FPW)/2);
364                 break;                          /* => 8 or 16 MB        */
365
366         case (FPW)INTEL_ID_28F640B3B:
367                 info->flash_id += FLASH_INTEL640B;
368                 info->sector_count = 135;
369                 info->size = 0x00800000 * (sizeof(FPW)/2);
370                 break;                          /* => 8 or 16 MB        */
371
372         default:
373                 info->flash_id = FLASH_UNKNOWN;
374                 info->sector_count = 0;
375                 info->size = 0;
376                 return (0);                     /* => no or unknown flash */
377         }
378
379         flash_get_offsets((ulong)addr, info);
380
381         /* Put FLASH back in read mode */
382         flash_reset(info);
383
384         return (info->size);
385 }
386
387 /*-----------------------------------------------------------------------
388  */
389
390 int     flash_erase (flash_info_t *info, int s_first, int s_last)
391 {
392         FPWV *addr;
393         int flag, prot, sect;
394         int intel = (info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL;
395         ulong start, now, last;
396         int rcode = 0;
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         switch (info->flash_id & FLASH_TYPEMASK) {
408         case FLASH_INTEL800B:
409         case FLASH_INTEL160B:
410         case FLASH_INTEL320B:
411         case FLASH_INTEL640B:
412         case FLASH_28F800C3B:
413         case FLASH_28F160C3B:
414         case FLASH_28F320C3B:
415         case FLASH_28F640C3B:
416         case FLASH_AM640U:
417                 break;
418         case FLASH_UNKNOWN:
419         default:
420                 printf ("Can't erase unknown flash type %08lx - aborted\n",
421                         info->flash_id);
422                 return 1;
423         }
424
425         prot = 0;
426         for (sect=s_first; sect<=s_last; ++sect) {
427                 if (info->protect[sect]) {
428                         prot++;
429                 }
430         }
431
432         if (prot) {
433                 printf ("- Warning: %d protected sectors will not be erased!\n",
434                         prot);
435         } else {
436                 printf ("\n");
437         }
438
439         last  = get_timer(0);
440
441         /* Start erase on unprotected sectors */
442         for (sect = s_first; sect<=s_last && rcode == 0; sect++) {
443
444                 if (info->protect[sect] != 0)   /* protected, skip it */
445                         continue;
446
447                 /* Disable interrupts which might cause a timeout here */
448                 flag = disable_interrupts();
449
450                 addr = (FPWV *)(info->start[sect]);
451                 if (intel) {
452                         *addr = (FPW)0x00500050; /* clear status register */
453                         *addr = (FPW)0x00200020; /* erase setup */
454                         *addr = (FPW)0x00D000D0; /* erase confirm */
455                 }
456                 else {
457                         /* must be AMD style if not Intel */
458                         FPWV *base;             /* first address in bank */
459
460                         base = (FPWV *)(info->start[0]);
461                         base[FLASH_CYCLE1] = (FPW)0x00AA00AA;   /* unlock */
462                         base[FLASH_CYCLE2] = (FPW)0x00550055;   /* unlock */
463                         base[FLASH_CYCLE1] = (FPW)0x00800080;   /* erase mode */
464                         base[FLASH_CYCLE1] = (FPW)0x00AA00AA;   /* unlock */
465                         base[FLASH_CYCLE2] = (FPW)0x00550055;   /* unlock */
466                         *addr = (FPW)0x00300030;        /* erase sector */
467                 }
468
469                 /* re-enable interrupts if necessary */
470                 if (flag)
471                         enable_interrupts();
472
473                 start = get_timer(0);
474
475                 /* wait at least 50us for AMD, 80us for Intel.
476                  * Let's wait 1 ms.
477                  */
478                 udelay (1000);
479
480                 while ((*addr & (FPW)0x00800080) != (FPW)0x00800080) {
481                         if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
482                                 printf ("Timeout\n");
483
484                                 if (intel) {
485                                         /* suspend erase        */
486                                         *addr = (FPW)0x00B000B0;
487                                 }
488
489                                 flash_reset(info);      /* reset to read mode */
490                                 rcode = 1;              /* failed */
491                                 break;
492                         }
493
494                         /* show that we're waiting */
495                         if ((get_timer(last)) > CFG_HZ) {/* every second */
496                                 putc ('.');
497                                 last = get_timer(0);
498                         }
499                 }
500
501                 /* show that we're waiting */
502                 if ((get_timer(last)) > CFG_HZ) {       /* every second */
503                         putc ('.');
504                         last = get_timer(0);
505                 }
506
507                 flash_reset(info);      /* reset to read mode   */
508         }
509
510         printf (" done\n");
511         return rcode;
512 }
513
514 /*-----------------------------------------------------------------------
515  * Copy memory to flash, returns:
516  * 0 - OK
517  * 1 - write timeout
518  * 2 - Flash not erased
519  */
520 int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
521 {
522     FPW data = 0; /* 16 or 32 bit word, matches flash bus width on MPC8XX */
523     int bytes;    /* number of bytes to program in current word         */
524     int left;     /* number of bytes left to program                    */
525     int i, res;
526
527     for (left = cnt, res = 0;
528          left > 0 && res == 0;
529          addr += sizeof(data), left -= sizeof(data) - bytes) {
530
531         bytes = addr & (sizeof(data) - 1);
532         addr &= ~(sizeof(data) - 1);
533
534         /* combine source and destination data so can program
535          * an entire word of 16 or 32 bits
536          */
537         for (i = 0; i < sizeof(data); i++) {
538             data <<= 8;
539             if (i < bytes || i - bytes >= left )
540                 data += *((uchar *)addr + i);
541             else
542                 data += *src++;
543         }
544
545         /* write one word to the flash */
546         switch (info->flash_id & FLASH_VENDMASK) {
547         case FLASH_MAN_AMD:
548                 res = write_word_amd(info, (FPWV *)addr, data);
549                 break;
550         case FLASH_MAN_INTEL:
551                 res = write_word_intel(info, (FPWV *)addr, data);
552                 break;
553         default:
554                 /* unknown flash type, error! */
555                 printf ("missing or unknown FLASH type\n");
556                 res = 1;        /* not really a timeout, but gives error */
557                 break;
558         }
559     }
560
561     return (res);
562 }
563
564 /*-----------------------------------------------------------------------
565  * Write a word to Flash for AMD FLASH
566  * A word is 16 or 32 bits, whichever the bus width of the flash bank
567  * (not an individual chip) is.
568  *
569  * returns:
570  * 0 - OK
571  * 1 - write timeout
572  * 2 - Flash not erased
573  */
574 static int write_word_amd (flash_info_t *info, FPWV *dest, FPW data)
575 {
576     ulong start;
577     int flag;
578     int res = 0;        /* result, assume success       */
579     FPWV *base;         /* first address in flash bank  */
580
581     /* Check if Flash is (sufficiently) erased */
582     if ((*dest & data) != data) {
583         return (2);
584     }
585
586
587     base = (FPWV *)(info->start[0]);
588
589     /* Disable interrupts which might cause a timeout here */
590     flag = disable_interrupts();
591
592     base[FLASH_CYCLE1] = (FPW)0x00AA00AA;       /* unlock */
593     base[FLASH_CYCLE2] = (FPW)0x00550055;       /* unlock */
594     base[FLASH_CYCLE1] = (FPW)0x00A000A0;       /* selects program mode */
595
596     *dest = data;               /* start programming the data   */
597
598     /* re-enable interrupts if necessary */
599     if (flag)
600         enable_interrupts();
601
602     start = get_timer (0);
603
604     /* data polling for D7 */
605     while (res == 0 && (*dest & (FPW)0x00800080) != (data & (FPW)0x00800080)) {
606         if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
607             *dest = (FPW)0x00F000F0;    /* reset bank */
608             res = 1;
609         }
610     }
611
612     return (res);
613 }
614
615 /*-----------------------------------------------------------------------
616  * Write a word to Flash for Intel FLASH
617  * A word is 16 or 32 bits, whichever the bus width of the flash bank
618  * (not an individual chip) is.
619  *
620  * returns:
621  * 0 - OK
622  * 1 - write timeout
623  * 2 - Flash not erased
624  */
625 static int write_word_intel (flash_info_t *info, FPWV *dest, FPW data)
626 {
627     ulong start;
628     int flag;
629     int res = 0;        /* result, assume success       */
630
631     /* Check if Flash is (sufficiently) erased */
632     if ((*dest & data) != data) {
633         return (2);
634     }
635
636     /* Disable interrupts which might cause a timeout here */
637     flag = disable_interrupts();
638
639     *dest = (FPW)0x00500050;    /* clear status register        */
640     *dest = (FPW)0x00FF00FF;    /* make sure in read mode       */
641     *dest = (FPW)0x00400040;    /* program setup                */
642
643     *dest = data;               /* start programming the data   */
644
645     /* re-enable interrupts if necessary */
646     if (flag)
647         enable_interrupts();
648
649     start = get_timer (0);
650
651     while (res == 0 && (*dest & (FPW)0x00800080) != (FPW)0x00800080) {
652         if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
653             *dest = (FPW)0x00B000B0;    /* Suspend program      */
654             res = 1;
655         }
656     }
657
658     if (res == 0 && (*dest & (FPW)0x00100010))
659         res = 1;        /* write failed, time out error is close enough */
660
661     *dest = (FPW)0x00500050;    /* clear status register        */
662     *dest = (FPW)0x00FF00FF;    /* make sure in read mode       */
663
664     return (res);
665 }