]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/atc/flash.c
rename CFG_ macros to CONFIG_SYS
[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[CONFIG_SYS_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 < CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
71 #if 0
72                 ulong flashbase = (i == 0) ? PHYS_FLASH_1 : PHYS_FLASH_2;
73 #else
74                 ulong flashbase = CONFIG_SYS_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 CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
91         /* monitor protection ON by default */
92         flash_protect(FLAG_PROTECT_SET,
93                       CONFIG_SYS_MONITOR_BASE,
94                       CONFIG_SYS_MONITOR_BASE+monitor_flash_len-1,
95                       flash_get_info(CONFIG_SYS_MONITOR_BASE));
96 #endif
97
98 #ifdef  CONFIG_ENV_IS_IN_FLASH
99         /* ENV protection ON by default */
100         flash_protect(FLAG_PROTECT_SET,
101                       CONFIG_ENV_ADDR,
102                       CONFIG_ENV_ADDR+CONFIG_ENV_SIZE-1,
103                       flash_get_info(CONFIG_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 < CONFIG_SYS_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 == CONFIG_SYS_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         char *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(100);
296         switch (addr[0] & 0xff) {
297
298         case (uchar)AMD_MANUFACT:
299                 info->flash_id = FLASH_MAN_AMD;
300                 break;
301
302         case (uchar)INTEL_MANUFACT:
303                 info->flash_id = FLASH_MAN_INTEL;
304                 break;
305
306         default:
307                 info->flash_id = FLASH_UNKNOWN;
308                 info->sector_count = 0;
309                 info->size = 0;
310                 break;
311         }
312
313         /* Check 16 bits or 32 bits of ID so work on 32 or 16 bit bus. */
314         if (info->flash_id != FLASH_UNKNOWN) switch (addr[1]) {
315
316         case (FPW)AMD_ID_LV640U:        /* 29LV640 and 29LV641 have same ID */
317                 info->flash_id += FLASH_AM640U;
318                 info->sector_count = 128;
319                 info->size = 0x00800000 * (sizeof(FPW)/2);
320                 break;                          /* => 8 or 16 MB        */
321
322         case (FPW)INTEL_ID_28F800C3B:
323                 info->flash_id += FLASH_28F800C3B;
324                 info->sector_count = 23;
325                 info->size = 0x00100000 * (sizeof(FPW)/2);
326                 break;                          /* => 1 or 2 MB         */
327
328         case (FPW)INTEL_ID_28F800B3B:
329                 info->flash_id += FLASH_INTEL800B;
330                 info->sector_count = 23;
331                 info->size = 0x00100000 * (sizeof(FPW)/2);
332                 break;                          /* => 1 or 2 MB         */
333
334         case (FPW)INTEL_ID_28F160C3B:
335                 info->flash_id += FLASH_28F160C3B;
336                 info->sector_count = 39;
337                 info->size = 0x00200000 * (sizeof(FPW)/2);
338                 break;                          /* => 2 or 4 MB         */
339
340         case (FPW)INTEL_ID_28F160B3B:
341                 info->flash_id += FLASH_INTEL160B;
342                 info->sector_count = 39;
343                 info->size = 0x00200000 * (sizeof(FPW)/2);
344                 break;                          /* => 2 or 4 MB         */
345
346         case (FPW)INTEL_ID_28F320C3B:
347                 info->flash_id += FLASH_28F320C3B;
348                 info->sector_count = 71;
349                 info->size = 0x00400000 * (sizeof(FPW)/2);
350                 break;                          /* => 4 or 8 MB         */
351
352         case (FPW)INTEL_ID_28F320B3B:
353                 info->flash_id += FLASH_INTEL320B;
354                 info->sector_count = 71;
355                 info->size = 0x00400000 * (sizeof(FPW)/2);
356                 break;                          /* => 4 or 8 MB         */
357
358         case (FPW)INTEL_ID_28F640C3B:
359                 info->flash_id += FLASH_28F640C3B;
360                 info->sector_count = 135;
361                 info->size = 0x00800000 * (sizeof(FPW)/2);
362                 break;                          /* => 8 or 16 MB        */
363
364         case (FPW)INTEL_ID_28F640B3B:
365                 info->flash_id += FLASH_INTEL640B;
366                 info->sector_count = 135;
367                 info->size = 0x00800000 * (sizeof(FPW)/2);
368                 break;                          /* => 8 or 16 MB        */
369
370         default:
371                 info->flash_id = FLASH_UNKNOWN;
372                 info->sector_count = 0;
373                 info->size = 0;
374                 return (0);                     /* => no or unknown flash */
375         }
376
377         flash_get_offsets((ulong)addr, info);
378
379         /* Put FLASH back in read mode */
380         flash_reset(info);
381
382         return (info->size);
383 }
384
385 /*-----------------------------------------------------------------------
386  */
387
388 int     flash_erase (flash_info_t *info, int s_first, int s_last)
389 {
390         FPWV *addr;
391         int flag, prot, sect;
392         int intel = (info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL;
393         ulong start, now, last;
394         int rcode = 0;
395
396         if ((s_first < 0) || (s_first > s_last)) {
397                 if (info->flash_id == FLASH_UNKNOWN) {
398                         printf ("- missing\n");
399                 } else {
400                         printf ("- no sectors to erase\n");
401                 }
402                 return 1;
403         }
404
405         switch (info->flash_id & FLASH_TYPEMASK) {
406         case FLASH_INTEL800B:
407         case FLASH_INTEL160B:
408         case FLASH_INTEL320B:
409         case FLASH_INTEL640B:
410         case FLASH_28F800C3B:
411         case FLASH_28F160C3B:
412         case FLASH_28F320C3B:
413         case FLASH_28F640C3B:
414         case FLASH_AM640U:
415                 break;
416         case FLASH_UNKNOWN:
417         default:
418                 printf ("Can't erase unknown flash type %08lx - aborted\n",
419                         info->flash_id);
420                 return 1;
421         }
422
423         prot = 0;
424         for (sect=s_first; sect<=s_last; ++sect) {
425                 if (info->protect[sect]) {
426                         prot++;
427                 }
428         }
429
430         if (prot) {
431                 printf ("- Warning: %d protected sectors will not be erased!\n",
432                         prot);
433         } else {
434                 printf ("\n");
435         }
436
437         last  = get_timer(0);
438
439         /* Start erase on unprotected sectors */
440         for (sect = s_first; sect<=s_last && rcode == 0; sect++) {
441
442                 if (info->protect[sect] != 0)   /* protected, skip it */
443                         continue;
444
445                 /* Disable interrupts which might cause a timeout here */
446                 flag = disable_interrupts();
447
448                 addr = (FPWV *)(info->start[sect]);
449                 if (intel) {
450                         *addr = (FPW)0x00500050; /* clear status register */
451                         *addr = (FPW)0x00200020; /* erase setup */
452                         *addr = (FPW)0x00D000D0; /* erase confirm */
453                 }
454                 else {
455                         /* must be AMD style if not Intel */
456                         FPWV *base;             /* first address in bank */
457
458                         base = (FPWV *)(info->start[0]);
459                         base[FLASH_CYCLE1] = (FPW)0x00AA00AA;   /* unlock */
460                         base[FLASH_CYCLE2] = (FPW)0x00550055;   /* unlock */
461                         base[FLASH_CYCLE1] = (FPW)0x00800080;   /* erase mode */
462                         base[FLASH_CYCLE1] = (FPW)0x00AA00AA;   /* unlock */
463                         base[FLASH_CYCLE2] = (FPW)0x00550055;   /* unlock */
464                         *addr = (FPW)0x00300030;        /* erase sector */
465                 }
466
467                 /* re-enable interrupts if necessary */
468                 if (flag)
469                         enable_interrupts();
470
471                 start = get_timer(0);
472
473                 /* wait at least 50us for AMD, 80us for Intel.
474                  * Let's wait 1 ms.
475                  */
476                 udelay (1000);
477
478                 while ((*addr & (FPW)0x00800080) != (FPW)0x00800080) {
479                         if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
480                                 printf ("Timeout\n");
481
482                                 if (intel) {
483                                         /* suspend erase        */
484                                         *addr = (FPW)0x00B000B0;
485                                 }
486
487                                 flash_reset(info);      /* reset to read mode */
488                                 rcode = 1;              /* failed */
489                                 break;
490                         }
491
492                         /* show that we're waiting */
493                         if ((get_timer(last)) > CONFIG_SYS_HZ) {/* every second */
494                                 putc ('.');
495                                 last = get_timer(0);
496                         }
497                 }
498
499                 /* show that we're waiting */
500                 if ((get_timer(last)) > CONFIG_SYS_HZ) {        /* every second */
501                         putc ('.');
502                         last = get_timer(0);
503                 }
504
505                 flash_reset(info);      /* reset to read mode   */
506         }
507
508         printf (" done\n");
509         return rcode;
510 }
511
512 /*-----------------------------------------------------------------------
513  * Copy memory to flash, returns:
514  * 0 - OK
515  * 1 - write timeout
516  * 2 - Flash not erased
517  */
518 int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
519 {
520         FPW data = 0; /* 16 or 32 bit word, matches flash bus width on MPC8XX */
521         int bytes;        /* number of bytes to program in current word         */
522         int left;         /* number of bytes left to program                    */
523         int i, res;
524
525         for (left = cnt, res = 0;
526                  left > 0 && res == 0;
527                  addr += sizeof(data), left -= sizeof(data) - bytes) {
528
529                 bytes = addr & (sizeof(data) - 1);
530                 addr &= ~(sizeof(data) - 1);
531
532                 /* combine source and destination data so can program
533                  * an entire word of 16 or 32 bits
534                  */
535                 for (i = 0; i < sizeof(data); i++) {
536                         data <<= 8;
537                         if (i < bytes || i - bytes >= left )
538                                 data += *((uchar *)addr + i);
539                         else
540                                 data += *src++;
541                 }
542
543                 /* write one word to the flash */
544                 switch (info->flash_id & FLASH_VENDMASK) {
545                 case FLASH_MAN_AMD:
546                         res = write_word_amd(info, (FPWV *)addr, data);
547                         break;
548                 case FLASH_MAN_INTEL:
549                         res = write_word_intel(info, (FPWV *)addr, data);
550                         break;
551                 default:
552                         /* unknown flash type, error! */
553                         printf ("missing or unknown FLASH type\n");
554                         res = 1;        /* not really a timeout, but gives error */
555                         break;
556                 }
557         }
558
559         return (res);
560 }
561
562 /*-----------------------------------------------------------------------
563  * Write a word to Flash for AMD FLASH
564  * A word is 16 or 32 bits, whichever the bus width of the flash bank
565  * (not an individual chip) is.
566  *
567  * returns:
568  * 0 - OK
569  * 1 - write timeout
570  * 2 - Flash not erased
571  */
572 static int write_word_amd (flash_info_t *info, FPWV *dest, FPW data)
573 {
574         ulong start;
575         int flag;
576         int res = 0;    /* result, assume success       */
577         FPWV *base;             /* first address in flash bank  */
578
579         /* Check if Flash is (sufficiently) erased */
580         if ((*dest & data) != data) {
581                 return (2);
582         }
583
584
585         base = (FPWV *)(info->start[0]);
586
587         /* Disable interrupts which might cause a timeout here */
588         flag = disable_interrupts();
589
590         base[FLASH_CYCLE1] = (FPW)0x00AA00AA;   /* unlock */
591         base[FLASH_CYCLE2] = (FPW)0x00550055;   /* unlock */
592         base[FLASH_CYCLE1] = (FPW)0x00A000A0;   /* selects program mode */
593
594         *dest = data;           /* start programming the data   */
595
596         /* re-enable interrupts if necessary */
597         if (flag)
598                 enable_interrupts();
599
600         start = get_timer (0);
601
602         /* data polling for D7 */
603         while (res == 0 && (*dest & (FPW)0x00800080) != (data & (FPW)0x00800080)) {
604                 if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
605                         *dest = (FPW)0x00F000F0;        /* reset bank */
606                         res = 1;
607                 }
608         }
609
610         return (res);
611 }
612
613 /*-----------------------------------------------------------------------
614  * Write a word to Flash for Intel FLASH
615  * A word is 16 or 32 bits, whichever the bus width of the flash bank
616  * (not an individual chip) is.
617  *
618  * returns:
619  * 0 - OK
620  * 1 - write timeout
621  * 2 - Flash not erased
622  */
623 static int write_word_intel (flash_info_t *info, FPWV *dest, FPW data)
624 {
625         ulong start;
626         int flag;
627         int res = 0;    /* result, assume success       */
628
629         /* Check if Flash is (sufficiently) erased */
630         if ((*dest & data) != data) {
631                 return (2);
632         }
633
634         /* Disable interrupts which might cause a timeout here */
635         flag = disable_interrupts();
636
637         *dest = (FPW)0x00500050;        /* clear status register        */
638         *dest = (FPW)0x00FF00FF;        /* make sure in read mode       */
639         *dest = (FPW)0x00400040;        /* program setup                */
640
641         *dest = data;           /* start programming the data   */
642
643         /* re-enable interrupts if necessary */
644         if (flag)
645                 enable_interrupts();
646
647         start = get_timer (0);
648
649         while (res == 0 && (*dest & (FPW)0x00800080) != (FPW)0x00800080) {
650                 if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
651                         *dest = (FPW)0x00B000B0;        /* Suspend program      */
652                         res = 1;
653                 }
654         }
655
656         if (res == 0 && (*dest & (FPW)0x00100010))
657                 res = 1;        /* write failed, time out error is close enough */
658
659         *dest = (FPW)0x00500050;        /* clear status register        */
660         *dest = (FPW)0x00FF00FF;        /* make sure in read mode       */
661
662         return (res);
663 }