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

Last change on this file since 55 was 55, checked in by Tim Harvey, 3 years ago

rincon: added latest u-boot source

restored form server backup

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

File size: 22.8 KB
Line 
1/*
2 * (C) Copyright 2001
3 * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
4 *
5 * (C) Copyright 2001-2004
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 <linux/byteorder/swab.h>
29
30
31flash_info_t flash_info[CFG_MAX_FLASH_BANKS];   /* info for FLASH chips    */
32
33/* Board support for 1 or 2 flash devices */
34#define FLASH_PORT_WIDTH8
35
36typedef unsigned char FLASH_PORT_WIDTH;
37typedef volatile unsigned char FLASH_PORT_WIDTHV;
38
39#define SWAP(x)         (x)
40
41/* Intel-compatible flash ID */
42#define INTEL_COMPAT    0x89
43#define INTEL_ALT       0xB0
44
45/* Intel-compatible flash commands */
46#define INTEL_PROGRAM   0x10
47#define INTEL_ERASE     0x20
48#define INTEL_CLEAR     0x50
49#define INTEL_LOCKBIT   0x60
50#define INTEL_PROTECT   0x01
51#define INTEL_STATUS    0x70
52#define INTEL_READID    0x90
53#define INTEL_CONFIRM   0xD0
54#define INTEL_RESET     0xFF
55
56/* Intel-compatible flash status bits */
57#define INTEL_FINISHED  0x80
58#define INTEL_OK        0x80
59
60#define FPW             FLASH_PORT_WIDTH
61#define FPWV            FLASH_PORT_WIDTHV
62
63#define FLASH_CYCLE1    0x0555
64#define FLASH_CYCLE2    0x02aa
65
66#define WR_BLOCK        0x20
67/*-----------------------------------------------------------------------
68 * Functions
69 */
70static ulong flash_get_size (FPW * addr, flash_info_t * info);
71static int write_data (flash_info_t * info, ulong dest, FPW data);
72static int write_data_block (flash_info_t * info, ulong src, ulong dest);
73static int write_word_amd (flash_info_t * info, FPWV * dest, FPW data);
74static void flash_get_offsets (ulong base, flash_info_t * info);
75void inline spin_wheel (void);
76static void flash_sync_real_protect (flash_info_t * info);
77static unsigned char intel_sector_protected (flash_info_t *info, ushort sector);
78static unsigned char same_chip_banks (int bank1, int bank2);
79
80/*-----------------------------------------------------------------------
81 */
82
83unsigned long flash_init (void)
84{
85        int i;
86        ulong size = 0;
87        ulong fsize = 0;
88
89        for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
90                memset (&flash_info[i], 0, sizeof (flash_info_t));
91
92                switch (i) {
93                case 0:
94                        flash_get_size ((FPW *) CFG_FLASH1_BASE,
95                                        &flash_info[i]);
96                        flash_get_offsets (CFG_FLASH1_BASE, &flash_info[i]);
97                        break;
98                case 1:
99                        flash_get_size ((FPW *) CFG_FLASH1_BASE,
100                                        &flash_info[i]);
101                        fsize = CFG_FLASH1_BASE + flash_info[i - 1].size;
102                        flash_get_offsets (fsize, &flash_info[i]);
103                        break;
104                case 2:
105                        flash_get_size ((FPW *) CFG_FLASH0_BASE,
106                                        &flash_info[i]);
107                        flash_get_offsets (CFG_FLASH0_BASE, &flash_info[i]);
108                        break;
109                case 3:
110                        flash_get_size ((FPW *) CFG_FLASH0_BASE,
111                                        &flash_info[i]);
112                        fsize = CFG_FLASH0_BASE + flash_info[i - 1].size;
113                        flash_get_offsets (fsize, &flash_info[i]);
114                        break;
115                default:
116                        panic ("configured to many flash banks!\n");
117                        break;
118                }
119                size += flash_info[i].size;
120
121                /* get the h/w and s/w protection status in sync */
122                flash_sync_real_protect(&flash_info[i]);
123        }
124
125        /* Protect monitor and environment sectors
126         */
127#if defined (CFG_AMD_BOOT)
128        flash_protect (FLAG_PROTECT_SET,
129                       CFG_MONITOR_BASE,
130                       CFG_MONITOR_BASE + monitor_flash_len - 1,
131                       &flash_info[2]);
132        flash_protect (FLAG_PROTECT_SET,
133                       CFG_INTEL_BASE,
134                       CFG_INTEL_BASE + monitor_flash_len - 1,
135                       &flash_info[1]);
136#else
137        flash_protect (FLAG_PROTECT_SET,
138                       CFG_MONITOR_BASE,
139                       CFG_MONITOR_BASE + monitor_flash_len - 1,
140                       &flash_info[3]);
141        flash_protect (FLAG_PROTECT_SET,
142                       CFG_AMD_BASE,
143                       CFG_AMD_BASE + monitor_flash_len - 1, &flash_info[0]);
144#endif
145
146        flash_protect (FLAG_PROTECT_SET,
147                       CONFIG_ENV1_ADDR,
148                       CONFIG_ENV1_ADDR + CONFIG_ENV1_SIZE - 1, &flash_info[1]);
149        flash_protect (FLAG_PROTECT_SET,
150                       CONFIG_ENV_ADDR,
151                       CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, &flash_info[3]);
152
153        return size;
154}
155
156/*-----------------------------------------------------------------------
157 */
158static void flash_get_offsets (ulong base, flash_info_t * info)
159{
160        int i;
161
162        if (info->flash_id == FLASH_UNKNOWN)
163                return;
164
165        if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD) {
166                for (i = 0; i < info->sector_count; i++) {
167                        info->start[i] = base + (i * PHYS_AMD_SECT_SIZE);
168                        info->protect[i] = 0;
169                }
170        }
171
172        if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
173                for (i = 0; i < info->sector_count; i++) {
174                        info->start[i] = base + (i * PHYS_INTEL_SECT_SIZE);
175                }
176        }
177}
178
179/*-----------------------------------------------------------------------
180 */
181void flash_print_info (flash_info_t * info)
182{
183        int i;
184
185        if (info->flash_id == FLASH_UNKNOWN) {
186                printf ("missing or unknown FLASH type\n");
187                return;
188        }
189
190        switch (info->flash_id & FLASH_VENDMASK) {
191        case FLASH_MAN_INTEL:
192                printf ("INTEL ");
193                break;
194        case FLASH_MAN_AMD:
195                printf ("AMD ");
196                break;
197        default:
198                printf ("Unknown Vendor ");
199                break;
200        }
201
202        switch (info->flash_id & FLASH_TYPEMASK) {
203        case FLASH_28F128J3A:
204                printf ("28F128J3A\n");
205                break;
206
207        case FLASH_AM040:
208                printf ("AMD29F040B\n");
209                break;
210
211        default:
212                printf ("Unknown Chip Type\n");
213                break;
214        }
215
216        printf ("  Size: %ld MB in %d Sectors\n",
217                info->size >> 20, info->sector_count);
218
219        printf ("  Sector Start Addresses:");
220        for (i = 0; i < info->sector_count; ++i) {
221                if ((i % 5) == 0)
222                        printf ("\n   ");
223                printf (" %08lX%s",
224                        info->start[i], info->protect[i] ? " (RO)" : "     ");
225        }
226        printf ("\n");
227        return;
228}
229
230/*
231 * The following code cannot be run from FLASH!
232 */
233static ulong flash_get_size (FPW * addr, flash_info_t * info)
234{
235        FPWV value;
236        static int amd = 0;
237
238        /* Write auto select command: read Manufacturer ID */
239        /* Write auto select command sequence and test FLASH answer */
240        addr[FLASH_CYCLE1] = (FPW) 0x00AA00AA;  /* for AMD, Intel ignores this */
241        __asm__ ("sync");
242        addr[FLASH_CYCLE2] = (FPW) 0x00550055;  /* for AMD, Intel ignores this */
243        __asm__ ("sync");
244        addr[FLASH_CYCLE1] = (FPW) 0x00900090;  /* selects Intel or AMD */
245        __asm__ ("sync");
246
247        udelay (100);
248
249        switch (addr[0] & 0xff) {
250
251        case (uchar) AMD_MANUFACT:
252                info->flash_id = FLASH_MAN_AMD;
253                value = addr[1];
254                break;
255
256        case (uchar) INTEL_MANUFACT:
257                info->flash_id = FLASH_MAN_INTEL;
258                value = addr[2];
259                break;
260
261        default:
262                printf ("unknown\n");
263                info->flash_id = FLASH_UNKNOWN;
264                info->sector_count = 0;
265                info->size = 0;
266                addr[0] = (FPW) 0x00FF00FF;     /* restore read mode */
267                return (0);     /* no or unknown flash  */
268        }
269
270        switch (value) {
271
272        case (FPW) INTEL_ID_28F128J3A:
273                info->flash_id += FLASH_28F128J3A;
274                info->sector_count = 64;
275                info->size = 0x00800000;        /* => 16 MB     */
276                break;
277
278        case (FPW) AMD_ID_LV040B:
279                info->flash_id += FLASH_AM040;
280                if (amd == 0) {
281                        info->sector_count = 7;
282                        info->size = 0x00070000;        /* => 448 KB     */
283                        amd = 1;
284                } else {
285                        /* for Environment settings */
286                        info->sector_count = 1;
287                        info->size = PHYS_AMD_SECT_SIZE;        /* => 64 KB     */
288                        amd = 0;
289                }
290                break;
291
292        default:
293                info->flash_id = FLASH_UNKNOWN;
294                break;
295        }
296
297        if (info->sector_count > CFG_MAX_FLASH_SECT) {
298                printf ("** ERROR: sector count %d > max (%d) **\n",
299                        info->sector_count, CFG_MAX_FLASH_SECT);
300                info->sector_count = CFG_MAX_FLASH_SECT;
301        }
302
303        if (value == (FPW) INTEL_ID_28F128J3A)
304                addr[0] = (FPW) 0x00FF00FF;     /* restore read mode */
305        else
306                addr[0] = (FPW) 0x00F000F0;     /* restore read mode */
307
308        return (info->size);
309}
310
311
312/*
313 * This function gets the u-boot flash sector protection status
314 * (flash_info_t.protect[]) in sync with the sector protection
315 * status stored in hardware.
316 */
317static void flash_sync_real_protect (flash_info_t * info)
318{
319        int i;
320
321        switch (info->flash_id & FLASH_TYPEMASK) {
322        case FLASH_28F128J3A:
323                for (i = 0; i < info->sector_count; ++i) {
324                        info->protect[i] = intel_sector_protected(info, i);
325                }
326                break;
327        case FLASH_AM040:
328        default:
329                /* no h/w protect support */
330                break;
331        }
332}
333
334
335/*
336 * checks if "sector" in bank "info" is protected. Should work on intel
337 * strata flash chips 28FxxxJ3x in 8-bit mode.
338 * Returns 1 if sector is protected (or timed-out while trying to read
339 * protection status), 0 if it is not.
340 */
341static unsigned char intel_sector_protected (flash_info_t *info, ushort sector)
342{
343        FPWV *addr;
344        FPWV *lock_conf_addr;
345        ulong start;
346        unsigned char ret;
347
348        /*
349         * first, wait for the WSM to be finished. The rationale for
350         * waiting for the WSM to become idle for at most
351         * CFG_FLASH_ERASE_TOUT is as follows. The WSM can be busy
352         * because of: (1) erase, (2) program or (3) lock bit
353         * configuration. So we just wait for the longest timeout of
354         * the (1)-(3), i.e. the erase timeout.
355         */
356
357        /* wait at least 35ns (W12) before issuing Read Status Register */
358        udelay(1);
359        addr = (FPWV *) info->start[sector];
360        *addr = (FPW) INTEL_STATUS;
361
362        start = get_timer (0);
363        while ((*addr & (FPW) INTEL_FINISHED) != (FPW) INTEL_FINISHED) {
364                if (get_timer (start) > CFG_FLASH_ERASE_TOUT) {
365                        *addr = (FPW) INTEL_RESET; /* restore read mode */
366                        printf("WSM busy too long, can't get prot status\n");
367                        return 1;
368                }
369        }
370
371        /* issue the Read Identifier Codes command */
372        *addr = (FPW) INTEL_READID;
373
374        /* wait at least 35ns (W12) before reading */
375        udelay(1);
376
377        /* Intel example code uses offset of 4 for 8-bit flash */
378        lock_conf_addr = (FPWV *) info->start[sector] + 4;
379        ret = (*lock_conf_addr & (FPW) INTEL_PROTECT) ? 1 : 0;
380
381        /* put flash back in read mode */
382        *addr = (FPW) INTEL_RESET;
383
384        return ret;
385}
386
387
388/*
389 * Checks if "bank1" and "bank2" are on the same chip.  Returns 1 if they
390 * are and 0 otherwise.
391 */
392static unsigned char same_chip_banks (int bank1, int bank2)
393{
394        unsigned char same_chip[CFG_MAX_FLASH_BANKS][CFG_MAX_FLASH_BANKS] = {
395                {1, 1, 0, 0},
396                {1, 1, 0, 0},
397                {0, 0, 1, 1},
398                {0, 0, 1, 1}
399        };
400        return same_chip[bank1][bank2];
401}
402
403
404/*-----------------------------------------------------------------------
405 */
406int flash_erase (flash_info_t * info, int s_first, int s_last)
407{
408        int flag, prot, sect;
409        ulong type, start, last;
410        int rcode = 0, intel = 0;
411
412        if ((s_first < 0) || (s_first > s_last)) {
413                if (info->flash_id == FLASH_UNKNOWN)
414                        printf ("- missing\n");
415                else
416                        printf ("- no sectors to erase\n");
417                return 1;
418        }
419
420        type = (info->flash_id & FLASH_VENDMASK);
421        if ((type != FLASH_MAN_INTEL)) {
422                type = (info->flash_id & FLASH_VENDMASK);
423                if ((type != FLASH_MAN_AMD)) {
424                        printf ("Can't erase unknown flash type %08lx - aborted\n",
425                                info->flash_id);
426                        return 1;
427                }
428        }
429
430        if (type == FLASH_MAN_INTEL)
431                intel = 1;
432
433        prot = 0;
434        for (sect = s_first; sect <= s_last; ++sect) {
435                if (info->protect[sect]) {
436                        prot++;
437                }
438        }
439
440        if (prot) {
441                printf ("- Warning: %d protected sectors will not be erased!\n", prot);
442        } else {
443                printf ("\n");
444        }
445
446        start = get_timer (0);
447        last = start;
448
449        /* Disable interrupts which might cause a timeout here */
450        flag = disable_interrupts ();
451
452        /* Start erase on unprotected sectors */
453        for (sect = s_first; sect <= s_last; sect++) {
454                if (info->protect[sect] == 0) { /* not protected */
455                        FPWV *addr = (FPWV *) (info->start[sect]);
456                        FPW status;
457
458                        printf ("Erasing sector %2d ... ", sect);
459
460                        /* arm simple, non interrupt dependent timer */
461                        start = get_timer (0);
462
463                        if (intel) {
464                                *addr = (FPW) 0x00500050;       /* clear status register */
465                                *addr = (FPW) 0x00200020;       /* erase setup */
466                                *addr = (FPW) 0x00D000D0;       /* erase confirm */
467                        } else {
468                                FPWV *base;     /* first address in bank */
469
470                                base = (FPWV *) (CFG_AMD_BASE);
471                                base[FLASH_CYCLE1] = (FPW) 0x00AA00AA;  /* unlock */
472                                base[FLASH_CYCLE2] = (FPW) 0x00550055;  /* unlock */
473                                base[FLASH_CYCLE1] = (FPW) 0x00800080;  /* erase mode */
474                                base[FLASH_CYCLE1] = (FPW) 0x00AA00AA;  /* unlock */
475                                base[FLASH_CYCLE2] = (FPW) 0x00550055;  /* unlock */
476                                *addr = (FPW) 0x00300030;       /* erase sector */
477                        }
478
479                        while (((status =
480                                 *addr) & (FPW) 0x00800080) !=
481                               (FPW) 0x00800080) {
482                                if (get_timer (start) > CFG_FLASH_ERASE_TOUT) {
483                                        printf ("Timeout\n");
484                                        if (intel) {
485                                                *addr = (FPW) 0x00B000B0;       /* suspend erase     */
486                                                *addr = (FPW) 0x00FF00FF;       /* reset to read mode */
487                                        } else
488                                                *addr = (FPW) 0x00F000F0;       /* reset to read mode */
489
490                                        rcode = 1;
491                                        break;
492                                }
493                        }
494
495                        if (intel) {
496                                *addr = (FPW) 0x00500050;       /* clear status register cmd.   */
497                                *addr = (FPW) 0x00FF00FF;       /* resest to read mode          */
498                        } else
499                                *addr = (FPW) 0x00F000F0;       /* reset to read mode */
500
501                        printf (" done\n");
502                }
503        }
504        return rcode;
505}
506
507/*-----------------------------------------------------------------------
508 * Copy memory to flash, returns:
509 * 0 - OK
510 * 1 - write timeout
511 * 2 - Flash not erased
512 * 4 - Flash not identified
513 */
514
515int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
516{
517        if (info->flash_id == FLASH_UNKNOWN) {
518                return 4;
519        }
520
521        switch (info->flash_id & FLASH_VENDMASK) {
522        case FLASH_MAN_AMD:
523            {
524                FPW data = 0;   /* 16 or 32 bit word, matches flash bus width */
525                int bytes;      /* number of bytes to program in current word */
526                int left;       /* number of bytes left to program */
527                int i, res;
528
529                for (left = cnt, res = 0;
530                     left > 0 && res == 0;
531                     addr += sizeof (data), left -=
532                     sizeof (data) - bytes) {
533
534                        bytes = addr & (sizeof (data) - 1);
535                        addr &= ~(sizeof (data) - 1);
536
537                        /* combine source and destination data so can program
538                         * an entire word of 16 or 32 bits
539                         */
540                        for (i = 0; i < sizeof (data); i++) {
541                                data <<= 8;
542                                if (i < bytes || i - bytes >= left)
543                                        data += *((uchar *) addr + i);
544                                else
545                                        data += *src++;
546                        }
547
548                        res = write_word_amd (info, (FPWV *) addr,
549                                              data);
550                }
551                return res;
552            }           /* case FLASH_MAN_AMD */
553
554        case FLASH_MAN_INTEL:
555            {
556                ulong cp, wp;
557                FPW data;
558                int count, i, l, rc, port_width;
559
560                /* get lower word aligned address */
561                wp = addr;
562                port_width = 1;
563
564                /*
565                 * handle unaligned start bytes
566                 */
567                if ((l = addr - wp) != 0) {
568                        data = 0;
569                        for (i = 0, cp = wp; i < l; ++i, ++cp) {
570                                data = (data << 8) | (*(uchar *) cp);
571                        }
572
573                        for (; i < port_width && cnt > 0; ++i) {
574                                data = (data << 8) | *src++;
575                                --cnt;
576                                ++cp;
577                        }
578
579                        for (; cnt == 0 && i < port_width; ++i, ++cp)
580                                data = (data << 8) | (*(uchar *) cp);
581
582                        if ((rc =
583                             write_data (info, wp, SWAP (data))) != 0)
584                                return (rc);
585                        wp += port_width;
586                }
587
588                if (cnt > WR_BLOCK) {
589                        /*
590                         * handle word aligned part
591                         */
592                        count = 0;
593                        while (cnt >= WR_BLOCK) {
594
595                                if ((rc =
596                                     write_data_block (info,
597                                                       (ulong) src,
598                                                       wp)) != 0)
599                                        return (rc);
600
601                                wp += WR_BLOCK;
602                                src += WR_BLOCK;
603                                cnt -= WR_BLOCK;
604
605                                if (count++ > 0x800) {
606                                        spin_wheel ();
607                                        count = 0;
608                                }
609                        }
610                }
611
612                if (cnt < WR_BLOCK) {
613                        /*
614                         * handle word aligned part
615                         */
616                        count = 0;
617                        while (cnt >= port_width) {
618                                data = 0;
619                                for (i = 0; i < port_width; ++i)
620                                        data = (data << 8) | *src++;
621
622                                if ((rc =
623                                     write_data (info, wp,
624                                                 SWAP (data))) != 0)
625                                        return (rc);
626
627                                wp += port_width;
628                                cnt -= port_width;
629                                if (count++ > 0x800) {
630                                        spin_wheel ();
631                                        count = 0;
632                                }
633                        }
634                }
635
636                if (cnt == 0)
637                        return (0);
638
639                /*
640                 * handle unaligned tail bytes
641                 */
642                data = 0;
643                for (i = 0, cp = wp; i < port_width && cnt > 0;
644                     ++i, ++cp) {
645                        data = (data << 8) | *src++;
646                        --cnt;
647                }
648
649                for (; i < port_width; ++i, ++cp)
650                        data = (data << 8) | (*(uchar *) cp);
651
652                return (write_data (info, wp, SWAP (data)));
653            }           /* case FLASH_MAN_INTEL */
654
655        }                       /* switch */
656        return (0);
657}
658
659/*-----------------------------------------------------------------------
660 * Write a word or halfword to Flash, returns:
661 * 0 - OK
662 * 1 - write timeout
663 * 2 - Flash not erased
664 */
665static int write_data (flash_info_t * info, ulong dest, FPW data)
666{
667        FPWV *addr = (FPWV *) dest;
668        ulong start;
669        int flag;
670
671        /* Check if Flash is (sufficiently) erased */
672        if ((*addr & data) != data) {
673                printf ("not erased at %08lx (%lx)\n", (ulong)addr, (ulong)*addr);
674                return (2);
675        }
676        /* Disable interrupts which might cause a timeout here */
677        flag = disable_interrupts ();
678
679        *addr = (FPW) 0x00400040;       /* write setup */
680        *addr = data;
681
682        /* arm simple, non interrupt dependent timer */
683        start = get_timer (0);
684
685        /* wait while polling the status register */
686        while ((*addr & (FPW) 0x00800080) != (FPW) 0x00800080) {
687                if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
688                        *addr = (FPW) 0x00FF00FF;       /* restore read mode */
689                        return (1);
690                }
691        }
692
693        *addr = (FPW) 0x00FF00FF;       /* restore read mode */
694
695        return (0);
696}
697
698/*-----------------------------------------------------------------------
699 * Write a word or halfword to Flash, returns:
700 * 0 - OK
701 * 1 - write timeout
702 * 2 - Flash not erased
703 */
704static int write_data_block (flash_info_t * info, ulong src, ulong dest)
705{
706        FPWV *srcaddr = (FPWV *) src;
707        FPWV *dstaddr = (FPWV *) dest;
708        ulong start;
709        int flag, i;
710
711        /* Check if Flash is (sufficiently) erased */
712        for (i = 0; i < WR_BLOCK; i++)
713                if ((*dstaddr++ & 0xff) != 0xff) {
714                        printf ("not erased at %08lx (%lx)\n",
715                                (ulong)dstaddr, (ulong)*dstaddr);
716                        return (2);
717                }
718
719        dstaddr = (FPWV *) dest;
720
721        /* Disable interrupts which might cause a timeout here */
722        flag = disable_interrupts ();
723
724        *dstaddr = (FPW) 0x00e800e8;    /* write block setup */
725
726        /* arm simple, non interrupt dependent timer */
727        start = get_timer (0);
728
729        /* wait while polling the status register */
730        while ((*dstaddr & (FPW) 0x00800080) != (FPW) 0x00800080) {
731                if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
732                        *dstaddr = (FPW) 0x00FF00FF;    /* restore read mode */
733                        return (1);
734                }
735        }
736
737        *dstaddr = (FPW) 0x001f001f;    /* write 32 to buffer */
738        for (i = 0; i < WR_BLOCK; i++)
739                *dstaddr++ = *srcaddr++;
740
741        dstaddr -= 1;
742        *dstaddr = (FPW) 0x00d000d0;    /* write 32 to buffer */
743
744        /* arm simple, non interrupt dependent timer */
745        start = get_timer (0);
746
747        /* wait while polling the status register */
748        while ((*dstaddr & (FPW) 0x00800080) != (FPW) 0x00800080) {
749                if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
750                        *dstaddr = (FPW) 0x00FF00FF;    /* restore read mode */
751                        return (1);
752                }
753        }
754
755        *dstaddr = (FPW) 0x00FF00FF;    /* restore read mode */
756
757        return (0);
758}
759
760/*-----------------------------------------------------------------------
761 * Write a word to Flash for AMD FLASH
762 * A word is 16 or 32 bits, whichever the bus width of the flash bank
763 * (not an individual chip) is.
764 *
765 * returns:
766 * 0 - OK
767 * 1 - write timeout
768 * 2 - Flash not erased
769 */
770static int write_word_amd (flash_info_t * info, FPWV * dest, FPW data)
771{
772        ulong start;
773        int flag;
774        int res = 0;            /* result, assume success */
775        FPWV *base;             /* first address in flash bank */
776
777        /* Check if Flash is (sufficiently) erased */
778        if ((*dest & data) != data) {
779                return (2);
780        }
781
782        base = (FPWV *) (CFG_AMD_BASE);
783
784        /* Disable interrupts which might cause a timeout here */
785        flag = disable_interrupts ();
786
787        base[FLASH_CYCLE1] = (FPW) 0x00AA00AA;  /* unlock */
788        base[FLASH_CYCLE2] = (FPW) 0x00550055;  /* unlock */
789        base[FLASH_CYCLE1] = (FPW) 0x00A000A0;  /* selects program mode */
790
791        *dest = data;           /* start programming the data */
792
793        /* re-enable interrupts if necessary */
794        if (flag)
795                enable_interrupts ();
796
797        start = get_timer (0);
798
799        /* data polling for D7 */
800        while (res == 0
801               && (*dest & (FPW) 0x00800080) != (data & (FPW) 0x00800080)) {
802                if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
803                        *dest = (FPW) 0x00F000F0;       /* reset bank */
804                        res = 1;
805                }
806        }
807
808        return (res);
809}
810
811void inline spin_wheel (void)
812{
813        static int p = 0;
814        static char w[] = "\\/-";
815
816        printf ("\010%c", w[p]);
817        (++p == 3) ? (p = 0) : 0;
818}
819
820/*-----------------------------------------------------------------------
821 * Set/Clear sector's lock bit, returns:
822 * 0 - OK
823 * 1 - Error (timeout, voltage problems, etc.)
824 */
825int flash_real_protect (flash_info_t * info, long sector, int prot)
826{
827        ulong start;
828        int i, j;
829        int curr_bank;
830        int bank;
831        int rc = 0;
832        FPWV *addr = (FPWV *) (info->start[sector]);
833        int flag = disable_interrupts ();
834
835        /*
836         * 29F040B AMD flash does not support software protection/unprotection,
837         * the only way to protect the AMD flash is marked it as prot bit.
838         * This flash only support hardware protection, by supply or not supply
839         * 12vpp to the flash
840         */
841        if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD) {
842                info->protect[sector] = prot;
843
844                return 0;
845        }
846
847        *addr = INTEL_CLEAR;    /* Clear status register    */
848        if (prot) {             /* Set sector lock bit      */
849                *addr = INTEL_LOCKBIT;  /* Sector lock bit          */
850                *addr = INTEL_PROTECT;  /* set                      */
851        } else {                /* Clear sector lock bit    */
852                *addr = INTEL_LOCKBIT;  /* All sectors lock bits    */
853                *addr = INTEL_CONFIRM;  /* clear                    */
854        }
855
856        start = get_timer (0);
857
858        while ((*addr & INTEL_FINISHED) != INTEL_FINISHED) {
859                if (get_timer (start) > CFG_FLASH_UNLOCK_TOUT) {
860                        printf ("Flash lock bit operation timed out\n");
861                        rc = 1;
862                        break;
863                }
864        }
865
866        if (*addr != INTEL_OK) {
867                printf ("Flash lock bit operation failed at %08X, CSR=%08X\n",
868                        (uint) addr, (uint) * addr);
869                rc = 1;
870        }
871
872        if (!rc)
873                info->protect[sector] = prot;
874
875        /*
876         * Clear lock bit command clears all sectors lock bits, so
877         * we have to restore lock bits of protected sectors.
878         */
879        if (!prot) {
880                /*
881                 * re-locking must be done for all banks that belong on one
882                 * FLASH chip, as all the sectors on the chip were unlocked
883                 * by INTEL_LOCKBIT/INTEL_CONFIRM commands. (let's hope
884                 * that banks never span chips, in particular chips which
885                 * support h/w protection differently).
886                 */
887
888                /* find the current bank number */
889                curr_bank = CFG_MAX_FLASH_BANKS + 1;
890                for (j = 0; j < CFG_MAX_FLASH_BANKS; ++j) {
891                        if (&flash_info[j] == info) {
892                                curr_bank = j;
893                        }
894                }
895                if (curr_bank == CFG_MAX_FLASH_BANKS + 1) {
896                        printf("Error: can't determine bank number!\n");
897                }
898
899                for (bank = 0; bank < CFG_MAX_FLASH_BANKS; ++bank) {
900                        if (!same_chip_banks(curr_bank, bank)) {
901                                continue;
902                        }
903                        info = &flash_info[bank];
904                        for (i = 0; i < info->sector_count; i++) {
905                                if (info->protect[i]) {
906                                        start = get_timer (0);
907                                        addr = (FPWV *) (info->start[i]);
908                                        *addr = INTEL_LOCKBIT;  /* Sector lock bit  */
909                                        *addr = INTEL_PROTECT;  /* set              */
910                                        while ((*addr & INTEL_FINISHED) !=
911                                               INTEL_FINISHED) {
912                                                if (get_timer (start) >
913                                                    CFG_FLASH_UNLOCK_TOUT) {
914                                                        printf ("Flash lock bit operation timed out\n");
915                                                        rc = 1;
916                                                        break;
917                                                }
918                                        }
919                                }
920                        }
921                }
922
923                /*
924                 * get the s/w sector protection status in sync with the h/w,
925                 * in case something went wrong during the re-locking.
926                 */
927                flash_sync_real_protect(info); /* resets flash to read  mode */
928        }
929
930        if (flag)
931                enable_interrupts ();
932
933        *addr = INTEL_RESET;    /* Reset to read array mode */
934
935        return rc;
936}
Note: See TracBrowser for help on using the repository browser.