]>
git.ipfire.org Git - people/ms/u-boot.git/blob - board/mpc8540eval/flash.c
2 * (C) Copyright 2003 Motorola Inc.
3 * Xianghua Xiao,(X.Xiao@motorola.com)
5 * (C) Copyright 2000, 2001
6 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
8 * (C) Copyright 2001, Stuart Hughes, Lineo Inc, stuarth@lineo.com
9 * Add support the Sharp chips on the mpc8260ads.
10 * I started with board/ip860/flash.c and made changes I found in
11 * the MTD project by David Schleef.
13 * See file CREDITS for list of people who contributed to this
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License as
18 * published by the Free Software Foundation; either version 2 of
19 * the License, or (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
34 #if !defined(CFG_NO_FLASH)
36 flash_info_t flash_info
[CFG_MAX_FLASH_BANKS
]; /* info for FLASH chips */
38 #if defined(CFG_ENV_IS_IN_FLASH)
40 # define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_ENV_OFFSET)
43 # define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
45 # ifndef CFG_ENV_SECT_SIZE
46 # define CFG_ENV_SECT_SIZE CFG_ENV_SIZE
51 * The variable should be in the flash info structure. Since it
52 * is only used in this board specific file it is declared here.
53 * In the future I think an endian flag should be part of the
54 * flash_info_t structure. (Ron Alder)
56 static ulong big_endian
= 0;
58 /*-----------------------------------------------------------------------
61 static ulong
flash_get_size (vu_long
*addr
, flash_info_t
*info
);
62 static int write_block (flash_info_t
*info
, uchar
* src
, ulong dest
, ulong cnt
);
63 static int write_short (flash_info_t
*info
, ulong dest
, ushort data
);
64 static int write_word (flash_info_t
*info
, ulong dest
, ulong data
);
65 static int clear_block_lock_bit(flash_info_t
*info
, vu_long
* addr
);
66 /*-----------------------------------------------------------------------
69 unsigned long flash_init (void)
74 /* Init: enable write,
75 * or we cannot even write flash commands
77 for (i
=0; i
<CFG_MAX_FLASH_BANKS
; ++i
) {
78 flash_info
[i
].flash_id
= FLASH_UNKNOWN
;
80 /* set the default sector offset */
83 /* Static FLASH Bank configuration here - FIXME XXX */
85 size
= flash_get_size((vu_long
*)CFG_FLASH_BASE
, &flash_info
[0]);
87 if (flash_info
[0].flash_id
== FLASH_UNKNOWN
) {
88 printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
92 /* Re-do sizing to get full correct info */
93 size
= flash_get_size((vu_long
*)CFG_FLASH_BASE
, &flash_info
[0]);
95 flash_info
[0].size
= size
;
97 #if !defined(CONFIG_RAM_AS_FLASH)
98 #if CFG_MONITOR_BASE >= CFG_FLASH_BASE
99 /* monitor protection ON by default */
100 flash_protect(FLAG_PROTECT_SET
,
102 CFG_MONITOR_BASE
+monitor_flash_len
-1,
106 #ifdef CFG_ENV_IS_IN_FLASH
107 /* ENV protection ON by default */
108 flash_protect(FLAG_PROTECT_SET
,
110 CFG_ENV_ADDR
+CFG_ENV_SECT_SIZE
-1,
117 /*-----------------------------------------------------------------------
119 void flash_print_info (flash_info_t
*info
)
123 if (info
->flash_id
== FLASH_UNKNOWN
) {
124 printf ("missing or unknown FLASH type\n");
128 switch (info
->flash_id
& FLASH_VENDMASK
) {
129 case FLASH_MAN_INTEL
: printf ("Intel "); break;
130 case FLASH_MAN_SHARP
: printf ("Sharp "); break;
131 default: printf ("Unknown Vendor "); break;
134 switch (info
->flash_id
& FLASH_TYPEMASK
) {
135 case FLASH_28F016SV
: printf ("28F016SV (16 Mbit, 32 x 64k)\n");
137 case FLASH_28F160S3
: printf ("28F160S3 (16 Mbit, 32 x 512K)\n");
139 case FLASH_28F320S3
: printf ("28F320S3 (32 Mbit, 64 x 512K)\n");
141 case FLASH_LH28F016SCT
: printf ("28F016SC (16 Mbit, 32 x 64K)\n");
143 case FLASH_28F640J3A
: printf ("28F640J3A (64 Mbit, 64 x 128K)\n");
145 default: printf ("Unknown Chip Type\n");
149 printf (" Size: %ld MB in %d Sectors\n",
150 info
->size
>> 20, info
->sector_count
);
152 printf (" Sector Start Addresses:");
153 for (i
=0; i
<info
->sector_count
; ++i
) {
158 info
->protect
[i
] ? " (RO)" : " "
164 /* only deal with 16 bit and 32 bit port width, 16bit chip */
165 static ulong
flash_get_size (vu_long
*addr
, flash_info_t
*info
)
168 ulong value
,va
,vb
,vc
,vd
;
169 ulong base
= (ulong
)addr
;
173 printf("Check flash at 0x%08x\n",(uint
)addr
);
175 /* Write "Intelligent Identifier" command: read Manufacturer ID */
180 #ifndef CFG_FLASH_CFI
181 printf("Not define CFG_FLASH_CFI\n");
185 va
=(value
& 0xFF000000)>>24;
186 vb
=(value
& 0x00FF0000)>>16;
187 vc
=(value
& 0x0000FF00)>>8;
188 vd
=(value
& 0x000000FF);
189 if ((va
==0) && (vb
==0)) {
190 printf("cannot identify Flash\n");
191 info
->flash_id
= FLASH_UNKNOWN
;
192 info
->sector_count
= 0;
194 return (0); /* no or unknown flash */
196 else if ((va
==0) && (vb
!=0)) {
198 info
->chipwidth
= FLASH_CFI_BY16
;
199 if(vb
== vd
) info
->portwidth
= FLASH_CFI_32BIT
;
200 else info
->portwidth
= FLASH_CFI_16BIT
;
202 else if ((va
!=0) && (vb
==0)) {
204 info
->chipwidth
= FLASH_CFI_BY16
;
205 if(va
== vc
) info
->portwidth
= FLASH_CFI_32BIT
;
206 else info
->portwidth
= FLASH_CFI_16BIT
;
208 else if ((va
!=0) && (vb
!=0)) {
209 big_endian
= 1; /* no meaning for 8bit chip */
210 info
->chipwidth
= FLASH_CFI_BY8
;
211 if(va
== vb
) info
->portwidth
= FLASH_CFI_16BIT
;
212 else info
->portwidth
= FLASH_CFI_8BIT
;
215 switch (info
->portwidth
) {
217 printf("port width is 8 bit.\n");
219 case FLASH_CFI_16BIT
:
220 printf("port width is 16 bit, ");
222 case FLASH_CFI_32BIT
:
223 printf("port width is 32 bit, ");
226 switch (info
->chipwidth
) {
228 printf("chip width is 16 bit, ");
229 switch (big_endian
) {
231 printf("Little Endian.\n");
234 printf("Big Endian.\n");
240 #endif /*#ifdef CFG_FLASH_CFI*/
242 if (big_endian
==0) value
= (addr
[0] & 0xFF000000) >>8;
243 else value
= (addr
[0] & 0x00FF0000);
245 printf("manufacturer=0x%x\n",(uint
)(value
>>16));
248 case MT_MANUFACT
& 0xFFFF0000: /* SHARP, MT or => Intel */
249 case INTEL_ALT_MANU
& 0xFFFF0000:
250 info
->flash_id
= FLASH_MAN_INTEL
;
253 printf("unknown manufacturer: %x\n", (unsigned int)value
);
254 info
->flash_id
= FLASH_UNKNOWN
;
255 info
->sector_count
= 0;
257 return (0); /* no or unknown flash */
260 if (info
->portwidth
==FLASH_CFI_16BIT
) {
261 switch (big_endian
) {
263 value
= (addr
[0] & 0x0000FF00)>>8;
266 value
= (addr
[0] & 0x000000FF);
270 else if (info
->portwidth
== FLASH_CFI_32BIT
) {
271 switch (big_endian
) {
273 value
= (addr
[1] & 0x0000FF00)>>8;
276 value
= (addr
[1] & 0x000000FF);
282 printf("deviceID=0x%x\n",(uint
)value
);
285 case (INTEL_ID_28F016S
& 0x0000FFFF):
286 info
->flash_id
+= FLASH_28F016SV
;
287 info
->sector_count
= 32;
288 sector_offset
= 0x10000;
291 case (INTEL_ID_28F160S3
& 0x0000FFFF):
292 info
->flash_id
+= FLASH_28F160S3
;
293 info
->sector_count
= 32;
294 sector_offset
= 0x10000;
297 case (INTEL_ID_28F320S3
& 0x0000FFFF):
298 info
->flash_id
+= FLASH_28F320S3
;
299 info
->sector_count
= 64;
300 sector_offset
= 0x10000;
303 case (INTEL_ID_28F640J3A
& 0x0000FFFF):
304 info
->flash_id
+= FLASH_28F640J3A
;
305 info
->sector_count
= 64;
306 sector_offset
= 0x20000;
309 case SHARP_ID_28F016SCL
& 0x0000FFFF:
310 case SHARP_ID_28F016SCZ
& 0x0000FFFF:
311 info
->flash_id
= FLASH_MAN_SHARP
| FLASH_LH28F016SCT
;
312 info
->sector_count
= 32;
313 sector_offset
= 0x10000;
318 info
->flash_id
= FLASH_UNKNOWN
;
319 return (0); /* => no or unknown flash */
323 sector_offset
= sector_offset
* (info
->portwidth
/ info
->chipwidth
);
324 info
->size
= info
->sector_count
* sector_offset
;
326 /* set up sector start address table */
327 for (i
= 0; i
< info
->sector_count
; i
++) {
328 info
->start
[i
] = base
;
329 base
+= sector_offset
;
330 /* don't know how to check sector protection */
331 info
->protect
[i
] = 0;
335 * Prevent writes to uninitialized FLASH.
337 if (info
->flash_id
!= FLASH_UNKNOWN
) {
338 addr
= (vu_long
*)info
->start
[0];
339 *addr
= 0xFFFFFF; /* reset bank to read array mode */
347 /*-----------------------------------------------------------------------
350 int flash_erase (flash_info_t
*info
, int s_first
, int s_last
)
352 int flag
, prot
, sect
;
353 ulong start
, now
, last
, ready
, erase_err_status
;
355 if (big_endian
== 1) {
357 erase_err_status
= 0x00a0;
361 erase_err_status
= 0xa000;
363 if ((info
->portwidth
/ info
->chipwidth
)==2) {
364 ready
+= (ready
<<16);
365 erase_err_status
+= (erase_err_status
<<16);
369 printf ("\nReady flag is 0x%lx\nErase error flag is 0x%lx", ready
, erase_err_status
);
372 if ((s_first
< 0) || (s_first
> s_last
)) {
373 if (info
->flash_id
== FLASH_UNKNOWN
) {
374 printf ("- missing\n");
376 printf ("- no sectors to erase\n");
381 if ( ((info
->flash_id
& FLASH_VENDMASK
) != FLASH_MAN_INTEL
)
382 && ((info
->flash_id
& FLASH_VENDMASK
) != FLASH_MAN_SHARP
) ) {
383 printf ("Can't erase unknown flash type %08lx - aborted\n",
389 for (sect
=s_first
; sect
<=s_last
; ++sect
) {
390 if (info
->protect
[sect
]) {
396 printf ("- Warning: %d protected sectors will not be erased!\n",
403 printf("\nFlash Erase:\n");
405 /* Make Sure Block Lock Bit is not set. */
406 if(clear_block_lock_bit(info
, (vu_long
*)(info
->start
[s_first
]))){
410 /* Start erase on unprotected sectors */
412 printf("Begin to erase now,s_first=0x%x s_last=0x%x...\n",s_first
,s_last
);
414 for (sect
= s_first
; sect
<=s_last
; sect
++) {
415 if (info
->protect
[sect
] == 0) { /* not protected */
416 vu_short
*addr16
= (vu_short
*)(info
->start
[sect
]);
417 vu_long
*addr
= (vu_long
*)(info
->start
[sect
]);
419 switch (info
->portwidth
) {
420 case FLASH_CFI_16BIT
:
422 last
= start
= get_timer (0);
423 /* Disable interrupts which might cause a timeout here */
424 flag
= disable_interrupts();
428 /* Clear Status Register */
431 /* Single Block Erase Command */
437 if((info
->flash_id
& FLASH_TYPEMASK
) != FLASH_LH28F016SCT
) {
438 /* Resume Command, as per errata update */
442 /* re-enable interrupts if necessary */
445 /* wait at least 80us - let's wait 1 ms */
448 while ((*addr16
& ready
) != ready
) {
449 if((*addr16
& erase_err_status
)== erase_err_status
){
450 printf("Error in Block Erase - Lock Bit may be set!\n");
451 printf("Status Register = 0x%X\n", (uint
)*addr16
);
452 *addr16
= 0xFFFF; /* reset bank */
456 if ((now
=get_timer(start
)) > CFG_FLASH_ERASE_TOUT
) {
457 printf ("Timeout\n");
458 *addr16
= 0xFFFF; /* reset bank */
462 /* show that we're waiting */
463 if ((now
- last
) > 1000) { /* every second */
468 /* reset to read mode */
472 case FLASH_CFI_32BIT
:
474 last
= start
= get_timer (0);
475 /* Disable interrupts which might cause a timeout here */
476 flag
= disable_interrupts();
480 /* Clear Status Register */
483 /* Single Block Erase Command */
489 if((info
->flash_id
& FLASH_TYPEMASK
) != FLASH_LH28F016SCT
) {
490 /* Resume Command, as per errata update */
494 /* re-enable interrupts if necessary */
497 /* wait at least 80us - let's wait 1 ms */
500 while ((*addr
& ready
) != ready
) {
501 if((*addr
& erase_err_status
)==erase_err_status
){
502 printf("Error in Block Erase - Lock Bit may be set!\n");
503 printf("Status Register = 0x%X\n", (uint
)*addr
);
504 *addr
= 0xFFFFFFFF; /* reset bank */
508 if ((now
=get_timer(start
)) > CFG_FLASH_ERASE_TOUT
) {
509 printf ("Timeout\n");
510 *addr
= 0xFFFFFFFF; /* reset bank */
514 /* show that we're waiting */
515 if ((now
- last
) > 1000) { /* every second */
520 /* reset to read mode */
528 printf ("flash erase done\n");
532 /*-----------------------------------------------------------------------
533 * Copy memory to flash, returns:
536 * 2 - Flash not erased
539 #define FLASH_BLOCK_SIZE 32
541 int write_buff (flash_info_t
*info
, uchar
*src
, ulong addr
, ulong cnt
)
543 ulong cp
, wp
, data
, count
, temp
;
544 /* ulong temp[FLASH_BLOCK_SIZE/4];*/
548 wp
= (addr
& ~3); /* get lower word aligned address */
551 * handle unaligned start bytes
553 if ((l
= addr
- wp
) != 0) {
555 for (i
=0, cp
=wp
; i
<l
; ++i
, ++cp
) {
556 data
= (data
<< 8) | (*(uchar
*)cp
);
558 for (; i
<4 && cnt
>0; ++i
) {
559 data
= (data
<< 8) | *src
++;
563 for (; cnt
==0 && i
<4; ++i
, ++cp
) {
564 data
= (data
<< 8) | (*(uchar
*)cp
);
567 if ((rc
= write_word(info
, wp
, data
)) != 0) {
574 /* handle unaligned block bytes , flash block size = 16bytes */
575 wp
= (cp
+FLASH_BLOCK_SIZE
-1) & ~(FLASH_BLOCK_SIZE
-1);
577 if ((rc
= write_block(info
,src
,cp
,wp
-cp
)) !=0)
582 /* handle aligned block bytes */
585 while ( cnt
>= FLASH_BLOCK_SIZE
) {
586 if ((rc
= write_block(info
,src
,cp
,FLASH_BLOCK_SIZE
)) !=0) {
589 src
+= FLASH_BLOCK_SIZE
;
590 cp
+= FLASH_BLOCK_SIZE
;
591 cnt
-= FLASH_BLOCK_SIZE
;
592 if (((count
-cnt
)>>10)>temp
) {
593 temp
=(count
-cnt
)>>10;
594 printf("\r%d KB",temp
);
600 * handle word aligned part
604 for (i
=0; i
<4; ++i
) {
605 data
= (data
<< 8) | *src
++;
607 if ((rc
= write_word(info
, wp
, data
)) != 0) {
619 * handle unaligned tail bytes
622 for (i
=0, cp
=wp
; i
<4 && cnt
>0; ++i
, ++cp
) {
623 data
= (data
<< 8) | *src
++;
626 for (; i
<4; ++i
, ++cp
) {
627 data
= (data
<< 8) | (*(uchar
*)cp
);
630 return (write_word(info
, wp
, data
));
632 #undef FLASH_BLOCK_SIZE
634 /*-----------------------------------------------------------------------
635 * Write block to Flash, returns:
638 * 2 - Flash not erased
641 static int write_block(flash_info_t
*info
, uchar
* src
, ulong dest
, ulong cnt
)
643 vu_short
*baddr
, *addr
= (vu_short
*)dest
;
645 ulong start
, now
, xsr
,csr
, ready
;
648 if (cnt
==0) return 0;
649 else if(cnt
!= (cnt
& ~1)) return -1;
651 /* Check if Flash is (sufficiently) erased */
653 data
= (data
<<8) | *(src
+1);
654 if ((*addr
& data
) != data
) {
657 if (big_endian
== 1) {
663 /* Disable interrupts which might cause a timeout here */
664 flag
= disable_interrupts();
672 } while (!(xsr
& ready
)); /*wait until read */
673 /*write count=BLOCK SIZE -1 */
676 *addr
= data
; /* word mode, cnt/2 */
681 data
= (data
<<8) | *src
++;
688 *addr
= 0xd0d0; /* confirm write */
689 start
= get_timer(0);
693 /* data polling for D7 */
695 while (((csr
= *addr
) & ready
) != ready
) {
696 if ((now
=get_timer(start
)) > CFG_FLASH_WRITE_TOUT
) {
702 printf ("CSR indicates write error (%04x) at %08lx\n", csr
, (ulong
)addr
);
705 /* Clear Status Registers Command */
708 /* Reset to read array mode */
715 /*-----------------------------------------------------------------------
716 * Write a short word to Flash, returns:
719 * 2 - Flash not erased
721 static int write_short (flash_info_t
*info
, ulong dest
, ushort data
)
723 vu_short
*addr
= (vu_short
*)dest
;
724 ulong start
, now
, csr
, ready
;
727 /* Check if Flash is (sufficiently) erased */
728 if ((*addr
& data
) != data
) {
731 /* Disable interrupts which might cause a timeout here */
732 flag
= disable_interrupts();
736 start
= get_timer (0);
741 /* re-enable interrupts if necessary */
744 if (big_endian
== 1) {
750 /* data polling for D7 */
752 while (((csr
= *addr
) & ready
) != ready
) {
753 if ((now
=get_timer(start
)) > CFG_FLASH_WRITE_TOUT
) {
759 printf ("CSR indicates write error (%04x) at %08lx\n", csr
, (ulong
)addr
);
762 /* Clear Status Registers Command */
765 /* Reset to read array mode */
771 /*-----------------------------------------------------------------------
772 * Write a word to Flash, returns:
775 * 2 - Flash not erased
777 static int write_word (flash_info_t
*info
, ulong dest
, ulong data
)
779 vu_long
*addr
= (vu_long
*)dest
;
780 ulong start
, csr
, ready
;
783 switch (info
->portwidth
) {
784 case FLASH_CFI_32BIT
:
785 /* Check if Flash is (sufficiently) erased */
786 if ((*addr
& data
) != data
) {
789 /* Disable interrupts which might cause a timeout here */
790 flag
= disable_interrupts();
792 if (big_endian
== 1) {
798 if ((info
->portwidth
/ info
->chipwidth
)==2) {
799 ready
+= (ready
<<16);
809 /* re-enable interrupts if necessary */
812 /* data polling for D7 */
813 start
= get_timer (0);
815 while (((csr
= *addr
) & ready
) != ready
) {
816 if (get_timer(start
) > CFG_FLASH_WRITE_TOUT
) {
821 if (csr
& 0x40404040) {
822 printf ("CSR indicates write error (%08lx) at %08lx\n", csr
, (ulong
)addr
);
825 /* Clear Status Registers Command */
828 /* Reset to read array mode */
832 case FLASH_CFI_16BIT
:
833 flag
= write_short (info
, dest
, (unsigned short) (data
>>16));
835 flag
= write_short (info
, dest
+2, (unsigned short) (data
));
841 /*-----------------------------------------------------------------------
842 * Clear Block Lock Bit, returns:
847 static int clear_block_lock_bit(flash_info_t
* info
, vu_long
* addr
)
849 ulong start
, now
, ready
;
854 /* Clear Status Register */
864 if (big_endian
== 1) {
870 if ((info
->portwidth
/ info
->chipwidth
)==2) {
871 ready
+= (ready
<<16);
877 printf ("%s: Ready flag is 0x%8lx\n", __FUNCTION__
, ready
);
879 *addr
= 0x70707070; /* read status */
880 start
= get_timer (0);
881 while((*addr
& ready
) != ready
){
882 if ((now
=get_timer(start
)) > CFG_FLASH_ERASE_TOUT
) {
883 printf ("Timeout on clearing Block Lock Bit\n");
884 *addr
= 0xFFFFFFFF; /* reset bank */
892 #endif /* !CFG_NO_FLASH */