]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/cpu87/flash.c
rename CFG_ macros to CONFIG_SYS
[karo-tx-uboot.git] / board / cpu87 / flash.c
1 /*
2  * (C) Copyright 2001-2005
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * Flash Routines for Intel devices
6  *
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 #include <common.h>
28 #include <mpc8xx.h>
29 #include "cpu87.h"
30
31 flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
32
33 /*-----------------------------------------------------------------------
34  */
35 ulong flash_int_get_size (volatile unsigned long *baseaddr,
36                                           flash_info_t * info)
37 {
38         short i;
39         unsigned long flashtest_h, flashtest_l;
40
41         info->sector_count = info->size = 0;
42         info->flash_id = FLASH_UNKNOWN;
43
44         /* Write identify command sequence and test FLASH answer
45          */
46         baseaddr[0] = 0x00900090;
47         baseaddr[1] = 0x00900090;
48
49         flashtest_h = baseaddr[0];      /* manufacturer ID      */
50         flashtest_l = baseaddr[1];
51
52         if (flashtest_h != INTEL_MANUFACT || flashtest_l != INTEL_MANUFACT)
53                 return (0);             /* no or unknown flash  */
54
55         flashtest_h = baseaddr[2];      /* device ID            */
56         flashtest_l = baseaddr[3];
57
58         if (flashtest_h != flashtest_l)
59                 return (0);
60
61         switch (flashtest_h) {
62         case INTEL_ID_28F160C3B:
63                 info->flash_id = FLASH_28F160C3B;
64                 info->sector_count = 39;
65                 info->size = 0x00800000;        /* 4 * 2 MB = 8 MB      */
66                 break;
67         case INTEL_ID_28F160F3B:
68                 info->flash_id = FLASH_28F160F3B;
69                 info->sector_count = 39;
70                 info->size = 0x00800000;        /* 4 * 2 MB = 8 MB      */
71                 break;
72         case INTEL_ID_28F640C3B:
73                 info->flash_id = FLASH_28F640C3B;
74                 info->sector_count = 135;
75                 info->size = 0x02000000;        /* 16 * 2 MB = 32 MB    */
76                 break;
77         default:
78                 return (0);                     /* no or unknown flash  */
79         }
80
81         info->flash_id |= INTEL_MANUFACT << 16; /* set manufacturer offset */
82
83         if (info->flash_id & FLASH_BTYPE) {
84                 volatile unsigned long *tmp = baseaddr;
85
86                 /* set up sector start adress table (bottom sector type)
87                  * AND unlock the sectors (if our chip is 160C3)
88                  */
89                 for (i = 0; i < info->sector_count; i++) {
90                         if (((info->flash_id & FLASH_TYPEMASK) == FLASH_28F160C3B) ||
91                             ((info->flash_id & FLASH_TYPEMASK) == FLASH_28F640C3B)) {
92                                 tmp[0] = 0x00600060;
93                                 tmp[1] = 0x00600060;
94                                 tmp[0] = 0x00D000D0;
95                                 tmp[1] = 0x00D000D0;
96                         }
97                         info->start[i] = (uint) tmp;
98                         tmp += i < 8 ? 0x2000 : 0x10000; /* pointer arith       */
99                 }
100         }
101
102         memset (info->protect, 0, info->sector_count);
103
104         baseaddr[0] = 0x00FF00FF;
105         baseaddr[1] = 0x00FF00FF;
106
107         return (info->size);
108 }
109
110 static ulong flash_amd_get_size (vu_char *addr, flash_info_t *info)
111 {
112         short i;
113         uchar vendor, devid;
114         ulong base = (ulong)addr;
115
116         /* Write auto select command: read Manufacturer ID */
117         addr[0x0555] = 0xAA;
118         addr[0x02AA] = 0x55;
119         addr[0x0555] = 0x90;
120
121         udelay(1000);
122
123         vendor = addr[0];
124         devid = addr[1] & 0xff;
125
126         /* only support AMD */
127         if (vendor != 0x01) {
128                 return 0;
129         }
130
131         vendor &= 0xf;
132         devid &= 0xff;
133
134         if (devid == AMD_ID_F040B) {
135                 info->flash_id     = vendor << 16 | devid;
136                 info->sector_count = 8;
137                 info->size         = info->sector_count * 0x10000;
138         }
139         else if (devid == AMD_ID_F080B) {
140                 info->flash_id     = vendor << 16 | devid;
141                 info->sector_count = 16;
142                 info->size         = 4 * info->sector_count * 0x10000;
143         }
144         else if (devid == AMD_ID_F016D) {
145                 info->flash_id     = vendor << 16 | devid;
146                 info->sector_count = 32;
147                 info->size         = 4 * info->sector_count * 0x10000;
148         }
149         else {
150                 printf ("## Unknown Flash Type: %02x\n", devid);
151                 return 0;
152         }
153
154         /* check for protected sectors */
155         for (i = 0; i < info->sector_count; i++) {
156                 /* sector base address */
157                 info->start[i] = base + i * (info->size / info->sector_count);
158                 /* read sector protection at sector address, (A7 .. A0) = 0x02 */
159                 /* D0 = 1 if protected */
160                 addr = (volatile unsigned char *)(info->start[i]);
161                 info->protect[i] = addr[2] & 1;
162         }
163
164         /*
165          * Prevent writes to uninitialized FLASH.
166          */
167         if (info->flash_id != FLASH_UNKNOWN) {
168                 addr = (vu_char *)info->start[0];
169                 addr[0] = 0xF0; /* reset bank */
170         }
171
172         return (info->size);
173 }
174
175
176 /*-----------------------------------------------------------------------
177  */
178 unsigned long flash_init (void)
179 {
180         unsigned long size_b0 = 0;
181         unsigned long size_b1 = 0;
182         int i;
183
184         /* Init: no FLASHes known
185          */
186         for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
187                 flash_info[i].flash_id = FLASH_UNKNOWN;
188         }
189
190         /* Disable flash protection */
191         CPU86_BCR |= (CPU86_BCR_FWPT | CPU86_BCR_FWRE);
192
193         /* Static FLASH Bank configuration here (only one bank) */
194
195         size_b0 = flash_int_get_size ((ulong *) CONFIG_SYS_FLASH_BASE, &flash_info[0]);
196         size_b1 = flash_amd_get_size ((uchar *) CONFIG_SYS_BOOTROM_BASE, &flash_info[1]);
197
198         if (size_b0 > 0 || size_b1 > 0) {
199
200                 printf("(");
201
202                 if (size_b0 > 0) {
203                         puts ("Bank#1 - ");
204                         print_size (size_b0, (size_b1 > 0) ? ", " : ") ");
205                 }
206
207                 if (size_b1 > 0) {
208                         puts ("Bank#2 - ");
209                         print_size (size_b1, ") ");
210                 }
211         }
212         else {
213                 printf ("## No FLASH found.\n");
214                 return 0;
215         }
216         /* protect monitor and environment sectors
217          */
218
219 #if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_BOOTROM_BASE
220         if (size_b1) {
221                 /* If U-Boot is booted from ROM the CONFIG_SYS_MONITOR_BASE > CONFIG_SYS_FLASH_BASE
222                  * but we shouldn't protect it.
223                  */
224
225                 flash_protect  (FLAG_PROTECT_SET,
226                                 CONFIG_SYS_MONITOR_BASE,
227                                 CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1, &flash_info[1]
228                 );
229         }
230 #else
231 #if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
232         flash_protect (FLAG_PROTECT_SET,
233                        CONFIG_SYS_MONITOR_BASE,
234                        CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1, &flash_info[0]
235         );
236 #endif
237 #endif
238
239 #if defined(CONFIG_ENV_IS_IN_FLASH) && defined(CONFIG_ENV_ADDR)
240 # ifndef  CONFIG_ENV_SIZE
241 #  define CONFIG_ENV_SIZE       CONFIG_ENV_SECT_SIZE
242 # endif
243 # if CONFIG_ENV_ADDR >= CONFIG_SYS_BOOTROM_BASE
244         if (size_b1) {
245                 flash_protect (FLAG_PROTECT_SET,
246                                 CONFIG_ENV_ADDR,
247                                 CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, &flash_info[1]);
248         }
249 # else
250         flash_protect (FLAG_PROTECT_SET,
251                        CONFIG_ENV_ADDR,
252                        CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, &flash_info[0]);
253 # endif
254 #endif
255
256         return (size_b0 + size_b1);
257 }
258
259 /*-----------------------------------------------------------------------
260  */
261 void flash_print_info (flash_info_t * info)
262 {
263         int i;
264
265         if (info->flash_id == FLASH_UNKNOWN) {
266                 printf ("missing or unknown FLASH type\n");
267                 return;
268         }
269
270         switch ((info->flash_id >> 16) & 0xff) {
271         case 0x89:
272                 printf ("INTEL ");
273                 break;
274         case 0x1:
275                 printf ("AMD ");
276                 break;
277         default:
278                 printf ("Unknown Vendor ");
279                 break;
280         }
281
282         switch (info->flash_id & FLASH_TYPEMASK) {
283         case FLASH_28F160C3B:
284                 printf ("28F160C3B (16 Mbit, bottom sector)\n");
285                 break;
286         case FLASH_28F160F3B:
287                 printf ("28F160F3B (16 Mbit, bottom sector)\n");
288                 break;
289         case FLASH_28F640C3B:
290                 printf ("28F640C3B (64 M, bottom sector)\n");
291                 break;
292         case AMD_ID_F040B:
293                 printf ("AM29F040B (4 Mbit)\n");
294                 break;
295         default:
296                 printf ("Unknown Chip Type\n");
297                 break;
298         }
299
300         if (info->size < 0x100000)
301                 printf ("  Size: %ld KB in %d Sectors\n",
302                                 info->size >> 10, info->sector_count);
303         else
304                 printf ("  Size: %ld MB in %d Sectors\n",
305                                 info->size >> 20, info->sector_count);
306
307         printf ("  Sector Start Addresses:");
308         for (i = 0; i < info->sector_count; ++i) {
309                 if ((i % 5) == 0)
310                         printf ("\n   ");
311                 printf (" %08lX%s",
312                         info->start[i],
313                         info->protect[i] ? " (RO)" : "     "
314                 );
315         }
316         printf ("\n");
317 }
318
319 /*-----------------------------------------------------------------------
320  */
321 int flash_erase (flash_info_t * info, int s_first, int s_last)
322 {
323         vu_char *addr = (vu_char *)(info->start[0]);
324         int flag, prot, sect, l_sect;
325         ulong start, now, last;
326
327         if ((s_first < 0) || (s_first > s_last)) {
328                 if (info->flash_id == FLASH_UNKNOWN) {
329                         printf ("- missing\n");
330                 } else {
331                         printf ("- no sectors to erase\n");
332                 }
333                 return 1;
334         }
335
336         prot = 0;
337         for (sect = s_first; sect <= s_last; sect++) {
338                 if (info->protect[sect])
339                         prot++;
340         }
341
342         if (prot) {
343                 printf ("- Warning: %d protected sectors will not be erased!\n",
344                                 prot);
345         } else {
346                 printf ("\n");
347         }
348
349         /* Check the type of erased flash
350          */
351         if (info->flash_id >> 16 == 0x1) {
352                 /* Erase AMD flash
353                  */
354                 l_sect = -1;
355
356                 /* Disable interrupts which might cause a timeout here */
357                 flag = disable_interrupts();
358
359                 addr[0x0555] = 0xAA;
360                 addr[0x02AA] = 0x55;
361                 addr[0x0555] = 0x80;
362                 addr[0x0555] = 0xAA;
363                 addr[0x02AA] = 0x55;
364
365                 /* wait at least 80us - let's wait 1 ms */
366                 udelay (1000);
367
368                 /* Start erase on unprotected sectors */
369                 for (sect = s_first; sect<=s_last; sect++) {
370                         if (info->protect[sect] == 0) { /* not protected */
371                                 addr = (vu_char *)(info->start[sect]);
372                                 addr[0] = 0x30;
373                                 l_sect = sect;
374                         }
375                 }
376
377                 /* re-enable interrupts if necessary */
378                 if (flag)
379                         enable_interrupts();
380
381                 /* wait at least 80us - let's wait 1 ms */
382                 udelay (1000);
383
384                 /*
385                  * We wait for the last triggered sector
386                  */
387                 if (l_sect < 0)
388                         goto AMD_DONE;
389
390                 start = get_timer (0);
391                 last  = start;
392                 addr = (vu_char *)(info->start[l_sect]);
393                 while ((addr[0] & 0x80) != 0x80) {
394                         if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
395                                 printf ("Timeout\n");
396                                 return 1;
397                         }
398                         /* show that we're waiting */
399                         if ((now - last) > 1000) {      /* every second */
400                                 serial_putc ('.');
401                                 last = now;
402                         }
403                 }
404
405 AMD_DONE:
406                 /* reset to read mode */
407                 addr = (volatile unsigned char *)info->start[0];
408                 addr[0] = 0xF0;     /* reset bank */
409
410         } else {
411                 /* Erase Intel flash
412                  */
413
414                 /* Start erase on unprotected sectors
415                  */
416                 for (sect = s_first; sect <= s_last; sect++) {
417                         volatile ulong *addr =
418                                 (volatile unsigned long *) info->start[sect];
419
420                         start = get_timer (0);
421                         last = start;
422                         if (info->protect[sect] == 0) {
423                         /* Disable interrupts which might cause a timeout here
424                          */
425                                 flag = disable_interrupts ();
426
427                                 /* Erase the block
428                                  */
429                                 addr[0] = 0x00200020;
430                                 addr[1] = 0x00200020;
431                                 addr[0] = 0x00D000D0;
432                                 addr[1] = 0x00D000D0;
433
434                                 /* re-enable interrupts if necessary
435                                  */
436                                 if (flag)
437                                         enable_interrupts ();
438
439                                 /* wait at least 80us - let's wait 1 ms
440                                  */
441                                 udelay (1000);
442
443                                 last = start;
444                                 while ((addr[0] & 0x00800080) != 0x00800080 ||
445                                    (addr[1] & 0x00800080) != 0x00800080) {
446                                         if ((now = get_timer (start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
447                                                 printf ("Timeout (erase suspended!)\n");
448                                                 /* Suspend erase
449                                                  */
450                                                 addr[0] = 0x00B000B0;
451                                                 addr[1] = 0x00B000B0;
452                                                 goto DONE;
453                                         }
454                                         /* show that we're waiting
455                                          */
456                                         if ((now - last) > 1000) {      /* every second */
457                                                 serial_putc ('.');
458                                                 last = now;
459                                         }
460                                 }
461                                 if (addr[0] & 0x00220022 || addr[1] & 0x00220022) {
462                                         printf ("*** ERROR: erase failed!\n");
463                                         goto DONE;
464                                 }
465                         }
466                         /* Clear status register and reset to read mode
467                          */
468                         addr[0] = 0x00500050;
469                         addr[1] = 0x00500050;
470                         addr[0] = 0x00FF00FF;
471                         addr[1] = 0x00FF00FF;
472                 }
473         }
474
475         printf (" done\n");
476
477 DONE:
478         return 0;
479 }
480
481 static int write_word (flash_info_t *, volatile unsigned long *, ulong);
482 static int write_byte (flash_info_t *info, ulong dest, uchar data);
483
484 /*-----------------------------------------------------------------------
485  * Copy memory to flash, returns:
486  * 0 - OK
487  * 1 - write timeout
488  * 2 - Flash not erased
489  */
490 int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
491 {
492         ulong v;
493         int i, l, rc, cc = cnt, res = 0;
494
495         if (info->flash_id >> 16 == 0x1) {
496
497                 /* Write to AMD 8-bit flash
498                  */
499                 while (cnt > 0) {
500                         if ((rc = write_byte(info, addr, *src)) != 0) {
501                                 return (rc);
502                         }
503                         addr++;
504                         src++;
505                         cnt--;
506                 }
507
508                 return (0);
509         } else {
510
511                 /* Write to Intel 64-bit flash
512                  */
513                 for (v=0; cc > 0; addr += 4, cc -= 4 - l) {
514                         l = (addr & 3);
515                         addr &= ~3;
516
517                         for (i = 0; i < 4; i++) {
518                                 v = (v << 8) + (i < l || i - l >= cc ?
519                                         *((unsigned char *) addr + i) : *src++);
520                         }
521
522                         if ((res = write_word (info, (volatile unsigned long *) addr, v)) != 0)
523                                 break;
524                 }
525         }
526
527         return (res);
528 }
529
530 /*-----------------------------------------------------------------------
531  * Write a word to Flash, returns:
532  * 0 - OK
533  * 1 - write timeout
534  * 2 - Flash not erased
535  */
536 static int write_word (flash_info_t * info, volatile unsigned long *addr,
537                                            ulong data)
538 {
539         int flag, res = 0;
540         ulong start;
541
542         /* Check if Flash is (sufficiently) erased
543          */
544         if ((*addr & data) != data)
545                 return (2);
546
547         /* Disable interrupts which might cause a timeout here
548          */
549         flag = disable_interrupts ();
550
551         *addr = 0x00400040;
552         *addr = data;
553
554         /* re-enable interrupts if necessary
555          */
556         if (flag)
557                 enable_interrupts ();
558
559         start = get_timer (0);
560         while ((*addr & 0x00800080) != 0x00800080) {
561                 if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
562                         /* Suspend program
563                          */
564                         *addr = 0x00B000B0;
565                         res = 1;
566                         goto OUT;
567                 }
568         }
569
570         if (*addr & 0x00220022) {
571                 printf ("*** ERROR: program failed!\n");
572                 res = 1;
573         }
574
575 OUT:
576         /* Clear status register and reset to read mode
577          */
578         *addr = 0x00500050;
579         *addr = 0x00FF00FF;
580
581         return (res);
582 }
583
584 /*-----------------------------------------------------------------------
585  * Write a byte to Flash, returns:
586  * 0 - OK
587  * 1 - write timeout
588  * 2 - Flash not erased
589  */
590 static int write_byte (flash_info_t *info, ulong dest, uchar data)
591 {
592         vu_char *addr = (vu_char *)(info->start[0]);
593         ulong start;
594         int flag;
595
596         /* Check if Flash is (sufficiently) erased */
597         if ((*((vu_char *)dest) & data) != data) {
598                 return (2);
599         }
600         /* Disable interrupts which might cause a timeout here */
601         flag = disable_interrupts();
602
603         addr[0x0555] = 0xAA;
604         addr[0x02AA] = 0x55;
605         addr[0x0555] = 0xA0;
606
607         *((vu_char *)dest) = data;
608
609         /* re-enable interrupts if necessary */
610         if (flag)
611                 enable_interrupts();
612
613         /* data polling for D7 */
614         start = get_timer (0);
615         while ((*((vu_char *)dest) & 0x80) != (data & 0x80)) {
616                 if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
617                         return (1);
618                 }
619         }
620         return (0);
621 }
622
623 /*-----------------------------------------------------------------------
624  */