3 * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
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,
25 * flash.c - flash support for the 512k, 8bit boot flash on the GEVB
26 * most of this file was based on the existing U-Boot
32 #include <galileo/gt64260R.h>
33 #include <galileo/memory.h>
34 #include "intel_flash.h"
36 #define FLASH_ROM 0xFFFD /* unknown flash type */
37 #define FLASH_RAM 0xFFFE /* unknown flash type */
38 #define FLASH_MAN_UNKNOWN 0xFFFF0000
41 /* #define FLASH_ID_OVERRIDE */ /* Hack to set type to 040B if ROM emulator is installed.
42 * Can be used to program a ROM in circuit if a programmer
43 * is not available by swapping the rom out. */
45 /* Intel flash commands */
46 int flash_erase_intel(flash_info_t
*info
, int s_first
, int s_last
);
47 int write_word_intel(bank_addr_t addr
, bank_word_t value
);
49 flash_info_t flash_info
[CONFIG_SYS_MAX_FLASH_BANKS
]; /* info for FLASH chips */
51 /*-----------------------------------------------------------------------
54 static ulong
flash_get_size (int portwidth
, vu_long
*addr
, flash_info_t
*info
);
55 static int write_word (flash_info_t
*info
, ulong dest
, ulong data
);
56 static void flash_get_offsets (ulong base
, flash_info_t
*info
);
57 static flash_info_t
*flash_get_info(ulong base
);
59 /*-----------------------------------------------------------------------
66 unsigned long size_b0
= 0, size_b1
= 0;
67 unsigned long base
, flash_size
;
69 /* Init: no FLASHes known */
70 for (i
=0; i
<CONFIG_SYS_MAX_FLASH_BANKS
; ++i
) {
71 flash_info
[i
].flash_id
= FLASH_UNKNOWN
;
75 base
= CONFIG_SYS_FLASH_BASE
;
76 #ifndef CONFIG_SYS_BOOT_FLASH_WIDTH
77 #define CONFIG_SYS_BOOT_FLASH_WIDTH 1
79 size_b0
= flash_get_size(CONFIG_SYS_BOOT_FLASH_WIDTH
, (vu_long
*)base
,
84 print_size (size_b0
, "");
85 printf("@%08lX] ", base
);
88 if (flash_info
[0].flash_id
== FLASH_UNKNOWN
) {
89 printf ("## Unknown FLASH at %08lx: Size = 0x%08lx = %ld MB\n",
90 base
, size_b0
, size_b0
<<20);
93 base
= memoryGetDeviceBaseAddress(CONFIG_SYS_EXTRA_FLASH_DEVICE
);
94 for(i
=1;i
<CONFIG_SYS_MAX_FLASH_BANKS
;i
++) {
95 unsigned long size
= flash_get_size(CONFIG_SYS_EXTRA_FLASH_WIDTH
, (vu_long
*)base
, &flash_info
[i
]);
99 print_size (size
, "");
100 printf("@%08lX] ", base
);
103 if (flash_info
[i
].flash_id
== FLASH_UNKNOWN
) {
105 printf ("## Unknown FLASH at %08lx: Size = 0x%08lx = %ld MB\n",
106 base
, size_b1
, size_b1
<<20);
114 #if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
115 /* monitor protection ON by default */
116 flash_protect(FLAG_PROTECT_SET
,
117 CONFIG_SYS_MONITOR_BASE
,
118 CONFIG_SYS_MONITOR_BASE
+ monitor_flash_len
- 1,
119 flash_get_info(CONFIG_SYS_MONITOR_BASE
));
122 #ifdef CONFIG_ENV_IS_IN_FLASH
123 /* ENV protection ON by default */
124 flash_protect(FLAG_PROTECT_SET
,
126 CONFIG_ENV_ADDR
+ CONFIG_ENV_SIZE
- 1,
127 flash_get_info(CONFIG_ENV_ADDR
));
130 flash_size
= size_b0
+ size_b1
;
134 /*-----------------------------------------------------------------------
137 flash_get_offsets (ulong base
, flash_info_t
*info
)
142 if(!info
->sector_count
) return;
144 /* set up sector start address table */
145 switch(info
->flash_id
& FLASH_TYPEMASK
) {
147 case FLASH_28F128J3A
:
148 case FLASH_28F640J3A
:
150 /* this chip has uniformly spaced sectors */
151 sector_size
=info
->size
/info
->sector_count
;
152 for (i
= 0; i
< info
->sector_count
; i
++)
153 info
->start
[i
] = base
+ (i
* sector_size
);
156 if (info
->flash_id
& FLASH_BTYPE
) {
157 /* set sector offsets for bottom boot block type */
158 info
->start
[0] = base
+ 0x00000000;
159 info
->start
[1] = base
+ 0x00008000;
160 info
->start
[2] = base
+ 0x0000C000;
161 info
->start
[3] = base
+ 0x00010000;
162 for (i
= 4; i
< info
->sector_count
; i
++) {
163 info
->start
[i
] = base
+ (i
* 0x00020000) - 0x00060000;
166 /* set sector offsets for top boot block type */
167 i
= info
->sector_count
- 1;
168 info
->start
[i
--] = base
+ info
->size
- 0x00008000;
169 info
->start
[i
--] = base
+ info
->size
- 0x0000C000;
170 info
->start
[i
--] = base
+ info
->size
- 0x00010000;
171 for (; i
>= 0; i
--) {
172 info
->start
[i
] = base
+ i
* 0x00020000;
178 /*-----------------------------------------------------------------------
181 static flash_info_t
*flash_get_info(ulong base
)
186 for (i
= 0; i
< CONFIG_SYS_MAX_FLASH_BANKS
; i
++) {
187 info
= & flash_info
[i
];
188 if (info
->start
[0] <= base
&& base
<= info
->start
[0] + info
->size
- 1)
192 return i
== CONFIG_SYS_MAX_FLASH_BANKS
? 0 : info
;
195 /*-----------------------------------------------------------------------
198 flash_print_info (flash_info_t
*info
)
202 if (info
->flash_id
== FLASH_UNKNOWN
) {
203 printf ("missing or unknown FLASH type\n");
207 switch (info
->flash_id
& FLASH_VENDMASK
) {
208 case FLASH_MAN_AMD
: printf ("AMD "); break;
209 case FLASH_MAN_FUJ
: printf ("FUJITSU "); break;
210 case FLASH_MAN_INTEL
: printf ("INTEL "); break;
211 default: printf ("Unknown Vendor "); break;
214 switch (info
->flash_id
& FLASH_TYPEMASK
) {
216 printf ("AM29LV040B (4 Mbit, bottom boot sect)\n");
219 printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
222 printf ("AM29LV400T (4 Mbit, top boot sector)\n");
225 printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
228 printf ("AM29LV800T (8 Mbit, top boot sector)\n");
231 printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
234 printf ("AM29LV160T (16 Mbit, top boot sector)\n");
237 printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
240 printf ("AM29LV320T (32 Mbit, top boot sector)\n");
242 case FLASH_28F640J3A
:
243 printf ("28F640J3A (64 Mbit)\n");
245 case FLASH_28F128J3A
:
246 printf ("28F128J3A (128 Mbit)\n");
255 printf ("Unknown Chip Type\n");
260 print_size (info
->size
, "");
261 printf (" in %d Sectors\n", info
->sector_count
);
263 printf (" Sector Start Addresses:");
264 for (i
=0; i
<info
->sector_count
; ++i
) {
269 info
->protect
[i
] ? " (RO)" : " "
276 /*-----------------------------------------------------------------------
280 /*-----------------------------------------------------------------------
284 * The following code cannot be run from FLASH!
287 static inline void flash_cmd(int width
, volatile unsigned char *addr
, int offset
, unsigned char cmd
)
289 /* supports 1x8, 1x16, and 2x16 */
290 /* 2x8 and 4x8 are not supported */
292 /* assuming chips are in 16 bit mode */
294 unsigned long cmd32
=(cmd
<<16)|cmd
;
295 *(volatile unsigned long *)(addr
+offset
*2)=cmd32
;
296 } else if (width
== 2) {
298 *(volatile unsigned short *)((unsigned short*)addr
+offset
)=cmd
;
301 *(volatile unsigned char *)(addr
+offset
)=cmd
;
306 flash_get_size (int portwidth
, vu_long
*addr
, flash_info_t
*info
)
309 volatile unsigned char *caddr
= (unsigned char *)addr
;
310 volatile unsigned short *saddr
= (unsigned short *)addr
;
311 volatile unsigned long *laddr
= (unsigned long *)addr
;
313 ulong id
, manu
, base
= (ulong
)addr
;
315 info
->portwidth
=portwidth
;
319 flash_cmd(portwidth
,caddr
,0,0xf0);
320 flash_cmd(portwidth
,caddr
,0,0xf0);
329 flash_cmd(portwidth
,caddr
,0,0xf0);
330 flash_cmd(portwidth
,caddr
,0,0xf0);
335 /* this area is ROM */
337 #ifndef FLASH_ID_OVERRIDE
338 info
->flash_id
= FLASH_ROM
+ FLASH_MAN_UNKNOWN
;
339 info
->sector_count
= 8;
340 info
->size
= 0x80000;
342 info
->flash_id
= FLASH_MAN_AMD
+ FLASH_AM040
;
343 info
->sector_count
= 8;
344 info
->size
= 0x80000;
347 flash_get_offsets(base
, info
);
356 /* this area is RAM */
358 info
->flash_id
= FLASH_RAM
+ FLASH_MAN_UNKNOWN
;
359 info
->sector_count
= 8;
360 info
->size
= 0x80000;
361 flash_get_offsets(base
, info
);
364 flash_cmd(portwidth
,caddr
,0,0xf0);
369 /* Write auto select command: read Manufacturer ID */
370 flash_cmd(portwidth
,caddr
,0x555,0xAA);
371 flash_cmd(portwidth
,caddr
,0x2AA,0x55);
372 flash_cmd(portwidth
,caddr
,0x555,0x90);
376 if ((caddr
[0] == old
[0]) &&
377 (caddr
[1] == old
[1])) {
379 /* this area is ROM */
380 #ifndef FLASH_ID_OVERRIDE
381 info
->flash_id
= FLASH_ROM
+ FLASH_MAN_UNKNOWN
;
382 info
->sector_count
= 8;
383 info
->size
= 0x80000;
385 info
->flash_id
= FLASH_MAN_AMD
+ FLASH_AM040
;
386 info
->sector_count
= 8;
387 info
->size
= 0x80000;
390 flash_get_offsets(base
, info
);
394 printf("%px%d: %02x:%02x -> %02x:%02x\n",
395 caddr
, portwidth
, old
[0], old
[1],
422 printf("\n%08lx:%08lx:%08lx\n", base
, manu
, id
);
423 printf("%08lx %08lx %08lx %08lx\n",
424 laddr
[0],laddr
[1],laddr
[2],laddr
[3]);
429 info
->flash_id
= FLASH_MAN_AMD
;
432 info
->flash_id
= FLASH_MAN_FUJ
;
435 info
->flash_id
= FLASH_MAN_INTEL
;
438 printf("Unknown Mfr [%08lx]:%08lx\n", manu
, id
);
439 info
->flash_id
= FLASH_UNKNOWN
;
440 info
->sector_count
= 0;
442 return (0); /* no or unknown flash */
447 info
->flash_id
+= FLASH_AM400T
;
448 info
->sector_count
= 11;
449 info
->size
= 0x00100000;
454 info
->flash_id
+= FLASH_AM400B
;
455 info
->sector_count
= 11;
456 info
->size
= 0x00100000;
461 info
->flash_id
+= FLASH_AM800T
;
462 info
->sector_count
= 19;
463 info
->size
= 0x00200000;
468 info
->flash_id
+= FLASH_AM800B
;
469 info
->sector_count
= 19;
470 info
->size
= 0x00200000;
475 info
->flash_id
+= FLASH_AM160T
;
476 info
->sector_count
= 35;
477 info
->size
= 0x00400000;
482 info
->flash_id
+= FLASH_AM160B
;
483 info
->sector_count
= 35;
484 info
->size
= 0x00400000;
487 #if 0 /* enable when device IDs are available */
489 info
->flash_id
+= FLASH_AM320T
;
490 info
->sector_count
= 67;
491 info
->size
= 0x00800000;
495 info
->flash_id
+= FLASH_AM320B
;
496 info
->sector_count
= 67;
497 info
->size
= 0x00800000;
501 info
->flash_id
+= FLASH_AM040
;
502 info
->sector_count
= 8;
503 info
->size
= 0x80000;
507 case INTEL_ID_28F640J3A
:
508 info
->flash_id
+= FLASH_28F640J3A
;
509 info
->sector_count
= 64;
510 info
->size
= 128*1024 * 64; /* 128kbytes x 64 blocks */
512 if(portwidth
==4) info
->size
*=2; /* 2x16 */
515 case INTEL_ID_28F128J3A
:
516 info
->flash_id
+= FLASH_28F128J3A
;
517 info
->sector_count
= 128;
518 info
->size
= 128*1024 * 128; /* 128kbytes x 128 blocks */
520 if(portwidth
==4) info
->size
*=2; /* 2x16 */
524 printf("Unknown id %lx:[%lx]\n", manu
, id
);
525 info
->flash_id
= FLASH_UNKNOWN
;
527 return (0); /* => no or unknown flash */
531 flash_get_offsets(base
, info
);
534 /* set up sector start address table */
535 if (info
->flash_id
& FLASH_AM040
) {
536 /* this chip has uniformly spaced sectors */
537 for (i
= 0; i
< info
->sector_count
; i
++)
538 info
->start
[i
] = base
+ (i
* 0x00010000);
540 } else if (info
->flash_id
& FLASH_BTYPE
) {
541 /* set sector offsets for bottom boot block type */
542 info
->start
[0] = base
+ 0x00000000;
543 info
->start
[1] = base
+ 0x00008000;
544 info
->start
[2] = base
+ 0x0000C000;
545 info
->start
[3] = base
+ 0x00010000;
546 for (i
= 4; i
< info
->sector_count
; i
++) {
547 info
->start
[i
] = base
+ (i
* 0x00020000) - 0x00060000;
550 /* set sector offsets for top boot block type */
551 i
= info
->sector_count
- 1;
552 info
->start
[i
--] = base
+ info
->size
- 0x00008000;
553 info
->start
[i
--] = base
+ info
->size
- 0x0000C000;
554 info
->start
[i
--] = base
+ info
->size
- 0x00010000;
555 for (; i
>= 0; i
--) {
556 info
->start
[i
] = base
+ i
* 0x00020000;
561 /* check for protected sectors */
562 for (i
= 0; i
< info
->sector_count
; i
++) {
563 /* read sector protection at sector address, (A7 .. A0)=0x02 */
564 /* D0 = 1 if protected */
565 caddr
= (volatile unsigned char *)(info
->start
[i
]);
566 saddr
= (volatile unsigned short *)(info
->start
[i
]);
567 laddr
= (volatile unsigned long *)(info
->start
[i
]);
569 info
->protect
[i
] = caddr
[2] & 1;
570 else if(portwidth
==2)
571 info
->protect
[i
] = saddr
[2] & 1;
573 info
->protect
[i
] = laddr
[2] & 1;
577 * Prevent writes to uninitialized FLASH.
579 if (info
->flash_id
!= FLASH_UNKNOWN
) {
580 caddr
= (volatile unsigned char *)info
->start
[0];
582 flash_cmd(portwidth
,caddr
,0,0xF0); /* reset bank */
588 /* TODO: 2x16 unsupported */
590 flash_erase (flash_info_t
*info
, int s_first
, int s_last
)
592 volatile unsigned char *addr
= (uchar
*)(info
->start
[0]);
593 int flag
, prot
, sect
, l_sect
;
594 ulong start
, now
, last
;
596 /* TODO: 2x16 unsupported */
597 if(info
->portwidth
==4) return 1;
599 if((info
->flash_id
& FLASH_TYPEMASK
) == FLASH_ROM
) return 1;
600 if((info
->flash_id
& FLASH_TYPEMASK
) == FLASH_RAM
) {
601 for (sect
= s_first
; sect
<=s_last
; sect
++) {
602 int sector_size
=info
->size
/info
->sector_count
;
603 addr
= (uchar
*)(info
->start
[sect
]);
604 memset((void *)addr
, 0, sector_size
);
609 if ((s_first
< 0) || (s_first
> s_last
)) {
610 if (info
->flash_id
== FLASH_UNKNOWN
) {
611 printf ("- missing\n");
613 printf ("- no sectors to erase\n");
618 if ((info
->flash_id
&FLASH_VENDMASK
) == FLASH_MAN_INTEL
) {
619 return flash_erase_intel(info
,
620 (unsigned short)s_first
,
621 (unsigned short)s_last
);
625 if ((info
->flash_id
== FLASH_UNKNOWN
) ||
626 (info
->flash_id
> FLASH_AMD_COMP
)) {
627 printf ("Can't erase unknown flash type %08lx - aborted\n",
634 for (sect
=s_first
; sect
<=s_last
; ++sect
) {
635 if (info
->protect
[sect
]) {
641 printf ("- Warning: %d protected sectors will not be erased!\n",
649 /* Disable interrupts which might cause a timeout here */
650 flag
= disable_interrupts();
652 flash_cmd(info
->portwidth
,addr
,0x555,0xAA);
653 flash_cmd(info
->portwidth
,addr
,0x2AA,0x55);
654 flash_cmd(info
->portwidth
,addr
,0x555,0x80);
655 flash_cmd(info
->portwidth
,addr
,0x555,0xAA);
656 flash_cmd(info
->portwidth
,addr
,0x2AA,0x55);
658 /* Start erase on unprotected sectors */
659 for (sect
= s_first
; sect
<=s_last
; sect
++) {
660 if (info
->protect
[sect
] == 0) { /* not protected */
661 addr
= (uchar
*)(info
->start
[sect
]);
662 flash_cmd(info
->portwidth
,addr
,0,0x30);
667 /* re-enable interrupts if necessary */
671 /* wait at least 80us - let's wait 1 ms */
675 * We wait for the last triggered sector
680 start
= get_timer (0);
682 addr
= (volatile unsigned char *)(info
->start
[l_sect
]);
683 /* broken for 2x16: TODO */
684 while ((addr
[0] & 0x80) != 0x80) {
685 if ((now
= get_timer(start
)) > CONFIG_SYS_FLASH_ERASE_TOUT
) {
686 printf ("Timeout\n");
689 /* show that we're waiting */
690 if ((now
- last
) > 1000) { /* every second */
697 /* reset to read mode */
698 addr
= (volatile unsigned char *)info
->start
[0];
699 flash_cmd(info
->portwidth
,addr
,0,0xf0);
700 flash_cmd(info
->portwidth
,addr
,0,0xf0);
706 /*-----------------------------------------------------------------------
707 * Copy memory to flash, returns:
710 * 2 - Flash not erased
713 /* broken for 2x16: TODO */
715 write_buff (flash_info_t
*info
, uchar
*src
, ulong addr
, ulong cnt
)
720 if(info
->portwidth
==4) return 1;
722 if((info
->flash_id
& FLASH_TYPEMASK
) == FLASH_ROM
) return 0;
723 if((info
->flash_id
& FLASH_TYPEMASK
) == FLASH_RAM
) {
724 memcpy((void *)addr
, src
, cnt
);
728 wp
= (addr
& ~3); /* get lower word aligned address */
731 * handle unaligned start bytes
733 if ((l
= addr
- wp
) != 0) {
735 for (i
=0, cp
=wp
; i
<l
; ++i
, ++cp
) {
736 data
= (data
<< 8) | (*(uchar
*)cp
);
738 for (; i
<4 && cnt
>0; ++i
) {
739 data
= (data
<< 8) | *src
++;
743 for (; cnt
==0 && i
<4; ++i
, ++cp
) {
744 data
= (data
<< 8) | (*(uchar
*)cp
);
747 if ((rc
= write_word(info
, wp
, data
)) != 0) {
754 * handle word aligned part
758 for (i
=0; i
<4; ++i
) {
759 data
= (data
<< 8) | *src
++;
761 if ((rc
= write_word(info
, wp
, data
)) != 0) {
773 * handle unaligned tail bytes
776 for (i
=0, cp
=wp
; i
<4 && cnt
>0; ++i
, ++cp
) {
777 data
= (data
<< 8) | *src
++;
780 for (; i
<4; ++i
, ++cp
) {
781 data
= (data
<< 8) | (*(uchar
*)cp
);
784 return (write_word(info
, wp
, data
));
787 /*-----------------------------------------------------------------------
788 * Write a word to Flash, returns:
791 * 2 - Flash not erased
793 /* broken for 2x16: TODO */
795 write_word (flash_info_t
*info
, ulong dest
, ulong data
)
797 volatile unsigned char *addr
= (uchar
*)(info
->start
[0]);
801 if(info
->portwidth
==4) return 1;
803 if((info
->flash_id
& FLASH_TYPEMASK
) == FLASH_ROM
) return 1;
804 if((info
->flash_id
& FLASH_TYPEMASK
) == FLASH_RAM
) {
805 *(unsigned long *)dest
=data
;
808 if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_INTEL
) {
809 unsigned short low
= data
& 0xffff;
810 unsigned short hi
= (data
>> 16) & 0xffff;
811 int ret
= write_word_intel((bank_addr_t
)dest
, hi
);
813 if (!ret
) ret
= write_word_intel((bank_addr_t
)(dest
+2), low
);
818 /* Check if Flash is (sufficiently) erased */
819 if ((*((vu_long
*)dest
) & data
) != data
) {
822 /* Disable interrupts which might cause a timeout here */
823 flag
= disable_interrupts();
825 /* first, perform an unlock bypass command to speed up flash writes */
830 /* write each byte out */
831 for (i
= 0; i
< 4; i
++) {
832 char *data_ch
= (char *)&data
;
834 *(((char *)dest
)+i
) = data_ch
[i
];
835 udelay(10); /* XXX */
838 /* we're done, now do an unlock bypass reset */
842 /* re-enable interrupts if necessary */
846 /* data polling for D7 */
847 start
= get_timer (0);
848 while ((*((vu_long
*)dest
) & 0x00800080) != (data
& 0x00800080)) {
849 if (get_timer(start
) > CONFIG_SYS_FLASH_WRITE_TOUT
) {