]> git.sur5r.net Git - u-boot/blob - board/snmc/qs860t/flash.c
Patch by Wolter Kamphuis, 05 Dec 2003:
[u-boot] / board / snmc / qs860t / flash.c
1 /*
2  * (C) Copyright 2003
3  * MuLogic B.V.
4  *
5  * (C) Copyright 2001
6  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
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 <ppc4xx.h>
29 #include <asm/u-boot.h>
30 #include <asm/processor.h>
31
32 flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
33
34
35 #ifdef CFG_FLASH_16BIT
36 #define FLASH_WORD_SIZE unsigned short
37 #define FLASH_ID_MASK   0xFFFF
38 #else
39 #define FLASH_WORD_SIZE unsigned long
40 #define FLASH_ID_MASK   0xFFFFFFFF
41 #endif
42
43 /*-----------------------------------------------------------------------
44  * Functions
45  */
46 /* stolen from esteem192e/flash.c */
47 ulong flash_get_size (volatile FLASH_WORD_SIZE *addr, flash_info_t *info);
48
49 #ifndef CFG_FLASH_16BIT
50 static int write_word (flash_info_t *info, ulong dest, ulong data);
51 #else
52 static int write_short (flash_info_t *info, ulong dest, ushort data);
53 #endif
54 static void flash_get_offsets (ulong base, flash_info_t *info);
55
56
57 /*-----------------------------------------------------------------------
58  */
59
60 unsigned long flash_init (void)
61 {
62         unsigned long size_b0, size_b1;
63         int i;
64         uint pbcr;
65         unsigned long base_b0, base_b1;
66
67         /* Init: no FLASHes known */
68         for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
69                 flash_info[i].flash_id = FLASH_UNKNOWN;
70         }
71
72         /* Static FLASH Bank configuration here - FIXME XXX */
73
74         size_b0 = flash_get_size((volatile FLASH_WORD_SIZE *)FLASH_BASE1_PRELIM, &flash_info[0]);
75
76         if (flash_info[0].flash_id == FLASH_UNKNOWN) {
77                 printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
78                         size_b0, size_b0<<20);
79         }
80
81         /* Only one bank */
82         if (CFG_MAX_FLASH_BANKS == 1)
83         {
84                 /* Setup offsets */
85                 flash_get_offsets (FLASH_BASE1_PRELIM, &flash_info[0]);
86
87                 /* Monitor protection ON by default */
88 #if 0   /* sand: */
89                 (void)flash_protect(FLAG_PROTECT_SET,
90                         FLASH_BASE1_PRELIM-CFG_MONITOR_LEN+size_b0,
91                         FLASH_BASE1_PRELIM-1+size_b0,
92                         &flash_info[0]);
93 #else
94                 (void)flash_protect(FLAG_PROTECT_SET,
95                         CFG_MONITOR_BASE,
96                         CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
97                         &flash_info[0]);
98 #endif
99                 size_b1 = 0 ;
100                 flash_info[0].size = size_b0;
101         }
102         /* 2 banks */
103         else
104         {
105                 size_b1 = flash_get_size((volatile FLASH_WORD_SIZE *)FLASH_BASE1_PRELIM, &flash_info[1]);
106
107                 /* Re-do sizing to get full correct info */
108                 if (size_b1)
109                 {
110                         mtdcr(ebccfga, pb0cr);
111                         pbcr = mfdcr(ebccfgd);
112                         mtdcr(ebccfga, pb0cr);
113                         base_b1 = -size_b1;
114                         pbcr = (pbcr & 0x0001ffff) | base_b1 | (((size_b1/1024/1024)-1)<<17);
115                         mtdcr(ebccfgd, pbcr);
116                 }
117
118                 if (size_b0)
119                 {
120                         mtdcr(ebccfga, pb1cr);
121                         pbcr = mfdcr(ebccfgd);
122                         mtdcr(ebccfga, pb1cr);
123                         base_b0 = base_b1 - size_b0;
124                         pbcr = (pbcr & 0x0001ffff) | base_b0 | (((size_b0/1024/1024)-1)<<17);
125                         mtdcr(ebccfgd, pbcr);
126                 }
127
128                 size_b0 = flash_get_size((volatile FLASH_WORD_SIZE *)base_b0, &flash_info[0]);
129
130                 flash_get_offsets (base_b0, &flash_info[0]);
131
132                 /* monitor protection ON by default */
133 #if 0   /* sand: */
134                 (void)flash_protect(FLAG_PROTECT_SET,
135                         FLASH_BASE1_PRELIM-CFG_MONITOR_LEN+size_b0,
136                         FLASH_BASE1_PRELIM-1+size_b0,
137                         &flash_info[0]);
138 #else
139                 (void)flash_protect(FLAG_PROTECT_SET,
140                         CFG_MONITOR_BASE,
141                         CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
142                         &flash_info[0]);
143 #endif
144
145                 if (size_b1) {
146                         /* Re-do sizing to get full correct info */
147                         size_b1 = flash_get_size((volatile FLASH_WORD_SIZE *)base_b1, &flash_info[1]);
148
149                         flash_get_offsets (base_b1, &flash_info[1]);
150
151                         /* monitor protection ON by default */
152                         (void)flash_protect(FLAG_PROTECT_SET,
153                                 base_b1+size_b1-CFG_MONITOR_LEN,
154                                 base_b1+size_b1-1,
155                                 &flash_info[1]);
156                         /* monitor protection OFF by default (one is enough) */
157                         (void)flash_protect(FLAG_PROTECT_CLEAR,
158                                 base_b0+size_b0-CFG_MONITOR_LEN,
159                                 base_b0+size_b0-1,
160                                 &flash_info[0]);
161                 } else {
162                         flash_info[1].flash_id = FLASH_UNKNOWN;
163                         flash_info[1].sector_count = -1;
164                 }
165
166                 flash_info[0].size = size_b0;
167                 flash_info[1].size = size_b1;
168         }/* else 2 banks */
169         return (size_b0 + size_b1);
170 }
171
172
173
174 /*-----------------------------------------------------------------------
175  */
176
177 static void flash_get_offsets (ulong base, flash_info_t *info)
178 {
179         int i;
180
181         /* set up sector start adress table */
182         if ((info->flash_id & FLASH_TYPEMASK) == INTEL_ID_28F320J3A ||
183                 (info->flash_id & FLASH_TYPEMASK) == INTEL_ID_28F640J3A ||
184                 (info->flash_id & FLASH_TYPEMASK) == INTEL_ID_28F128J3A) {
185                 for (i = 0; i < info->sector_count; i++) {
186                         info->start[i] = base + (i * info->size/info->sector_count);
187                 }
188         }
189         else if (info->flash_id & FLASH_BTYPE) {
190                 if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
191
192 #ifndef CFG_FLASH_16BIT
193                         /* set sector offsets for bottom boot block type */
194                         info->start[0] = base + 0x00000000;
195                         info->start[1] = base + 0x00004000;
196                         info->start[2] = base + 0x00008000;
197                         info->start[3] = base + 0x0000C000;
198                         info->start[4] = base + 0x00010000;
199                         info->start[5] = base + 0x00014000;
200                         info->start[6] = base + 0x00018000;
201                         info->start[7] = base + 0x0001C000;
202                         for (i = 8; i < info->sector_count; i++) {
203                                 info->start[i] = base + (i * 0x00020000) - 0x000E0000;
204                         }
205                 } else {
206                         /* set sector offsets for bottom boot block type */
207                         info->start[0] = base + 0x00000000;
208                         info->start[1] = base + 0x00008000;
209                         info->start[2] = base + 0x0000C000;
210                         info->start[3] = base + 0x00010000;
211                         for (i = 4; i < info->sector_count; i++) {
212                                 info->start[i] = base + (i * 0x00020000) - 0x00060000;
213                         }
214                 }
215 #else
216                         /* set sector offsets for bottom boot block type */
217                         info->start[0] = base + 0x00000000;
218                         info->start[1] = base + 0x00002000;
219                         info->start[2] = base + 0x00004000;
220                         info->start[3] = base + 0x00006000;
221                         info->start[4] = base + 0x00008000;
222                         info->start[5] = base + 0x0000A000;
223                         info->start[6] = base + 0x0000C000;
224                         info->start[7] = base + 0x0000E000;
225                         for (i = 8; i < info->sector_count; i++) {
226                                 info->start[i] = base + (i * 0x00010000) - 0x00070000;
227                         }
228                 } else {
229                         /* set sector offsets for bottom boot block type */
230                         info->start[0] = base + 0x00000000;
231                         info->start[1] = base + 0x00004000;
232                         info->start[2] = base + 0x00006000;
233                         info->start[3] = base + 0x00008000;
234                         for (i = 4; i < info->sector_count; i++) {
235                                 info->start[i] = base + (i * 0x00010000) - 0x00030000;
236                         }
237                 }
238 #endif
239         } else {
240                 /* set sector offsets for top boot block type */
241                 i = info->sector_count - 1;
242                 if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
243
244 #ifndef CFG_FLASH_16BIT
245                         info->start[i--] = base + info->size - 0x00004000;
246                         info->start[i--] = base + info->size - 0x00008000;
247                         info->start[i--] = base + info->size - 0x0000C000;
248                         info->start[i--] = base + info->size - 0x00010000;
249                         info->start[i--] = base + info->size - 0x00014000;
250                         info->start[i--] = base + info->size - 0x00018000;
251                         info->start[i--] = base + info->size - 0x0001C000;
252                         for (; i >= 0; i--) {
253                                 info->start[i] = base + i * 0x00020000;
254                         }
255                 } else {
256
257                         info->start[i--] = base + info->size - 0x00008000;
258                         info->start[i--] = base + info->size - 0x0000C000;
259                         info->start[i--] = base + info->size - 0x00010000;
260                         for (; i >= 0; i--) {
261                                 info->start[i] = base + i * 0x00020000;
262                         }
263                 }
264 #else
265                         info->start[i--] = base + info->size - 0x00002000;
266                         info->start[i--] = base + info->size - 0x00004000;
267                         info->start[i--] = base + info->size - 0x00006000;
268                         info->start[i--] = base + info->size - 0x00008000;
269                         info->start[i--] = base + info->size - 0x0000A000;
270                         info->start[i--] = base + info->size - 0x0000C000;
271                         info->start[i--] = base + info->size - 0x0000E000;
272                         for (; i >= 0; i--) {
273                                 info->start[i] = base + i * 0x00010000;
274                         }
275                 } else {
276                         info->start[i--] = base + info->size - 0x00004000;
277                         info->start[i--] = base + info->size - 0x00006000;
278                         info->start[i--] = base + info->size - 0x00008000;
279                         for (; i >= 0; i--) {
280                                 info->start[i] = base + i * 0x00010000;
281                         }
282                 }
283 #endif
284         }
285 }
286
287 /*-----------------------------------------------------------------------
288  */
289
290 void flash_print_info  (flash_info_t *info)
291 {
292         int i;
293         uchar *boottype;
294         uchar botboot[]=", bottom boot sect)\n";
295         uchar topboot[]=", top boot sector)\n";
296
297         if (info->flash_id == FLASH_UNKNOWN) {
298                 printf ("missing or unknown FLASH type\n");
299                 return;
300         }
301
302         switch (info->flash_id & FLASH_VENDMASK) {
303         case FLASH_MAN_AMD:     printf ("AMD ");                break;
304         case FLASH_MAN_FUJ:     printf ("FUJITSU ");            break;
305         case FLASH_MAN_SST:     printf ("SST ");                break;
306         case FLASH_MAN_STM:     printf ("STM ");                break;
307         case FLASH_MAN_INTEL:   printf ("INTEL ");              break;
308         default:                printf ("Unknown Vendor ");     break;
309         }
310
311         if (info->flash_id & 0x0001 ) {
312                 boottype = botboot;
313         } else {
314                 boottype = topboot;
315         }
316
317         switch (info->flash_id & FLASH_TYPEMASK) {
318         case FLASH_AM400B:      printf ("AM29LV400B (4 Mbit%s",boottype);
319                                 break;
320         case FLASH_AM400T:      printf ("AM29LV400T (4 Mbit%s",boottype);
321                                 break;
322         case FLASH_AM800B:      printf ("AM29LV800B (8 Mbit%s",boottype);
323                                 break;
324         case FLASH_AM800T:      printf ("AM29LV800T (8 Mbit%s",boottype);
325                                 break;
326         case FLASH_AM160B:      printf ("AM29LV160B (16 Mbit%s",boottype);
327                                 break;
328         case FLASH_AM160T:      printf ("AM29LV160T (16 Mbit%s",boottype);
329                                 break;
330         case FLASH_AM320B:      printf ("AM29LV320B (32 Mbit%s",boottype);
331                                 break;
332         case FLASH_AM320T:      printf ("AM29LV320T (32 Mbit%s",boottype);
333                                 break;
334         case FLASH_INTEL800B:   printf ("INTEL28F800B (8 Mbit%s",boottype);
335                                 break;
336         case FLASH_INTEL800T:   printf ("INTEL28F800T (8 Mbit%s",boottype);
337                                 break;
338         case FLASH_INTEL160B:   printf ("INTEL28F160B (16 Mbit%s",boottype);
339                                 break;
340         case FLASH_INTEL160T:   printf ("INTEL28F160T (16 Mbit%s",boottype);
341                                 break;
342         case FLASH_INTEL320B:   printf ("INTEL28F320B (32 Mbit%s",boottype);
343                                 break;
344         case FLASH_INTEL320T:   printf ("INTEL28F320T (32 Mbit%s",boottype);
345                                 break;
346         case FLASH_AMDL322T:    printf ("AM29DL322T (32 Mbit%s",boottype);
347                                 break;
348
349 #if 0 /* enable when devices are available */
350
351         case FLASH_INTEL640B:   printf ("INTEL28F640B (64 Mbit%s",boottype);
352                                 break;
353         case FLASH_INTEL640T:   printf ("INTEL28F640T (64 Mbit%s",boottype);
354                                 break;
355 #endif
356         case INTEL_ID_28F320J3A:        printf ("INTEL28F320JA3 (32 Mbit%s",boottype);
357                                 break;
358         case INTEL_ID_28F640J3A:        printf ("INTEL28F640JA3 (64 Mbit%s",boottype);
359                                 break;
360         case INTEL_ID_28F128J3A:        printf ("INTEL28F128JA3 (128 Mbit%s",boottype);
361                                 break;
362
363         default:                printf ("Unknown Chip Type\n");
364                                 break;
365         }
366
367         printf ("  Size: %ld MB in %d Sectors\n",
368                 info->size >> 20, info->sector_count);
369
370         printf ("  Sector Start Addresses:");
371         for (i=0; i<info->sector_count; ++i) {
372                 if ((i % 5) == 0)
373                         printf ("\n   ");
374                 printf (" %08lX%s",
375                         info->start[i],
376                         info->protect[i] ? " (RO)" : "     "
377                 );
378         }
379         printf ("\n");
380         return;
381 }
382
383
384 /*-----------------------------------------------------------------------
385  */
386
387
388 /*-----------------------------------------------------------------------
389  */
390
391 /*
392  * The following code cannot be run from FLASH!
393  */
394 ulong flash_get_size (volatile FLASH_WORD_SIZE *addr, flash_info_t *info)
395 {
396         short i;
397         ulong base = (ulong)addr;
398         FLASH_WORD_SIZE value;
399
400         /* Write auto select command: read Manufacturer ID */
401
402
403 #ifndef CFG_FLASH_16BIT
404
405         /*
406          * Note: if it is an AMD flash and the word at addr[0000]
407          * is 0x00890089 this routine will think it is an Intel
408          * flash device and may(most likely) cause trouble.
409          */
410
411         addr[0x0000] = 0x00900090;
412         if(addr[0x0000] != 0x00890089){
413                 addr[0x0555] = 0x00AA00AA;
414                 addr[0x02AA] = 0x00550055;
415                 addr[0x0555] = 0x00900090;
416 #else
417
418         /*
419          * Note: if it is an AMD flash and the word at addr[0000]
420          * is 0x0089 this routine will think it is an Intel
421          * flash device and may(most likely) cause trouble.
422          */
423
424         addr[0x0000] = 0x0090;
425
426         if(addr[0x0000] != 0x0089){
427                 addr[0x0555] = 0x00AA;
428                 addr[0x02AA] = 0x0055;
429                 addr[0x0555] = 0x0090;
430 #endif
431         }
432         value = addr[0];
433
434         switch (value) {
435         case (AMD_MANUFACT & FLASH_ID_MASK):
436                 info->flash_id = FLASH_MAN_AMD;
437                 break;
438         case (FUJ_MANUFACT & FLASH_ID_MASK):
439                 info->flash_id = FLASH_MAN_FUJ;
440                 break;
441         case (STM_MANUFACT & FLASH_ID_MASK):
442                 info->flash_id = FLASH_MAN_STM;
443                 break;
444         case (SST_MANUFACT & FLASH_ID_MASK):
445                 info->flash_id = FLASH_MAN_SST;
446                 break;
447         case (INTEL_MANUFACT & FLASH_ID_MASK):
448                 info->flash_id = FLASH_MAN_INTEL;
449                 break;
450         default:
451                 info->flash_id = FLASH_UNKNOWN;
452                 info->sector_count = 0;
453                 info->size = 0;
454                 return (0); /* no or unknown flash */
455
456         }
457
458         value = addr[1];                        /* device ID            */
459
460         switch (value) {
461
462         case (AMD_ID_LV400T & FLASH_ID_MASK):
463                 info->flash_id += FLASH_AM400T;
464                 info->sector_count = 11;
465                 info->size = 0x00100000;
466                 break;                          /* => 1 MB              */
467
468         case (AMD_ID_LV400B & FLASH_ID_MASK):
469                 info->flash_id += FLASH_AM400B;
470                 info->sector_count = 11;
471                 info->size = 0x00100000;
472                 break;                          /* => 1 MB              */
473
474         case (AMD_ID_LV800T & FLASH_ID_MASK):
475                 info->flash_id += FLASH_AM800T;
476                 info->sector_count = 19;
477                 info->size = 0x00200000;
478                 break;                          /* => 2 MB              */
479
480         case (AMD_ID_LV800B & FLASH_ID_MASK):
481                 info->flash_id += FLASH_AM800B;
482                 info->sector_count = 19;
483                 info->size = 0x00200000;
484                 break;                          /* => 2 MB              */
485
486         case (AMD_ID_LV160T & FLASH_ID_MASK):
487                 info->flash_id += FLASH_AM160T;
488                 info->sector_count = 35;
489                 info->size = 0x00400000;
490                 break;                          /* => 4 MB              */
491
492         case (AMD_ID_LV160B & FLASH_ID_MASK):
493                 info->flash_id += FLASH_AM160B;
494                 info->sector_count = 35;
495                 info->size = 0x00400000;
496                 break;                          /* => 4 MB              */
497 #if 0   /* enable when device IDs are available */
498         case (AMD_ID_LV320T & FLASH_ID_MASK):
499                 info->flash_id += FLASH_AM320T;
500                 info->sector_count = 67;
501                 info->size = 0x00800000;
502                 break;                          /* => 8 MB              */
503
504         case (AMD_ID_LV320B & FLASH_ID_MASK):
505                 info->flash_id += FLASH_AM320B;
506                 info->sector_count = 67;
507                 info->size = 0x00800000;
508                 break;                          /* => 8 MB              */
509 #endif
510
511         case (AMD_ID_DL322T & FLASH_ID_MASK):
512                 info->flash_id += FLASH_AMDL322T;
513                 info->sector_count = 71;
514                 info->size = 0x00800000;
515                 break;                          /* => 8 MB              */
516
517         case (INTEL_ID_28F800B3T & FLASH_ID_MASK):
518                 info->flash_id += FLASH_INTEL800T;
519                 info->sector_count = 23;
520                 info->size = 0x00200000;
521                 break;                          /* => 2 MB              */
522
523         case (INTEL_ID_28F800B3B & FLASH_ID_MASK):
524                 info->flash_id += FLASH_INTEL800B;
525                 info->sector_count = 23;
526                 info->size = 0x00200000;
527                 break;                          /* => 2 MB              */
528
529         case (INTEL_ID_28F160B3T & FLASH_ID_MASK):
530                 info->flash_id += FLASH_INTEL160T;
531                 info->sector_count = 39;
532                 info->size = 0x00400000;
533                 break;                          /* => 4 MB              */
534
535         case (INTEL_ID_28F160B3B & FLASH_ID_MASK):
536                 info->flash_id += FLASH_INTEL160B;
537                 info->sector_count = 39;
538                 info->size = 0x00400000;
539                 break;                          /* => 4 MB              */
540
541         case (INTEL_ID_28F320B3T & FLASH_ID_MASK):
542                 info->flash_id += FLASH_INTEL320T;
543                 info->sector_count = 71;
544                 info->size = 0x00800000;
545                 break;                          /* => 8 MB              */
546
547         case (INTEL_ID_28F320B3B & FLASH_ID_MASK):
548                 info->flash_id += FLASH_AM320B;
549                 info->sector_count = 71;
550                 info->size = 0x00800000;
551                 break;                          /* => 8 MB              */
552
553 #if 0 /* enable when devices are available */
554         case (INTEL_ID_28F320B3T & FLASH_ID_MASK):
555                 info->flash_id += FLASH_INTEL320T;
556                 info->sector_count = 135;
557                 info->size = 0x01000000;
558                 break;                          /* => 16 MB             */
559
560         case (INTEL_ID_28F320B3B & FLASH_ID_MASK):
561                 info->flash_id += FLASH_AM320B;
562                 info->sector_count = 135;
563                 info->size = 0x01000000;
564                 break;                          /* => 16 MB             */
565 #endif
566         case (INTEL_ID_28F320J3A & FLASH_ID_MASK):
567                 info->flash_id += FLASH_28F320J3A;
568                 info->sector_count = 32;
569                 info->size = 0x00400000;
570                 break;                          /* => 32 MBit   */
571         case (INTEL_ID_28F640J3A & FLASH_ID_MASK):
572                 info->flash_id += FLASH_28F640J3A;
573                 info->sector_count = 64;
574                 info->size = 0x00800000;
575                 break;                          /* => 64 MBit   */
576         case (INTEL_ID_28F128J3A & FLASH_ID_MASK):
577                 info->flash_id += FLASH_28F128J3A;
578                 info->sector_count = 128;
579                 info->size = 0x01000000;
580                 break;                          /* => 128 MBit          */
581
582         default:
583                 /* FIXME*/
584                 info->flash_id = FLASH_UNKNOWN;
585                 return (0);                     /* => no or unknown flash */
586         }
587
588         flash_get_offsets(base, info);
589
590         /* check for protected sectors */
591         for (i = 0; i < info->sector_count; i++) {
592                 /* read sector protection at sector address, (A7 .. A0) = 0x02 */
593                 /* D0 = 1 if protected */
594                 addr = (volatile FLASH_WORD_SIZE *)(info->start[i]);
595                 info->protect[i] = addr[2] & 1;
596         }
597
598         /*
599          * Prevent writes to uninitialized FLASH.
600          */
601         if (info->flash_id != FLASH_UNKNOWN) {
602                 addr = (volatile FLASH_WORD_SIZE *)info->start[0];
603                 if( (info->flash_id & 0xFF00) == FLASH_MAN_INTEL){
604                         *addr = (0x00F000F0 & FLASH_ID_MASK);   /* reset bank */
605                 } else {
606                         *addr = (0x00FF00FF & FLASH_ID_MASK);   /* reset bank */
607                 }
608         }
609
610         return (info->size);
611 }
612
613
614 /*-----------------------------------------------------------------------
615  */
616
617 int flash_erase (flash_info_t *info, int s_first, int s_last)
618 {
619
620         volatile FLASH_WORD_SIZE *addr=(volatile FLASH_WORD_SIZE*)(info->start[0]);
621         int flag, prot, sect, l_sect, barf;
622         ulong start, now, last;
623         int rcode = 0;
624
625         if ((s_first < 0) || (s_first > s_last)) {
626                 if (info->flash_id == FLASH_UNKNOWN) {
627                         printf ("- missing\n");
628                 } else {
629                         printf ("- no sectors to erase\n");
630                 }
631                 return 1;
632         }
633
634         if ((info->flash_id == FLASH_UNKNOWN) ||
635                 ((info->flash_id > FLASH_AMD_COMP) &&
636                 ( (info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL ) ) ){
637                 printf ("Can't erase unknown flash type - aborted\n");
638                 return 1;
639         }
640
641         prot = 0;
642         for (sect=s_first; sect<=s_last; ++sect) {
643                 if (info->protect[sect]) {
644                         prot++;
645                 }
646         }
647
648         if (prot) {
649                 printf ("- Warning: %d protected sectors will not be erased!\n",
650                         prot);
651         } else {
652                 printf ("\n");
653         }
654
655         l_sect = -1;
656
657         /* Disable interrupts which might cause a timeout here */
658         flag = disable_interrupts();
659     if(info->flash_id < FLASH_AMD_COMP) {
660 #ifndef CFG_FLASH_16BIT
661         addr[0x0555] = 0x00AA00AA;
662         addr[0x02AA] = 0x00550055;
663         addr[0x0555] = 0x00800080;
664         addr[0x0555] = 0x00AA00AA;
665         addr[0x02AA] = 0x00550055;
666 #else
667         addr[0x0555] = 0x00AA;
668         addr[0x02AA] = 0x0055;
669         addr[0x0555] = 0x0080;
670         addr[0x0555] = 0x00AA;
671         addr[0x02AA] = 0x0055;
672 #endif
673         /* Start erase on unprotected sectors */
674         for (sect = s_first; sect<=s_last; sect++) {
675                 if (info->protect[sect] == 0) { /* not protected */
676                         addr = (volatile FLASH_WORD_SIZE *)(info->start[sect]);
677                         addr[0] = (0x00300030 & FLASH_ID_MASK);
678                         l_sect = sect;
679                 }
680         }
681
682         /* re-enable interrupts if necessary */
683         if (flag)
684                 enable_interrupts();
685
686         /* wait at least 80us - let's wait 1 ms */
687         udelay (1000);
688
689         /*
690          * We wait for the last triggered sector
691          */
692         if (l_sect < 0)
693                 goto DONE;
694
695         start = get_timer (0);
696         last  = start;
697         addr = (volatile FLASH_WORD_SIZE*)(info->start[l_sect]);
698         while ((addr[0] & (0x00800080&FLASH_ID_MASK)) !=
699                 (0x00800080&FLASH_ID_MASK)  )
700         {
701                 if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
702                         printf ("Timeout\n");
703                         return 1;
704                 }
705                 /* show that we're waiting */
706                 if ((now - last) > 1000) {      /* every second */
707                         serial_putc ('.');
708                         last = now;
709                 }
710         }
711
712 DONE:
713         /* reset to read mode */
714         addr = (volatile FLASH_WORD_SIZE *)info->start[0];
715         addr[0] = (0x00F000F0 & FLASH_ID_MASK); /* reset bank */
716     } else {
717
718
719         for (sect = s_first; sect<=s_last; sect++) {
720                 if (info->protect[sect] == 0) { /* not protected */
721                         barf = 0;
722 #ifndef CFG_FLASH_16BIT
723                         addr = (vu_long*)(info->start[sect]);
724                         addr[0] = 0x00200020;
725                         addr[0] = 0x00D000D0;
726                         while(!(addr[0] & 0x00800080)); /* wait for error or finish */
727                         if( addr[0] & 0x003A003A) {     /* check for error */
728                                 barf = addr[0] & 0x003A0000;
729                                 if( barf ) {
730                                         barf >>=16;
731                                 } else {
732                                         barf = addr[0] & 0x0000003A;
733                                 }
734                         }
735 #else
736                         addr = (vu_short*)(info->start[sect]);
737                         addr[0] = 0x0020;
738                         addr[0] = 0x00D0;
739                         while(!(addr[0] & 0x0080));     /* wait for error or finish */
740                         if( addr[0] & 0x003A)   /* check for error */
741                                 barf = addr[0] & 0x003A;
742 #endif
743                         if(barf) {
744                                 printf("\nFlash error in sector at %lx\n",(unsigned long)addr);
745                                 if(barf & 0x0002) printf("Block locked, not erased.\n");
746                                 if((barf & 0x0030) == 0x0030)
747                                         printf("Command Sequence error.\n");
748                                 if((barf & 0x0030) == 0x0020)
749                                         printf("Block Erase error.\n");
750                                 if(barf & 0x0008) printf("Vpp Low error.\n");
751                                 rcode = 1;
752                         } else printf(".");
753                         l_sect = sect;
754                 }
755         addr = (volatile FLASH_WORD_SIZE *)info->start[0];
756         addr[0] = (0x00FF00FF & FLASH_ID_MASK); /* reset bank */
757
758         }
759
760     }
761         printf (" done\n");
762         return rcode;
763 }
764
765 /*-----------------------------------------------------------------------
766  */
767
768 /*flash_info_t *addr2info (ulong addr)
769 {
770         flash_info_t *info;
771         int i;
772
773         for (i=0, info=&flash_info[0]; i<CFG_MAX_FLASH_BANKS; ++i, ++info) {
774                 if ((addr >= info->start[0]) &&
775                     (addr < (info->start[0] + info->size)) ) {
776                         return (info);
777                 }
778         }
779
780         return (NULL);
781 }
782 */
783 /*-----------------------------------------------------------------------
784  * Copy memory to flash.
785  * Make sure all target addresses are within Flash bounds,
786  * and no protected sectors are hit.
787  * Returns:
788  * 0 - OK
789  * 1 - write timeout
790  * 2 - Flash not erased
791  * 4 - target range includes protected sectors
792  * 8 - target address not in Flash memory
793  */
794
795 /*int flash_write (uchar *src, ulong addr, ulong cnt)
796 {
797         int i;
798         ulong         end        = addr + cnt - 1;
799         flash_info_t *info_first = addr2info (addr);
800         flash_info_t *info_last  = addr2info (end );
801         flash_info_t *info;
802
803         if (cnt == 0) {
804                 return (0);
805         }
806
807         if (!info_first || !info_last) {
808                 return (8);
809         }
810
811         for (info = info_first; info <= info_last; ++info) {
812                 ulong b_end = info->start[0] + info->size;*/    /* bank end addr */
813 /*              short s_end = info->sector_count - 1;
814                 for (i=0; i<info->sector_count; ++i) {
815                         ulong e_addr = (i == s_end) ? b_end : info->start[i + 1];
816
817                         if ((end >= info->start[i]) && (addr < e_addr) &&
818                             (info->protect[i] != 0) ) {
819                                 return (4);
820                         }
821                 }
822         }
823
824 */      /* finally write data to flash */
825 /*      for (info = info_first; info <= info_last && cnt>0; ++info) {
826                 ulong len;
827
828                 len = info->start[0] + info->size - addr;
829                 if (len > cnt)
830                         len = cnt;
831                 if ((i = write_buff(info, src, addr, len)) != 0) {
832                         return (i);
833                 }
834                 cnt  -= len;
835                 addr += len;
836                 src  += len;
837         }
838         return (0);
839 }
840 */
841 /*-----------------------------------------------------------------------
842  * Copy memory to flash, returns:
843  * 0 - OK
844  * 1 - write timeout
845  * 2 - Flash not erased
846  */
847
848 int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
849 {
850 #ifndef CFG_FLASH_16BIT
851         ulong cp, wp, data;
852         int l;
853 #else
854         ulong cp, wp;
855         ushort data;
856 #endif
857         int i, rc;
858
859 #ifndef CFG_FLASH_16BIT
860
861
862         wp = (addr & ~3);       /* get lower word aligned address */
863
864         /*
865          * handle unaligned start bytes
866          */
867         if ((l = addr - wp) != 0) {
868                 data = 0;
869                 for (i=0, cp=wp; i<l; ++i, ++cp) {
870                         data = (data << 8) | (*(uchar *)cp);
871                 }
872                 for (; i<4 && cnt>0; ++i) {
873                         data = (data << 8) | *src++;
874                         --cnt;
875                         ++cp;
876                 }
877                 for (; cnt==0 && i<4; ++i, ++cp) {
878                         data = (data << 8) | (*(uchar *)cp);
879                 }
880
881                 if ((rc = write_word(info, wp, data)) != 0) {
882                         return (rc);
883                 }
884                 wp += 4;
885         }
886
887         /*
888          * handle word aligned part
889          */
890         while (cnt >= 4) {
891                 data = 0;
892                 for (i=0; i<4; ++i) {
893                         data = (data << 8) | *src++;
894                 }
895                 if ((rc = write_word(info, wp, data)) != 0) {
896                         return (rc);
897                 }
898                 wp  += 4;
899                 cnt -= 4;
900         }
901
902         if (cnt == 0) {
903                 return (0);
904         }
905
906         /*
907          * handle unaligned tail bytes
908          */
909         data = 0;
910         for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
911                 data = (data << 8) | *src++;
912                 --cnt;
913         }
914         for (; i<4; ++i, ++cp) {
915                 data = (data << 8) | (*(uchar *)cp);
916         }
917
918         return (write_word(info, wp, data));
919
920 #else
921         wp = (addr & ~1);       /* get lower word aligned address */
922
923         /*
924          * handle unaligned start byte
925          */
926         if (addr - wp) {
927                 data = 0;
928                 data = (data << 8) | *src++;
929                 --cnt;
930                 if ((rc = write_short(info, wp, data)) != 0) {
931                         return (rc);
932                 }
933                 wp += 2;
934         }
935
936         /*
937          * handle word aligned part
938          */
939 /*      l = 0; used for debuging  */
940         while (cnt >= 2) {
941                 data = 0;
942                 for (i=0; i<2; ++i) {
943                         data = (data << 8) | *src++;
944                 }
945
946 /*              if(!l){
947                         printf("%x",data);
948                         l = 1;
949                 }  used for debuging */
950
951                 if ((rc = write_short(info, wp, data)) != 0) {
952                         return (rc);
953                 }
954                 wp  += 2;
955                 cnt -= 2;
956         }
957
958         if (cnt == 0) {
959                 return (0);
960         }
961
962         /*
963          * handle unaligned tail bytes
964          */
965         data = 0;
966         for (i=0, cp=wp; i<2 && cnt>0; ++i, ++cp) {
967                 data = (data << 8) | *src++;
968                 --cnt;
969         }
970         for (; i<2; ++i, ++cp) {
971                 data = (data << 8) | (*(uchar *)cp);
972         }
973
974         return (write_short(info, wp, data));
975
976
977 #endif
978 }
979
980 /*-----------------------------------------------------------------------
981  * Write a word to Flash, returns:
982  * 0 - OK
983  * 1 - write timeout
984  * 2 - Flash not erased
985  */
986 #ifndef CFG_FLASH_16BIT
987 static int write_word (flash_info_t *info, ulong dest, ulong data)
988 {
989         vu_long *addr = (vu_long*)(info->start[0]);
990         ulong start,barf;
991         int flag;
992
993
994         /* Check if Flash is (sufficiently) erased */
995         if ((*((vu_long *)dest) & data) != data) {
996                 return (2);
997         }
998
999         /* Disable interrupts which might cause a timeout here */
1000         flag = disable_interrupts();
1001
1002         if(info->flash_id > FLASH_AMD_COMP) {
1003                 /* AMD stuff */
1004                 addr[0x0555] = 0x00AA00AA;
1005                 addr[0x02AA] = 0x00550055;
1006                 addr[0x0555] = 0x00A000A0;
1007         } else {
1008                 /* intel stuff */
1009                 *addr = 0x00400040;
1010         }
1011         *((vu_long *)dest) = data;
1012
1013         /* re-enable interrupts if necessary */
1014         if (flag)
1015                 enable_interrupts();
1016
1017         /* data polling for D7 */
1018         start = get_timer (0);
1019
1020         if(info->flash_id > FLASH_AMD_COMP) {
1021                 while ((*((vu_long *)dest) & 0x00800080) != (data & 0x00800080)) {
1022                         if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
1023                                 return (1);
1024                         }
1025                 }
1026         } else {
1027                 while(!(addr[0] & 0x00800080)) {        /* wait for error or finish */
1028                         if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
1029                                 return (1);
1030                         }
1031
1032                 if( addr[0] & 0x003A003A) {     /* check for error */
1033                         barf = addr[0] & 0x003A0000;
1034                         if( barf ) {
1035                                 barf >>=16;
1036                         } else {
1037                                 barf = addr[0] & 0x0000003A;
1038                         }
1039                         printf("\nFlash write error at address %lx\n",(unsigned long)dest);
1040                         if(barf & 0x0002) printf("Block locked, not erased.\n");
1041                         if(barf & 0x0010) printf("Programming error.\n");
1042                         if(barf & 0x0008) printf("Vpp Low error.\n");
1043                         return(2);
1044                 }
1045         }
1046
1047         return (0);
1048 }
1049
1050 #else
1051
1052 static int write_short (flash_info_t *info, ulong dest, ushort data)
1053 {
1054         vu_short *addr = (vu_short*)(info->start[0]);
1055         ulong start,barf;
1056         int flag;
1057
1058         /* Check if Flash is (sufficiently) erased */
1059         if ((*((vu_short *)dest) & data) != data) {
1060                 return (2);
1061         }
1062
1063         /* Disable interrupts which might cause a timeout here */
1064         flag = disable_interrupts();
1065
1066         if(info->flash_id < FLASH_AMD_COMP) {
1067                 /* AMD stuff */
1068                 addr[0x0555] = 0x00AA;
1069                 addr[0x02AA] = 0x0055;
1070                 addr[0x0555] = 0x00A0;
1071         } else {
1072                 /* intel stuff */
1073                 *addr = 0x00D0;
1074                 *addr = 0x0040;
1075         }
1076         *((vu_short *)dest) = data;
1077
1078         /* re-enable interrupts if necessary */
1079         if (flag)
1080                 enable_interrupts();
1081
1082         /* data polling for D7 */
1083         start = get_timer (0);
1084
1085         if(info->flash_id < FLASH_AMD_COMP) {
1086                 /* AMD stuff */
1087                 while ((*((vu_short *)dest) & 0x0080) != (data & 0x0080)) {
1088                         if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
1089                                 return (1);
1090                         }
1091                 }
1092
1093         } else {
1094                 /* intel stuff */
1095                 while(!(addr[0] & 0x0080)){     /* wait for error or finish */
1096                         if (get_timer(start) > CFG_FLASH_WRITE_TOUT) return (1);
1097                 }
1098
1099                 if( addr[0] & 0x003A) { /* check for error */
1100                         barf = addr[0] & 0x003A;
1101                         printf("\nFlash write error at address %lx\n",(unsigned long)dest);
1102                         if(barf & 0x0002) printf("Block locked, not erased.\n");
1103                         if(barf & 0x0010) printf("Programming error.\n");
1104                         if(barf & 0x0008) printf("Vpp Low error.\n");
1105                         return(2);
1106                 }
1107                 *addr = 0x00B0;
1108                 *addr = 0x0070;
1109                 while(!(addr[0] & 0x0080)){     /* wait for error or finish */
1110                         if (get_timer(start) > CFG_FLASH_WRITE_TOUT) return (1);
1111                 }
1112                 *addr = 0x00FF;
1113         }
1114         return (0);
1115 }
1116
1117
1118 #endif
1119
1120 /*-----------------------------------------------------------------------
1121  */