]>
git.ipfire.org Git - people/ms/u-boot.git/blob - board/mpl/common/flash.c
2 * (C) Copyright 2000, 2001
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5 * See file CREDITS for list of people who contributed to this
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.
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.
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,
26 * Wait for completion of each sector erase command issued
28 * Chris Hallinan - DS4.COM, Inc. - clh@net1plus.com
33 * - adopted for pip405, Denis Peter, MPL AG Switzerland
40 #include <asm/processor.h>
42 #include "../pip405/pip405.h"
45 #include "../mip405/mip405.h"
47 #include "common_util.h"
49 flash_info_t flash_info
[CFG_MAX_FLASH_BANKS
]; /* info for FLASH chips */
50 /*-----------------------------------------------------------------------
53 static ulong
flash_get_size (vu_long
*addr
, flash_info_t
*info
);
54 static int write_word (flash_info_t
*info
, ulong dest
, ulong data
);
55 static void flash_get_offsets (ulong base
, flash_info_t
*info
);
57 void unlock_intel_sectors(flash_info_t
*info
,ulong addr
,ulong cnt
);
63 #define FLASH_WORD_SIZE unsigned char
69 #define FLASH_WORD_SIZE unsigned short
75 #define FLASH_WORD_SIZE unsigned short
81 #define FLASH_WORD_SIZE unsigned short
87 /*-----------------------------------------------------------------------
91 unsigned long flash_init (void)
93 unsigned long size_b0
, size_b1
;
96 unsigned long base_b0
, base_b1
;
99 rc
=switch_cs(FALSE
); /* map Flash High */
102 printf("(MPS Boot) ");
104 printf("(Flash Boot) ");
105 /* Init: no FLASHes known */
106 for (i
=0; i
<CFG_MAX_FLASH_BANKS
; ++i
) {
107 flash_info
[i
].flash_id
= FLASH_UNKNOWN
;
110 /* Static FLASH Bank configuration here - FIXME XXX */
112 size_b0
= flash_get_size((vu_long
*)FLASH_BASE0_PRELIM
, &flash_info
[0]);
114 if (flash_info
[0].flash_id
== FLASH_UNKNOWN
) {
115 printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
116 size_b0
, size_b0
<<20);
119 if (CFG_MAX_FLASH_BANKS
== 1)
122 /* flash_get_offsets (FLASH_BASE0_PRELIM, &flash_info[0]); */
123 /* Monitor protection ON by default */
124 #if CFG_MONITOR_BASE >= CFG_FLASH_BASE
125 flash_protect(FLAG_PROTECT_SET
,
127 CFG_MONITOR_BASE
+CFG_MONITOR_LEN
-1,
131 flash_info
[0].size
= size_b0
;
137 size_b1
= flash_get_size((vu_long
*)FLASH_BASE1_PRELIM
, &flash_info
[1]);
139 /* Re-do sizing to get full correct info */
143 mtdcr(ebccfga
, pb0cr
);
144 pbcr
= mfdcr(ebccfgd
);
145 mtdcr(ebccfga
, pb0cr
);
147 pbcr
= (pbcr
& 0x0001ffff) | base_b1
| (((size_b1
/1024/1024)-1)<<17);
148 mtdcr(ebccfgd
, pbcr
);
149 /* printf("pb1cr = %x\n", pbcr); */
154 mtdcr(ebccfga
, pb1cr
);
155 pbcr
= mfdcr(ebccfgd
);
156 mtdcr(ebccfga
, pb1cr
);
157 base_b0
= base_b1
- size_b0
;
158 pbcr
= (pbcr
& 0x0001ffff) | base_b0
| (((size_b0
/1024/1024)-1)<<17);
159 mtdcr(ebccfgd
, pbcr
);
160 /* printf("pb0cr = %x\n", pbcr); */
163 size_b0
= flash_get_size((vu_long
*)base_b0
, &flash_info
[0]);
165 flash_get_offsets (base_b0
, &flash_info
[0]);
167 /* monitor protection ON by default */
168 (void)flash_protect(FLAG_PROTECT_SET
,
169 base_b0
+size_b0
-CFG_MONITOR_LEN
,
174 /* Re-do sizing to get full correct info */
175 size_b1
= flash_get_size((vu_long
*)base_b1
, &flash_info
[1]);
177 flash_get_offsets (base_b1
, &flash_info
[1]);
179 /* monitor protection ON by default */
180 (void)flash_protect(FLAG_PROTECT_SET
,
181 base_b1
+size_b1
-CFG_MONITOR_LEN
,
184 /* monitor protection OFF by default (one is enough) */
185 (void)flash_protect(FLAG_PROTECT_CLEAR
,
186 base_b0
+size_b0
-CFG_MONITOR_LEN
,
190 flash_info
[1].flash_id
= FLASH_UNKNOWN
;
191 flash_info
[1].sector_count
= -1;
194 flash_info
[0].size
= size_b0
;
195 flash_info
[1].size
= size_b1
;
197 switch_cs(rc
); /* switch mode back */
198 return (size_b0
+ size_b1
);
202 static void flash_get_offsets (ulong base
, flash_info_t
*info
)
207 /*-----------------------------------------------------------------------
209 static void flash_get_offsets (ulong base
, flash_info_t
*info
)
213 /* set up sector start address table */
214 if (((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_SST
) ||
215 (info
->flash_id
== FLASH_AM040
)){
216 for (i
= 0; i
< info
->sector_count
; i
++)
217 info
->start
[i
] = base
+ (i
* 0x00010000);
220 if (info
->flash_id
& FLASH_BTYPE
) {
221 /* set sector offsets for bottom boot block type */
222 info
->start
[0] = base
+ 0x00000000;
223 info
->start
[1] = base
+ 0x00004000;
224 info
->start
[2] = base
+ 0x00006000;
225 info
->start
[3] = base
+ 0x00008000;
226 for (i
= 4; i
< info
->sector_count
; i
++) {
227 info
->start
[i
] = base
+ (i
* 0x00010000) - 0x00030000;
230 /* set sector offsets for top boot block type */
231 i
= info
->sector_count
- 1;
232 info
->start
[i
--] = base
+ info
->size
- 0x00004000;
233 info
->start
[i
--] = base
+ info
->size
- 0x00006000;
234 info
->start
[i
--] = base
+ info
->size
- 0x00008000;
235 for (; i
>= 0; i
--) {
236 info
->start
[i
] = base
+ i
* 0x00010000;
243 /*-----------------------------------------------------------------------
245 void flash_print_info (flash_info_t
*info
)
251 volatile unsigned long *flash
;
253 if (info
->flash_id
== FLASH_UNKNOWN
) {
254 printf ("missing or unknown FLASH type\n");
258 switch (info
->flash_id
& FLASH_VENDMASK
) {
259 case FLASH_MAN_AMD
: printf ("AMD "); break;
260 case FLASH_MAN_FUJ
: printf ("FUJITSU "); break;
261 case FLASH_MAN_SST
: printf ("SST "); break;
262 case FLASH_MAN_INTEL
: printf ("Intel "); break;
263 default: printf ("Unknown Vendor "); break;
266 switch (info
->flash_id
& FLASH_TYPEMASK
) {
267 case FLASH_AM040
: printf ("AM29F040 (512 Kbit, uniform sector size)\n");
269 case FLASH_AM400B
: printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
271 case FLASH_AM400T
: printf ("AM29LV400T (4 Mbit, top boot sector)\n");
273 case FLASH_AM800B
: printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
275 case FLASH_AM800T
: printf ("AM29LV800T (8 Mbit, top boot sector)\n");
277 case FLASH_AM160B
: printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
279 case FLASH_AM160T
: printf ("AM29LV160T (16 Mbit, top boot sector)\n");
281 case FLASH_AM320B
: printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
283 case FLASH_AM320T
: printf ("AM29LV320T (32 Mbit, top boot sector)\n");
285 case FLASH_SST800A
: printf ("SST39LF/VF800 (8 Mbit, uniform sector size)\n");
287 case FLASH_SST160A
: printf ("SST39LF/VF160 (16 Mbit, uniform sector size)\n");
289 case FLASH_INTEL320T
: printf ("TE28F320C3 (32 Mbit, top sector size)\n");
291 default: printf ("Unknown Chip Type\n");
295 printf (" Size: %ld KB in %d Sectors\n",
296 info
->size
>> 10, info
->sector_count
);
298 printf (" Sector Start Addresses:");
299 for (i
=0; i
<info
->sector_count
; ++i
) {
301 * Check if whole sector is erased
303 if (i
!= (info
->sector_count
-1))
304 size
= info
->start
[i
+1] - info
->start
[i
];
306 size
= info
->start
[0] + info
->size
- info
->start
[i
];
308 flash
= (volatile unsigned long *)info
->start
[i
];
309 size
= size
>> 2; /* divide by 4 for longword access */
310 for (k
=0; k
<size
; k
++)
312 if (*flash
++ != 0xffffffff)
320 #if 0 /* test-only */
323 info
->protect
[i
] ? " (RO)" : " "
325 printf (" %08lX%s%s",
328 info
->protect
[i
] ? "RO " : " "
336 /*-----------------------------------------------------------------------
340 /*-----------------------------------------------------------------------
344 * The following code cannot be run from FLASH!
346 static ulong
flash_get_size (vu_long
*addr
, flash_info_t
*info
)
349 FLASH_WORD_SIZE value
;
350 ulong base
= (ulong
)addr
;
351 volatile FLASH_WORD_SIZE
*addr2
= (FLASH_WORD_SIZE
*)addr
;
353 /* Write auto select command: read Manufacturer ID */
354 addr2
[ADDR0
] = (FLASH_WORD_SIZE
)0x00AA00AA;
355 addr2
[ADDR1
] = (FLASH_WORD_SIZE
)0x00550055;
356 addr2
[ADDR0
] = (FLASH_WORD_SIZE
)0x00900090;
359 /* printf("flash_get_size value: %x\n",value); */
361 case (FLASH_WORD_SIZE
)AMD_MANUFACT
:
362 info
->flash_id
= FLASH_MAN_AMD
;
364 case (FLASH_WORD_SIZE
)FUJ_MANUFACT
:
365 info
->flash_id
= FLASH_MAN_FUJ
;
367 case (FLASH_WORD_SIZE
)INTEL_MANUFACT
:
368 info
->flash_id
= FLASH_MAN_INTEL
;
370 case (FLASH_WORD_SIZE
)SST_MANUFACT
:
371 info
->flash_id
= FLASH_MAN_SST
;
374 info
->flash_id
= FLASH_UNKNOWN
;
375 info
->sector_count
= 0;
377 return (0); /* no or unknown flash */
379 value
= addr2
[1]; /* device ID */
380 /* printf("Device value %x\n",value); */
382 case (FLASH_WORD_SIZE
)AMD_ID_F040B
:
383 info
->flash_id
+= FLASH_AM040
;
384 info
->sector_count
= 8;
385 info
->size
= 0x0080000; /* => 512 ko */
387 case (FLASH_WORD_SIZE
)AMD_ID_LV400T
:
388 info
->flash_id
+= FLASH_AM400T
;
389 info
->sector_count
= 11;
390 info
->size
= 0x00080000;
391 break; /* => 0.5 MB */
393 case (FLASH_WORD_SIZE
)AMD_ID_LV400B
:
394 info
->flash_id
+= FLASH_AM400B
;
395 info
->sector_count
= 11;
396 info
->size
= 0x00080000;
397 break; /* => 0.5 MB */
399 case (FLASH_WORD_SIZE
)AMD_ID_LV800T
:
400 info
->flash_id
+= FLASH_AM800T
;
401 info
->sector_count
= 19;
402 info
->size
= 0x00100000;
405 case (FLASH_WORD_SIZE
)AMD_ID_LV800B
:
406 info
->flash_id
+= FLASH_AM800B
;
407 info
->sector_count
= 19;
408 info
->size
= 0x00100000;
411 case (FLASH_WORD_SIZE
)AMD_ID_LV160T
:
412 info
->flash_id
+= FLASH_AM160T
;
413 info
->sector_count
= 35;
414 info
->size
= 0x00200000;
417 case (FLASH_WORD_SIZE
)AMD_ID_LV160B
:
418 info
->flash_id
+= FLASH_AM160B
;
419 info
->sector_count
= 35;
420 info
->size
= 0x00200000;
422 #if 0 /* enable when device IDs are available */
423 case (FLASH_WORD_SIZE
)AMD_ID_LV320T
:
424 info
->flash_id
+= FLASH_AM320T
;
425 info
->sector_count
= 67;
426 info
->size
= 0x00400000;
429 case (FLASH_WORD_SIZE
)AMD_ID_LV320B
:
430 info
->flash_id
+= FLASH_AM320B
;
431 info
->sector_count
= 67;
432 info
->size
= 0x00400000;
435 case (FLASH_WORD_SIZE
)SST_ID_xF800A
:
436 info
->flash_id
+= FLASH_SST800A
;
437 info
->sector_count
= 16;
438 info
->size
= 0x00100000;
440 case (FLASH_WORD_SIZE
)INTEL_ID_28F320C3T
:
441 info
->flash_id
+= FLASH_INTEL320T
;
442 info
->sector_count
= 71;
443 info
->size
= 0x00400000;
447 case (FLASH_WORD_SIZE
)SST_ID_xF160A
:
448 info
->flash_id
+= FLASH_SST160A
;
449 info
->sector_count
= 32;
450 info
->size
= 0x00200000;
454 info
->flash_id
= FLASH_UNKNOWN
;
455 return (0); /* => no or unknown flash */
459 /* set up sector start address table */
460 if (((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_SST
) ||
461 (info
->flash_id
== FLASH_AM040
)){
462 for (i
= 0; i
< info
->sector_count
; i
++)
463 info
->start
[i
] = base
+ (i
* 0x00010000);
465 if (info
->flash_id
& FLASH_BTYPE
) {
466 /* set sector offsets for bottom boot block type */
467 info
->start
[0] = base
+ 0x00000000;
468 info
->start
[1] = base
+ 0x00004000;
469 info
->start
[2] = base
+ 0x00006000;
470 info
->start
[3] = base
+ 0x00008000;
471 for (i
= 4; i
< info
->sector_count
; i
++)
472 info
->start
[i
] = base
+ (i
* 0x00010000) - 0x00030000;
475 /* set sector offsets for top boot block type */
476 i
= info
->sector_count
- 1;
477 if(info
->sector_count
==71) {
479 info
->start
[i
--] = base
+ info
->size
- 0x00002000;
480 info
->start
[i
--] = base
+ info
->size
- 0x00004000;
481 info
->start
[i
--] = base
+ info
->size
- 0x00006000;
482 info
->start
[i
--] = base
+ info
->size
- 0x00008000;
483 info
->start
[i
--] = base
+ info
->size
- 0x0000A000;
484 info
->start
[i
--] = base
+ info
->size
- 0x0000C000;
485 info
->start
[i
--] = base
+ info
->size
- 0x0000E000;
487 info
->start
[i
] = base
+ i
* 0x000010000;
490 info
->start
[i
--] = base
+ info
->size
- 0x00004000;
491 info
->start
[i
--] = base
+ info
->size
- 0x00006000;
492 info
->start
[i
--] = base
+ info
->size
- 0x00008000;
494 info
->start
[i
] = base
+ i
* 0x00010000;
499 /* check for protected sectors */
500 for (i
= 0; i
< info
->sector_count
; i
++) {
501 /* read sector protection at sector address, (A7 .. A0) = 0x02 */
502 /* D0 = 1 if protected */
503 addr2
= (volatile FLASH_WORD_SIZE
*)(info
->start
[i
]);
504 if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_INTEL
)
505 info
->protect
[i
] = 0;
507 info
->protect
[i
] = addr2
[2] & 1;
511 * Prevent writes to uninitialized FLASH.
513 if (info
->flash_id
!= FLASH_UNKNOWN
) {
514 #if 0 /* test-only */
516 addr2
= (volatile unsigned char *)info
->start
[0];
519 addr2
[ADDR0
] = 0xF0; /* reset bank */
521 addr2
= (FLASH_WORD_SIZE
*)info
->start
[0];
522 *addr2
= (FLASH_WORD_SIZE
)0x00F000F0; /* reset bank */
524 #else /* test-only */
525 addr2
= (FLASH_WORD_SIZE
*)info
->start
[0];
526 *addr2
= (FLASH_WORD_SIZE
)0x00F000F0; /* reset bank */
527 #endif /* test-only */
532 int wait_for_DQ7(flash_info_t
*info
, int sect
)
534 ulong start
, now
, last
;
535 volatile FLASH_WORD_SIZE
*addr
= (FLASH_WORD_SIZE
*)(info
->start
[sect
]);
537 start
= get_timer (0);
539 while ((addr
[0] & (FLASH_WORD_SIZE
)0x00800080) != (FLASH_WORD_SIZE
)0x00800080) {
540 if ((now
= get_timer(start
)) > CFG_FLASH_ERASE_TOUT
) {
541 printf ("Timeout\n");
544 /* show that we're waiting */
545 if ((now
- last
) > 1000) { /* every second */
553 int intel_wait_for_DQ7(flash_info_t
*info
, int sect
)
555 ulong start
, now
, last
;
556 volatile FLASH_WORD_SIZE
*addr
= (FLASH_WORD_SIZE
*)(info
->start
[sect
]);
558 start
= get_timer (0);
560 while ((addr
[0] & (FLASH_WORD_SIZE
)0x00800080) != (FLASH_WORD_SIZE
)0x00800080) {
561 if ((now
= get_timer(start
)) > CFG_FLASH_ERASE_TOUT
) {
562 printf ("Timeout\n");
565 /* show that we're waiting */
566 if ((now
- last
) > 1000) { /* every second */
571 addr
[0]=(FLASH_WORD_SIZE
)0x00500050;
575 /*-----------------------------------------------------------------------
578 int flash_erase (flash_info_t
*info
, int s_first
, int s_last
)
580 volatile FLASH_WORD_SIZE
*addr
= (FLASH_WORD_SIZE
*)(info
->start
[0]);
581 volatile FLASH_WORD_SIZE
*addr2
;
582 int flag
, prot
, sect
, l_sect
;
586 if ((s_first
< 0) || (s_first
> s_last
)) {
587 if (info
->flash_id
== FLASH_UNKNOWN
) {
588 printf ("- missing\n");
590 printf ("- no sectors to erase\n");
595 if (info
->flash_id
== FLASH_UNKNOWN
) {
596 printf ("Can't erase unknown flash type - aborted\n");
601 for (sect
=s_first
; sect
<=s_last
; ++sect
) {
602 if (info
->protect
[sect
]) {
608 printf ("- Warning: %d protected sectors will not be erased!\n",
616 /* Disable interrupts which might cause a timeout here */
617 flag
= disable_interrupts();
619 /* Start erase on unprotected sectors */
620 for (sect
= s_first
; sect
<=s_last
; sect
++) {
621 if (info
->protect
[sect
] == 0) { /* not protected */
622 addr2
= (FLASH_WORD_SIZE
*)(info
->start
[sect
]);
623 /* printf("Erasing sector %p\n", addr2); */ /* CLH */
624 if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_SST
) {
625 addr
[ADDR0
] = (FLASH_WORD_SIZE
)0x00AA00AA;
626 addr
[ADDR1
] = (FLASH_WORD_SIZE
)0x00550055;
627 addr
[ADDR0
] = (FLASH_WORD_SIZE
)0x00800080;
628 addr
[ADDR0
] = (FLASH_WORD_SIZE
)0x00AA00AA;
629 addr
[ADDR1
] = (FLASH_WORD_SIZE
)0x00550055;
630 addr2
[0] = (FLASH_WORD_SIZE
)0x00500050; /* block erase */
632 udelay(1000); /* wait 1 ms */
633 wait_for_DQ7(info
, sect
);
636 if((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_INTEL
){
637 addr2
[0] = (FLASH_WORD_SIZE
)0x00600060; /* unlock sector */
638 addr2
[0] = (FLASH_WORD_SIZE
)0x00D000D0; /* sector erase */
639 intel_wait_for_DQ7(info
, sect
);
640 addr2
[0] = (FLASH_WORD_SIZE
)0x00200020; /* sector erase */
641 addr2
[0] = (FLASH_WORD_SIZE
)0x00D000D0; /* sector erase */
642 intel_wait_for_DQ7(info
, sect
);
645 addr
[ADDR0
] = (FLASH_WORD_SIZE
)0x00AA00AA;
646 addr
[ADDR1
] = (FLASH_WORD_SIZE
)0x00550055;
647 addr
[ADDR0
] = (FLASH_WORD_SIZE
)0x00800080;
648 addr
[ADDR0
] = (FLASH_WORD_SIZE
)0x00AA00AA;
649 addr
[ADDR1
] = (FLASH_WORD_SIZE
)0x00550055;
650 addr2
[0] = (FLASH_WORD_SIZE
)0x00300030; /* sector erase */
651 wait_for_DQ7(info
, sect
);
656 * Wait for each sector to complete, it's more
657 * reliable. According to AMD Spec, you must
658 * issue all erase commands within a specified
659 * timeout. This has been seen to fail, especially
660 * if printf()s are included (for debug)!!
662 /* wait_for_DQ7(info, sect); */
666 /* re-enable interrupts if necessary */
670 /* wait at least 80us - let's wait 1 ms */
675 * We wait for the last triggered sector
679 wait_for_DQ7(info
, l_sect
);
683 /* reset to read mode */
684 addr
= (FLASH_WORD_SIZE
*)info
->start
[0];
685 addr
[0] = (FLASH_WORD_SIZE
)0x00F000F0; /* reset bank */
691 void unlock_intel_sectors(flash_info_t
*info
,ulong addr
,ulong cnt
)
694 volatile FLASH_WORD_SIZE
*addr2
;
697 for(i
=info
->sector_count
-1;i
>0;i
--)
699 if(addr
>=info
->start
[i
])
703 addr2
= (FLASH_WORD_SIZE
*)(info
->start
[i
]);
704 addr2
[0] = (FLASH_WORD_SIZE
)0x00600060; /* unlock sector setup */
705 addr2
[0] = (FLASH_WORD_SIZE
)0x00D000D0; /* unlock sector */
706 intel_wait_for_DQ7(info
, i
);
708 c
-=(info
->start
[i
]-info
->start
[i
-1]);
715 /*-----------------------------------------------------------------------
716 * Copy memory to flash, returns:
719 * 2 - Flash not erased
722 int write_buff (flash_info_t
*info
, uchar
*src
, ulong addr
, ulong cnt
)
727 if((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_INTEL
){
728 unlock_intel_sectors(info
,addr
,cnt
);
730 wp
= (addr
& ~3); /* get lower word aligned address */
732 * handle unaligned start bytes
734 if ((l
= addr
- wp
) != 0) {
736 for (i
=0, cp
=wp
; i
<l
; ++i
, ++cp
) {
737 data
= (data
<< 8) | (*(uchar
*)cp
);
739 for (; i
<4 && cnt
>0; ++i
) {
740 data
= (data
<< 8) | *src
++;
744 for (; cnt
==0 && i
<4; ++i
, ++cp
) {
745 data
= (data
<< 8) | (*(uchar
*)cp
);
748 if ((rc
= write_word(info
, wp
, data
)) != 0) {
755 * handle word aligned part
759 for (i
=0; i
<4; ++i
) {
760 data
= (data
<< 8) | *src
++;
762 if ((rc
= write_word(info
, wp
, data
)) != 0) {
766 if((wp
% 0x10000)==0)
767 printf("."); /* show Progress */
776 * handle unaligned tail bytes
779 for (i
=0, cp
=wp
; i
<4 && cnt
>0; ++i
, ++cp
) {
780 data
= (data
<< 8) | *src
++;
783 for (; i
<4; ++i
, ++cp
) {
784 data
= (data
<< 8) | (*(uchar
*)cp
);
786 rc
=write_word(info
, wp
, data
);
790 /*-----------------------------------------------------------------------
791 * Write a word to Flash, returns:
794 * 2 - Flash not erased
796 static FLASH_WORD_SIZE
*read_val
= (FLASH_WORD_SIZE
*)0x200000;
798 static int write_word (flash_info_t
*info
, ulong dest
, ulong data
)
800 volatile FLASH_WORD_SIZE
*addr2
= (FLASH_WORD_SIZE
*)(info
->start
[0]);
801 volatile FLASH_WORD_SIZE
*dest2
= (FLASH_WORD_SIZE
*)dest
;
802 volatile FLASH_WORD_SIZE
*data2
= (FLASH_WORD_SIZE
*)&data
;
807 /* Check if Flash is (sufficiently) erased */
808 if ((*((volatile FLASH_WORD_SIZE
*)dest
) &
809 (FLASH_WORD_SIZE
)data
) != (FLASH_WORD_SIZE
)data
) {
812 /* Disable interrupts which might cause a timeout here */
813 flag
= disable_interrupts();
814 for (i
=0; i
<4/sizeof(FLASH_WORD_SIZE
); i
++)
816 if((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_INTEL
){
817 /* intel style writting */
818 dest2
[i
] = (FLASH_WORD_SIZE
)0x00500050;
819 dest2
[i
] = (FLASH_WORD_SIZE
)0x00400040;
820 *read_val
++ = data2
[i
];
824 /* data polling for D7 */
825 start
= get_timer (0);
827 while ((dest2
[i
] & (FLASH_WORD_SIZE
)0x00800080) != (FLASH_WORD_SIZE
)0x00800080)
829 if (get_timer(start
) > CFG_FLASH_WRITE_TOUT
)
832 dest2
[i
] = (FLASH_WORD_SIZE
)0x00FF00FF; /* return to read mode */
834 dest2
[i
] = (FLASH_WORD_SIZE
)0x00FF00FF; /* return to read mode */
835 if(dest2
[i
]!=data2
[i
])
836 printf("Error at %p 0x%04X != 0x%04X\n",&dest2
[i
],dest2
[i
],data2
[i
]);
839 addr2
[ADDR0
] = (FLASH_WORD_SIZE
)0x00AA00AA;
840 addr2
[ADDR1
] = (FLASH_WORD_SIZE
)0x00550055;
841 addr2
[ADDR0
] = (FLASH_WORD_SIZE
)0x00A000A0;
843 /* re-enable interrupts if necessary */
846 /* data polling for D7 */
847 start
= get_timer (0);
848 while ((dest2
[i
] & (FLASH_WORD_SIZE
)0x00800080) !=
849 (data2
[i
] & (FLASH_WORD_SIZE
)0x00800080)) {
850 if (get_timer(start
) > CFG_FLASH_WRITE_TOUT
) {
859 /*-----------------------------------------------------------------------