source: SVN/rincon/u-boot/board/esteem192e/flash.c @ 55

Last change on this file since 55 was 55, checked in by Tim Harvey, 22 months ago

rincon: added latest u-boot source

restored form server backup

Signed-off-by: Tim Harvey <tharvey@…>

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