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