]>
git.ipfire.org Git - people/ms/u-boot.git/blob - board/sc520_spunk/flash.c
0b4bf68894f15de688b8661cddd242632f88feac
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
];
36 #define SC520_MAX_FLASH_BANKS 1
37 #define SC520_FLASH_BANK0_BASE 0x38000000 /* BOOTCS */
38 #define SC520_FLASH_BANKSIZE 0x8000000
40 #define A29LV641DH_SIZE 0x800000
41 #define A29LV641DH_SECTORS 128
43 #define A29LV641MH_SIZE 0x800000
44 #define A29LV641MH_SECTORS 128
46 #define I28F320J3A_SIZE 0x400000
47 #define I28F320J3A_SECTORS 32
49 #define I28F640J3A_SIZE 0x800000
50 #define I28F640J3A_SECTORS 64
52 #define I28F128J3A_SIZE 0x1000000
53 #define I28F128J3A_SECTORS 128
55 flash_info_t flash_info
[SC520_MAX_FLASH_BANKS
];
61 /*-----------------------------------------------------------------------
64 static u32
_probe_flash(u32 addr
, u32 bw
, int il
)
68 /* First do an unlock cycle for the benefit of
69 * devices that need it */
74 *(volatile u8
*)(addr
+0x5555) = 0xaa;
75 *(volatile u8
*)(addr
+0x2aaa) = 0x55;
76 *(volatile u8
*)(addr
+0x5555) = 0x90;
79 result
= *(volatile u8
*)addr
;
83 result
|= *(volatile u8
*)(addr
+2);
85 /* Return device to data mode */
86 *(volatile u8
*)addr
= 0xff;
87 *(volatile u8
*)(addr
+0x5555), 0xf0;
91 *(volatile u16
*)(addr
+0xaaaa) = 0xaaaa;
92 *(volatile u16
*)(addr
+0x5554) = 0x5555;
94 /* Issue identification command */
96 *(volatile u16
*)(addr
+0xaaaa) = 0x9090;
99 result
= *(volatile u8
*)addr
;
103 result
|= *(volatile u8
*)(addr
+2);
105 /* Return device to data mode */
106 *(volatile u16
*)addr
= 0xffff;
107 *(volatile u16
*)(addr
+0xaaaa), 0xf0f0;
110 *(volatile u8
*)(addr
+0xaaaa) = 0x90;
112 result
= *(volatile u16
*)addr
;
116 result
|= *(volatile u16
*)(addr
+2);
118 /* Return device to data mode */
119 *(volatile u8
*)addr
= 0xff;
120 *(volatile u8
*)(addr
+0xaaaa), 0xf0;
126 *(volatile u32
*)(addr
+0x5554) = 0xaaaaaaaa;
127 *(volatile u32
*)(addr
+0xaaa8) = 0x55555555;
131 /* Issue identification command */
132 *(volatile u8
*)(addr
+0x5554) = 0x90;
135 result
= *(volatile u16
*)addr
;
139 result
|= *(volatile u16
*)(addr
+4);
141 /* Return device to data mode */
142 *(volatile u8
*)addr
= 0xff;
143 *(volatile u8
*)(addr
+0x5554), 0xf0;
147 /* Issue identification command */
148 *(volatile u32
*)(addr
+ 0x5554) = 0x00900090;
151 result
= *(volatile u16
*)addr
;
155 result
|= *(volatile u16
*)(addr
+4);
157 /* Return device to data mode */
158 *(volatile u32
*)addr
= 0x00ff00ff;
159 *(volatile u32
*)(addr
+0x5554), 0x00f000f0;
163 /* Issue identification command */
164 *(volatile u32
*)(addr
+0x5554) = 0x90909090;
167 result
= *(volatile u8
*)addr
;
171 result
|= *(volatile u8
*)(addr
+4);
173 /* Return device to data mode */
174 *(volatile u32
*)addr
= 0xffffffff;
175 *(volatile u32
*)(addr
+0x5554), 0xf0f0f0f0;
184 extern int _probe_flash_end
;
185 asm ("_probe_flash_end:\n"
188 static int identify_flash(unsigned address
, int width
)
196 u32 (*_probe_flash_ptr
)(u32 a
, u32 bw
, int il
);
198 size
= (unsigned)&_probe_flash_end
- (unsigned)_probe_flash
;
200 if (size
> PROBE_BUFFER_SIZE
) {
201 printf("_probe_flash() routine too large (%d) %p - %p\n",
202 size
, &_probe_flash_end
, _probe_flash
);
206 memcpy(buffer
, _probe_flash
, size
);
207 _probe_flash_ptr
= (void*)buffer
;
209 is
= disable_interrupts();
210 res
= _probe_flash_ptr(address
, width
, 1);
216 device
= res
& 0xffff;
221 ulong
flash_init(void)
226 for (i
= 0; i
< SC520_MAX_FLASH_BANKS
; i
++) {
231 memset(flash_info
[i
].protect
, 0, CFG_MAX_FLASH_SECT
);
234 flashbase
= SC520_FLASH_BANK0_BASE
;
237 panic("configured too many flash banks!\n");
240 id
= identify_flash(flashbase
, 2);
244 flash_info
[i
].flash_id
=
245 (AMD_MANUFACT
& FLASH_VENDMASK
) |
246 (AMD_ID_LV640U
& FLASH_TYPEMASK
);
248 flash_info
[i
].size
= A29LV641DH_SIZE
;
249 flash_info
[i
].sector_count
= A29LV641DH_SECTORS
;
250 sectsize
= A29LV641DH_SIZE
/A29LV641DH_SECTORS
;
251 printf("Bank %d: AMD 29LV641DH\n", i
);
256 flash_info
[i
].flash_id
=
257 (AMD_MANUFACT
& FLASH_VENDMASK
) |
258 (AMD_ID_DL640
& FLASH_TYPEMASK
);
260 flash_info
[i
].size
= A29LV641MH_SIZE
;
261 flash_info
[i
].sector_count
= A29LV641MH_SECTORS
;
262 sectsize
= A29LV641MH_SIZE
/A29LV641MH_SECTORS
;
263 printf("Bank %d: AMD 29LV641MH\n", i
);
268 flash_info
[i
].flash_id
=
269 (INTEL_MANUFACT
& FLASH_VENDMASK
) |
270 (INTEL_ID_28F320J3A
& FLASH_TYPEMASK
);
272 flash_info
[i
].size
= I28F320J3A_SIZE
;
273 flash_info
[i
].sector_count
= I28F320J3A_SECTORS
;
274 sectsize
= I28F320J3A_SIZE
/I28F320J3A_SECTORS
;
275 printf("Bank %d: Intel 28F320J3A\n", i
);
280 flash_info
[i
].flash_id
=
281 (INTEL_MANUFACT
& FLASH_VENDMASK
) |
282 (INTEL_ID_28F640J3A
& FLASH_TYPEMASK
);
284 flash_info
[i
].size
= I28F640J3A_SIZE
;
285 flash_info
[i
].sector_count
= I28F640J3A_SECTORS
;
286 sectsize
= I28F640J3A_SIZE
/I28F640J3A_SECTORS
;
287 printf("Bank %d: Intel 28F640J3A\n", i
);
292 flash_info
[i
].flash_id
=
293 (INTEL_MANUFACT
& FLASH_VENDMASK
) |
294 (INTEL_ID_28F128J3A
& FLASH_TYPEMASK
);
296 flash_info
[i
].size
= I28F128J3A_SIZE
;
297 flash_info
[i
].sector_count
= I28F128J3A_SECTORS
;
298 sectsize
= I28F128J3A_SIZE
/I28F128J3A_SECTORS
;
299 printf("Bank %d: Intel 28F128J3A\n", i
);
303 printf("Bank %d have unknown flash %08x\n", i
, id
);
304 flash_info
[i
].flash_id
= FLASH_UNKNOWN
;
308 for (j
= 0; j
< flash_info
[i
].sector_count
; j
++) {
309 flash_info
[i
].start
[j
] = flashbase
+ j
* sectsize
;
311 size
+= flash_info
[i
].size
;
313 flash_protect(FLAG_PROTECT_CLEAR
,
314 flash_info
[i
].start
[0],
315 flash_info
[i
].start
[0] + flash_info
[i
].size
- 1,
320 * Protect monitor and environment sectors
322 flash_protect(FLAG_PROTECT_SET
,
327 flash_protect(FLAG_PROTECT_SET
,
329 CFG_ENV_ADDR
+ CFG_ENV_SIZE
- 1,
335 /*-----------------------------------------------------------------------
337 void flash_print_info(flash_info_t
*info
)
341 switch (info
->flash_id
& FLASH_VENDMASK
) {
342 case (INTEL_MANUFACT
& FLASH_VENDMASK
):
344 switch (info
->flash_id
& FLASH_TYPEMASK
) {
345 case (INTEL_ID_28F320J3A
& FLASH_TYPEMASK
):
346 printf("1x I28F320J3A (32Mbit)\n");
348 case (INTEL_ID_28F640J3A
& FLASH_TYPEMASK
):
349 printf("1x I28F640J3A (64Mbit)\n");
351 case (INTEL_ID_28F128J3A
& FLASH_TYPEMASK
):
352 printf("1x I28F128J3A (128Mbit)\n");
355 printf("Unknown Chip Type\n");
362 case (AMD_MANUFACT
& FLASH_VENDMASK
):
364 switch (info
->flash_id
& FLASH_TYPEMASK
) {
365 case (AMD_ID_LV640U
& FLASH_TYPEMASK
):
366 printf("1x AMD29LV641DH (64Mbit)\n");
368 case (AMD_ID_DL640
& FLASH_TYPEMASK
):
369 printf("1x AMD29LV641MH (64Mbit)\n");
372 printf("Unknown Chip Type\n");
379 printf("Unknown Vendor ");
383 printf(" Size: %ld MB in %d Sectors\n",
384 info
->size
>> 20, info
->sector_count
);
386 printf(" Sector Start Addresses:");
387 for (i
= 0; i
< info
->sector_count
; i
++) {
391 printf (" %08lX%s", info
->start
[i
],
392 info
->protect
[i
] ? " (RO)" : " ");
400 /*-----------------------------------------------------------------------
403 static u32
_amd_erase_flash(u32 addr
, u32 sector
)
408 *(volatile u16
*)(addr
+ 0xaaaa) = 0x00AA;
409 *(volatile u16
*)(addr
+ 0x5554) = 0x0055;
410 *(volatile u16
*)(addr
+ 0xaaaa) = 0x0080;
412 *(volatile u16
*)(addr
+ 0xaaaa) = 0x00AA;
413 *(volatile u16
*)(addr
+ 0x5554) = 0x0055;
414 /* Sector erase command comes last */
415 *(volatile u16
*)(addr
+ sector
) = 0x0030;
417 elapsed
= *(volatile u16
*)(0xfffef000+SC520_SWTMRMILLI
); /* dummy read */
419 while (((*(volatile u16
*)(addr
+ sector
)) & 0x0080) != 0x0080) {
421 elapsed
+= *(volatile u16
*)(0xfffef000+SC520_SWTMRMILLI
);
422 if (elapsed
> ((CFG_FLASH_ERASE_TOUT
/CFG_HZ
) * 1000)) {
423 *(volatile u16
*)(addr
) = 0x00f0;
428 *(volatile u16
*)(addr
) = 0x00f0;
433 extern int _amd_erase_flash_end
;
434 asm ("_amd_erase_flash_end:\n"
437 /* this needs to be inlined, the SWTMRMMILLI register is reset by each read */
438 #define __udelay(delay) \
443 micro = *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI); \
447 milli += *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI); \
448 micro = *(volatile u16*)(0xfffef000+SC520_SWTMRMICRO); \
450 if ((delay) <= (micro + (milli * 1000))) { \
456 static u32
_intel_erase_flash(u32 addr
, u32 sector
)
460 *(volatile u16
*)(addr
+ sector
) = 0x0050; /* clear status register */
461 *(volatile u16
*)(addr
+ sector
) = 0x0020; /* erase setup */
462 *(volatile u16
*)(addr
+ sector
) = 0x00D0; /* erase confirm */
464 /* Wait at least 80us - let's wait 1 ms */
468 while (((*(volatile u16
*)(addr
+ sector
)) & 0x0080) != 0x0080) {
469 elapsed
+= *(volatile u16
*)(0xfffef000+SC520_SWTMRMILLI
);
470 if (elapsed
> ((CFG_FLASH_ERASE_TOUT
/CFG_HZ
) * 1000)) {
471 *(volatile u16
*)(addr
+ sector
) = 0x00B0; /* suspend erase */
472 *(volatile u16
*)(addr
+ sector
) = 0x00FF; /* reset to read mode */
477 *(volatile u16
*)(addr
+ sector
) = 0x00FF; /* reset to read mode */
482 extern int _intel_erase_flash_end
;
483 asm ("_intel_erase_flash_end:\n"
486 int flash_erase(flash_info_t
*info
, int s_first
, int s_last
)
488 u32 (*_erase_flash_ptr
)(u32 a
, u32 so
);
493 if ((s_first
< 0) || (s_first
> s_last
)) {
494 if (info
->flash_id
== FLASH_UNKNOWN
) {
495 printf("- missing\n");
497 printf("- no sectors to erase\n");
502 if ((info
->flash_id
& FLASH_VENDMASK
) == (AMD_MANUFACT
& FLASH_VENDMASK
)) {
503 size
= (unsigned)&_amd_erase_flash_end
- (unsigned)_amd_erase_flash
;
505 if (size
> PROBE_BUFFER_SIZE
) {
506 printf("_amd_erase_flash() routine too large (%d) %p - %p\n",
507 size
, &_amd_erase_flash_end
, _amd_erase_flash
);
511 memcpy(buffer
, _amd_erase_flash
, size
);
512 _erase_flash_ptr
= (void*)buffer
;
514 } else if ((info
->flash_id
& FLASH_VENDMASK
) == (INTEL_MANUFACT
& FLASH_VENDMASK
)) {
515 size
= (unsigned)&_intel_erase_flash_end
- (unsigned)_intel_erase_flash
;
517 if (size
> PROBE_BUFFER_SIZE
) {
518 printf("_intel_erase_flash() routine too large (%d) %p - %p\n",
519 size
, &_intel_erase_flash_end
, _intel_erase_flash
);
523 memcpy(buffer
, _intel_erase_flash
, size
);
524 _erase_flash_ptr
= (void*)buffer
;
526 printf ("Can't erase unknown flash type - aborted\n");
531 for (sect
=s_first
; sect
<=s_last
; ++sect
) {
532 if (info
->protect
[sect
]) {
538 printf ("- Warning: %d protected sectors will not be erased!\n", prot
);
543 /* Start erase on unprotected sectors */
544 for (sect
= s_first
; sect
<=s_last
; sect
++) {
546 if (info
->protect
[sect
] == 0) { /* not protected */
550 /* Disable interrupts which might cause a timeout here */
551 flag
= disable_interrupts();
553 res
= _erase_flash_ptr(info
->start
[0], info
->start
[sect
]-info
->start
[0]);
555 /* re-enable interrupts if necessary */
561 printf("Erase timed out, sector %d\n", sect
);
572 /*-----------------------------------------------------------------------
573 * Write a word to Flash, returns:
576 * 2 - Flash not erased
578 static int _amd_write_word(unsigned start
, unsigned dest
, u16 data
)
580 volatile u16
*addr2
= (volatile u16
*)start
;
581 volatile u16
*dest2
= (volatile u16
*)dest
;
582 volatile u16
*data2
= (volatile u16
*)&data
;
586 /* Check if Flash is (sufficiently) erased */
587 if ((*((volatile u16
*)dest
) & (u16
)data
) != (u16
)data
) {
591 for (i
= 0; i
< 2; i
++) {
593 addr2
[0x5555] = 0x00AA;
594 addr2
[0x2aaa] = 0x0055;
595 addr2
[0x5555] = 0x00A0;
597 dest2
[i
] = (data
>> (i
*16)) & 0xffff;
599 elapsed
= *(volatile u16
*)(0xfffef000+SC520_SWTMRMILLI
); /* dummy read */
602 /* data polling for D7 */
603 while ((dest2
[i
] & 0x0080) != (data2
[i
] & 0x0080)) {
604 elapsed
+= *(volatile u16
*)(0xfffef000+SC520_SWTMRMILLI
);
605 if (elapsed
> ((CFG_FLASH_WRITE_TOUT
/CFG_HZ
) * 1000)) {
617 extern int _amd_write_word_end
;
618 asm ("_amd_write_word_end:\n"
621 static int _intel_write_word(unsigned start
, unsigned dest
, unsigned data
)
626 /* Check if Flash is (sufficiently) erased */
627 if ((*((volatile u16
*)dest
) & (u16
)data
) != (u16
)data
) {
631 for (i
= 0; i
< 2; i
++) {
633 *(volatile u16
*)(dest
+2*i
) = 0x0040; /* write setup */
634 *(volatile u16
*)(dest
+2*i
) = (data
>> (i
*16)) & 0xffff;
636 elapsed
= *(volatile u16
*)(0xfffef000+SC520_SWTMRMILLI
); /* dummy read */
639 /* data polling for D7 */
640 while ((*(volatile u16
*)dest
& 0x0080) != 0x0080) {
641 elapsed
+= *(volatile u16
*)(0xfffef000+SC520_SWTMRMILLI
);
642 if (elapsed
> ((CFG_FLASH_WRITE_TOUT
/CFG_HZ
) * 1000)) {
643 *(volatile u16
*)dest
= 0x00ff;
649 *(volatile u16
*)dest
= 0x00ff;
655 extern int _intel_write_word_end
;
656 asm ("_intel_write_word_end:\n"
659 /*-----------------------------------------------------------------------
660 * Copy memory to flash, returns:
663 * 2 - Flash not erased
664 * 3 - Unsupported flash type
667 int write_buff(flash_info_t
*info
, uchar
*src
, ulong addr
, ulong cnt
)
672 u32 (*_write_word_ptr
)(unsigned start
, unsigned dest
, unsigned data
);
675 if ((info
->flash_id
& FLASH_VENDMASK
) == (AMD_MANUFACT
& FLASH_VENDMASK
)) {
676 size
= (unsigned)&_amd_write_word_end
- (unsigned)_amd_write_word
;
678 if (size
> PROBE_BUFFER_SIZE
) {
679 printf("_amd_write_word() routine too large (%d) %p - %p\n",
680 size
, &_amd_write_word_end
, _amd_write_word
);
684 memcpy(buffer
, _amd_write_word
, size
);
685 _write_word_ptr
= (void*)buffer
;
687 } else if ((info
->flash_id
& FLASH_VENDMASK
) == (INTEL_MANUFACT
& FLASH_VENDMASK
)) {
688 size
= (unsigned)&_intel_write_word_end
- (unsigned)_intel_write_word
;
690 if (size
> PROBE_BUFFER_SIZE
) {
691 printf("_intel_write_word() routine too large (%d) %p - %p\n",
692 size
, &_intel_write_word_end
, _intel_write_word
);
696 memcpy(buffer
, _intel_write_word
, size
);
697 _write_word_ptr
= (void*)buffer
;
699 printf ("Can't program unknown flash type - aborted\n");
703 wp
= (addr
& ~3); /* get lower word aligned address */
706 * handle unaligned start bytes
708 if ((l
= addr
- wp
) != 0) {
710 for (i
=0, cp
=wp
; i
<l
; ++i
, ++cp
) {
711 data
|= (*(uchar
*)cp
) << (8*i
);
713 for (; i
<4 && cnt
>0; ++i
) {
714 data
|= *src
++ << (8*i
);
718 for (; cnt
==0 && i
<4; ++i
, ++cp
) {
719 data
|= (*(uchar
*)cp
) << (8*i
);
722 /* Disable interrupts which might cause a timeout here */
723 flag
= disable_interrupts();
725 rc
= _write_word_ptr(info
->start
[0], wp
, data
);
727 /* re-enable interrupts if necessary */
738 * handle word aligned part
743 for (i
=0; i
<4; ++i
) {
744 data
|= *src
++ << (8*i
);
747 /* Disable interrupts which might cause a timeout here */
748 flag
= disable_interrupts();
750 rc
= _write_word_ptr(info
->start
[0], wp
, data
);
752 /* re-enable interrupts if necessary */
768 * handle unaligned tail bytes
771 for (i
=0, cp
=wp
; i
<4 && cnt
>0; ++i
, ++cp
) {
772 data
|= *src
++ << (8*i
);
776 for (; i
<4; ++i
, ++cp
) {
777 data
|= (*(uchar
*)cp
) << (8*i
);
780 /* Disable interrupts which might cause a timeout here */
781 flag
= disable_interrupts();
783 rc
= _write_word_ptr(info
->start
[0], wp
, data
);
785 /* re-enable interrupts if necessary */