3 * Stefan Roese, DENX Software Engineering, sr@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,
25 #include <asm/processor.h>
27 flash_info_t flash_info
[CONFIG_SYS_MAX_FLASH_BANKS
]; /* info for FLASH chips */
32 static int write_word(flash_info_t
*info
, ulong dest
, ulong data
);
34 void flash_print_info(flash_info_t
*info
)
40 volatile unsigned long *flash
;
42 if (info
->flash_id
== FLASH_UNKNOWN
) {
43 printf ("missing or unknown FLASH type\n");
47 switch (info
->flash_id
& FLASH_VENDMASK
) {
48 case FLASH_MAN_AMD
: printf ("AMD "); break;
49 case FLASH_MAN_FUJ
: printf ("FUJITSU "); break;
50 case FLASH_MAN_SST
: printf ("SST "); break;
51 case FLASH_MAN_STM
: printf ("ST "); break;
52 case FLASH_MAN_EXCEL
: printf ("Excel Semiconductor "); break;
53 default: printf ("Unknown Vendor "); break;
56 switch (info
->flash_id
& FLASH_TYPEMASK
) {
57 case FLASH_AM400B
: printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
59 case FLASH_AM400T
: printf ("AM29LV400T (4 Mbit, top boot sector)\n");
61 case FLASH_AM800B
: printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
63 case FLASH_AM800T
: printf ("AM29LV800T (8 Mbit, top boot sector)\n");
65 case FLASH_AM160B
: printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
67 case FLASH_AM160T
: printf ("AM29LV160T (16 Mbit, top boot sector)\n");
69 case FLASH_AM320T
: printf ("AM29LV320T (32 M, top sector)\n");
71 case FLASH_AM320B
: printf ("AM29LV320B (32 M, bottom sector)\n");
73 case FLASH_AMDL322T
: printf ("AM29DL322T (32 M, top sector)\n");
75 case FLASH_AMDL322B
: printf ("AM29DL322B (32 M, bottom sector)\n");
77 case FLASH_AMDL323T
: printf ("AM29DL323T (32 M, top sector)\n");
79 case FLASH_AMDL323B
: printf ("AM29DL323B (32 M, bottom sector)\n");
81 case FLASH_SST020
: printf ("SST39LF/VF020 (2 Mbit, uniform sector size)\n");
83 case FLASH_SST040
: printf ("SST39LF/VF040 (4 Mbit, uniform sector size)\n");
85 default: printf ("Unknown Chip Type\n");
89 printf (" Size: %ld MB in %d Sectors\n",
90 info
->size
>> 20, info
->sector_count
);
92 printf (" Sector Start Addresses:");
93 for (i
=0; i
<info
->sector_count
; ++i
) {
94 #ifdef CONFIG_SYS_FLASH_EMPTY_INFO
96 * Check if whole sector is erased
98 if (i
!= (info
->sector_count
-1))
99 size
= info
->start
[i
+1] - info
->start
[i
];
101 size
= info
->start
[0] + info
->size
- info
->start
[i
];
103 flash
= (volatile unsigned long *)info
->start
[i
];
104 size
= size
>> 2; /* divide by 4 for longword access */
105 for (k
=0; k
<size
; k
++) {
106 if (*flash
++ != 0xffffffff) {
114 /* print empty and read-only info */
115 printf (" %08lX%s%s",
118 info
->protect
[i
] ? "RO " : " ");
124 info
->protect
[i
] ? " (RO)" : " ");
133 * The following code cannot be run from FLASH!
135 static ulong
flash_get_size(vu_long
*addr
, flash_info_t
*info
)
139 CONFIG_SYS_FLASH_WORD_SIZE value
;
140 ulong base
= (ulong
)addr
;
141 volatile CONFIG_SYS_FLASH_WORD_SIZE
*addr2
= (CONFIG_SYS_FLASH_WORD_SIZE
*)addr
;
143 /* Write auto select command: read Manufacturer ID */
144 addr2
[CONFIG_SYS_FLASH_ADDR0
] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00AA00AA;
145 addr2
[CONFIG_SYS_FLASH_ADDR1
] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00550055;
146 addr2
[CONFIG_SYS_FLASH_ADDR0
] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00900090;
148 value
= addr2
[CONFIG_SYS_FLASH_READ0
];
151 case (CONFIG_SYS_FLASH_WORD_SIZE
)AMD_MANUFACT
:
152 info
->flash_id
= FLASH_MAN_AMD
;
154 case (CONFIG_SYS_FLASH_WORD_SIZE
)FUJ_MANUFACT
:
155 info
->flash_id
= FLASH_MAN_FUJ
;
157 case (CONFIG_SYS_FLASH_WORD_SIZE
)SST_MANUFACT
:
158 info
->flash_id
= FLASH_MAN_SST
;
160 case (CONFIG_SYS_FLASH_WORD_SIZE
)STM_MANUFACT
:
161 info
->flash_id
= FLASH_MAN_STM
;
163 case (CONFIG_SYS_FLASH_WORD_SIZE
)EXCEL_MANUFACT
:
164 info
->flash_id
= FLASH_MAN_EXCEL
;
167 info
->flash_id
= FLASH_UNKNOWN
;
168 info
->sector_count
= 0;
170 return (0); /* no or unknown flash */
173 value
= addr2
[CONFIG_SYS_FLASH_READ1
]; /* device ID */
176 case (CONFIG_SYS_FLASH_WORD_SIZE
)AMD_ID_LV400T
:
177 info
->flash_id
+= FLASH_AM400T
;
178 info
->sector_count
= 11;
179 info
->size
= 0x00080000;
180 break; /* => 0.5 MB */
182 case (CONFIG_SYS_FLASH_WORD_SIZE
)AMD_ID_LV400B
:
183 info
->flash_id
+= FLASH_AM400B
;
184 info
->sector_count
= 11;
185 info
->size
= 0x00080000;
186 break; /* => 0.5 MB */
188 case (CONFIG_SYS_FLASH_WORD_SIZE
)AMD_ID_LV800T
:
189 info
->flash_id
+= FLASH_AM800T
;
190 info
->sector_count
= 19;
191 info
->size
= 0x00100000;
194 case (CONFIG_SYS_FLASH_WORD_SIZE
)AMD_ID_LV800B
:
195 info
->flash_id
+= FLASH_AM800B
;
196 info
->sector_count
= 19;
197 info
->size
= 0x00100000;
200 case (CONFIG_SYS_FLASH_WORD_SIZE
)AMD_ID_LV160T
:
201 info
->flash_id
+= FLASH_AM160T
;
202 info
->sector_count
= 35;
203 info
->size
= 0x00200000;
206 case (CONFIG_SYS_FLASH_WORD_SIZE
)AMD_ID_LV160B
:
207 info
->flash_id
+= FLASH_AM160B
;
208 info
->sector_count
= 35;
209 info
->size
= 0x00200000;
212 case (CONFIG_SYS_FLASH_WORD_SIZE
)AMD_ID_LV320T
:
213 info
->flash_id
+= FLASH_AM320T
;
214 info
->sector_count
= 71;
215 info
->size
= 0x00400000; break; /* => 4 MB */
217 case (CONFIG_SYS_FLASH_WORD_SIZE
)AMD_ID_LV320B
:
218 info
->flash_id
+= FLASH_AM320B
;
219 info
->sector_count
= 71;
220 info
->size
= 0x00400000; break; /* => 4 MB */
222 case (CONFIG_SYS_FLASH_WORD_SIZE
)AMD_ID_DL322T
:
223 info
->flash_id
+= FLASH_AMDL322T
;
224 info
->sector_count
= 71;
225 info
->size
= 0x00400000; break; /* => 4 MB */
227 case (CONFIG_SYS_FLASH_WORD_SIZE
)AMD_ID_DL322B
:
228 info
->flash_id
+= FLASH_AMDL322B
;
229 info
->sector_count
= 71;
230 info
->size
= 0x00400000; break; /* => 4 MB */
232 case (CONFIG_SYS_FLASH_WORD_SIZE
)AMD_ID_DL323T
:
233 info
->flash_id
+= FLASH_AMDL323T
;
234 info
->sector_count
= 71;
235 info
->size
= 0x00400000; break; /* => 4 MB */
237 case (CONFIG_SYS_FLASH_WORD_SIZE
)AMD_ID_DL323B
:
238 info
->flash_id
+= FLASH_AMDL323B
;
239 info
->sector_count
= 71;
240 info
->size
= 0x00400000; break; /* => 4 MB */
242 case (CONFIG_SYS_FLASH_WORD_SIZE
)SST_ID_xF020
:
243 info
->flash_id
+= FLASH_SST020
;
244 info
->sector_count
= 64;
245 info
->size
= 0x00040000;
246 break; /* => 256 kB */
248 case (CONFIG_SYS_FLASH_WORD_SIZE
)SST_ID_xF040
:
249 info
->flash_id
+= FLASH_SST040
;
250 info
->sector_count
= 128;
251 info
->size
= 0x00080000;
252 break; /* => 512 kB */
255 info
->flash_id
= FLASH_UNKNOWN
;
256 return (0); /* => no or unknown flash */
260 /* set up sector start address table */
261 if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_SST
) {
262 for (i
= 0; i
< info
->sector_count
; i
++)
263 info
->start
[i
] = base
+ (i
* 0x00001000);
264 } else if (((info
->flash_id
& FLASH_TYPEMASK
) == FLASH_AMDL322B
) ||
265 ((info
->flash_id
& FLASH_TYPEMASK
) == FLASH_AMDL323B
) ||
266 ((info
->flash_id
& FLASH_TYPEMASK
) == FLASH_AM320B
) ||
267 ((info
->flash_id
& FLASH_TYPEMASK
) == FLASH_AMDL324B
)) {
268 /* set sector offsets for bottom boot block type */
269 for (i
=0; i
<8; ++i
) { /* 8 x 8k boot sectors */
270 info
->start
[i
] = base
;
273 while (i
< info
->sector_count
) { /* 64k regular sectors */
274 info
->start
[i
] = base
;
278 } else if (((info
->flash_id
& FLASH_TYPEMASK
) == FLASH_AMDL322T
) ||
279 ((info
->flash_id
& FLASH_TYPEMASK
) == FLASH_AMDL323T
) ||
280 ((info
->flash_id
& FLASH_TYPEMASK
) == FLASH_AM320T
) ||
281 ((info
->flash_id
& FLASH_TYPEMASK
) == FLASH_AMDL324T
)) {
282 /* set sector offsets for top boot block type */
284 i
= info
->sector_count
;
285 for (n
=0; n
<8; ++n
) { /* 8 x 8k boot sectors */
288 info
->start
[i
] = base
;
290 while (i
> 0) { /* 64k regular sectors */
293 info
->start
[i
] = base
;
296 if (info
->flash_id
& FLASH_BTYPE
) {
297 /* set sector offsets for bottom boot block type */
298 info
->start
[0] = base
+ 0x00000000;
299 info
->start
[1] = base
+ 0x00004000;
300 info
->start
[2] = base
+ 0x00006000;
301 info
->start
[3] = base
+ 0x00008000;
302 for (i
= 4; i
< info
->sector_count
; i
++) {
303 info
->start
[i
] = base
+ (i
* 0x00010000) - 0x00030000;
306 /* set sector offsets for top boot block type */
307 i
= info
->sector_count
- 1;
308 info
->start
[i
--] = base
+ info
->size
- 0x00004000;
309 info
->start
[i
--] = base
+ info
->size
- 0x00006000;
310 info
->start
[i
--] = base
+ info
->size
- 0x00008000;
311 for (; i
>= 0; i
--) {
312 info
->start
[i
] = base
+ i
* 0x00010000;
317 /* check for protected sectors */
318 for (i
= 0; i
< info
->sector_count
; i
++) {
319 /* read sector protection at sector address, (A7 .. A0) = 0x02 */
320 /* D0 = 1 if protected */
321 addr2
= (volatile CONFIG_SYS_FLASH_WORD_SIZE
*)(info
->start
[i
]);
322 if ((info
->flash_id
& FLASH_VENDMASK
) != FLASH_MAN_AMD
)
323 info
->protect
[i
] = 0;
325 info
->protect
[i
] = addr2
[CONFIG_SYS_FLASH_READ2
] & 1;
329 * Prevent writes to uninitialized FLASH.
331 if (info
->flash_id
!= FLASH_UNKNOWN
) {
332 addr2
= (CONFIG_SYS_FLASH_WORD_SIZE
*)info
->start
[0];
333 *addr2
= (CONFIG_SYS_FLASH_WORD_SIZE
)0x00F000F0; /* reset bank */
340 int flash_erase(flash_info_t
*info
, int s_first
, int s_last
)
342 volatile CONFIG_SYS_FLASH_WORD_SIZE
*addr
= (CONFIG_SYS_FLASH_WORD_SIZE
*)(info
->start
[0]);
343 volatile CONFIG_SYS_FLASH_WORD_SIZE
*addr2
;
344 int flag
, prot
, sect
, l_sect
;
345 ulong start
, now
, last
;
347 if ((s_first
< 0) || (s_first
> s_last
)) {
348 if (info
->flash_id
== FLASH_UNKNOWN
)
349 printf ("- missing\n");
351 printf ("- no sectors to erase\n");
355 if (info
->flash_id
== FLASH_UNKNOWN
) {
356 printf ("Can't erase unknown flash type - aborted\n");
361 for (sect
=s_first
; sect
<=s_last
; ++sect
)
362 if (info
->protect
[sect
])
366 printf ("- Warning: %d protected sectors will not be erased!\n", prot
);
372 /* Disable interrupts which might cause a timeout here */
373 flag
= disable_interrupts();
375 /* Start erase on unprotected sectors */
376 for (sect
= s_first
; sect
<=s_last
; sect
++) {
377 if (info
->protect
[sect
] == 0) { /* not protected */
378 addr2
= (CONFIG_SYS_FLASH_WORD_SIZE
*)(info
->start
[sect
]);
379 if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_SST
) {
380 addr
[CONFIG_SYS_FLASH_ADDR0
] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00AA00AA;
381 addr
[CONFIG_SYS_FLASH_ADDR1
] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00550055;
382 addr
[CONFIG_SYS_FLASH_ADDR0
] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00800080;
383 addr
[CONFIG_SYS_FLASH_ADDR0
] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00AA00AA;
384 addr
[CONFIG_SYS_FLASH_ADDR1
] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00550055;
385 addr2
[0] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00300030; /* sector erase */
387 /* re-enable interrupts if necessary */
393 /* data polling for D7 */
394 start
= get_timer (0);
395 while ((addr2
[0] & (CONFIG_SYS_FLASH_WORD_SIZE
)0x00800080) !=
396 (CONFIG_SYS_FLASH_WORD_SIZE
)0x00800080) {
397 if (get_timer(start
) > CONFIG_SYS_FLASH_WRITE_TOUT
)
401 if (sect
== s_first
) {
402 addr
[CONFIG_SYS_FLASH_ADDR0
] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00AA00AA;
403 addr
[CONFIG_SYS_FLASH_ADDR1
] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00550055;
404 addr
[CONFIG_SYS_FLASH_ADDR0
] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00800080;
405 addr
[CONFIG_SYS_FLASH_ADDR0
] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00AA00AA;
406 addr
[CONFIG_SYS_FLASH_ADDR1
] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00550055;
408 addr2
[0] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00300030; /* sector erase */
414 /* re-enable interrupts if necessary */
418 /* wait at least 80us - let's wait 1 ms */
422 * We wait for the last triggered sector
427 start
= get_timer (0);
429 addr
= (CONFIG_SYS_FLASH_WORD_SIZE
*)(info
->start
[l_sect
]);
430 while ((addr
[0] & (CONFIG_SYS_FLASH_WORD_SIZE
)0x00800080) != (CONFIG_SYS_FLASH_WORD_SIZE
)0x00800080) {
431 if ((now
= get_timer(start
)) > CONFIG_SYS_FLASH_ERASE_TOUT
) {
432 printf ("Timeout\n");
435 /* show that we're waiting */
436 if ((now
- last
) > 1000) { /* every second */
443 /* reset to read mode */
444 addr
= (CONFIG_SYS_FLASH_WORD_SIZE
*)info
->start
[0];
445 addr
[0] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00F000F0; /* reset bank */
452 * Copy memory to flash, returns:
455 * 2 - Flash not erased
457 int write_buff(flash_info_t
*info
, uchar
*src
, ulong addr
, ulong cnt
)
462 wp
= (addr
& ~3); /* get lower word aligned address */
465 * handle unaligned start bytes
467 if ((l
= addr
- wp
) != 0) {
469 for (i
=0, cp
=wp
; i
<l
; ++i
, ++cp
) {
470 data
= (data
<< 8) | (*(uchar
*)cp
);
472 for (; i
<4 && cnt
>0; ++i
) {
473 data
= (data
<< 8) | *src
++;
477 for (; cnt
==0 && i
<4; ++i
, ++cp
) {
478 data
= (data
<< 8) | (*(uchar
*)cp
);
481 if ((rc
= write_word(info
, wp
, data
)) != 0) {
488 * handle word aligned part
493 data
= (data
<< 8) | *src
++;
494 if ((rc
= write_word(info
, wp
, data
)) != 0)
504 * handle unaligned tail bytes
507 for (i
=0, cp
=wp
; i
<4 && cnt
>0; ++i
, ++cp
) {
508 data
= (data
<< 8) | *src
++;
511 for (; i
<4; ++i
, ++cp
)
512 data
= (data
<< 8) | (*(uchar
*)cp
);
514 return (write_word(info
, wp
, data
));
518 * Write a word to Flash, returns:
521 * 2 - Flash not erased
523 static int write_word(flash_info_t
*info
, ulong dest
, ulong data
)
525 volatile CONFIG_SYS_FLASH_WORD_SIZE
*addr2
= (CONFIG_SYS_FLASH_WORD_SIZE
*)(info
->start
[0]);
526 volatile CONFIG_SYS_FLASH_WORD_SIZE
*dest2
= (CONFIG_SYS_FLASH_WORD_SIZE
*)dest
;
527 volatile CONFIG_SYS_FLASH_WORD_SIZE
*data2
= (CONFIG_SYS_FLASH_WORD_SIZE
*)&data
;
532 /* Check if Flash is (sufficiently) erased */
533 if ((*((vu_long
*)dest
) & data
) != data
)
536 /* Disable interrupts which might cause a timeout here */
537 flag
= disable_interrupts();
539 for (i
=0; i
<4/sizeof(CONFIG_SYS_FLASH_WORD_SIZE
); i
++) {
540 addr2
[CONFIG_SYS_FLASH_ADDR0
] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00AA00AA;
541 addr2
[CONFIG_SYS_FLASH_ADDR1
] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00550055;
542 addr2
[CONFIG_SYS_FLASH_ADDR0
] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00A000A0;
546 /* re-enable interrupts if necessary */
550 /* data polling for D7 */
551 start
= get_timer (0);
552 while ((dest2
[i
] & (CONFIG_SYS_FLASH_WORD_SIZE
)0x00800080) !=
553 (data2
[i
] & (CONFIG_SYS_FLASH_WORD_SIZE
)0x00800080)) {
554 if (get_timer(start
) > CONFIG_SYS_FLASH_WRITE_TOUT
)