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
);
58 /*-----------------------------------------------------------------------
65 unsigned long size_b0
= 0, size_b1
= 0;
66 unsigned long base
, flash_size
;
68 /* Init: no FLASHes known */
69 for (i
=0; i
<CONFIG_SYS_MAX_FLASH_BANKS
; ++i
) {
70 flash_info
[i
].flash_id
= FLASH_UNKNOWN
;
74 base
= CONFIG_SYS_FLASH_BASE
;
75 #ifndef CONFIG_SYS_BOOT_FLASH_WIDTH
76 #define CONFIG_SYS_BOOT_FLASH_WIDTH 1
78 size_b0
= flash_get_size(CONFIG_SYS_BOOT_FLASH_WIDTH
, (vu_long
*)base
,
83 print_size (size_b0
, "");
84 printf("@%08lX] ", base
);
87 if (flash_info
[0].flash_id
== FLASH_UNKNOWN
) {
88 printf ("## Unknown FLASH at %08lx: Size = 0x%08lx = %ld MB\n",
89 base
, size_b0
, size_b0
<<20);
92 base
= memoryGetDeviceBaseAddress(CONFIG_SYS_EXTRA_FLASH_DEVICE
);
93 for(i
=1;i
<CONFIG_SYS_MAX_FLASH_BANKS
;i
++) {
94 unsigned long size
= flash_get_size(CONFIG_SYS_EXTRA_FLASH_WIDTH
, (vu_long
*)base
, &flash_info
[i
]);
98 print_size (size
, "");
99 printf("@%08lX] ", base
);
102 if (flash_info
[i
].flash_id
== FLASH_UNKNOWN
) {
104 printf ("## Unknown FLASH at %08lx: Size = 0x%08lx = %ld MB\n",
105 base
, size_b1
, size_b1
<<20);
113 #if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
114 /* monitor protection ON by default */
115 flash_protect(FLAG_PROTECT_SET
,
116 CONFIG_SYS_MONITOR_BASE
,
117 CONFIG_SYS_MONITOR_BASE
+ monitor_flash_len
- 1,
118 flash_get_info(CONFIG_SYS_MONITOR_BASE
));
121 #ifdef CONFIG_ENV_IS_IN_FLASH
122 /* ENV protection ON by default */
123 flash_protect(FLAG_PROTECT_SET
,
125 CONFIG_ENV_ADDR
+ CONFIG_ENV_SIZE
- 1,
126 flash_get_info(CONFIG_ENV_ADDR
));
129 flash_size
= size_b0
+ size_b1
;
133 /*-----------------------------------------------------------------------
136 flash_get_offsets (ulong base
, flash_info_t
*info
)
141 if(!info
->sector_count
) return;
143 /* set up sector start address table */
144 switch(info
->flash_id
& FLASH_TYPEMASK
) {
146 case FLASH_28F128J3A
:
147 case FLASH_28F640J3A
:
149 /* this chip has uniformly spaced sectors */
150 sector_size
=info
->size
/info
->sector_count
;
151 for (i
= 0; i
< info
->sector_count
; i
++)
152 info
->start
[i
] = base
+ (i
* sector_size
);
155 if (info
->flash_id
& FLASH_BTYPE
) {
156 /* set sector offsets for bottom boot block type */
157 info
->start
[0] = base
+ 0x00000000;
158 info
->start
[1] = base
+ 0x00008000;
159 info
->start
[2] = base
+ 0x0000C000;
160 info
->start
[3] = base
+ 0x00010000;
161 for (i
= 4; i
< info
->sector_count
; i
++) {
162 info
->start
[i
] = base
+ (i
* 0x00020000) - 0x00060000;
165 /* set sector offsets for top boot block type */
166 i
= info
->sector_count
- 1;
167 info
->start
[i
--] = base
+ info
->size
- 0x00008000;
168 info
->start
[i
--] = base
+ info
->size
- 0x0000C000;
169 info
->start
[i
--] = base
+ info
->size
- 0x00010000;
170 for (; i
>= 0; i
--) {
171 info
->start
[i
] = base
+ i
* 0x00020000;
177 /*-----------------------------------------------------------------------
180 flash_info_t
*flash_get_info(ulong base
)
185 for (i
= 0; i
< CONFIG_SYS_MAX_FLASH_BANKS
; i
++) {
186 info
= & flash_info
[i
];
187 if (info
->start
[0] <= base
&& base
<= info
->start
[0] + info
->size
- 1)
191 return i
== CONFIG_SYS_MAX_FLASH_BANKS
? 0 : info
;
194 /*-----------------------------------------------------------------------
197 flash_print_info (flash_info_t
*info
)
201 if (info
->flash_id
== FLASH_UNKNOWN
) {
202 printf ("missing or unknown FLASH type\n");
206 switch (info
->flash_id
& FLASH_VENDMASK
) {
207 case FLASH_MAN_AMD
: printf ("AMD "); break;
208 case FLASH_MAN_FUJ
: printf ("FUJITSU "); break;
209 case FLASH_MAN_INTEL
: printf ("INTEL "); break;
210 default: printf ("Unknown Vendor "); break;
213 switch (info
->flash_id
& FLASH_TYPEMASK
) {
215 printf ("AM29LV040B (4 Mbit, bottom boot sect)\n");
218 printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
221 printf ("AM29LV400T (4 Mbit, top boot sector)\n");
224 printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
227 printf ("AM29LV800T (8 Mbit, top boot sector)\n");
230 printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
233 printf ("AM29LV160T (16 Mbit, top boot sector)\n");
236 printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
239 printf ("AM29LV320T (32 Mbit, top boot sector)\n");
241 case FLASH_28F640J3A
:
242 printf ("28F640J3A (64 Mbit)\n");
244 case FLASH_28F128J3A
:
245 printf ("28F128J3A (128 Mbit)\n");
254 printf ("Unknown Chip Type\n");
259 print_size (info
->size
, "");
260 printf (" in %d Sectors\n", info
->sector_count
);
262 printf (" Sector Start Addresses:");
263 for (i
=0; i
<info
->sector_count
; ++i
) {
268 info
->protect
[i
] ? " (RO)" : " "
275 /*-----------------------------------------------------------------------
279 /*-----------------------------------------------------------------------
283 * The following code cannot be run from FLASH!
286 static inline void flash_cmd(int width
, volatile unsigned char *addr
, int offset
, unsigned char cmd
)
288 /* supports 1x8, 1x16, and 2x16 */
289 /* 2x8 and 4x8 are not supported */
291 /* assuming chips are in 16 bit mode */
293 unsigned long cmd32
=(cmd
<<16)|cmd
;
294 *(volatile unsigned long *)(addr
+offset
*2)=cmd32
;
295 } else if (width
== 2) {
297 *(volatile unsigned short *)((unsigned short*)addr
+offset
)=cmd
;
300 *(volatile unsigned char *)(addr
+offset
)=cmd
;
305 flash_get_size (int portwidth
, vu_long
*addr
, flash_info_t
*info
)
308 volatile unsigned char *caddr
= (unsigned char *)addr
;
309 volatile unsigned short *saddr
= (unsigned short *)addr
;
310 volatile unsigned long *laddr
= (unsigned long *)addr
;
312 ulong id
, manu
, base
= (ulong
)addr
;
314 info
->portwidth
=portwidth
;
318 flash_cmd(portwidth
,caddr
,0,0xf0);
319 flash_cmd(portwidth
,caddr
,0,0xf0);
328 flash_cmd(portwidth
,caddr
,0,0xf0);
329 flash_cmd(portwidth
,caddr
,0,0xf0);
334 /* this area is ROM */
336 #ifndef FLASH_ID_OVERRIDE
337 info
->flash_id
= FLASH_ROM
+ FLASH_MAN_UNKNOWN
;
338 info
->sector_count
= 8;
339 info
->size
= 0x80000;
341 info
->flash_id
= FLASH_MAN_AMD
+ FLASH_AM040
;
342 info
->sector_count
= 8;
343 info
->size
= 0x80000;
346 flash_get_offsets(base
, info
);
355 /* this area is RAM */
357 info
->flash_id
= FLASH_RAM
+ FLASH_MAN_UNKNOWN
;
358 info
->sector_count
= 8;
359 info
->size
= 0x80000;
360 flash_get_offsets(base
, info
);
363 flash_cmd(portwidth
,caddr
,0,0xf0);
368 /* Write auto select command: read Manufacturer ID */
369 flash_cmd(portwidth
,caddr
,0x555,0xAA);
370 flash_cmd(portwidth
,caddr
,0x2AA,0x55);
371 flash_cmd(portwidth
,caddr
,0x555,0x90);
375 if ((caddr
[0] == old
[0]) &&
376 (caddr
[1] == old
[1])) {
378 /* this area is ROM */
379 #ifndef FLASH_ID_OVERRIDE
380 info
->flash_id
= FLASH_ROM
+ FLASH_MAN_UNKNOWN
;
381 info
->sector_count
= 8;
382 info
->size
= 0x80000;
384 info
->flash_id
= FLASH_MAN_AMD
+ FLASH_AM040
;
385 info
->sector_count
= 8;
386 info
->size
= 0x80000;
389 flash_get_offsets(base
, info
);
393 printf("%px%d: %02x:%02x -> %02x:%02x\n",
394 caddr
, portwidth
, old
[0], old
[1],
421 printf("\n%08lx:%08lx:%08lx\n", base
, manu
, id
);
422 printf("%08lx %08lx %08lx %08lx\n",
423 laddr
[0],laddr
[1],laddr
[2],laddr
[3]);
428 info
->flash_id
= FLASH_MAN_AMD
;
431 info
->flash_id
= FLASH_MAN_FUJ
;
434 info
->flash_id
= FLASH_MAN_INTEL
;
437 printf("Unknown Mfr [%08lx]:%08lx\n", manu
, id
);
438 info
->flash_id
= FLASH_UNKNOWN
;
439 info
->sector_count
= 0;
441 return (0); /* no or unknown flash */
446 info
->flash_id
+= FLASH_AM400T
;
447 info
->sector_count
= 11;
448 info
->size
= 0x00100000;
453 info
->flash_id
+= FLASH_AM400B
;
454 info
->sector_count
= 11;
455 info
->size
= 0x00100000;
460 info
->flash_id
+= FLASH_AM800T
;
461 info
->sector_count
= 19;
462 info
->size
= 0x00200000;
467 info
->flash_id
+= FLASH_AM800B
;
468 info
->sector_count
= 19;
469 info
->size
= 0x00200000;
474 info
->flash_id
+= FLASH_AM160T
;
475 info
->sector_count
= 35;
476 info
->size
= 0x00400000;
481 info
->flash_id
+= FLASH_AM160B
;
482 info
->sector_count
= 35;
483 info
->size
= 0x00400000;
486 #if 0 /* enable when device IDs are available */
488 info
->flash_id
+= FLASH_AM320T
;
489 info
->sector_count
= 67;
490 info
->size
= 0x00800000;
494 info
->flash_id
+= FLASH_AM320B
;
495 info
->sector_count
= 67;
496 info
->size
= 0x00800000;
500 info
->flash_id
+= FLASH_AM040
;
501 info
->sector_count
= 8;
502 info
->size
= 0x80000;
506 case INTEL_ID_28F640J3A
:
507 info
->flash_id
+= FLASH_28F640J3A
;
508 info
->sector_count
= 64;
509 info
->size
= 128*1024 * 64; /* 128kbytes x 64 blocks */
511 if(portwidth
==4) info
->size
*=2; /* 2x16 */
514 case INTEL_ID_28F128J3A
:
515 info
->flash_id
+= FLASH_28F128J3A
;
516 info
->sector_count
= 128;
517 info
->size
= 128*1024 * 128; /* 128kbytes x 128 blocks */
519 if(portwidth
==4) info
->size
*=2; /* 2x16 */
523 printf("Unknown id %lx:[%lx]\n", manu
, id
);
524 info
->flash_id
= FLASH_UNKNOWN
;
526 return (0); /* => no or unknown flash */
530 flash_get_offsets(base
, info
);
533 /* set up sector start address table */
534 if (info
->flash_id
& FLASH_AM040
) {
535 /* this chip has uniformly spaced sectors */
536 for (i
= 0; i
< info
->sector_count
; i
++)
537 info
->start
[i
] = base
+ (i
* 0x00010000);
539 } else if (info
->flash_id
& FLASH_BTYPE
) {
540 /* set sector offsets for bottom boot block type */
541 info
->start
[0] = base
+ 0x00000000;
542 info
->start
[1] = base
+ 0x00008000;
543 info
->start
[2] = base
+ 0x0000C000;
544 info
->start
[3] = base
+ 0x00010000;
545 for (i
= 4; i
< info
->sector_count
; i
++) {
546 info
->start
[i
] = base
+ (i
* 0x00020000) - 0x00060000;
549 /* set sector offsets for top boot block type */
550 i
= info
->sector_count
- 1;
551 info
->start
[i
--] = base
+ info
->size
- 0x00008000;
552 info
->start
[i
--] = base
+ info
->size
- 0x0000C000;
553 info
->start
[i
--] = base
+ info
->size
- 0x00010000;
554 for (; i
>= 0; i
--) {
555 info
->start
[i
] = base
+ i
* 0x00020000;
560 /* check for protected sectors */
561 for (i
= 0; i
< info
->sector_count
; i
++) {
562 /* read sector protection at sector address, (A7 .. A0)=0x02 */
563 /* D0 = 1 if protected */
564 caddr
= (volatile unsigned char *)(info
->start
[i
]);
565 saddr
= (volatile unsigned short *)(info
->start
[i
]);
566 laddr
= (volatile unsigned long *)(info
->start
[i
]);
568 info
->protect
[i
] = caddr
[2] & 1;
569 else if(portwidth
==2)
570 info
->protect
[i
] = saddr
[2] & 1;
572 info
->protect
[i
] = laddr
[2] & 1;
576 * Prevent writes to uninitialized FLASH.
578 if (info
->flash_id
!= FLASH_UNKNOWN
) {
579 caddr
= (volatile unsigned char *)info
->start
[0];
581 flash_cmd(portwidth
,caddr
,0,0xF0); /* reset bank */
587 /* TODO: 2x16 unsupported */
589 flash_erase (flash_info_t
*info
, int s_first
, int s_last
)
591 volatile unsigned char *addr
= (uchar
*)(info
->start
[0]);
592 int flag
, prot
, sect
, l_sect
;
593 ulong start
, now
, last
;
595 /* TODO: 2x16 unsupported */
596 if(info
->portwidth
==4) return 1;
598 if((info
->flash_id
& FLASH_TYPEMASK
) == FLASH_ROM
) return 1;
599 if((info
->flash_id
& FLASH_TYPEMASK
) == FLASH_RAM
) {
600 for (sect
= s_first
; sect
<=s_last
; sect
++) {
601 int sector_size
=info
->size
/info
->sector_count
;
602 addr
= (uchar
*)(info
->start
[sect
]);
603 memset((void *)addr
, 0, sector_size
);
608 if ((s_first
< 0) || (s_first
> s_last
)) {
609 if (info
->flash_id
== FLASH_UNKNOWN
) {
610 printf ("- missing\n");
612 printf ("- no sectors to erase\n");
617 if ((info
->flash_id
&FLASH_VENDMASK
) == FLASH_MAN_INTEL
) {
618 return flash_erase_intel(info
,
619 (unsigned short)s_first
,
620 (unsigned short)s_last
);
624 if ((info
->flash_id
== FLASH_UNKNOWN
) ||
625 (info
->flash_id
> FLASH_AMD_COMP
)) {
626 printf ("Can't erase unknown flash type %08lx - aborted\n",
633 for (sect
=s_first
; sect
<=s_last
; ++sect
) {
634 if (info
->protect
[sect
]) {
640 printf ("- Warning: %d protected sectors will not be erased!\n",
648 /* Disable interrupts which might cause a timeout here */
649 flag
= disable_interrupts();
651 flash_cmd(info
->portwidth
,addr
,0x555,0xAA);
652 flash_cmd(info
->portwidth
,addr
,0x2AA,0x55);
653 flash_cmd(info
->portwidth
,addr
,0x555,0x80);
654 flash_cmd(info
->portwidth
,addr
,0x555,0xAA);
655 flash_cmd(info
->portwidth
,addr
,0x2AA,0x55);
657 /* Start erase on unprotected sectors */
658 for (sect
= s_first
; sect
<=s_last
; sect
++) {
659 if (info
->protect
[sect
] == 0) { /* not protected */
660 addr
= (uchar
*)(info
->start
[sect
]);
661 flash_cmd(info
->portwidth
,addr
,0,0x30);
666 /* re-enable interrupts if necessary */
670 /* wait at least 80us - let's wait 1 ms */
674 * We wait for the last triggered sector
679 start
= get_timer (0);
681 addr
= (volatile unsigned char *)(info
->start
[l_sect
]);
682 /* broken for 2x16: TODO */
683 while ((addr
[0] & 0x80) != 0x80) {
684 if ((now
= get_timer(start
)) > CONFIG_SYS_FLASH_ERASE_TOUT
) {
685 printf ("Timeout\n");
688 /* show that we're waiting */
689 if ((now
- last
) > 1000) { /* every second */
696 /* reset to read mode */
697 addr
= (volatile unsigned char *)info
->start
[0];
698 flash_cmd(info
->portwidth
,addr
,0,0xf0);
699 flash_cmd(info
->portwidth
,addr
,0,0xf0);
705 /*-----------------------------------------------------------------------
706 * Copy memory to flash, returns:
709 * 2 - Flash not erased
712 /* broken for 2x16: TODO */
714 write_buff (flash_info_t
*info
, uchar
*src
, ulong addr
, ulong cnt
)
719 if(info
->portwidth
==4) return 1;
721 if((info
->flash_id
& FLASH_TYPEMASK
) == FLASH_ROM
) return 0;
722 if((info
->flash_id
& FLASH_TYPEMASK
) == FLASH_RAM
) {
723 memcpy((void *)addr
, src
, cnt
);
727 wp
= (addr
& ~3); /* get lower word aligned address */
730 * handle unaligned start bytes
732 if ((l
= addr
- wp
) != 0) {
734 for (i
=0, cp
=wp
; i
<l
; ++i
, ++cp
) {
735 data
= (data
<< 8) | (*(uchar
*)cp
);
737 for (; i
<4 && cnt
>0; ++i
) {
738 data
= (data
<< 8) | *src
++;
742 for (; cnt
==0 && i
<4; ++i
, ++cp
) {
743 data
= (data
<< 8) | (*(uchar
*)cp
);
746 if ((rc
= write_word(info
, wp
, data
)) != 0) {
753 * handle word aligned part
757 for (i
=0; i
<4; ++i
) {
758 data
= (data
<< 8) | *src
++;
760 if ((rc
= write_word(info
, wp
, data
)) != 0) {
772 * handle unaligned tail bytes
775 for (i
=0, cp
=wp
; i
<4 && cnt
>0; ++i
, ++cp
) {
776 data
= (data
<< 8) | *src
++;
779 for (; i
<4; ++i
, ++cp
) {
780 data
= (data
<< 8) | (*(uchar
*)cp
);
783 return (write_word(info
, wp
, data
));
786 /*-----------------------------------------------------------------------
787 * Write a word to Flash, returns:
790 * 2 - Flash not erased
792 /* broken for 2x16: TODO */
794 write_word (flash_info_t
*info
, ulong dest
, ulong data
)
796 volatile unsigned char *addr
= (uchar
*)(info
->start
[0]);
800 if(info
->portwidth
==4) return 1;
802 if((info
->flash_id
& FLASH_TYPEMASK
) == FLASH_ROM
) return 1;
803 if((info
->flash_id
& FLASH_TYPEMASK
) == FLASH_RAM
) {
804 *(unsigned long *)dest
=data
;
807 if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_INTEL
) {
808 unsigned short low
= data
& 0xffff;
809 unsigned short hi
= (data
>> 16) & 0xffff;
810 int ret
= write_word_intel((bank_addr_t
)dest
, hi
);
812 if (!ret
) ret
= write_word_intel((bank_addr_t
)(dest
+2), low
);
817 /* Check if Flash is (sufficiently) erased */
818 if ((*((vu_long
*)dest
) & data
) != data
) {
821 /* Disable interrupts which might cause a timeout here */
822 flag
= disable_interrupts();
824 /* first, perform an unlock bypass command to speed up flash writes */
829 /* write each byte out */
830 for (i
= 0; i
< 4; i
++) {
831 char *data_ch
= (char *)&data
;
833 *(((char *)dest
)+i
) = data_ch
[i
];
834 udelay(10); /* XXX */
837 /* we're done, now do an unlock bypass reset */
841 /* re-enable interrupts if necessary */
845 /* data polling for D7 */
846 start
= get_timer (0);
847 while ((*((vu_long
*)dest
) & 0x00800080) != (data
& 0x00800080)) {
848 if (get_timer(start
) > CONFIG_SYS_FLASH_WRITE_TOUT
) {