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