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