source: SVN/rincon/u-boot/board/tqc/tqm5200/cam5200_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: 20.8 KB
Line 
1/*
2 * (C) Copyright 2006
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 <mpc5xxx.h>
26#include <asm/processor.h>
27
28#if defined(CONFIG_CAM5200) && defined(CONFIG_CAM5200_NIOSFLASH)
29
30#if 0
31#define DEBUGF(x...) printf(x)
32#else
33#define DEBUGF(x...)
34#endif
35
36#define swap16(x) __swab16(x)
37
38flash_info_t flash_info[CFG_MAX_FLASH_BANKS];   /* info for FLASH chips */
39
40/*
41 * CAM5200 is a TQM5200B based board. Additionally it also features
42 * a NIOS cpu. The NIOS CPU peripherals are accessible through MPC5xxx
43 * Local Bus on CS5. This includes 32 bit wide RAM and SRAM as well as
44 * 16 bit wide flash device. Big Endian order on a 32 bit CS5 makes
45 * access to flash chip slightly more complicated as additional byte
46 * swapping is necessary within each 16 bit wide flash 'word'.
47 *
48 * This driver's task is to handle both flash devices: 32 bit TQM5200B
49 * flash chip and 16 bit NIOS cpu flash chip. In the below
50 * flash_addr_table table we use least significant address bit to mark
51 * 16 bit flash bank and two sets of routines *_32 and *_16 to handle
52 * specifics of both flashes.
53 */
54static unsigned long flash_addr_table[][CFG_MAX_FLASH_BANKS] = {
55        {CFG_BOOTCS_START, CFG_CS5_START | 1}
56};
57
58/*-----------------------------------------------------------------------
59 * Functions
60 */
61static int write_word(flash_info_t * info, ulong dest, ulong data);
62#ifdef CFG_FLASH_2ND_16BIT_DEV
63static int write_word_32(flash_info_t * info, ulong dest, ulong data);
64static int write_word_16(flash_info_t * info, ulong dest, ulong data);
65static int flash_erase_32(flash_info_t * info, int s_first, int s_last);
66static int flash_erase_16(flash_info_t * info, int s_first, int s_last);
67static ulong flash_get_size_32(vu_long * addr, flash_info_t * info);
68static ulong flash_get_size_16(vu_long * addr, flash_info_t * info);
69#endif
70
71void flash_print_info(flash_info_t * info)
72{
73        int i, k;
74        int size, erased;
75        volatile unsigned long *flash;
76
77        if (info->flash_id == FLASH_UNKNOWN) {
78                printf("missing or unknown FLASH type\n");
79                return;
80        }
81
82        switch (info->flash_id & FLASH_VENDMASK) {
83                case FLASH_MAN_AMD:
84                        printf("AMD ");
85                        break;
86                case FLASH_MAN_FUJ:
87                        printf("FUJITSU ");
88                        break;
89                default:
90                        printf("Unknown Vendor ");
91                        break;
92        }
93
94        switch (info->flash_id & FLASH_TYPEMASK) {
95                case FLASH_S29GL128N:
96                        printf ("S29GL128N (256 Mbit, uniform sector size)\n");
97                        break;
98                case FLASH_AM320B:
99                        printf ("29LV320B (32 Mbit, bottom boot sect)\n");
100                        break;
101                case FLASH_AM320T:
102                        printf ("29LV320T (32 Mbit, top boot sect)\n");
103                        break;
104                default:
105                        printf("Unknown Chip Type\n");
106                        break;
107        }
108
109        printf("  Size: %ld KB in %d Sectors\n",
110                        info->size >> 10, info->sector_count);
111
112        printf("  Sector Start Addresses:");
113        for (i = 0; i < info->sector_count; ++i) {
114                /*
115                 * Check if whole sector is erased
116                 */
117                if (i != (info->sector_count - 1))
118                        size = info->start[i + 1] - info->start[i];
119                else
120                        size = info->start[0] + info->size - info->start[i];
121
122                erased = 1;
123                flash = (volatile unsigned long *)info->start[i];
124                size = size >> 2;       /* divide by 4 for longword access */
125
126                for (k = 0; k < size; k++) {
127                        if (*flash++ != 0xffffffff) {
128                                erased = 0;
129                                break;
130                        }
131                }
132
133                if ((i % 5) == 0)
134                        printf("\n   ");
135
136                printf(" %08lX%s%s", info->start[i],
137                                erased ? " E" : "  ",
138                                info->protect[i] ? "RO " : "   ");
139        }
140        printf("\n");
141        return;
142}
143
144
145/*
146 * The following code cannot be run from FLASH!
147 */
148#ifdef CFG_FLASH_2ND_16BIT_DEV
149static ulong flash_get_size(vu_long * addr, flash_info_t * info)
150{
151
152        DEBUGF("get_size: FLASH ADDR %08lx\n", addr);
153
154        /* bit 0 used for big flash marking */
155        if ((ulong)addr & 0x1)
156                return flash_get_size_16((vu_long *)((ulong)addr & 0xfffffffe), info);
157        else
158                return flash_get_size_32(addr, info);
159}
160
161static ulong flash_get_size_32(vu_long * addr, flash_info_t * info)
162#else
163static ulong flash_get_size(vu_long * addr, flash_info_t * info)
164#endif
165{
166        short i;
167        CFG_FLASH_WORD_SIZE value;
168        ulong base = (ulong) addr;
169        volatile CFG_FLASH_WORD_SIZE *addr2 = (CFG_FLASH_WORD_SIZE *) addr;
170
171        DEBUGF("get_size32: FLASH ADDR: %08x\n", (unsigned)addr);
172
173        /* Write auto select command: read Manufacturer ID */
174        addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00AA00AA;
175        addr2[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x00550055;
176        addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00900090;
177        udelay(1000);
178
179        value = addr2[0];
180        DEBUGF("FLASH MANUFACT: %x\n", value);
181
182        switch (value) {
183                case (CFG_FLASH_WORD_SIZE) AMD_MANUFACT:
184                        info->flash_id = FLASH_MAN_AMD;
185                        break;
186                default:
187                        info->flash_id = FLASH_UNKNOWN;
188                        info->sector_count = 0;
189                        info->size = 0;
190                        return (0);     /* no or unknown flash  */
191        }
192
193        value = addr2[1];       /* device ID            */
194        DEBUGF("\nFLASH DEVICEID: %x\n", value);
195
196        switch (value) {
197                case AMD_ID_MIRROR:
198                        DEBUGF("Mirror Bit flash: addr[14] = %08lX  addr[15] = %08lX\n",
199                                        addr[14], addr[15]);
200                        switch(addr[14]) {
201                                case AMD_ID_GL128N_2:
202                                        if (addr[15] != AMD_ID_GL128N_3) {
203                                                DEBUGF("Chip: S29GL128N -> unknown\n");
204                                                info->flash_id = FLASH_UNKNOWN;
205                                        } else {
206                                                DEBUGF("Chip: S29GL128N\n");
207                                                info->flash_id += FLASH_S29GL128N;
208                                                info->sector_count = 128;
209                                                info->size = 0x02000000;
210                                        }
211                                        break;
212                                default:
213                                        info->flash_id = FLASH_UNKNOWN;
214                                        return(0);
215                        }
216                        break;
217
218                default:
219                        info->flash_id = FLASH_UNKNOWN;
220                        return (0);     /* => no or unknown flash */
221        }
222
223        /* set up sector start address table */
224        for (i = 0; i < info->sector_count; i++)
225                info->start[i] = base + (i * 0x00040000);
226
227        /* check for protected sectors */
228        for (i = 0; i < info->sector_count; i++) {
229                /* read sector protection at sector address, (A7 .. A0) = 0x02 */
230                /* D0 = 1 if protected */
231                addr2 = (volatile CFG_FLASH_WORD_SIZE *)(info->start[i]);
232
233                info->protect[i] = addr2[2] & 1;
234        }
235
236        /* issue bank reset to return to read mode */
237        addr2[0] = (CFG_FLASH_WORD_SIZE) 0x00F000F0;
238
239        return (info->size);
240}
241
242static int wait_for_DQ7_32(flash_info_t * info, int sect)
243{
244        ulong start, now, last;
245        volatile CFG_FLASH_WORD_SIZE *addr =
246                (CFG_FLASH_WORD_SIZE *) (info->start[sect]);
247
248        start = get_timer(0);
249        last = start;
250        while ((addr[0] & (CFG_FLASH_WORD_SIZE) 0x00800080) !=
251                        (CFG_FLASH_WORD_SIZE) 0x00800080) {
252                if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
253                        printf("Timeout\n");
254                        return -1;
255                }
256                /* show that we're waiting */
257                if ((now - last) > 1000) {      /* every second */
258                        putc('.');
259                        last = now;
260                }
261        }
262        return 0;
263}
264
265#ifdef CFG_FLASH_2ND_16BIT_DEV
266int flash_erase(flash_info_t * info, int s_first, int s_last)
267{
268        if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B) {
269                return flash_erase_16(info, s_first, s_last);
270        } else {
271                return flash_erase_32(info, s_first, s_last);
272        }
273}
274
275static int flash_erase_32(flash_info_t * info, int s_first, int s_last)
276#else
277int flash_erase(flash_info_t * info, int s_first, int s_last)
278#endif
279{
280        volatile CFG_FLASH_WORD_SIZE *addr = (CFG_FLASH_WORD_SIZE *) (info->start[0]);
281        volatile CFG_FLASH_WORD_SIZE *addr2;
282        int flag, prot, sect, l_sect;
283
284        if ((s_first < 0) || (s_first > s_last)) {
285                if (info->flash_id == FLASH_UNKNOWN)
286                        printf("- missing\n");
287                else
288                        printf("- no sectors to erase\n");
289                return 1;
290        }
291
292        if (info->flash_id == FLASH_UNKNOWN) {
293                printf("Can't erase unknown flash type - aborted\n");
294                return 1;
295        }
296
297        prot = 0;
298        for (sect = s_first; sect <= s_last; ++sect) {
299                if (info->protect[sect])
300                        prot++;
301        }
302
303        if (prot)
304                printf("- Warning: %d protected sectors will not be erased!", prot);
305
306        printf("\n");
307
308        l_sect = -1;
309
310        /* Disable interrupts which might cause a timeout here */
311        flag = disable_interrupts();
312
313        /* Start erase on unprotected sectors */
314        for (sect = s_first; sect <= s_last; sect++) {
315                if (info->protect[sect] == 0) { /* not protected */
316                        addr2 = (CFG_FLASH_WORD_SIZE *) (info->start[sect]);
317
318                        addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00AA00AA;
319                        addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x00550055;
320                        addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00800080;
321                        addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00AA00AA;
322                        addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x00550055;
323                        addr2[0] = (CFG_FLASH_WORD_SIZE) 0x00300030;    /* sector erase */
324
325                        l_sect = sect;
326                        /*
327                         * Wait for each sector to complete, it's more
328                         * reliable.  According to AMD Spec, you must
329                         * issue all erase commands within a specified
330                         * timeout.  This has been seen to fail, especially
331                         * if printf()s are included (for debug)!!
332                         */
333                        wait_for_DQ7_32(info, sect);
334                }
335        }
336
337        /* re-enable interrupts if necessary */
338        if (flag)
339                enable_interrupts();
340
341        /* wait at least 80us - let's wait 1 ms */
342        udelay(1000);
343
344        /* reset to read mode */
345        addr = (CFG_FLASH_WORD_SIZE *) info->start[0];
346        addr[0] = (CFG_FLASH_WORD_SIZE) 0x00F000F0;     /* reset bank */
347
348        printf(" done\n");
349        return 0;
350}
351
352/*-----------------------------------------------------------------------
353 * Copy memory to flash, returns:
354 * 0 - OK
355 * 1 - write timeout
356 * 2 - Flash not erased
357 */
358int write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt)
359{
360        ulong cp, wp, data;
361        int i, l, rc;
362
363        wp = (addr & ~3);       /* get lower word aligned address */
364
365        /*
366         * handle unaligned start bytes
367         */
368        if ((l = addr - wp) != 0) {
369                data = 0;
370                for (i = 0, cp = wp; i < l; ++i, ++cp)
371                        data = (data << 8) | (*(uchar *) cp);
372
373                for (; i < 4 && cnt > 0; ++i) {
374                        data = (data << 8) | *src++;
375                        --cnt;
376                        ++cp;
377                }
378
379                for (; cnt == 0 && i < 4; ++i, ++cp)
380                        data = (data << 8) | (*(uchar *) cp);
381
382                if ((rc = write_word(info, wp, data)) != 0)
383                        return (rc);
384
385                wp += 4;
386        }
387
388        /*
389         * handle word aligned part
390         */
391        while (cnt >= 4) {
392                data = 0;
393                for (i = 0; i < 4; ++i)
394                        data = (data << 8) | *src++;
395
396                if ((rc = write_word(info, wp, data)) != 0)
397                        return (rc);
398
399                wp += 4;
400                cnt -= 4;
401        }
402
403        if (cnt == 0)
404                return (0);
405
406        /*
407         * handle unaligned tail bytes
408         */
409        data = 0;
410        for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
411                data = (data << 8) | *src++;
412                --cnt;
413        }
414        for (; i < 4; ++i, ++cp)
415                data = (data << 8) | (*(uchar *) cp);
416
417        return (write_word(info, wp, data));
418}
419
420/*-----------------------------------------------------------------------
421 * Copy memory to flash, returns:
422 * 0 - OK
423 * 1 - write timeout
424 * 2 - Flash not erased
425 */
426#ifdef CFG_FLASH_2ND_16BIT_DEV
427static int write_word(flash_info_t * info, ulong dest, ulong data)
428{
429        if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B) {
430                return write_word_16(info, dest, data);
431        } else {
432                return write_word_32(info, dest, data);
433        }
434}
435
436static int write_word_32(flash_info_t * info, ulong dest, ulong data)
437#else
438static int write_word(flash_info_t * info, ulong dest, ulong data)
439#endif
440{
441        volatile CFG_FLASH_WORD_SIZE *addr2 = (CFG_FLASH_WORD_SIZE *) (info->start[0]);
442        volatile CFG_FLASH_WORD_SIZE *dest2 = (CFG_FLASH_WORD_SIZE *) dest;
443        volatile CFG_FLASH_WORD_SIZE *data2 = (CFG_FLASH_WORD_SIZE *) & data;
444        ulong start;
445        int i, flag;
446
447        /* Check if Flash is (sufficiently) erased */
448        if ((*((vu_long *)dest) & data) != data)
449                return (2);
450
451        for (i = 0; i < 4 / sizeof(CFG_FLASH_WORD_SIZE); i++) {
452                /* Disable interrupts which might cause a timeout here */
453                flag = disable_interrupts();
454
455                addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00AA00AA;
456                addr2[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x00550055;
457                addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00A000A0;
458
459                dest2[i] = data2[i];
460
461                /* re-enable interrupts if necessary */
462                if (flag)
463                        enable_interrupts();
464
465                /* data polling for D7 */
466                start = get_timer(0);
467                while ((dest2[i] & (CFG_FLASH_WORD_SIZE) 0x00800080) !=
468                                (data2[i] & (CFG_FLASH_WORD_SIZE) 0x00800080)) {
469
470                        if (get_timer(start) > CFG_FLASH_WRITE_TOUT)
471                                return (1);
472                }
473        }
474
475        return (0);
476}
477
478#ifdef CFG_FLASH_2ND_16BIT_DEV
479
480#undef  CFG_FLASH_WORD_SIZE
481#define CFG_FLASH_WORD_SIZE unsigned short
482
483/*
484 * The following code cannot be run from FLASH!
485 */
486static ulong flash_get_size_16(vu_long * addr, flash_info_t * info)
487{
488        short i;
489        CFG_FLASH_WORD_SIZE value;
490        ulong base = (ulong) addr;
491        volatile CFG_FLASH_WORD_SIZE *addr2 = (CFG_FLASH_WORD_SIZE *) addr;
492
493        DEBUGF("get_size16: FLASH ADDR: %08x\n", (unsigned)addr);
494
495        /* issue bank reset to return to read mode */
496        addr2[0] = (CFG_FLASH_WORD_SIZE) 0xF000F000;
497
498        /* Write auto select command: read Manufacturer ID */
499        addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0xAA00AA00;
500        addr2[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x55005500;
501        addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x90009000;
502        udelay(1000);
503
504        value = swap16(addr2[0]);
505        DEBUGF("FLASH MANUFACT: %x\n", value);
506
507        switch (value) {
508                case (CFG_FLASH_WORD_SIZE) AMD_MANUFACT:
509                        info->flash_id = FLASH_MAN_AMD;
510                        break;
511                case (CFG_FLASH_WORD_SIZE) FUJ_MANUFACT:
512                        info->flash_id = FLASH_MAN_FUJ;
513                        break;
514                default:
515                        info->flash_id = FLASH_UNKNOWN;
516                        info->sector_count = 0;
517                        info->size = 0;
518                        return (0);     /* no or unknown flash  */
519        }
520
521        value = swap16(addr2[1]);       /* device ID            */
522        DEBUGF("\nFLASH DEVICEID: %x\n", value);
523
524        switch (value) {
525                case (CFG_FLASH_WORD_SIZE)AMD_ID_LV320B:
526                        info->flash_id += FLASH_AM320B;
527                        info->sector_count = 71;
528                        info->size = 0x00400000;
529                        break;  /* => 4 MB      */
530                case (CFG_FLASH_WORD_SIZE)AMD_ID_LV320T:
531                        info->flash_id += FLASH_AM320T;
532                        info->sector_count = 71;
533                        info->size = 0x00400000;
534                        break;  /* => 4 MB      */
535                default:
536                        info->flash_id = FLASH_UNKNOWN;
537                        return (0);     /* => no or unknown flash */
538        }
539
540        if (info->flash_id & FLASH_BTYPE) {
541                /* set sector offsets for bottom boot block type        */
542                info->start[0] = base + 0x00000000;
543                info->start[1] = base + 0x00002000;
544                info->start[2] = base + 0x00004000;
545                info->start[3] = base + 0x00006000;
546                info->start[4] = base + 0x00008000;
547                info->start[5] = base + 0x0000a000;
548                info->start[6] = base + 0x0000c000;
549                info->start[7] = base + 0x0000e000;
550
551                for (i = 8; i < info->sector_count; i++)
552                        info->start[i] = base + (i * 0x00010000) - 0x00070000;
553        } else {
554                /* set sector offsets for top boot block type           */
555                i = info->sector_count - 1;
556                info->start[i--] = base + info->size - 0x00002000;
557                info->start[i--] = base + info->size - 0x00004000;
558                info->start[i--] = base + info->size - 0x00006000;
559                info->start[i--] = base + info->size - 0x00008000;
560                info->start[i--] = base + info->size - 0x0000a000;
561                info->start[i--] = base + info->size - 0x0000c000;
562                info->start[i--] = base + info->size - 0x0000e000;
563
564                for (; i >= 0; i--)
565                        info->start[i] = base + i * 0x00010000;
566        }
567
568        /* check for protected sectors */
569        for (i = 0; i < info->sector_count; i++) {
570                /* read sector protection at sector address, (A7 .. A0) = 0x02 */
571                /* D0 = 1 if protected */
572                addr2 = (volatile CFG_FLASH_WORD_SIZE *)(info->start[i]);
573
574                info->protect[i] = addr2[2] & 1;
575        }
576
577        /* issue bank reset to return to read mode */
578        addr2[0] = (CFG_FLASH_WORD_SIZE) 0xF000F000;
579
580        return (info->size);
581}
582
583static int wait_for_DQ7_16(flash_info_t * info, int sect)
584{
585        ulong start, now, last;
586        volatile CFG_FLASH_WORD_SIZE *addr =
587                (CFG_FLASH_WORD_SIZE *) (info->start[sect]);
588
589        start = get_timer(0);
590        last = start;
591        while ((addr[0] & (CFG_FLASH_WORD_SIZE) 0x80008000) !=
592                        (CFG_FLASH_WORD_SIZE) 0x80008000) {
593                if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
594                        printf("Timeout\n");
595                        return -1;
596                }
597                /* show that we're waiting */
598                if ((now - last) > 1000) {      /* every second */
599                        putc('.');
600                        last = now;
601                }
602        }
603        return 0;
604}
605
606static int flash_erase_16(flash_info_t * info, int s_first, int s_last)
607{
608        volatile CFG_FLASH_WORD_SIZE *addr = (CFG_FLASH_WORD_SIZE *) (info->start[0]);
609        volatile CFG_FLASH_WORD_SIZE *addr2;
610        int flag, prot, sect, l_sect;
611
612        if ((s_first < 0) || (s_first > s_last)) {
613                if (info->flash_id == FLASH_UNKNOWN)
614                        printf("- missing\n");
615                else
616                        printf("- no sectors to erase\n");
617                return 1;
618        }
619
620        if (info->flash_id == FLASH_UNKNOWN) {
621                printf("Can't erase unknown flash type - aborted\n");
622                return 1;
623        }
624
625        prot = 0;
626        for (sect = s_first; sect <= s_last; ++sect) {
627                if (info->protect[sect])
628                        prot++;
629        }
630
631        if (prot)
632                printf("- Warning: %d protected sectors will not be erased!",   prot);
633
634        printf("\n");
635
636        l_sect = -1;
637
638        /* Disable interrupts which might cause a timeout here */
639        flag = disable_interrupts();
640
641        /* Start erase on unprotected sectors */
642        for (sect = s_first; sect <= s_last; sect++) {
643                if (info->protect[sect] == 0) { /* not protected */
644                        addr2 = (CFG_FLASH_WORD_SIZE *) (info->start[sect]);
645
646                        addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0xAA00AA00;
647                        addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x55005500;
648                        addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x80008000;
649                        addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0xAA00AA00;
650                        addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x55005500;
651                        addr2[0] = (CFG_FLASH_WORD_SIZE) 0x30003000;    /* sector erase */
652
653                        l_sect = sect;
654                        /*
655                         * Wait for each sector to complete, it's more
656                         * reliable.  According to AMD Spec, you must
657                         * issue all erase commands within a specified
658                         * timeout.  This has been seen to fail, especially
659                         * if printf()s are included (for debug)!!
660                         */
661                        wait_for_DQ7_16(info, sect);
662                }
663        }
664
665        /* re-enable interrupts if necessary */
666        if (flag)
667                enable_interrupts();
668
669        /* wait at least 80us - let's wait 1 ms */
670        udelay(1000);
671
672        /* reset to read mode */
673        addr = (CFG_FLASH_WORD_SIZE *) info->start[0];
674        addr[0] = (CFG_FLASH_WORD_SIZE) 0xF000F000;     /* reset bank */
675
676        printf(" done\n");
677        return 0;
678}
679
680static int write_word_16(flash_info_t * info, ulong dest, ulong data)
681{
682        volatile CFG_FLASH_WORD_SIZE *addr2 = (CFG_FLASH_WORD_SIZE *) (info->start[0]);
683        volatile CFG_FLASH_WORD_SIZE *dest2 = (CFG_FLASH_WORD_SIZE *) dest;
684        volatile CFG_FLASH_WORD_SIZE *data2 = (CFG_FLASH_WORD_SIZE *) & data;
685        ulong start;
686        int i;
687
688        /* Check if Flash is (sufficiently) erased */
689        for (i = 0; i < 4 / sizeof(CFG_FLASH_WORD_SIZE); i++) {
690                if ((dest2[i] & swap16(data2[i])) != swap16(data2[i]))
691                        return (2);
692        }
693
694        for (i = 0; i < 4 / sizeof(CFG_FLASH_WORD_SIZE); i++) {
695                int flag;
696
697                /* Disable interrupts which might cause a timeout here */
698                flag = disable_interrupts();
699
700                addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0xAA00AA00;
701                addr2[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x55005500;
702                addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0xA000A000;
703
704                dest2[i] = swap16(data2[i]);
705
706                /* re-enable interrupts if necessary */
707                if (flag)
708                        enable_interrupts();
709
710                /* data polling for D7 */
711                start = get_timer(0);
712                while ((dest2[i] & (CFG_FLASH_WORD_SIZE) 0x80008000) !=
713                                (swap16(data2[i]) & (CFG_FLASH_WORD_SIZE) 0x80008000)) {
714
715                        if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
716                                return (1);
717                        }
718                }
719        }
720
721        return (0);
722}
723#endif /* CFG_FLASH_2ND_16BIT_DEV */
724
725/*-----------------------------------------------------------------------
726 * Functions
727 */
728static ulong flash_get_size(vu_long * addr, flash_info_t * info);
729static int write_word(flash_info_t * info, ulong dest, ulong data);
730
731/*-----------------------------------------------------------------------
732 */
733
734unsigned long flash_init(void)
735{
736        unsigned long total_b = 0;
737        unsigned long size_b[CFG_MAX_FLASH_BANKS];
738        unsigned short index = 0;
739        int i;
740
741        DEBUGF("\n");
742        DEBUGF("FLASH: Index: %d\n", index);
743
744        /* Init: no FLASHes known */
745        for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
746                flash_info[i].flash_id = FLASH_UNKNOWN;
747                flash_info[i].sector_count = -1;
748                flash_info[i].size = 0;
749
750                /* check whether the address is 0 */
751                if (flash_addr_table[index][i] == 0)
752                        continue;
753
754                /* call flash_get_size() to initialize sector address */
755                size_b[i] = flash_get_size((vu_long *) flash_addr_table[index][i],
756                                &flash_info[i]);
757
758                flash_info[i].size = size_b[i];
759
760                if (flash_info[i].flash_id == FLASH_UNKNOWN) {
761                        printf("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n",
762                                        i+1, size_b[i], size_b[i] << 20);
763                        flash_info[i].sector_count = -1;
764                        flash_info[i].size = 0;
765                }
766
767                /* Monitor protection ON by default */
768                (void)flash_protect(FLAG_PROTECT_SET, CFG_MONITOR_BASE,
769                                    CFG_MONITOR_BASE + CFG_MONITOR_LEN - 1,
770                                    &flash_info[i]);
771#if defined(CONFIG_ENV_IS_IN_FLASH)
772                (void)flash_protect(FLAG_PROTECT_SET, CONFIG_ENV_ADDR,
773                                    CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE - 1,
774                                    &flash_info[i]);
775#if defined(CONFIG_ENV_ADDR_REDUND)
776                (void)flash_protect(FLAG_PROTECT_SET, CONFIG_ENV_ADDR_REDUND,
777                                    CONFIG_ENV_ADDR_REDUND + CONFIG_ENV_SECT_SIZE - 1,
778                                    &flash_info[i]);
779#endif
780#endif
781                total_b += flash_info[i].size;
782        }
783
784        return total_b;
785}
786#endif /* if defined(CONFIG_CAM5200) && defined(CONFIG_CAM5200_NIOSFLASH) */
Note: See TracBrowser for help on using the repository browser.