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

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

rincon: added latest u-boot source

restored form server backup

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

File size: 20.2 KB
Line 
1/*
2 * MOUSSE/MPC8240 Board definitions.
3 * Flash Routines for MOUSSE onboard AMD29LV106DB devices
4 *
5 * (C) Copyright 2000
6 * Marius Groeger <mgroeger@sysgo.de>
7 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
8 *
9 * (C) Copyright 2000
10 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
11 *
12 * (C) Copyright 1999, by Curt McDowell, 08-06-99, Broadcom Corp.
13 * (C) Copyright 2001, James Dougherty, 07/18/01, Broadcom Corp.
14 *
15 * See file CREDITS for list of people who contributed to this
16 * project.
17 *
18 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License as
20 * published by the Free Software Foundation; either version 2 of
21 * the License, or (at your option) any later version.
22 *
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
31 * MA 02111-1307 USA
32 */
33
34#include <common.h>
35#include <mpc8xx.h>
36#include <malloc.h>
37#include "mousse.h"
38#include "flash.h"
39
40int flashLibDebug = 0;
41int flashLibInited = 0;
42
43#define OK  0
44#define ERROR -1
45#define STATUS int
46#define PRINTF                  if (flashLibDebug) printf
47#if 0
48#define PRIVATE                 static
49#else
50#define PRIVATE
51#endif
52
53flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
54
55#define SLEEP_DELAY    166
56#define FLASH_SECTOR_SIZE   (64*1024)
57/***********************************************************************
58 *
59 * Virtual Flash Devices on Mousse board
60 *
61 * These must be kept in sync with the definitions in flashLib.h.
62 *
63 ***********************************************************************/
64
65PRIVATE flash_dev_t flashDev[] = {
66    /* Bank 0 sector SA0 (16 kB) */
67    {   "SA0",FLASH0_BANK, FLASH0_SEG0_START, 1, 14,
68        FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
69    },
70    /* Bank 0 sector SA1 (8 kB) */
71    {   "SA1", FLASH0_BANK, FLASH0_SEG0_START + 0x4000, 1, 13,
72        FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
73    },
74    /* Bank 0 sector SA2 (8 kB) */
75    {   "SA2", FLASH0_BANK, FLASH0_SEG0_START + 0x6000, 1, 13,
76        FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
77    },
78    /* Bank 0 sector SA3 is occluded by Mousse I/O devices */
79    /* Bank 0 sectors SA4-SA18, after Mousse devices up to PLCC (960 kB)  */
80    {   "KERNEL", FLASH0_BANK, FLASH0_SEG1_START, 15, 16,
81        FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
82    },
83    /* Bank 0 sectors SA19-SA26, jumper can occlude this by PLCC (512 kB) */
84    /* This is where the Kahlua boot vector and boot ROM code resides. */
85    {   "BOOT",FLASH0_BANK, FLASH0_SEG2_START, 8, 16,
86        FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
87    },
88    /* Bank 0 sectors SA27-SA34 (512 kB) */
89    {   "RAMDISK",FLASH0_BANK, FLASH0_SEG3_START, 8, 16,
90        FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
91    },
92};
93
94int flashDevCount = (sizeof (flashDev) / sizeof (flashDev[0]));
95
96#define DEV(no)                 (&flashDev[no])
97#define DEV_NO(dev)             ((dev) - flashDev)
98
99/***********************************************************************
100 *
101 * Private Flash Routines
102 *
103 ***********************************************************************/
104
105/*
106 * The convention is:
107 *
108 * "addr" is always the PROM raw address, which is the address of an
109 * 8-bit quantity for flash 0 and 16-bit quantity for flash 1.
110 *
111 * "pos" is always a logical byte position from the PROM beginning.
112 */
113
114#define FLASH0_ADDR(dev, addr) \
115        ((unsigned char *) ((dev)->base + (addr)))
116
117#define FLASH0_WRITE(dev, addr, value) \
118        (*FLASH0_ADDR(dev, addr) = (value))
119
120#define FLASH0_READ(dev, addr) \
121        (*FLASH0_ADDR(dev, addr))
122
123PRIVATE int flashCheck (flash_dev_t * dev)
124{
125        if (!flashLibInited) {
126                printf ("flashCheck: flashLib not initialized\n");
127                return ERROR;
128        }
129
130        if (dev < &flashDev[0] || dev >= &flashDev[flashDevCount]) {
131                printf ("flashCheck: Bad dev parameter\n");
132                return ERROR;
133        }
134
135        if (!dev->found) {
136                printf ("flashCheck: Device %d not available\n", DEV_NO (dev));
137                return ERROR;
138        }
139
140        return OK;
141}
142
143PRIVATE void flashReset (flash_dev_t * dev)
144{
145        PRINTF ("flashReset: dev=%d\n", DEV_NO (dev));
146
147        if (dev->bank == FLASH0_BANK) {
148                FLASH0_WRITE (dev, 0x555, 0xaa);
149                FLASH0_WRITE (dev, 0xaaa, 0x55);
150                FLASH0_WRITE (dev, 0x555, 0xf0);
151        }
152
153        udelay (SLEEP_DELAY);
154
155        PRINTF ("flashReset: done\n");
156}
157
158PRIVATE int flashProbe (flash_dev_t * dev)
159{
160        int rv, deviceID, vendorID;
161
162        PRINTF ("flashProbe: dev=%d\n", DEV_NO (dev));
163
164        if (dev->bank != FLASH0_BANK) {
165                rv = ERROR;
166                goto DONE;
167        }
168
169        FLASH0_WRITE (dev, 0xaaa, 0xaa);
170        FLASH0_WRITE (dev, 0x555, 0x55);
171        FLASH0_WRITE (dev, 0xaaa, 0x90);
172
173        udelay (SLEEP_DELAY);
174
175        vendorID = FLASH0_READ (dev, 0);
176        deviceID = FLASH0_READ (dev, 2);
177
178        FLASH0_WRITE (dev, 0, 0xf0);
179
180        PRINTF ("flashProbe: vendor=0x%x device=0x%x\n", vendorID, deviceID);
181
182        if (vendorID == dev->vendorID && deviceID == dev->deviceID)
183                rv = OK;
184        else
185                rv = ERROR;
186
187  DONE:
188        PRINTF ("flashProbe: rv=%d\n", rv);
189
190        return rv;
191}
192
193PRIVATE int flashWait (flash_dev_t * dev, int addr, int expect, int erase)
194{
195        int rv = ERROR;
196        int i, data;
197        int polls;
198
199#if 0
200        PRINTF ("flashWait: dev=%d addr=0x%x expect=0x%x erase=%d\n",
201                DEV_NO (dev), addr, expect, erase);
202#endif
203
204        if (dev->bank != FLASH0_BANK) {
205                rv = ERROR;
206                goto done;
207        }
208
209        if (erase)
210                polls = FLASH_ERASE_SECTOR_TIMEOUT;     /* Ticks */
211        else
212                polls = FLASH_PROGRAM_POLLS;    /* Loops */
213
214        for (i = 0; i < polls; i++) {
215                if (erase)
216                        udelay (SLEEP_DELAY);
217
218                data = FLASH0_READ (dev, addr);
219
220                if (((data ^ expect) & 0x80) == 0) {
221                        rv = OK;
222                        goto done;
223                }
224
225                if (data & 0x20) {
226                        /*
227                         * If the 0x20 bit has come on, it could actually be because
228                         * the operation succeeded, so check the done bit again.
229                         */
230
231                        data = FLASH0_READ (dev, addr);
232
233                        if (((data ^ expect) & 0x80) == 0) {
234                                rv = OK;
235                                goto done;
236                        }
237
238                        printf ("flashWait: Program error (dev: %d, addr: 0x%x)\n",
239                                        DEV_NO (dev), addr);
240
241                        flashReset (dev);
242                        rv = ERROR;
243                        goto done;
244                }
245        }
246
247        printf ("flashWait: Timeout %s (dev: %d, addr: 0x%x)\n",
248                erase ? "erasing sector" : "programming byte",
249                DEV_NO (dev), addr);
250
251  done:
252
253#if 0
254        PRINTF ("flashWait: rv=%d\n", rv);
255#endif
256
257        return rv;
258}
259
260/***********************************************************************
261 *
262 * Public Flash Routines
263 *
264 ***********************************************************************/
265
266STATUS flashLibInit (void)
267{
268        int i;
269
270        PRINTF ("flashLibInit: devices=%d\n", flashDevCount);
271
272        for (i = 0; i < flashDevCount; i++) {
273                flash_dev_t *dev = &flashDev[i];
274
275                /*
276                 * For bank 1, probe both without and with byte swappage,
277                 * so that this module works on both old and new Mousse boards.
278                 */
279
280                flashReset (dev);
281
282                if (flashProbe (dev) != ERROR)
283                        dev->found = 1;
284
285                flashReset (dev);
286
287                if (flashProbe (dev) != ERROR)
288                        dev->found = 1;
289
290                dev->swap = 0;
291
292                if (dev->found) {
293                        PRINTF ("\n  FLASH %s[%d]: iobase=0x%x - %d sectors %d KB",
294                                flashDev[i].name, i, flashDev[i].base,
295                                flashDev[i].sectors,
296                                (flashDev[i].sectors * FLASH_SECTOR_SIZE) / 1024);
297
298                }
299        }
300
301        flashLibInited = 1;
302
303        PRINTF ("flashLibInit: done\n");
304
305        return OK;
306}
307
308STATUS flashEraseSector (flash_dev_t * dev, int sector)
309{
310        int pos, addr;
311
312        PRINTF ("flashErasesector: dev=%d sector=%d\n", DEV_NO (dev), sector);
313
314        if (flashCheck (dev) == ERROR)
315                return ERROR;
316
317        if (sector < 0 || sector >= dev->sectors) {
318                printf ("flashEraseSector: Sector out of range (dev: %d, sector: %d)\n", DEV_NO (dev), sector);
319                return ERROR;
320        }
321
322        pos = FLASH_SECTOR_POS (dev, sector);
323
324        if (dev->bank != FLASH0_BANK) {
325                return ERROR;
326        }
327
328        addr = pos;
329
330        FLASH0_WRITE (dev, 0xaaa, 0xaa);
331        FLASH0_WRITE (dev, 0x555, 0x55);
332        FLASH0_WRITE (dev, 0xaaa, 0x80);
333        FLASH0_WRITE (dev, 0xaaa, 0xaa);
334        FLASH0_WRITE (dev, 0x555, 0x55);
335        FLASH0_WRITE (dev, addr, 0x30);
336
337        return flashWait (dev, addr, 0xff, 1);
338}
339
340/*
341 * Note: it takes about as long to flash all sectors together with Chip
342 * Erase as it does to flash them one at a time (about 30 seconds for 2
343 * MB).  Also since we want to be able to treat subsets of sectors as if
344 * they were complete devices, we don't use Chip Erase.
345 */
346
347STATUS flashErase (flash_dev_t * dev)
348{
349        int sector;
350
351        PRINTF ("flashErase: dev=%d sectors=%d\n", DEV_NO (dev), dev->sectors);
352
353        if (flashCheck (dev) == ERROR)
354                return ERROR;
355
356        for (sector = 0; sector < dev->sectors; sector++) {
357                if (flashEraseSector (dev, sector) == ERROR)
358                        return ERROR;
359        }
360        return OK;
361}
362
363/*
364 * Read and write bytes
365 */
366
367STATUS flashRead (flash_dev_t * dev, int pos, char *buf, int len)
368{
369        int addr, words;
370
371        PRINTF ("flashRead: dev=%d pos=0x%x buf=0x%x len=0x%x\n",
372                DEV_NO (dev), pos, (int) buf, len);
373
374        if (flashCheck (dev) == ERROR)
375                return ERROR;
376
377        if (pos < 0 || len < 0 || pos + len > FLASH_MAX_POS (dev)) {
378                printf ("flashRead: Position out of range "
379                        "(dev: %d, pos: 0x%x, len: 0x%x)\n",
380                        DEV_NO (dev), pos, len);
381                return ERROR;
382        }
383
384        if (len == 0)
385                return OK;
386
387        if (dev->bank == FLASH0_BANK) {
388                addr = pos;
389                words = len;
390
391                PRINTF ("flashRead: memcpy(0x%x, 0x%x, 0x%x)\n",
392                        (int) buf, (int) FLASH0_ADDR (dev, pos), len);
393
394                memcpy (buf, FLASH0_ADDR (dev, addr), words);
395
396        }
397        PRINTF ("flashRead: rv=OK\n");
398
399        return OK;
400}
401
402STATUS flashWrite (flash_dev_t * dev, int pos, char *buf, int len)
403{
404        int addr, words;
405
406        PRINTF ("flashWrite: dev=%d pos=0x%x buf=0x%x len=0x%x\n",
407                DEV_NO (dev), pos, (int) buf, len);
408
409        if (flashCheck (dev) == ERROR)
410                return ERROR;
411
412        if (pos < 0 || len < 0 || pos + len > FLASH_MAX_POS (dev)) {
413                printf ("flashWrite: Position out of range "
414                        "(dev: %d, pos: 0x%x, len: 0x%x)\n",
415                        DEV_NO (dev), pos, len);
416                return ERROR;
417        }
418
419        if (len == 0)
420                return OK;
421
422        if (dev->bank == FLASH0_BANK) {
423                unsigned char tmp;
424
425                addr = pos;
426                words = len;
427
428                while (words--) {
429                        tmp = *buf;
430                        if (~FLASH0_READ (dev, addr) & tmp) {
431                                printf ("flashWrite: Attempt to program 0 to 1 "
432                                        "(dev: %d, addr: 0x%x, data: 0x%x)\n",
433                                        DEV_NO (dev), addr, tmp);
434                                return ERROR;
435                        }
436                        FLASH0_WRITE (dev, 0xaaa, 0xaa);
437                        FLASH0_WRITE (dev, 0x555, 0x55);
438                        FLASH0_WRITE (dev, 0xaaa, 0xa0);
439                        FLASH0_WRITE (dev, addr, tmp);
440                        if (flashWait (dev, addr, tmp, 0) < 0)
441                                return ERROR;
442                        buf++;
443                        addr++;
444                }
445        }
446
447        PRINTF ("flashWrite: rv=OK\n");
448
449        return OK;
450}
451
452/*
453 * flashWritable returns TRUE if a range contains all F's.
454 */
455
456STATUS flashWritable (flash_dev_t * dev, int pos, int len)
457{
458        int addr, words;
459        int rv = ERROR;
460
461        PRINTF ("flashWritable: dev=%d pos=0x%x len=0x%x\n",
462                        DEV_NO (dev), pos, len);
463
464        if (flashCheck (dev) == ERROR)
465                goto done;
466
467        if (pos < 0 || len < 0 || pos + len > FLASH_MAX_POS (dev)) {
468                printf ("flashWritable: Position out of range "
469                        "(dev: %d, pos: 0x%x, len: 0x%x)\n",
470                        DEV_NO (dev), pos, len);
471                goto done;
472        }
473
474        if (len == 0) {
475                rv = 1;
476                goto done;
477        }
478
479        if (dev->bank == FLASH0_BANK) {
480                addr = pos;
481                words = len;
482
483                while (words--) {
484                        if (FLASH0_READ (dev, addr) != 0xff) {
485                                rv = 0;
486                                goto done;
487                        }
488                        addr++;
489                }
490        }
491
492        rv = 1;
493
494  done:
495        PRINTF ("flashWrite: rv=%d\n", rv);
496        return rv;
497}
498
499
500/*
501 * NOTE: the below code cannot run from FLASH!!!
502 */
503/***********************************************************************
504 *
505 * Flash Diagnostics
506 *
507 ***********************************************************************/
508
509STATUS flashDiag (flash_dev_t * dev)
510{
511        unsigned int *buf = 0;
512        int i, len, sector;
513        int rv = ERROR;
514
515        if (flashCheck (dev) == ERROR)
516                return ERROR;
517
518        printf ("flashDiag: Testing device %d, "
519                "base: 0x%x, %d sectors @ %d kB = %d kB\n",
520                DEV_NO (dev), dev->base,
521                dev->sectors,
522                1 << (dev->lgSectorSize - 10),
523                dev->sectors << (dev->lgSectorSize - 10));
524
525        len = 1 << dev->lgSectorSize;
526
527        printf ("flashDiag: Erasing\n");
528
529        if (flashErase (dev) == ERROR) {
530                printf ("flashDiag: Erase failed\n");
531                goto done;
532        }
533        printf ("%d bytes requested ...\n", len);
534        buf = malloc (len);
535        printf ("allocated %d bytes ...\n", len);
536        if (buf == 0) {
537                printf ("flashDiag: Out of memory\n");
538                goto done;
539        }
540
541        /*
542         * Write unique counting pattern to each sector
543         */
544
545        for (sector = 0; sector < dev->sectors; sector++) {
546                printf ("flashDiag: Write sector %d\n", sector);
547
548                for (i = 0; i < len / 4; i++)
549                        buf[i] = sector << 24 | i;
550
551                if (flashWrite (dev,
552                                sector << dev->lgSectorSize,
553                                (char *) buf, len) == ERROR) {
554                        printf ("flashDiag: Write failed (dev: %d, sector: %d)\n",
555                                DEV_NO (dev), sector);
556                        goto done;
557                }
558        }
559
560        /*
561         * Verify
562         */
563
564        for (sector = 0; sector < dev->sectors; sector++) {
565                printf ("flashDiag: Verify sector %d\n", sector);
566
567                if (flashRead (dev,
568                                   sector << dev->lgSectorSize,
569                                   (char *) buf, len) == ERROR) {
570                        printf ("flashDiag: Read failed (dev: %d, sector: %d)\n",
571                                DEV_NO (dev), sector);
572                        goto done;
573                }
574
575                for (i = 0; i < len / 4; i++) {
576                        if (buf[i] != (sector << 24 | i)) {
577                                printf ("flashDiag: Verify error "
578                                        "(dev: %d, sector: %d, offset: 0x%x)\n",
579                                        DEV_NO (dev), sector, i);
580                                printf ("flashDiag: Expected 0x%08x, got 0x%08x\n",
581                                        sector << 24 | i, buf[i]);
582
583                                goto done;
584                        }
585                }
586        }
587
588        printf ("flashDiag: Erasing\n");
589
590        if (flashErase (dev) == ERROR) {
591                printf ("flashDiag: Final erase failed\n");
592                goto done;
593        }
594
595        rv = OK;
596
597  done:
598        if (buf)
599                free (buf);
600
601        if (rv == OK)
602                printf ("flashDiag: Device %d passed\n", DEV_NO (dev));
603        else
604                printf ("flashDiag: Device %d failed\n", DEV_NO (dev));
605
606        return rv;
607}
608
609STATUS flashDiagAll (void)
610{
611        int i;
612        int rv = OK;
613
614        PRINTF ("flashDiagAll: devices=%d\n", flashDevCount);
615
616        for (i = 0; i < flashDevCount; i++) {
617                flash_dev_t *dev = &flashDev[i];
618
619                if (dev->found && flashDiag (dev) == ERROR)
620                        rv = ERROR;
621        }
622
623        if (rv == OK)
624                printf ("flashDiagAll: Passed\n");
625        else
626                printf ("flashDiagAll: Failed because of earlier errors\n");
627
628        return OK;
629}
630
631
632/*-----------------------------------------------------------------------
633 */
634unsigned long flash_init (void)
635{
636        unsigned long size = 0;
637        flash_dev_t *dev = NULL;
638
639        flashLibInit ();
640
641        /*
642         * Provide info for FLASH (up to 960K) of Kernel Image data.
643         */
644        dev = FLASH_DEV_BANK0_LOW;
645        flash_info[FLASH_BANK_KERNEL].flash_id =
646                        (dev->vendorID << 16) | dev->deviceID;
647        flash_info[FLASH_BANK_KERNEL].sector_count = dev->sectors;
648        flash_info[FLASH_BANK_KERNEL].size =
649                        flash_info[FLASH_BANK_KERNEL].sector_count * FLASH_SECTOR_SIZE;
650        flash_info[FLASH_BANK_KERNEL].start[FIRST_SECTOR] = dev->base;
651        size += flash_info[FLASH_BANK_KERNEL].size;
652
653        /*
654         * Provide info for 512K PLCC FLASH ROM (U-Boot)
655         */
656        dev = FLASH_DEV_BANK0_BOOT;
657        flash_info[FLASH_BANK_BOOT].flash_id =
658                        (dev->vendorID << 16) | dev->deviceID;
659        flash_info[FLASH_BANK_BOOT].sector_count = dev->sectors;
660        flash_info[FLASH_BANK_BOOT].size =
661                        flash_info[FLASH_BANK_BOOT].sector_count * FLASH_SECTOR_SIZE;
662        flash_info[FLASH_BANK_BOOT].start[FIRST_SECTOR] = dev->base;
663        size += flash_info[FLASH_BANK_BOOT].size;
664
665
666        /*
667         * Provide info for 512K FLASH0 segment (U-Boot)
668         */
669        dev = FLASH_DEV_BANK0_HIGH;
670        flash_info[FLASH_BANK_AUX].flash_id =
671                        (dev->vendorID << 16) | dev->deviceID;
672        flash_info[FLASH_BANK_AUX].sector_count = dev->sectors;
673        flash_info[FLASH_BANK_AUX].size =
674                        flash_info[FLASH_BANK_AUX].sector_count * FLASH_SECTOR_SIZE;
675        flash_info[FLASH_BANK_AUX].start[FIRST_SECTOR] = dev->base;
676        size += flash_info[FLASH_BANK_AUX].size;
677
678
679        return size;
680}
681
682/*
683 * Get flash device from U-Boot flash info.
684 */
685flash_dev_t *getFlashDevFromInfo (flash_info_t * info)
686{
687        int i;
688
689        if (!info)
690                return NULL;
691
692        for (i = 0; i < flashDevCount; i++) {
693                flash_dev_t *dev = &flashDev[i];
694
695                if (dev->found && (dev->base == info->start[0]))
696                        return dev;
697        }
698        printf ("ERROR: notice, no FLASH mapped at address 0x%x\n",
699                        (unsigned int) info->start[0]);
700        return NULL;
701}
702
703ulong flash_get_size (vu_long * addr, flash_info_t * info)
704{
705        int i;
706
707        for (i = 0; i < flashDevCount; i++) {
708                flash_dev_t *dev = &flashDev[i];
709
710                if (dev->found) {
711                        if (dev->base == (unsigned int) addr) {
712                                info->flash_id = (dev->vendorID << 16) | dev->deviceID;
713                                info->sector_count = dev->sectors;
714                                info->size = info->sector_count * FLASH_SECTOR_SIZE;
715                                return dev->sectors * FLASH_SECTOR_SIZE;
716                        }
717                }
718        }
719        return 0;
720}
721
722void flash_print_info (flash_info_t * info)
723{
724        int i;
725        unsigned int chip;
726
727        if (info->flash_id == FLASH_UNKNOWN) {
728                printf ("missing or unknown FLASH type\n");
729                return;
730        }
731
732        switch ((info->flash_id >> 16) & 0xff) {
733        case 0x1:
734                printf ("AMD ");
735                break;
736        default:
737                printf ("Unknown Vendor ");
738                break;
739        }
740        chip = (unsigned int) info->flash_id & 0x000000ff;
741
742        switch (chip) {
743
744        case AMD_ID_F040B:
745                printf ("AM29F040B (4 Mbit)\n");
746                break;
747
748        case AMD_ID_LV160B:
749        case FLASH_AM160LV:
750        case 0x49:
751                printf ("AM29LV160B (16 Mbit / 2M x 8bit)\n");
752                break;
753
754        default:
755                printf ("Unknown Chip Type:0x%x\n", chip);
756                break;
757        }
758
759        printf ("  Size: %ld bytes in %d Sectors\n",
760                info->size, info->sector_count);
761
762        printf ("  Sector Start Addresses:");
763        for (i = 0; i < info->sector_count; ++i) {
764                if ((i % 5) == 0)
765                        printf ("\n   ");
766                printf (" %08lX%s",
767                        info->start[FIRST_SECTOR] + i * FLASH_SECTOR_SIZE,
768                        info->protect[i] ? " (RO)" : "     ");
769        }
770        printf ("\n");
771}
772
773
774/*
775 * Erase a range of flash sectors.
776 */
777int flash_erase (flash_info_t * info, int s_first, int s_last)
778{
779        vu_long *addr = (vu_long *) (info->start[0]);
780        int prot, sect, l_sect;
781        flash_dev_t *dev = NULL;
782
783        if ((s_first < 0) || (s_first > s_last)) {
784                if (info->flash_id == FLASH_UNKNOWN) {
785                        printf ("- missing\n");
786                } else {
787                        printf ("- no sectors to erase\n");
788                }
789                return 1;
790        }
791
792        prot = 0;
793        for (sect = s_first; sect <= s_last; sect++) {
794                if (info->protect[sect]) {
795                        prot++;
796                }
797        }
798
799        if (prot) {
800                printf ("- Warning: %d protected sectors will not be erased!\n",
801                        prot);
802        } else {
803                printf ("\n");
804        }
805
806        l_sect = -1;
807
808        /* Start erase on unprotected sectors */
809        dev = getFlashDevFromInfo (info);
810        if (dev) {
811                printf ("Erase FLASH[%s] -%d sectors:", dev->name, dev->sectors);
812                for (sect = s_first; sect <= s_last; sect++) {
813                        if (info->protect[sect] == 0) { /* not protected */
814                                addr = (vu_long *) (dev->base);
815                                /*   printf("erase_sector: sector=%d, addr=0x%x\n",
816                                   sect, addr); */
817                                printf (".");
818                                if (ERROR == flashEraseSector (dev, sect)) {
819                                        printf ("ERROR: could not erase sector %d on FLASH[%s]\n", sect, dev->name);
820                                        return 1;
821                                }
822                        }
823                }
824        }
825        printf (" done\n");
826        return 0;
827}
828
829/*-----------------------------------------------------------------------
830 * Write a word to Flash, returns:
831 * 0 - OK
832 * 1 - write timeout
833 * 2 - Flash not erased
834 */
835static int write_word (flash_info_t * info, ulong dest, ulong data)
836{
837
838        flash_dev_t *dev = getFlashDevFromInfo (info);
839        int addr = dest - info->start[0];
840
841        if (!dev)
842                return 1;
843
844        if (OK != flashWrite (dev, addr, (char *) &data, sizeof (ulong))) {
845                printf ("ERROR: could not write to addr=0x%x, data=0x%x\n",
846                        (unsigned int) addr, (unsigned) data);
847                return 1;
848        }
849
850        if ((addr % FLASH_SECTOR_SIZE) == 0)
851                printf (".");
852
853
854        PRINTF ("write_word:0x%x, base=0x%x, addr=0x%x, data=0x%x\n",
855                (unsigned) info->start[0],
856                (unsigned) dest,
857                (unsigned) (dest - info->start[0]), (unsigned) data);
858
859        return (0);
860}
861
862
863/*-----------------------------------------------------------------------
864 * Copy memory to flash, returns:
865 * 0 - OK
866 * 1 - write timeout
867 * 2 - Flash not erased
868 */
869
870int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
871{
872        ulong cp, wp, data;
873        int i, l, rc;
874        flash_dev_t *dev = getFlashDevFromInfo (info);
875
876        if (dev) {
877                printf ("FLASH[%s]:", dev->name);
878                wp = (addr & ~3);       /* get lower word aligned address */
879
880                /*
881                 * handle unaligned start bytes
882                 */
883                if ((l = addr - wp) != 0) {
884                        data = 0;
885                        for (i = 0, cp = wp; i < l; ++i, ++cp) {
886                                data = (data << 8) | (*(uchar *) cp);
887                        }
888                        for (; i < 4 && cnt > 0; ++i) {
889                                data = (data << 8) | *src++;
890                                --cnt;
891                                ++cp;
892                        }
893                        for (; cnt == 0 && i < 4; ++i, ++cp) {
894                                data = (data << 8) | (*(uchar *) cp);
895                        }
896                        if ((rc = write_word (info, wp, data)) != 0) {
897                                return (rc);
898                        }
899                        wp += 4;
900                }
901
902                /*
903                 * handle word aligned part
904                 */
905                while (cnt >= 4) {
906                        data = 0;
907                        for (i = 0; i < 4; ++i) {
908                                data = (data << 8) | *src++;
909                        }
910                        if ((rc = write_word (info, wp, data)) != 0) {
911                                return (rc);
912                        }
913                        wp += 4;
914                        cnt -= 4;
915                }
916
917                if (cnt == 0) {
918                        return (0);
919                }
920
921                /*
922                 * handle unaligned tail bytes
923                 */
924                data = 0;
925                for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
926                        data = (data << 8) | *src++;
927                        --cnt;
928                }
929                for (; i < 4; ++i, ++cp) {
930                        data = (data << 8) | (*(uchar *) cp);
931                }
932
933                return (write_word (info, wp, data));
934        }
935        return 1;
936}
937
938/*-----------------------------------------------------------------------
939 */
Note: See TracBrowser for help on using the repository browser.