3 * Stefan Roese, DENX Software Engineering, sr@denx.de.
5 * SPDX-License-Identifier: GPL-2.0+
9 #include <asm/processor.h>
11 flash_info_t flash_info
[CONFIG_SYS_MAX_FLASH_BANKS
]; /* info for FLASH chips */
16 static int write_word(flash_info_t
*info
, ulong dest
, ulong data
);
18 void flash_print_info(flash_info_t
*info
)
24 volatile unsigned long *flash
;
26 if (info
->flash_id
== FLASH_UNKNOWN
) {
27 printf ("missing or unknown FLASH type\n");
31 switch (info
->flash_id
& FLASH_VENDMASK
) {
32 case FLASH_MAN_AMD
: printf ("AMD "); break;
33 case FLASH_MAN_FUJ
: printf ("FUJITSU "); break;
34 case FLASH_MAN_SST
: printf ("SST "); break;
35 case FLASH_MAN_STM
: printf ("ST "); break;
36 case FLASH_MAN_EXCEL
: printf ("Excel Semiconductor "); break;
37 default: printf ("Unknown Vendor "); break;
40 switch (info
->flash_id
& FLASH_TYPEMASK
) {
41 case FLASH_AM400B
: printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
43 case FLASH_AM400T
: printf ("AM29LV400T (4 Mbit, top boot sector)\n");
45 case FLASH_AM800B
: printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
47 case FLASH_AM800T
: printf ("AM29LV800T (8 Mbit, top boot sector)\n");
49 case FLASH_AM160B
: printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
51 case FLASH_AM160T
: printf ("AM29LV160T (16 Mbit, top boot sector)\n");
53 case FLASH_AM320T
: printf ("AM29LV320T (32 M, top sector)\n");
55 case FLASH_AM320B
: printf ("AM29LV320B (32 M, bottom sector)\n");
57 case FLASH_AMDL322T
: printf ("AM29DL322T (32 M, top sector)\n");
59 case FLASH_AMDL322B
: printf ("AM29DL322B (32 M, bottom sector)\n");
61 case FLASH_AMDL323T
: printf ("AM29DL323T (32 M, top sector)\n");
63 case FLASH_AMDL323B
: printf ("AM29DL323B (32 M, bottom sector)\n");
65 case FLASH_SST020
: printf ("SST39LF/VF020 (2 Mbit, uniform sector size)\n");
67 case FLASH_SST040
: printf ("SST39LF/VF040 (4 Mbit, uniform sector size)\n");
69 default: printf ("Unknown Chip Type\n");
73 printf (" Size: %ld MB in %d Sectors\n",
74 info
->size
>> 20, info
->sector_count
);
76 printf (" Sector Start Addresses:");
77 for (i
=0; i
<info
->sector_count
; ++i
) {
78 #ifdef CONFIG_SYS_FLASH_EMPTY_INFO
80 * Check if whole sector is erased
82 if (i
!= (info
->sector_count
-1))
83 size
= info
->start
[i
+1] - info
->start
[i
];
85 size
= info
->start
[0] + info
->size
- info
->start
[i
];
87 flash
= (volatile unsigned long *)info
->start
[i
];
88 size
= size
>> 2; /* divide by 4 for longword access */
89 for (k
=0; k
<size
; k
++) {
90 if (*flash
++ != 0xffffffff) {
98 /* print empty and read-only info */
102 info
->protect
[i
] ? "RO " : " ");
108 info
->protect
[i
] ? " (RO)" : " ");
117 * The following code cannot be run from FLASH!
119 static ulong
flash_get_size(vu_long
*addr
, flash_info_t
*info
)
123 CONFIG_SYS_FLASH_WORD_SIZE value
;
124 ulong base
= (ulong
)addr
;
125 volatile CONFIG_SYS_FLASH_WORD_SIZE
*addr2
= (CONFIG_SYS_FLASH_WORD_SIZE
*)addr
;
127 /* Write auto select command: read Manufacturer ID */
128 addr2
[CONFIG_SYS_FLASH_ADDR0
] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00AA00AA;
129 addr2
[CONFIG_SYS_FLASH_ADDR1
] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00550055;
130 addr2
[CONFIG_SYS_FLASH_ADDR0
] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00900090;
132 value
= addr2
[CONFIG_SYS_FLASH_READ0
];
135 case (CONFIG_SYS_FLASH_WORD_SIZE
)AMD_MANUFACT
:
136 info
->flash_id
= FLASH_MAN_AMD
;
138 case (CONFIG_SYS_FLASH_WORD_SIZE
)FUJ_MANUFACT
:
139 info
->flash_id
= FLASH_MAN_FUJ
;
141 case (CONFIG_SYS_FLASH_WORD_SIZE
)SST_MANUFACT
:
142 info
->flash_id
= FLASH_MAN_SST
;
144 case (CONFIG_SYS_FLASH_WORD_SIZE
)STM_MANUFACT
:
145 info
->flash_id
= FLASH_MAN_STM
;
147 case (CONFIG_SYS_FLASH_WORD_SIZE
)EXCEL_MANUFACT
:
148 info
->flash_id
= FLASH_MAN_EXCEL
;
151 info
->flash_id
= FLASH_UNKNOWN
;
152 info
->sector_count
= 0;
154 return (0); /* no or unknown flash */
157 value
= addr2
[CONFIG_SYS_FLASH_READ1
]; /* device ID */
160 case (CONFIG_SYS_FLASH_WORD_SIZE
)AMD_ID_LV400T
:
161 info
->flash_id
+= FLASH_AM400T
;
162 info
->sector_count
= 11;
163 info
->size
= 0x00080000;
164 break; /* => 0.5 MB */
166 case (CONFIG_SYS_FLASH_WORD_SIZE
)AMD_ID_LV400B
:
167 info
->flash_id
+= FLASH_AM400B
;
168 info
->sector_count
= 11;
169 info
->size
= 0x00080000;
170 break; /* => 0.5 MB */
172 case (CONFIG_SYS_FLASH_WORD_SIZE
)AMD_ID_LV800T
:
173 info
->flash_id
+= FLASH_AM800T
;
174 info
->sector_count
= 19;
175 info
->size
= 0x00100000;
178 case (CONFIG_SYS_FLASH_WORD_SIZE
)AMD_ID_LV800B
:
179 info
->flash_id
+= FLASH_AM800B
;
180 info
->sector_count
= 19;
181 info
->size
= 0x00100000;
184 case (CONFIG_SYS_FLASH_WORD_SIZE
)AMD_ID_LV160T
:
185 info
->flash_id
+= FLASH_AM160T
;
186 info
->sector_count
= 35;
187 info
->size
= 0x00200000;
190 case (CONFIG_SYS_FLASH_WORD_SIZE
)AMD_ID_LV160B
:
191 info
->flash_id
+= FLASH_AM160B
;
192 info
->sector_count
= 35;
193 info
->size
= 0x00200000;
196 case (CONFIG_SYS_FLASH_WORD_SIZE
)AMD_ID_LV320T
:
197 info
->flash_id
+= FLASH_AM320T
;
198 info
->sector_count
= 71;
199 info
->size
= 0x00400000; break; /* => 4 MB */
201 case (CONFIG_SYS_FLASH_WORD_SIZE
)AMD_ID_LV320B
:
202 info
->flash_id
+= FLASH_AM320B
;
203 info
->sector_count
= 71;
204 info
->size
= 0x00400000; break; /* => 4 MB */
206 case (CONFIG_SYS_FLASH_WORD_SIZE
)AMD_ID_DL322T
:
207 info
->flash_id
+= FLASH_AMDL322T
;
208 info
->sector_count
= 71;
209 info
->size
= 0x00400000; break; /* => 4 MB */
211 case (CONFIG_SYS_FLASH_WORD_SIZE
)AMD_ID_DL322B
:
212 info
->flash_id
+= FLASH_AMDL322B
;
213 info
->sector_count
= 71;
214 info
->size
= 0x00400000; break; /* => 4 MB */
216 case (CONFIG_SYS_FLASH_WORD_SIZE
)AMD_ID_DL323T
:
217 info
->flash_id
+= FLASH_AMDL323T
;
218 info
->sector_count
= 71;
219 info
->size
= 0x00400000; break; /* => 4 MB */
221 case (CONFIG_SYS_FLASH_WORD_SIZE
)AMD_ID_DL323B
:
222 info
->flash_id
+= FLASH_AMDL323B
;
223 info
->sector_count
= 71;
224 info
->size
= 0x00400000; break; /* => 4 MB */
226 case (CONFIG_SYS_FLASH_WORD_SIZE
)SST_ID_xF020
:
227 info
->flash_id
+= FLASH_SST020
;
228 info
->sector_count
= 64;
229 info
->size
= 0x00040000;
230 break; /* => 256 kB */
232 case (CONFIG_SYS_FLASH_WORD_SIZE
)SST_ID_xF040
:
233 info
->flash_id
+= FLASH_SST040
;
234 info
->sector_count
= 128;
235 info
->size
= 0x00080000;
236 break; /* => 512 kB */
239 info
->flash_id
= FLASH_UNKNOWN
;
240 return (0); /* => no or unknown flash */
244 /* set up sector start address table */
245 if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_SST
) {
246 for (i
= 0; i
< info
->sector_count
; i
++)
247 info
->start
[i
] = base
+ (i
* 0x00001000);
248 } else if (((info
->flash_id
& FLASH_TYPEMASK
) == FLASH_AMDL322B
) ||
249 ((info
->flash_id
& FLASH_TYPEMASK
) == FLASH_AMDL323B
) ||
250 ((info
->flash_id
& FLASH_TYPEMASK
) == FLASH_AM320B
) ||
251 ((info
->flash_id
& FLASH_TYPEMASK
) == FLASH_AMDL324B
)) {
252 /* set sector offsets for bottom boot block type */
253 for (i
=0; i
<8; ++i
) { /* 8 x 8k boot sectors */
254 info
->start
[i
] = base
;
257 while (i
< info
->sector_count
) { /* 64k regular sectors */
258 info
->start
[i
] = base
;
262 } else if (((info
->flash_id
& FLASH_TYPEMASK
) == FLASH_AMDL322T
) ||
263 ((info
->flash_id
& FLASH_TYPEMASK
) == FLASH_AMDL323T
) ||
264 ((info
->flash_id
& FLASH_TYPEMASK
) == FLASH_AM320T
) ||
265 ((info
->flash_id
& FLASH_TYPEMASK
) == FLASH_AMDL324T
)) {
266 /* set sector offsets for top boot block type */
268 i
= info
->sector_count
;
269 for (n
=0; n
<8; ++n
) { /* 8 x 8k boot sectors */
272 info
->start
[i
] = base
;
274 while (i
> 0) { /* 64k regular sectors */
277 info
->start
[i
] = base
;
280 if (info
->flash_id
& FLASH_BTYPE
) {
281 /* set sector offsets for bottom boot block type */
282 info
->start
[0] = base
+ 0x00000000;
283 info
->start
[1] = base
+ 0x00004000;
284 info
->start
[2] = base
+ 0x00006000;
285 info
->start
[3] = base
+ 0x00008000;
286 for (i
= 4; i
< info
->sector_count
; i
++) {
287 info
->start
[i
] = base
+ (i
* 0x00010000) - 0x00030000;
290 /* set sector offsets for top boot block type */
291 i
= info
->sector_count
- 1;
292 info
->start
[i
--] = base
+ info
->size
- 0x00004000;
293 info
->start
[i
--] = base
+ info
->size
- 0x00006000;
294 info
->start
[i
--] = base
+ info
->size
- 0x00008000;
295 for (; i
>= 0; i
--) {
296 info
->start
[i
] = base
+ i
* 0x00010000;
301 /* check for protected sectors */
302 for (i
= 0; i
< info
->sector_count
; i
++) {
303 /* read sector protection at sector address, (A7 .. A0) = 0x02 */
304 /* D0 = 1 if protected */
305 addr2
= (volatile CONFIG_SYS_FLASH_WORD_SIZE
*)(info
->start
[i
]);
306 if ((info
->flash_id
& FLASH_VENDMASK
) != FLASH_MAN_AMD
)
307 info
->protect
[i
] = 0;
309 info
->protect
[i
] = addr2
[CONFIG_SYS_FLASH_READ2
] & 1;
313 * Prevent writes to uninitialized FLASH.
315 if (info
->flash_id
!= FLASH_UNKNOWN
) {
316 addr2
= (CONFIG_SYS_FLASH_WORD_SIZE
*)info
->start
[0];
317 *addr2
= (CONFIG_SYS_FLASH_WORD_SIZE
)0x00F000F0; /* reset bank */
324 int flash_erase(flash_info_t
*info
, int s_first
, int s_last
)
326 volatile CONFIG_SYS_FLASH_WORD_SIZE
*addr
= (CONFIG_SYS_FLASH_WORD_SIZE
*)(info
->start
[0]);
327 volatile CONFIG_SYS_FLASH_WORD_SIZE
*addr2
;
328 int flag
, prot
, sect
, l_sect
;
329 ulong start
, now
, last
;
331 if ((s_first
< 0) || (s_first
> s_last
)) {
332 if (info
->flash_id
== FLASH_UNKNOWN
)
333 printf ("- missing\n");
335 printf ("- no sectors to erase\n");
339 if (info
->flash_id
== FLASH_UNKNOWN
) {
340 printf ("Can't erase unknown flash type - aborted\n");
345 for (sect
=s_first
; sect
<=s_last
; ++sect
)
346 if (info
->protect
[sect
])
350 printf ("- Warning: %d protected sectors will not be erased!\n", prot
);
356 /* Disable interrupts which might cause a timeout here */
357 flag
= disable_interrupts();
359 /* Start erase on unprotected sectors */
360 for (sect
= s_first
; sect
<=s_last
; sect
++) {
361 if (info
->protect
[sect
] == 0) { /* not protected */
362 addr2
= (CONFIG_SYS_FLASH_WORD_SIZE
*)(info
->start
[sect
]);
363 if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_SST
) {
364 addr
[CONFIG_SYS_FLASH_ADDR0
] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00AA00AA;
365 addr
[CONFIG_SYS_FLASH_ADDR1
] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00550055;
366 addr
[CONFIG_SYS_FLASH_ADDR0
] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00800080;
367 addr
[CONFIG_SYS_FLASH_ADDR0
] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00AA00AA;
368 addr
[CONFIG_SYS_FLASH_ADDR1
] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00550055;
369 addr2
[0] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00300030; /* sector erase */
371 /* re-enable interrupts if necessary */
377 /* data polling for D7 */
378 start
= get_timer (0);
379 while ((addr2
[0] & (CONFIG_SYS_FLASH_WORD_SIZE
)0x00800080) !=
380 (CONFIG_SYS_FLASH_WORD_SIZE
)0x00800080) {
381 if (get_timer(start
) > CONFIG_SYS_FLASH_WRITE_TOUT
)
385 if (sect
== s_first
) {
386 addr
[CONFIG_SYS_FLASH_ADDR0
] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00AA00AA;
387 addr
[CONFIG_SYS_FLASH_ADDR1
] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00550055;
388 addr
[CONFIG_SYS_FLASH_ADDR0
] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00800080;
389 addr
[CONFIG_SYS_FLASH_ADDR0
] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00AA00AA;
390 addr
[CONFIG_SYS_FLASH_ADDR1
] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00550055;
392 addr2
[0] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00300030; /* sector erase */
398 /* re-enable interrupts if necessary */
402 /* wait at least 80us - let's wait 1 ms */
406 * We wait for the last triggered sector
411 start
= get_timer (0);
413 addr
= (CONFIG_SYS_FLASH_WORD_SIZE
*)(info
->start
[l_sect
]);
414 while ((addr
[0] & (CONFIG_SYS_FLASH_WORD_SIZE
)0x00800080) != (CONFIG_SYS_FLASH_WORD_SIZE
)0x00800080) {
415 if ((now
= get_timer(start
)) > CONFIG_SYS_FLASH_ERASE_TOUT
) {
416 printf ("Timeout\n");
419 /* show that we're waiting */
420 if ((now
- last
) > 1000) { /* every second */
427 /* reset to read mode */
428 addr
= (CONFIG_SYS_FLASH_WORD_SIZE
*)info
->start
[0];
429 addr
[0] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00F000F0; /* reset bank */
436 * Copy memory to flash, returns:
439 * 2 - Flash not erased
441 int write_buff(flash_info_t
*info
, uchar
*src
, ulong addr
, ulong cnt
)
446 wp
= (addr
& ~3); /* get lower word aligned address */
449 * handle unaligned start bytes
451 if ((l
= addr
- wp
) != 0) {
453 for (i
=0, cp
=wp
; i
<l
; ++i
, ++cp
) {
454 data
= (data
<< 8) | (*(uchar
*)cp
);
456 for (; i
<4 && cnt
>0; ++i
) {
457 data
= (data
<< 8) | *src
++;
461 for (; cnt
==0 && i
<4; ++i
, ++cp
) {
462 data
= (data
<< 8) | (*(uchar
*)cp
);
465 if ((rc
= write_word(info
, wp
, data
)) != 0) {
472 * handle word aligned part
477 data
= (data
<< 8) | *src
++;
478 if ((rc
= write_word(info
, wp
, data
)) != 0)
488 * handle unaligned tail bytes
491 for (i
=0, cp
=wp
; i
<4 && cnt
>0; ++i
, ++cp
) {
492 data
= (data
<< 8) | *src
++;
495 for (; i
<4; ++i
, ++cp
)
496 data
= (data
<< 8) | (*(uchar
*)cp
);
498 return (write_word(info
, wp
, data
));
502 * Write a word to Flash, returns:
505 * 2 - Flash not erased
507 static int write_word(flash_info_t
*info
, ulong dest
, ulong data
)
509 volatile CONFIG_SYS_FLASH_WORD_SIZE
*addr2
= (CONFIG_SYS_FLASH_WORD_SIZE
*)(info
->start
[0]);
510 volatile CONFIG_SYS_FLASH_WORD_SIZE
*dest2
= (CONFIG_SYS_FLASH_WORD_SIZE
*)dest
;
511 volatile CONFIG_SYS_FLASH_WORD_SIZE
*data2
= (CONFIG_SYS_FLASH_WORD_SIZE
*)&data
;
516 /* Check if Flash is (sufficiently) erased */
517 if ((*((vu_long
*)dest
) & data
) != data
)
520 /* Disable interrupts which might cause a timeout here */
521 flag
= disable_interrupts();
523 for (i
=0; i
<4/sizeof(CONFIG_SYS_FLASH_WORD_SIZE
); i
++) {
524 addr2
[CONFIG_SYS_FLASH_ADDR0
] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00AA00AA;
525 addr2
[CONFIG_SYS_FLASH_ADDR1
] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00550055;
526 addr2
[CONFIG_SYS_FLASH_ADDR0
] = (CONFIG_SYS_FLASH_WORD_SIZE
)0x00A000A0;
530 /* re-enable interrupts if necessary */
534 /* data polling for D7 */
535 start
= get_timer (0);
536 while ((dest2
[i
] & (CONFIG_SYS_FLASH_WORD_SIZE
)0x00800080) !=
537 (data2
[i
] & (CONFIG_SYS_FLASH_WORD_SIZE
)0x00800080)) {
538 if (get_timer(start
) > CONFIG_SYS_FLASH_WRITE_TOUT
)