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