]>
git.ipfire.org Git - 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 * - adapted for pip405, Denis Peter, MPL AG Switzerland
40 #include <asm/processor.h>
41 #include "common_util.h"
43 flash_info_t flash_info
[CFG_MAX_FLASH_BANKS
]; /* info for FLASH chips */
44 /*-----------------------------------------------------------------------
47 static ulong
flash_get_size (vu_long
*addr
, flash_info_t
*info
);
48 static int write_word (flash_info_t
*info
, ulong dest
, ulong data
);
50 void unlock_intel_sectors(flash_info_t
*info
,ulong addr
,ulong cnt
);
56 #define FLASH_WORD_SIZE unsigned short
62 #define FLASH_WORD_SIZE unsigned short
68 /*-----------------------------------------------------------------------
72 unsigned long flash_init (void)
74 unsigned long size_b0
, size_b1
;
77 /* Since we are relocated, we can set-up the CS finally */
79 /* get and display boot mode */
82 printf("(PCI Boot %s Map) ",(i
& BOOT_MPS
) ?
85 printf("(%s Boot) ",(i
& BOOT_MPS
) ?
87 /* Init: no FLASHes known */
88 for (i
=0; i
<CFG_MAX_FLASH_BANKS
; ++i
) {
89 flash_info
[i
].flash_id
= FLASH_UNKNOWN
;
92 /* Static FLASH Bank configuration here - FIXME XXX */
94 size_b0
= flash_get_size((vu_long
*)FLASH_BASE0_PRELIM
, &flash_info
[0]);
96 if (flash_info
[0].flash_id
== FLASH_UNKNOWN
) {
97 printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
98 size_b0
, size_b0
<<20);
100 /* protect the bootloader */
101 /* Monitor protection ON by default */
102 #if CFG_MONITOR_BASE >= CFG_FLASH_BASE
103 flash_protect(FLAG_PROTECT_SET
,
105 CFG_MONITOR_BASE
+monitor_flash_len
-1,
109 flash_info
[0].size
= size_b0
;
111 /* include this if you want to test if
112 the relocation has be done ok.
113 This will disable both Chipselects */
114 mtdcr (ebccfga
, pb0cr
);
116 mtdcr (ebccfga
, pb1cr
);
118 printf("CS0 & CS1 switched off for test\n");
124 /*-----------------------------------------------------------------------
126 void flash_print_info (flash_info_t
*info
)
132 volatile unsigned long *flash
;
134 if (info
->flash_id
== FLASH_UNKNOWN
) {
135 printf ("missing or unknown FLASH type\n");
139 switch (info
->flash_id
& FLASH_VENDMASK
) {
140 case FLASH_MAN_AMD
: printf ("AMD "); break;
141 case FLASH_MAN_FUJ
: printf ("FUJITSU "); break;
142 case FLASH_MAN_SST
: printf ("SST "); break;
143 case FLASH_MAN_INTEL
: printf ("Intel "); break;
144 default: printf ("Unknown Vendor "); break;
147 switch (info
->flash_id
& FLASH_TYPEMASK
) {
148 case FLASH_AM040
: printf ("AM29F040 (512 Kbit, uniform sector size)\n");
150 case FLASH_AM400B
: printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
152 case FLASH_AM400T
: printf ("AM29LV400T (4 Mbit, top boot sector)\n");
154 case FLASH_AM800B
: printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
156 case FLASH_AM800T
: printf ("AM29LV800T (8 Mbit, top boot sector)\n");
158 case FLASH_AM160B
: printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
160 case FLASH_AM160T
: printf ("AM29LV160T (16 Mbit, top boot sector)\n");
162 case FLASH_AM320B
: printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
164 case FLASH_AM320T
: printf ("AM29LV320T (32 Mbit, top boot sector)\n");
166 case FLASH_SST800A
: printf ("SST39LF/VF800 (8 Mbit, uniform sector size)\n");
168 case FLASH_SST160A
: printf ("SST39LF/VF160 (16 Mbit, uniform sector size)\n");
170 case FLASH_INTEL320T
: printf ("TE28F320C3 (32 Mbit, top sector size)\n");
172 default: printf ("Unknown Chip Type\n");
176 printf (" Size: %ld KB in %d Sectors\n",
177 info
->size
>> 10, info
->sector_count
);
179 printf (" Sector Start Addresses:");
180 for (i
=0; i
<info
->sector_count
; ++i
) {
182 * Check if whole sector is erased
184 if (i
!= (info
->sector_count
-1))
185 size
= info
->start
[i
+1] - info
->start
[i
];
187 size
= info
->start
[0] + info
->size
- info
->start
[i
];
189 flash
= (volatile unsigned long *)info
->start
[i
];
190 size
= size
>> 2; /* divide by 4 for longword access */
191 for (k
=0; k
<size
; k
++) {
192 if (*flash
++ != 0xffffffff) {
199 printf (" %08lX%s%s",
202 info
->protect
[i
] ? "RO " : " ");
207 /*-----------------------------------------------------------------------
211 /*-----------------------------------------------------------------------
215 * The following code cannot be run from FLASH!
217 static ulong
flash_get_size (vu_long
*addr
, flash_info_t
*info
)
220 FLASH_WORD_SIZE value
;
221 ulong base
= (ulong
)addr
;
222 volatile FLASH_WORD_SIZE
*addr2
= (FLASH_WORD_SIZE
*)addr
;
224 /* Write auto select command: read Manufacturer ID */
225 addr2
[ADDR0
] = (FLASH_WORD_SIZE
)0x00AA00AA;
226 addr2
[ADDR1
] = (FLASH_WORD_SIZE
)0x00550055;
227 addr2
[ADDR0
] = (FLASH_WORD_SIZE
)0x00900090;
230 /* printf("flash_get_size value: %x\n",value); */
232 case (FLASH_WORD_SIZE
)AMD_MANUFACT
:
233 info
->flash_id
= FLASH_MAN_AMD
;
235 case (FLASH_WORD_SIZE
)FUJ_MANUFACT
:
236 info
->flash_id
= FLASH_MAN_FUJ
;
238 case (FLASH_WORD_SIZE
)INTEL_MANUFACT
:
239 info
->flash_id
= FLASH_MAN_INTEL
;
241 case (FLASH_WORD_SIZE
)SST_MANUFACT
:
242 info
->flash_id
= FLASH_MAN_SST
;
245 info
->flash_id
= FLASH_UNKNOWN
;
246 info
->sector_count
= 0;
248 return (0); /* no or unknown flash */
250 value
= addr2
[1]; /* device ID */
251 /* printf("Device value %x\n",value); */
253 case (FLASH_WORD_SIZE
)AMD_ID_F040B
:
254 info
->flash_id
+= FLASH_AM040
;
255 info
->sector_count
= 8;
256 info
->size
= 0x0080000; /* => 512 ko */
258 case (FLASH_WORD_SIZE
)AMD_ID_LV400T
:
259 info
->flash_id
+= FLASH_AM400T
;
260 info
->sector_count
= 11;
261 info
->size
= 0x00080000;
262 break; /* => 0.5 MB */
264 case (FLASH_WORD_SIZE
)AMD_ID_LV400B
:
265 info
->flash_id
+= FLASH_AM400B
;
266 info
->sector_count
= 11;
267 info
->size
= 0x00080000;
268 break; /* => 0.5 MB */
270 case (FLASH_WORD_SIZE
)AMD_ID_LV800T
:
271 info
->flash_id
+= FLASH_AM800T
;
272 info
->sector_count
= 19;
273 info
->size
= 0x00100000;
276 case (FLASH_WORD_SIZE
)AMD_ID_LV800B
:
277 info
->flash_id
+= FLASH_AM800B
;
278 info
->sector_count
= 19;
279 info
->size
= 0x00100000;
282 case (FLASH_WORD_SIZE
)AMD_ID_LV160T
:
283 info
->flash_id
+= FLASH_AM160T
;
284 info
->sector_count
= 35;
285 info
->size
= 0x00200000;
288 case (FLASH_WORD_SIZE
)AMD_ID_LV160B
:
289 info
->flash_id
+= FLASH_AM160B
;
290 info
->sector_count
= 35;
291 info
->size
= 0x00200000;
293 #if 0 /* enable when device IDs are available */
294 case (FLASH_WORD_SIZE
)AMD_ID_LV320T
:
295 info
->flash_id
+= FLASH_AM320T
;
296 info
->sector_count
= 67;
297 info
->size
= 0x00400000;
300 case (FLASH_WORD_SIZE
)AMD_ID_LV320B
:
301 info
->flash_id
+= FLASH_AM320B
;
302 info
->sector_count
= 67;
303 info
->size
= 0x00400000;
306 case (FLASH_WORD_SIZE
)SST_ID_xF800A
:
307 info
->flash_id
+= FLASH_SST800A
;
308 info
->sector_count
= 16;
309 info
->size
= 0x00100000;
311 case (FLASH_WORD_SIZE
)INTEL_ID_28F320C3T
:
312 info
->flash_id
+= FLASH_INTEL320T
;
313 info
->sector_count
= 71;
314 info
->size
= 0x00400000;
318 case (FLASH_WORD_SIZE
)SST_ID_xF160A
:
319 info
->flash_id
+= FLASH_SST160A
;
320 info
->sector_count
= 32;
321 info
->size
= 0x00200000;
325 info
->flash_id
= FLASH_UNKNOWN
;
326 return (0); /* => no or unknown flash */
330 /* set up sector start address table */
331 if (((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_SST
) ||
332 (info
->flash_id
== FLASH_AM040
)){
333 for (i
= 0; i
< info
->sector_count
; i
++)
334 info
->start
[i
] = base
+ (i
* 0x00010000);
337 if (info
->flash_id
& FLASH_BTYPE
) {
338 /* set sector offsets for bottom boot block type */
339 info
->start
[0] = base
+ 0x00000000;
340 info
->start
[1] = base
+ 0x00004000;
341 info
->start
[2] = base
+ 0x00006000;
342 info
->start
[3] = base
+ 0x00008000;
343 for (i
= 4; i
< info
->sector_count
; i
++)
344 info
->start
[i
] = base
+ (i
* 0x00010000) - 0x00030000;
347 /* set sector offsets for top boot block type */
348 i
= info
->sector_count
- 1;
349 if(info
->sector_count
==71) {
351 info
->start
[i
--] = base
+ info
->size
- 0x00002000;
352 info
->start
[i
--] = base
+ info
->size
- 0x00004000;
353 info
->start
[i
--] = base
+ info
->size
- 0x00006000;
354 info
->start
[i
--] = base
+ info
->size
- 0x00008000;
355 info
->start
[i
--] = base
+ info
->size
- 0x0000A000;
356 info
->start
[i
--] = base
+ info
->size
- 0x0000C000;
357 info
->start
[i
--] = base
+ info
->size
- 0x0000E000;
359 info
->start
[i
] = base
+ i
* 0x000010000;
362 info
->start
[i
--] = base
+ info
->size
- 0x00004000;
363 info
->start
[i
--] = base
+ info
->size
- 0x00006000;
364 info
->start
[i
--] = base
+ info
->size
- 0x00008000;
366 info
->start
[i
] = base
+ i
* 0x00010000;
371 /* check for protected sectors */
372 for (i
= 0; i
< info
->sector_count
; i
++) {
373 /* read sector protection at sector address, (A7 .. A0) = 0x02 */
374 /* D0 = 1 if protected */
375 addr2
= (volatile FLASH_WORD_SIZE
*)(info
->start
[i
]);
376 if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_INTEL
)
377 info
->protect
[i
] = 0;
379 info
->protect
[i
] = addr2
[2] & 1;
383 * Prevent writes to uninitialized FLASH.
385 if (info
->flash_id
!= FLASH_UNKNOWN
) {
386 addr2
= (FLASH_WORD_SIZE
*)info
->start
[0];
387 *addr2
= (FLASH_WORD_SIZE
)0x00F000F0; /* reset bank */
393 int wait_for_DQ7(flash_info_t
*info
, int sect
)
395 ulong start
, now
, last
;
396 volatile FLASH_WORD_SIZE
*addr
= (FLASH_WORD_SIZE
*)(info
->start
[sect
]);
398 start
= get_timer (0);
400 while ((addr
[0] & (FLASH_WORD_SIZE
)0x00800080) != (FLASH_WORD_SIZE
)0x00800080) {
401 if ((now
= get_timer(start
)) > CFG_FLASH_ERASE_TOUT
) {
402 printf ("Timeout\n");
405 /* show that we're waiting */
406 if ((now
- last
) > 1000) { /* every second */
414 int intel_wait_for_DQ7(flash_info_t
*info
, int sect
)
416 ulong start
, now
, last
;
417 volatile FLASH_WORD_SIZE
*addr
= (FLASH_WORD_SIZE
*)(info
->start
[sect
]);
419 start
= get_timer (0);
421 while ((addr
[0] & (FLASH_WORD_SIZE
)0x00800080) != (FLASH_WORD_SIZE
)0x00800080) {
422 if ((now
= get_timer(start
)) > CFG_FLASH_ERASE_TOUT
) {
423 printf ("Timeout\n");
426 /* show that we're waiting */
427 if ((now
- last
) > 1000) { /* every second */
432 addr
[0]=(FLASH_WORD_SIZE
)0x00500050;
436 /*-----------------------------------------------------------------------
439 int flash_erase (flash_info_t
*info
, int s_first
, int s_last
)
441 volatile FLASH_WORD_SIZE
*addr
= (FLASH_WORD_SIZE
*)(info
->start
[0]);
442 volatile FLASH_WORD_SIZE
*addr2
;
443 int flag
, prot
, sect
, l_sect
;
447 if ((s_first
< 0) || (s_first
> s_last
)) {
448 if (info
->flash_id
== FLASH_UNKNOWN
) {
449 printf ("- missing\n");
451 printf ("- no sectors to erase\n");
456 if (info
->flash_id
== FLASH_UNKNOWN
) {
457 printf ("Can't erase unknown flash type - aborted\n");
462 for (sect
=s_first
; sect
<=s_last
; ++sect
) {
463 if (info
->protect
[sect
]) {
469 printf ("- Warning: %d protected sectors will not be erased!\n",
477 /* Disable interrupts which might cause a timeout here */
478 flag
= disable_interrupts();
480 /* Start erase on unprotected sectors */
481 for (sect
= s_first
; sect
<=s_last
; sect
++) {
482 if (info
->protect
[sect
] == 0) { /* not protected */
483 addr2
= (FLASH_WORD_SIZE
*)(info
->start
[sect
]);
484 /* printf("Erasing sector %p\n", addr2); */ /* CLH */
485 if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_SST
) {
486 addr
[ADDR0
] = (FLASH_WORD_SIZE
)0x00AA00AA;
487 addr
[ADDR1
] = (FLASH_WORD_SIZE
)0x00550055;
488 addr
[ADDR0
] = (FLASH_WORD_SIZE
)0x00800080;
489 addr
[ADDR0
] = (FLASH_WORD_SIZE
)0x00AA00AA;
490 addr
[ADDR1
] = (FLASH_WORD_SIZE
)0x00550055;
491 addr2
[0] = (FLASH_WORD_SIZE
)0x00500050; /* block erase */
493 udelay(1000); /* wait 1 ms */
494 wait_for_DQ7(info
, sect
);
497 if((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_INTEL
){
498 addr2
[0] = (FLASH_WORD_SIZE
)0x00600060; /* unlock sector */
499 addr2
[0] = (FLASH_WORD_SIZE
)0x00D000D0; /* sector erase */
500 intel_wait_for_DQ7(info
, sect
);
501 addr2
[0] = (FLASH_WORD_SIZE
)0x00200020; /* sector erase */
502 addr2
[0] = (FLASH_WORD_SIZE
)0x00D000D0; /* sector erase */
503 intel_wait_for_DQ7(info
, sect
);
506 addr
[ADDR0
] = (FLASH_WORD_SIZE
)0x00AA00AA;
507 addr
[ADDR1
] = (FLASH_WORD_SIZE
)0x00550055;
508 addr
[ADDR0
] = (FLASH_WORD_SIZE
)0x00800080;
509 addr
[ADDR0
] = (FLASH_WORD_SIZE
)0x00AA00AA;
510 addr
[ADDR1
] = (FLASH_WORD_SIZE
)0x00550055;
511 addr2
[0] = (FLASH_WORD_SIZE
)0x00300030; /* sector erase */
512 wait_for_DQ7(info
, sect
);
517 * Wait for each sector to complete, it's more
518 * reliable. According to AMD Spec, you must
519 * issue all erase commands within a specified
520 * timeout. This has been seen to fail, especially
521 * if printf()s are included (for debug)!!
523 /* wait_for_DQ7(info, sect); */
527 /* re-enable interrupts if necessary */
531 /* wait at least 80us - let's wait 1 ms */
536 * We wait for the last triggered sector
540 wait_for_DQ7(info
, l_sect
);
544 /* reset to read mode */
545 addr
= (FLASH_WORD_SIZE
*)info
->start
[0];
546 addr
[0] = (FLASH_WORD_SIZE
)0x00F000F0; /* reset bank */
553 void unlock_intel_sectors(flash_info_t
*info
,ulong addr
,ulong cnt
)
556 volatile FLASH_WORD_SIZE
*addr2
;
559 for(i
=info
->sector_count
-1;i
>0;i
--)
561 if(addr
>=info
->start
[i
])
565 addr2
= (FLASH_WORD_SIZE
*)(info
->start
[i
]);
566 addr2
[0] = (FLASH_WORD_SIZE
)0x00600060; /* unlock sector setup */
567 addr2
[0] = (FLASH_WORD_SIZE
)0x00D000D0; /* unlock sector */
568 intel_wait_for_DQ7(info
, i
);
570 c
-=(info
->start
[i
]-info
->start
[i
-1]);
575 /*-----------------------------------------------------------------------
576 * Copy memory to flash, returns:
579 * 2 - Flash not erased
582 int write_buff (flash_info_t
*info
, uchar
*src
, ulong addr
, ulong cnt
)
587 if((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_INTEL
){
588 unlock_intel_sectors(info
,addr
,cnt
);
590 wp
= (addr
& ~3); /* get lower word aligned address */
592 * handle unaligned start bytes
594 if ((l
= addr
- wp
) != 0) {
596 for (i
=0, cp
=wp
; i
<l
; ++i
, ++cp
) {
597 data
= (data
<< 8) | (*(uchar
*)cp
);
599 for (; i
<4 && cnt
>0; ++i
) {
600 data
= (data
<< 8) | *src
++;
604 for (; cnt
==0 && i
<4; ++i
, ++cp
) {
605 data
= (data
<< 8) | (*(uchar
*)cp
);
608 if ((rc
= write_word(info
, wp
, data
)) != 0) {
615 * handle word aligned part
619 for (i
=0; i
<4; ++i
) {
620 data
= (data
<< 8) | *src
++;
622 if ((rc
= write_word(info
, wp
, data
)) != 0) {
626 if((wp
% 0x10000)==0)
627 printf("."); /* show Progress */
636 * handle unaligned tail bytes
639 for (i
=0, cp
=wp
; i
<4 && cnt
>0; ++i
, ++cp
) {
640 data
= (data
<< 8) | *src
++;
643 for (; i
<4; ++i
, ++cp
) {
644 data
= (data
<< 8) | (*(uchar
*)cp
);
646 rc
=write_word(info
, wp
, data
);
650 /*-----------------------------------------------------------------------
651 * Write a word to Flash, returns:
654 * 2 - Flash not erased
656 static FLASH_WORD_SIZE
*read_val
= (FLASH_WORD_SIZE
*)0x200000;
658 static int write_word (flash_info_t
*info
, ulong dest
, ulong data
)
660 volatile FLASH_WORD_SIZE
*addr2
= (FLASH_WORD_SIZE
*)(info
->start
[0]);
661 volatile FLASH_WORD_SIZE
*dest2
= (FLASH_WORD_SIZE
*)dest
;
662 volatile FLASH_WORD_SIZE
*data2
= (FLASH_WORD_SIZE
*)&data
;
667 /* Check if Flash is (sufficiently) erased */
668 if ((*((volatile FLASH_WORD_SIZE
*)dest
) &
669 (FLASH_WORD_SIZE
)data
) != (FLASH_WORD_SIZE
)data
) {
672 /* Disable interrupts which might cause a timeout here */
673 flag
= disable_interrupts();
674 for (i
=0; i
<4/sizeof(FLASH_WORD_SIZE
); i
++)
676 if((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_INTEL
){
677 /* intel style writting */
678 dest2
[i
] = (FLASH_WORD_SIZE
)0x00500050;
679 dest2
[i
] = (FLASH_WORD_SIZE
)0x00400040;
680 *read_val
++ = data2
[i
];
684 /* data polling for D7 */
685 start
= get_timer (0);
687 while ((dest2
[i
] & (FLASH_WORD_SIZE
)0x00800080) != (FLASH_WORD_SIZE
)0x00800080)
689 if (get_timer(start
) > CFG_FLASH_WRITE_TOUT
)
692 dest2
[i
] = (FLASH_WORD_SIZE
)0x00FF00FF; /* return to read mode */
694 dest2
[i
] = (FLASH_WORD_SIZE
)0x00FF00FF; /* return to read mode */
695 if(dest2
[i
]!=data2
[i
])
696 printf("Error at %p 0x%04X != 0x%04X\n",&dest2
[i
],dest2
[i
],data2
[i
]);
699 addr2
[ADDR0
] = (FLASH_WORD_SIZE
)0x00AA00AA;
700 addr2
[ADDR1
] = (FLASH_WORD_SIZE
)0x00550055;
701 addr2
[ADDR0
] = (FLASH_WORD_SIZE
)0x00A000A0;
703 /* re-enable interrupts if necessary */
706 /* data polling for D7 */
707 start
= get_timer (0);
708 while ((dest2
[i
] & (FLASH_WORD_SIZE
)0x00800080) !=
709 (data2
[i
] & (FLASH_WORD_SIZE
)0x00800080)) {
710 if (get_timer(start
) > CFG_FLASH_WRITE_TOUT
) {
719 /*-----------------------------------------------------------------------