]>
git.ipfire.org Git - u-boot.git/blob - board/sc520_spunk/flash.c
2 * (C) Copyright 2002, 2003
3 * Daniel Engström, Omicron Ceti AB, daniel@omicron.se
6 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
7 * Alex Zuepke <azu@sysgo.de>
9 * See file CREDITS for list of people who contributed to this
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License as
14 * published by the Free Software Foundation; either version 2 of
15 * the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
31 #include <asm/ic/sc520.h>
33 #define PROBE_BUFFER_SIZE 1024
34 static unsigned char buffer
[PROBE_BUFFER_SIZE
];
37 #define SC520_MAX_FLASH_BANKS 1
38 #define SC520_FLASH_BANK0_BASE 0x38000000 /* BOOTCS */
39 #define SC520_FLASH_BANKSIZE 0x8000000
41 #define A29LV641DH_SIZE 0x800000
42 #define A29LV641DH_SECTORS 128
44 #define A29LV641MH_SIZE 0x800000
45 #define A29LV641MH_SECTORS 128
47 #define I28F320J3A_SIZE 0x400000
48 #define I28F320J3A_SECTORS 32
50 #define I28F640J3A_SIZE 0x800000
51 #define I28F640J3A_SECTORS 64
53 #define I28F128J3A_SIZE 0x1000000
54 #define I28F128J3A_SECTORS 128
56 flash_info_t flash_info
[SC520_MAX_FLASH_BANKS
];
62 /*-----------------------------------------------------------------------
66 static u32
_probe_flash(u32 addr
, u32 bw
, int il
)
70 /* First do an unlock cycle for the benefit of
71 * devices that need it */
76 *(volatile u8
*)(addr
+0x5555) = 0xaa;
77 *(volatile u8
*)(addr
+0x2aaa) = 0x55;
78 *(volatile u8
*)(addr
+0x5555) = 0x90;
81 result
= *(volatile u8
*)addr
;
85 result
|= *(volatile u8
*)(addr
+2);
87 /* Return device to data mode */
88 *(volatile u8
*)addr
= 0xff;
89 *(volatile u8
*)(addr
+0x5555), 0xf0;
93 *(volatile u16
*)(addr
+0xaaaa) = 0xaaaa;
94 *(volatile u16
*)(addr
+0x5554) = 0x5555;
96 /* Issue identification command */
98 *(volatile u16
*)(addr
+0xaaaa) = 0x9090;
101 result
= *(volatile u8
*)addr
;
105 result
|= *(volatile u8
*)(addr
+2);
107 /* Return device to data mode */
108 *(volatile u16
*)addr
= 0xffff;
109 *(volatile u16
*)(addr
+0xaaaa), 0xf0f0;
112 *(volatile u8
*)(addr
+0xaaaa) = 0x90;
114 result
= *(volatile u16
*)addr
;
118 result
|= *(volatile u16
*)(addr
+2);
120 /* Return device to data mode */
121 *(volatile u8
*)addr
= 0xff;
122 *(volatile u8
*)(addr
+0xaaaa), 0xf0;
128 *(volatile u32
*)(addr
+0x5554) = 0xaaaaaaaa;
129 *(volatile u32
*)(addr
+0xaaa8) = 0x55555555;
133 /* Issue identification command */
134 *(volatile u8
*)(addr
+0x5554) = 0x90;
137 result
= *(volatile u16
*)addr
;
141 result
|= *(volatile u16
*)(addr
+4);
143 /* Return device to data mode */
144 *(volatile u8
*)addr
= 0xff;
145 *(volatile u8
*)(addr
+0x5554), 0xf0;
149 /* Issue identification command */
150 *(volatile u32
*)(addr
+ 0x5554) = 0x00900090;
153 result
= *(volatile u16
*)addr
;
157 result
|= *(volatile u16
*)(addr
+4);
159 /* Return device to data mode */
160 *(volatile u32
*)addr
= 0x00ff00ff;
161 *(volatile u32
*)(addr
+0x5554), 0x00f000f0;
165 /* Issue identification command */
166 *(volatile u32
*)(addr
+0x5554) = 0x90909090;
169 result
= *(volatile u8
*)addr
;
173 result
|= *(volatile u8
*)(addr
+4);
175 /* Return device to data mode */
176 *(volatile u32
*)addr
= 0xffffffff;
177 *(volatile u32
*)(addr
+0x5554), 0xf0f0f0f0;
187 extern int _probe_flash_end
;
188 asm ("_probe_flash_end:\n"
191 static int identify_flash(unsigned address
, int width
)
199 u32 (*_probe_flash_ptr
)(u32 a
, u32 bw
, int il
);
201 size
= (unsigned)&_probe_flash_end
- (unsigned)_probe_flash
;
203 if (size
> PROBE_BUFFER_SIZE
) {
204 printf("_probe_flash() routine too large (%d) %p - %p\n",
205 size
, &_probe_flash_end
, _probe_flash
);
209 memcpy(buffer
, _probe_flash
, size
);
210 _probe_flash_ptr
= (void*)buffer
;
212 is
= disable_interrupts();
213 res
= _probe_flash_ptr(address
, width
, 1);
220 device
= res
& 0xffff;
226 ulong
flash_init(void)
231 for (i
= 0; i
< SC520_MAX_FLASH_BANKS
; i
++) {
236 memset(flash_info
[i
].protect
, 0, CFG_MAX_FLASH_SECT
);
239 flashbase
= SC520_FLASH_BANK0_BASE
;
242 panic("configured to many flash banks!\n");
245 id
= identify_flash(flashbase
, 2);
249 flash_info
[i
].flash_id
=
250 (AMD_MANUFACT
& FLASH_VENDMASK
) |
251 (AMD_ID_LV640U
& FLASH_TYPEMASK
);
253 flash_info
[i
].size
= A29LV641DH_SIZE
;
254 flash_info
[i
].sector_count
= A29LV641DH_SECTORS
;
255 sectsize
= A29LV641DH_SIZE
/A29LV641DH_SECTORS
;
256 printf("Bank %d: AMD 29LV641DH\n", i
);
261 flash_info
[i
].flash_id
=
262 (AMD_MANUFACT
& FLASH_VENDMASK
) |
263 (AMD_ID_DL640
& FLASH_TYPEMASK
);
265 flash_info
[i
].size
= A29LV641MH_SIZE
;
266 flash_info
[i
].sector_count
= A29LV641MH_SECTORS
;
267 sectsize
= A29LV641MH_SIZE
/A29LV641MH_SECTORS
;
268 printf("Bank %d: AMD 29LV641MH\n", i
);
273 flash_info
[i
].flash_id
=
274 (INTEL_MANUFACT
& FLASH_VENDMASK
) |
275 (INTEL_ID_28F320J3A
& FLASH_TYPEMASK
);
277 flash_info
[i
].size
= I28F320J3A_SIZE
;
278 flash_info
[i
].sector_count
= I28F320J3A_SECTORS
;
279 sectsize
= I28F320J3A_SIZE
/I28F320J3A_SECTORS
;
280 printf("Bank %d: Intel 28F320J3A\n", i
);
285 flash_info
[i
].flash_id
=
286 (INTEL_MANUFACT
& FLASH_VENDMASK
) |
287 (INTEL_ID_28F640J3A
& FLASH_TYPEMASK
);
289 flash_info
[i
].size
= I28F640J3A_SIZE
;
290 flash_info
[i
].sector_count
= I28F640J3A_SECTORS
;
291 sectsize
= I28F640J3A_SIZE
/I28F640J3A_SECTORS
;
292 printf("Bank %d: Intel 28F640J3A\n", i
);
297 flash_info
[i
].flash_id
=
298 (INTEL_MANUFACT
& FLASH_VENDMASK
) |
299 (INTEL_ID_28F128J3A
& FLASH_TYPEMASK
);
301 flash_info
[i
].size
= I28F128J3A_SIZE
;
302 flash_info
[i
].sector_count
= I28F128J3A_SECTORS
;
303 sectsize
= I28F128J3A_SIZE
/I28F128J3A_SECTORS
;
304 printf("Bank %d: Intel 28F128J3A\n", i
);
308 printf("Bank %d have unknown flash %08x\n", i
, id
);
309 flash_info
[i
].flash_id
= FLASH_UNKNOWN
;
313 for (j
= 0; j
< flash_info
[i
].sector_count
; j
++) {
314 flash_info
[i
].start
[j
] = flashbase
+ j
* sectsize
;
316 size
+= flash_info
[i
].size
;
318 flash_protect(FLAG_PROTECT_CLEAR
,
319 flash_info
[i
].start
[0],
320 flash_info
[i
].start
[0] + flash_info
[i
].size
- 1,
325 * Protect monitor and environment sectors
327 flash_protect(FLAG_PROTECT_SET
,
332 flash_protect(FLAG_PROTECT_SET
,
334 CFG_ENV_ADDR
+ CFG_ENV_SIZE
- 1,
340 /*-----------------------------------------------------------------------
342 void flash_print_info(flash_info_t
*info
)
346 switch (info
->flash_id
& FLASH_VENDMASK
) {
347 case (INTEL_MANUFACT
& FLASH_VENDMASK
):
349 switch (info
->flash_id
& FLASH_TYPEMASK
) {
350 case (INTEL_ID_28F320J3A
& FLASH_TYPEMASK
):
351 printf("1x I28F320J3A (32Mbit)\n");
353 case (INTEL_ID_28F640J3A
& FLASH_TYPEMASK
):
354 printf("1x I28F640J3A (64Mbit)\n");
356 case (INTEL_ID_28F128J3A
& FLASH_TYPEMASK
):
357 printf("1x I28F128J3A (128Mbit)\n");
360 printf("Unknown Chip Type\n");
367 case (AMD_MANUFACT
& FLASH_VENDMASK
):
369 switch (info
->flash_id
& FLASH_TYPEMASK
) {
370 case (AMD_ID_LV640U
& FLASH_TYPEMASK
):
371 printf("1x AMD29LV641DH (64Mbit)\n");
373 case (AMD_ID_DL640
& FLASH_TYPEMASK
):
374 printf("1x AMD29LV641MH (64Mbit)\n");
377 printf("Unknown Chip Type\n");
384 printf("Unknown Vendor ");
389 printf(" Size: %ld MB in %d Sectors\n",
390 info
->size
>> 20, info
->sector_count
);
392 printf(" Sector Start Addresses:");
393 for (i
= 0; i
< info
->sector_count
; i
++) {
397 printf (" %08lX%s", info
->start
[i
],
398 info
->protect
[i
] ? " (RO)" : " ");
405 /*-----------------------------------------------------------------------
409 static u32
_amd_erase_flash(u32 addr
, u32 sector
)
414 *(volatile u16
*)(addr
+ 0xaaaa) = 0x00AA;
415 *(volatile u16
*)(addr
+ 0x5554) = 0x0055;
416 *(volatile u16
*)(addr
+ 0xaaaa) = 0x0080;
418 *(volatile u16
*)(addr
+ 0xaaaa) = 0x00AA;
419 *(volatile u16
*)(addr
+ 0x5554) = 0x0055;
420 /* Sector erase command comes last */
421 *(volatile u16
*)(addr
+ sector
) = 0x0030;
423 elapsed
= *(volatile u16
*)(0xfffef000+SC520_SWTMRMILLI
); /* dummy read */
425 while (((*(volatile u16
*)(addr
+ sector
)) & 0x0080) != 0x0080) {
427 elapsed
+= *(volatile u16
*)(0xfffef000+SC520_SWTMRMILLI
);
428 if (elapsed
> ((CFG_FLASH_ERASE_TOUT
/CFG_HZ
) * 1000)) {
429 *(volatile u16
*)(addr
) = 0x00f0;
434 *(volatile u16
*)(addr
) = 0x00f0;
439 extern int _amd_erase_flash_end
;
440 asm ("_amd_erase_flash_end:\n"
443 /* this needs to be inlined, the SWTMRMMILLI register is reset by each read */
444 #define __udelay(delay) \
449 micro = *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI); \
453 milli += *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI); \
454 micro = *(volatile u16*)(0xfffef000+SC520_SWTMRMICRO); \
456 if ((delay) <= (micro + (milli * 1000))) { \
462 static u32
_intel_erase_flash(u32 addr
, u32 sector
)
466 *(volatile u16
*)(addr
+ sector
) = 0x0050; /* clear status register */
467 *(volatile u16
*)(addr
+ sector
) = 0x0020; /* erase setup */
468 *(volatile u16
*)(addr
+ sector
) = 0x00D0; /* erase confirm */
471 /* Wait at least 80us - let's wait 1 ms */
475 while (((*(volatile u16
*)(addr
+ sector
)) & 0x0080) != 0x0080) {
476 elapsed
+= *(volatile u16
*)(0xfffef000+SC520_SWTMRMILLI
);
477 if (elapsed
> ((CFG_FLASH_ERASE_TOUT
/CFG_HZ
) * 1000)) {
478 *(volatile u16
*)(addr
+ sector
) = 0x00B0; /* suspend erase */
479 *(volatile u16
*)(addr
+ sector
) = 0x00FF; /* reset to read mode */
484 *(volatile u16
*)(addr
+ sector
) = 0x00FF; /* reset to read mode */
490 extern int _intel_erase_flash_end
;
491 asm ("_intel_erase_flash_end:\n"
494 int flash_erase(flash_info_t
*info
, int s_first
, int s_last
)
496 u32 (*_erase_flash_ptr
)(u32 a
, u32 so
);
501 if ((s_first
< 0) || (s_first
> s_last
)) {
502 if (info
->flash_id
== FLASH_UNKNOWN
) {
503 printf("- missing\n");
505 printf("- no sectors to erase\n");
510 if ((info
->flash_id
& FLASH_VENDMASK
) == (AMD_MANUFACT
& FLASH_VENDMASK
)) {
511 size
= (unsigned)&_amd_erase_flash_end
- (unsigned)_amd_erase_flash
;
513 if (size
> PROBE_BUFFER_SIZE
) {
514 printf("_amd_erase_flash() routine too large (%d) %p - %p\n",
515 size
, &_amd_erase_flash_end
, _amd_erase_flash
);
519 memcpy(buffer
, _amd_erase_flash
, size
);
520 _erase_flash_ptr
= (void*)buffer
;
522 } else if ((info
->flash_id
& FLASH_VENDMASK
) == (INTEL_MANUFACT
& FLASH_VENDMASK
)) {
523 size
= (unsigned)&_intel_erase_flash_end
- (unsigned)_intel_erase_flash
;
525 if (size
> PROBE_BUFFER_SIZE
) {
526 printf("_intel_erase_flash() routine too large (%d) %p - %p\n",
527 size
, &_intel_erase_flash_end
, _intel_erase_flash
);
531 memcpy(buffer
, _intel_erase_flash
, size
);
532 _erase_flash_ptr
= (void*)buffer
;
534 printf ("Can't erase unknown flash type - aborted\n");
539 for (sect
=s_first
; sect
<=s_last
; ++sect
) {
540 if (info
->protect
[sect
]) {
546 printf ("- Warning: %d protected sectors will not be erased!\n", prot
);
552 /* Start erase on unprotected sectors */
553 for (sect
= s_first
; sect
<=s_last
; sect
++) {
555 if (info
->protect
[sect
] == 0) { /* not protected */
559 /* Disable interrupts which might cause a timeout here */
560 flag
= disable_interrupts();
562 res
= _erase_flash_ptr(info
->start
[0], info
->start
[sect
]-info
->start
[0]);
564 /* re-enable interrupts if necessary */
571 printf("Erase timed out, sector %d\n", sect
);
583 /*-----------------------------------------------------------------------
584 * Write a word to Flash, returns:
587 * 2 - Flash not erased
589 static int _amd_write_word(unsigned start
, unsigned dest
, unsigned data
)
591 volatile u16
*addr2
= (u16
*)start
;
592 volatile u16
*dest2
= (u16
*)dest
;
593 volatile u16
*data2
= (u16
*)&data
;
597 /* Check if Flash is (sufficiently) erased */
598 if ((*((volatile u16
*)dest
) & (u16
)data
) != (u16
)data
) {
602 for (i
= 0; i
< 2; i
++) {
605 addr2
[0x5555] = 0x00AA;
606 addr2
[0x2aaa] = 0x0055;
607 addr2
[0x5555] = 0x00A0;
609 dest2
[i
] = (data
>> (i
*16)) & 0xffff;
611 elapsed
= *(volatile u16
*)(0xfffef000+SC520_SWTMRMILLI
); /* dummy read */
614 /* data polling for D7 */
615 while ((dest2
[i
] & 0x0080) != (data2
[i
] & 0x0080)) {
616 elapsed
+= *(volatile u16
*)(0xfffef000+SC520_SWTMRMILLI
);
617 if (elapsed
> ((CFG_FLASH_WRITE_TOUT
/CFG_HZ
) * 1000)) {
629 extern int _amd_write_word_end
;
630 asm ("_amd_write_word_end:\n"
634 static int _intel_write_word(unsigned start
, unsigned dest
, unsigned data
)
639 /* Check if Flash is (sufficiently) erased */
640 if ((*((volatile u16
*)dest
) & (u16
)data
) != (u16
)data
) {
644 for (i
= 0; i
< 2; i
++) {
646 *(volatile u16
*)(dest
+2*i
) = 0x0040; /* write setup */
647 *(volatile u16
*)(dest
+2*i
) = (data
>> (i
*16)) & 0xffff;
649 elapsed
= *(volatile u16
*)(0xfffef000+SC520_SWTMRMILLI
); /* dummy read */
652 /* data polling for D7 */
653 while ((*(volatile u16
*)dest
& 0x0080) != 0x0080) {
654 elapsed
+= *(volatile u16
*)(0xfffef000+SC520_SWTMRMILLI
);
655 if (elapsed
> ((CFG_FLASH_WRITE_TOUT
/CFG_HZ
) * 1000)) {
656 *(volatile u16
*)dest
= 0x00ff;
662 *(volatile u16
*)dest
= 0x00ff;
669 extern int _intel_write_word_end
;
670 asm ("_intel_write_word_end:\n"
674 /*-----------------------------------------------------------------------
675 * Copy memory to flash, returns:
678 * 2 - Flash not erased
679 * 3 - Unsupported flash type
682 int write_buff(flash_info_t
*info
, uchar
*src
, ulong addr
, ulong cnt
)
687 u32 (*_write_word_ptr
)(unsigned start
, unsigned dest
, unsigned data
);
690 if ((info
->flash_id
& FLASH_VENDMASK
) == (AMD_MANUFACT
& FLASH_VENDMASK
)) {
691 size
= (unsigned)&_amd_write_word_end
- (unsigned)_amd_write_word
;
693 if (size
> PROBE_BUFFER_SIZE
) {
694 printf("_amd_write_word() routine too large (%d) %p - %p\n",
695 size
, &_amd_write_word_end
, _amd_write_word
);
699 memcpy(buffer
, _amd_write_word
, size
);
700 _write_word_ptr
= (void*)buffer
;
702 } else if ((info
->flash_id
& FLASH_VENDMASK
) == (INTEL_MANUFACT
& FLASH_VENDMASK
)) {
703 size
= (unsigned)&_intel_write_word_end
- (unsigned)_intel_write_word
;
705 if (size
> PROBE_BUFFER_SIZE
) {
706 printf("_intel_write_word() routine too large (%d) %p - %p\n",
707 size
, &_intel_write_word_end
, _intel_write_word
);
711 memcpy(buffer
, _intel_write_word
, size
);
712 _write_word_ptr
= (void*)buffer
;
714 printf ("Can't program unknown flash type - aborted\n");
719 wp
= (addr
& ~3); /* get lower word aligned address */
723 * handle unaligned start bytes
725 if ((l
= addr
- wp
) != 0) {
727 for (i
=0, cp
=wp
; i
<l
; ++i
, ++cp
) {
728 data
|= (*(uchar
*)cp
) << (8*i
);
730 for (; i
<4 && cnt
>0; ++i
) {
731 data
|= *src
++ << (8*i
);
735 for (; cnt
==0 && i
<4; ++i
, ++cp
) {
736 data
|= (*(uchar
*)cp
) << (8*i
);
739 /* Disable interrupts which might cause a timeout here */
740 flag
= disable_interrupts();
742 rc
= _write_word_ptr(info
->start
[0], wp
, data
);
744 /* re-enable interrupts if necessary */
755 * handle word aligned part
760 for (i
=0; i
<4; ++i
) {
761 data
|= *src
++ << (8*i
);
764 /* Disable interrupts which might cause a timeout here */
765 flag
= disable_interrupts();
767 rc
= _write_word_ptr(info
->start
[0], wp
, data
);
769 /* re-enable interrupts if necessary */
785 * handle unaligned tail bytes
788 for (i
=0, cp
=wp
; i
<4 && cnt
>0; ++i
, ++cp
) {
789 data
|= *src
++ << (8*i
);
793 for (; i
<4; ++i
, ++cp
) {
794 data
|= (*(uchar
*)cp
) << (8*i
);
797 /* Disable interrupts which might cause a timeout here */
798 flag
= disable_interrupts();
800 rc
= _write_word_ptr(info
->start
[0], wp
, data
);
802 /* re-enable interrupts if necessary */