blob: 3c4a802da61bf675859ed1e3dfe5272f25dba92e [file] [log] [blame]
wdenkcc1c8a12002-11-02 22:58:18 +00001/*
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
187DONE:
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#if 0
199 PRINTF("flashWait: dev=%d addr=0x%x expect=0x%x erase=%d\n",
200 DEV_NO(dev), addr, expect, erase);
201#endif
202
203 if (dev->bank != FLASH0_BANK) {
204 rv = ERROR;
205 goto done;
206 }
207
208 if (erase)
209 polls = FLASH_ERASE_SECTOR_TIMEOUT; /* Ticks */
210 else
211 polls = FLASH_PROGRAM_POLLS; /* Loops */
212
213 for (i = 0; i < polls; i++) {
214 if (erase)
215 udelay(SLEEP_DELAY);
216
217 data = FLASH0_READ(dev, addr);
218
219 if (((data ^ expect) & 0x80) == 0) {
220 rv = OK;
221 goto done;
222 }
223
224 if (data & 0x20) {
225 /*
226 * If the 0x20 bit has come on, it could actually be because
227 * the operation succeeded, so check the done bit again.
228 */
229
230 data = FLASH0_READ(dev, addr);
231
232 if (((data ^ expect) & 0x80) == 0) {
233 rv = OK;
234 goto done;
235 }
236
237 printf("flashWait: Program error (dev: %d, addr: 0x%x)\n",
238 DEV_NO(dev), addr);
239
240 flashReset(dev);
241 rv = ERROR;
242 goto done;
243 }
244 }
245
246 printf("flashWait: Timeout %s (dev: %d, addr: 0x%x)\n",
247 erase ? "erasing sector" : "programming byte",
248 DEV_NO(dev), addr);
249
250done:
251
252#if 0
253 PRINTF("flashWait: rv=%d\n", rv);
254#endif
255
256 return rv;
257}
258
259/***********************************************************************
260 *
261 * Public Flash Routines
262 *
263 ***********************************************************************/
264
265STATUS flashLibInit(void)
266{
267 int i;
268
269 PRINTF("flashLibInit: devices=%d\n", flashDevCount);
270
271 for (i = 0; i < flashDevCount; i++) {
272 flash_dev_t *dev = &flashDev[i];
273 /*
274 * For bank 1, probe both without and with byte swappage,
275 * so that this module works on both old and new Mousse boards.
276 */
277
278 flashReset(dev);
279
280 if (flashProbe(dev) != ERROR)
281 dev->found = 1;
282
283 flashReset(dev);
284
285 if (flashProbe(dev) != ERROR)
286 dev->found = 1;
287
288 dev->swap = 0;
289
290 if(dev->found){
291 PRINTF("\n FLASH %s[%d]: iobase=0x%x - %d sectors %d KB",
292 flashDev[i].name,i,flashDev[i].base, flashDev[i].sectors,
293 (flashDev[i].sectors * FLASH_SECTOR_SIZE)/1024);
294
295 }
296 }
297
298 flashLibInited = 1;
299
300 PRINTF("flashLibInit: done\n");
301
302 return OK;
303}
304
305STATUS flashEraseSector(flash_dev_t *dev, int sector)
306{
307 int pos, addr;
308
309 PRINTF("flashErasesector: dev=%d sector=%d\n", DEV_NO(dev), sector);
310
311 if (flashCheck(dev) == ERROR)
312 return ERROR;
313
314 if (sector < 0 || sector >= dev->sectors) {
315 printf("flashEraseSector: Sector out of range (dev: %d, sector: %d)\n",
316 DEV_NO(dev), sector);
317 return ERROR;
318 }
319
320 pos = FLASH_SECTOR_POS(dev, sector);
321
322 if (dev->bank != FLASH0_BANK) {
323 return ERROR;
324 }
325
326 addr = pos;
327
328 FLASH0_WRITE(dev, 0xaaa, 0xaa);
329 FLASH0_WRITE(dev, 0x555, 0x55);
330 FLASH0_WRITE(dev, 0xaaa, 0x80);
331 FLASH0_WRITE(dev, 0xaaa, 0xaa);
332 FLASH0_WRITE(dev, 0x555, 0x55);
333 FLASH0_WRITE(dev, addr, 0x30);
334
335 return flashWait(dev, addr, 0xff, 1);
336}
337
338/*
339 * Note: it takes about as long to flash all sectors together with Chip
340 * Erase as it does to flash them one at a time (about 30 seconds for 2
341 * MB). Also since we want to be able to treat subsets of sectors as if
342 * they were complete devices, we don't use Chip Erase.
343 */
344
345STATUS flashErase(flash_dev_t *dev)
346{
347 int sector;
348
349 PRINTF("flashErase: dev=%d sectors=%d\n", DEV_NO(dev), dev->sectors);
350
351 if (flashCheck(dev) == ERROR)
352 return ERROR;
353
354 for (sector = 0; sector < dev->sectors; sector++) {
355 if (flashEraseSector(dev, sector) == ERROR)
356 return ERROR;
357 }
358 return OK;
359}
360
361/*
362 * Read and write bytes
363 */
364
365STATUS flashRead(flash_dev_t *dev, int pos, char *buf, int len)
366{
367 int addr, words;
368
369 PRINTF("flashRead: dev=%d pos=0x%x buf=0x%x len=0x%x\n",
370 DEV_NO(dev), pos, (int) buf, len);
371
372 if (flashCheck(dev) == ERROR)
373 return ERROR;
374
375 if (pos < 0 || len < 0 || pos + len > FLASH_MAX_POS(dev)) {
376 printf("flashRead: Position out of range "
377 "(dev: %d, pos: 0x%x, len: 0x%x)\n",
378 DEV_NO(dev), pos, len);
379 return ERROR;
380 }
381
382 if (len == 0)
383 return OK;
384
385 if (dev->bank == FLASH0_BANK) {
386 addr = pos;
387 words = len;
388
389 PRINTF("flashRead: memcpy(0x%x, 0x%x, 0x%x)\n",
390 (int) buf, (int) FLASH0_ADDR(dev, pos), len);
391
392 memcpy(buf, FLASH0_ADDR(dev, addr), words);
393
394 }
395 PRINTF("flashRead: rv=OK\n");
396
397 return OK;
398}
399
400STATUS flashWrite(flash_dev_t *dev, int pos, char *buf, int len)
401{
402 int addr, words;
403
404 PRINTF("flashWrite: dev=%d pos=0x%x buf=0x%x len=0x%x\n",
405 DEV_NO(dev), pos, (int) buf, len);
406
407 if (flashCheck(dev) == ERROR)
408 return ERROR;
409
410 if (pos < 0 || len < 0 || pos + len > FLASH_MAX_POS(dev)) {
411 printf("flashWrite: Position out of range "
412 "(dev: %d, pos: 0x%x, len: 0x%x)\n",
413 DEV_NO(dev), pos, len);
414 return ERROR;
415 }
416
417 if (len == 0)
418 return OK;
419
420 if (dev->bank == FLASH0_BANK) {
421 unsigned char tmp;
422
423 addr = pos;
424 words = len;
425
426 while (words--) {
427 tmp = *buf;
428 if (~FLASH0_READ(dev, addr) & tmp) {
429 printf("flashWrite: Attempt to program 0 to 1 "
430 "(dev: %d, addr: 0x%x, data: 0x%x)\n",
431 DEV_NO(dev), addr, tmp);
432 return ERROR;
433 }
434 FLASH0_WRITE(dev, 0xaaa, 0xaa);
435 FLASH0_WRITE(dev, 0x555, 0x55);
436 FLASH0_WRITE(dev, 0xaaa, 0xa0);
437 FLASH0_WRITE(dev, addr, tmp);
438 if (flashWait(dev, addr, tmp, 0) < 0)
439 return ERROR;
440 buf++;
441 addr++;
442 }
443 }
444
445 PRINTF("flashWrite: rv=OK\n");
446
447 return OK;
448}
449
450/*
451 * flashWritable returns TRUE if a range contains all F's.
452 */
453
454STATUS flashWritable(flash_dev_t *dev, int pos, int len)
455{
456 int addr, words;
457 int rv = ERROR;
458
459 PRINTF("flashWritable: dev=%d pos=0x%x len=0x%x\n",
460 DEV_NO(dev), pos, len);
461
462 if (flashCheck(dev) == ERROR)
463 goto done;
464
465 if (pos < 0 || len < 0 || pos + len > FLASH_MAX_POS(dev)) {
466 printf("flashWritable: Position out of range "
467 "(dev: %d, pos: 0x%x, len: 0x%x)\n",
468 DEV_NO(dev), pos, len);
469 goto done;
470 }
471
472 if (len == 0) {
473 rv = 1;
474 goto done;
475 }
476
477 if (dev->bank == FLASH0_BANK) {
478 addr = pos;
479 words = len;
480
481 while (words--) {
482 if (FLASH0_READ(dev, addr) != 0xff) {
483 rv = 0;
484 goto done;
485 }
486 addr++;
487 }
488 }
489
490 rv = 1;
491
492 done:
493 PRINTF("flashWrite: rv=%d\n", rv);
494 return rv;
495}
496
497
498/*
499 * NOTE: the below code cannot run from FLASH!!!
500 */
501/***********************************************************************
502 *
503 * Flash Diagnostics
504 *
505 ***********************************************************************/
506
507STATUS flashDiag(flash_dev_t *dev)
508{
509 unsigned int *buf = 0;
510 int i, len, sector;
511 int rv = ERROR;
512
513 if (flashCheck(dev) == ERROR)
514 return ERROR;
515
516 printf("flashDiag: Testing device %d, "
517 "base: 0x%x, %d sectors @ %d kB = %d kB\n",
518 DEV_NO(dev), dev->base,
519 dev->sectors,
520 1 << (dev->lgSectorSize - 10),
521 dev->sectors << (dev->lgSectorSize - 10));
522
523 len = 1 << dev->lgSectorSize;
524
525 printf("flashDiag: Erasing\n");
526
527 if (flashErase(dev) == ERROR) {
528 printf("flashDiag: Erase failed\n");
529 goto done;
530 }
531 printf("%d bytes requested ...\n", len);
532 buf = malloc(len);
533 printf("allocated %d bytes ...\n", len);
534 if (buf == 0) {
535 printf("flashDiag: Out of memory\n");
536 goto done;
537 }
538
539 /*
540 * Write unique counting pattern to each sector
541 */
542
543 for (sector = 0; sector < dev->sectors; sector++) {
544 printf("flashDiag: Write sector %d\n", sector);
545
546 for (i = 0; i < len / 4; i++)
547 buf[i] = sector << 24 | i;
548
549 if (flashWrite(dev,
550 sector << dev->lgSectorSize,
551 (char *) buf,
552 len) == ERROR) {
553 printf("flashDiag: Write failed (dev: %d, sector: %d)\n",
554 DEV_NO(dev), sector);
555 goto done;
556 }
557 }
558
559 /*
560 * Verify
561 */
562
563 for (sector = 0; sector < dev->sectors; sector++) {
564 printf("flashDiag: Verify sector %d\n", sector);
565
566 if (flashRead(dev,
567 sector << dev->lgSectorSize,
568 (char *) buf,
569 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 flashLibInit();
639
640 /*
641 * Provide info for FLASH (up to 960K) of Kernel Image data.
642 */
643 dev = FLASH_DEV_BANK0_LOW;
644 flash_info[FLASH_BANK_KERNEL].flash_id =
645 (dev->vendorID << 16) | dev->deviceID;
646 flash_info[FLASH_BANK_KERNEL].sector_count = dev->sectors;
647 flash_info[FLASH_BANK_KERNEL].size =
648 flash_info[FLASH_BANK_KERNEL].sector_count * FLASH_SECTOR_SIZE;
649 flash_info[FLASH_BANK_KERNEL].start[FIRST_SECTOR] = dev->base;
650 size += flash_info[FLASH_BANK_KERNEL].size;
651
652 /*
653 * Provide info for 512K PLCC FLASH ROM (U-Boot)
654 */
655 dev = FLASH_DEV_BANK0_BOOT;
656 flash_info[FLASH_BANK_BOOT].flash_id =
657 (dev->vendorID << 16) | dev->deviceID;
658 flash_info[FLASH_BANK_BOOT].sector_count = dev->sectors;
659 flash_info[FLASH_BANK_BOOT].size =
660 flash_info[FLASH_BANK_BOOT].sector_count * FLASH_SECTOR_SIZE;
661 flash_info[FLASH_BANK_BOOT].start[FIRST_SECTOR] = dev->base;
662 size += flash_info[FLASH_BANK_BOOT].size;
663
664
665 /*
666 * Provide info for 512K FLASH0 segment (U-Boot)
667 */
668 dev = FLASH_DEV_BANK0_HIGH;
669 flash_info[FLASH_BANK_AUX].flash_id =
670 (dev->vendorID << 16) | dev->deviceID;
671 flash_info[FLASH_BANK_AUX].sector_count = dev->sectors;
672 flash_info[FLASH_BANK_AUX].size =
673 flash_info[FLASH_BANK_AUX].sector_count * FLASH_SECTOR_SIZE;
674 flash_info[FLASH_BANK_AUX].start[FIRST_SECTOR] = dev->base;
675 size += flash_info[FLASH_BANK_AUX].size;
676
677
678 return size;
679}
680
681/*
682 * Get flash device from U-Boot flash info.
683 */
684flash_dev_t*
685getFlashDevFromInfo(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 if(dev->found && (dev->base == info->start[0]))
695 return dev;
696 }
697 printf("ERROR: notice, no FLASH mapped at address 0x%x\n",
698 (unsigned int)info->start[0]);
699 return NULL;
700}
701
702ulong
703flash_get_size (vu_long *addr, flash_info_t *info)
704{
705 int i;
706 for(i = 0; i < flashDevCount; i++) {
707 flash_dev_t *dev = &flashDev[i];
708 if(dev->found){
709 if(dev->base == (unsigned int)addr){
710 info->flash_id = (dev->vendorID << 16) | dev->deviceID;
711 info->sector_count = dev->sectors;
712 info->size = info->sector_count * FLASH_SECTOR_SIZE;
713 return dev->sectors * FLASH_SECTOR_SIZE;
714 }
715 }
716 }
717 return 0;
718}
719
720void
721flash_print_info (flash_info_t *info)
722{
723 int i;
724 unsigned int chip;
725
726 if (info->flash_id == FLASH_UNKNOWN) {
727 printf ("missing or unknown FLASH type\n");
728 return;
729 }
730
731 switch ((info->flash_id >> 16) & 0xff) {
732 case 0x1:
733 printf ("AMD ");
734 break;
735 default:
736 printf ("Unknown Vendor ");
737 break;
738 }
739 chip = (unsigned int) info->flash_id & 0x000000ff;
740
741 switch (chip) {
742
743 case AMD_ID_F040B:
744 printf ("AM29F040B (4 Mbit)\n");
745 break;
746
747 case AMD_ID_LV160B:
748 case FLASH_AM160LV:
749 case 0x49:
750 printf ("AM29LV160B (16 Mbit / 2M x 8bit)\n");
751 break;
752
753 default:
754 printf ("Unknown Chip Type:0x%x\n", chip);
755 break;
756 }
757
758 printf (" Size: %ld bytes in %d Sectors\n",
759 info->size, info->sector_count);
760
761 printf (" Sector Start Addresses:");
762 for (i=0; i<info->sector_count; ++i) {
763 if ((i % 5) == 0)
764 printf ("\n ");
765 printf (" %08lX%s",
766 info->start[FIRST_SECTOR] + i*FLASH_SECTOR_SIZE,
767 info->protect[i] ? " (RO)" : " "
768 );
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",
820 sect, dev->name);
821 return 1;
822 }
823 }
824 }
825 }
826 printf (" done\n");
827 return 0;
828}
829
830/*-----------------------------------------------------------------------
831 * Write a word to Flash, returns:
832 * 0 - OK
833 * 1 - write timeout
834 * 2 - Flash not erased
835 */
836static int
837write_word (flash_info_t *info, ulong dest, ulong data)
838{
839
840 flash_dev_t* dev = getFlashDevFromInfo(info);
841 int addr = dest - info->start[0];
842
843 if (! dev)
844 return 1;
845
846 if(OK != flashWrite(dev, addr, (char*)&data, sizeof(ulong))){
847 printf("ERROR: could not write to addr=0x%x, data=0x%x\n",
848 (unsigned int)addr, (unsigned)data);
849 return 1;
850 }
851
852 if((addr % FLASH_SECTOR_SIZE) == 0)
853 printf(".");
854
855
856 PRINTF("write_word:0x%x, base=0x%x, addr=0x%x, data=0x%x\n",
857 (unsigned)info->start[0],
858 (unsigned)dest,
859 (unsigned)(dest - info->start[0]),
860 (unsigned)data);
861
862
863
864 return (0);
865}
866
867
868/*-----------------------------------------------------------------------
869 * Copy memory to flash, returns:
870 * 0 - OK
871 * 1 - write timeout
872 * 2 - Flash not erased
873 */
874
875int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
876{
877 ulong cp, wp, data;
878 int i, l, rc;
879 flash_dev_t* dev = getFlashDevFromInfo(info);
880
881 if( dev ) {
882 printf("FLASH[%s]:", dev->name);
883 wp = (addr & ~3); /* get lower word aligned address */
884
885 /*
886 * handle unaligned start bytes
887 */
888 if ((l = addr - wp) != 0) {
889 data = 0;
890 for (i=0, cp=wp; i<l; ++i, ++cp) {
891 data = (data << 8) | (*(uchar *)cp);
892 }
893 for (; i<4 && cnt>0; ++i) {
894 data = (data << 8) | *src++;
895 --cnt;
896 ++cp;
897 }
898 for (; cnt==0 && i<4; ++i, ++cp) {
899 data = (data << 8) | (*(uchar *)cp);
900 }
901 if ((rc = write_word(info, wp, data)) != 0) {
902 return (rc);
903 }
904 wp += 4;
905 }
906
907 /*
908 * handle word aligned part
909 */
910 while (cnt >= 4) {
911 data = 0;
912 for (i=0; i<4; ++i) {
913 data = (data << 8) | *src++;
914 }
915 if ((rc = write_word(info, wp, data)) != 0) {
916 return (rc);
917 }
918 wp += 4;
919 cnt -= 4;
920 }
921
922 if (cnt == 0) {
923 return (0);
924 }
925
926 /*
927 * handle unaligned tail bytes
928 */
929 data = 0;
930 for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
931 data = (data << 8) | *src++;
932 --cnt;
933 }
934 for (; i<4; ++i, ++cp) {
935 data = (data << 8) | (*(uchar *)cp);
936 }
937
938 return (write_word(info, wp, data));
939 }
940 return 1;
941}
942
943/*-----------------------------------------------------------------------
944 */