6 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
8 * See file CREDITS for list of people who contributed to this
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of
14 * the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
29 #include <asm/u-boot.h>
30 #include <asm/processor.h>
32 flash_info_t flash_info
[CONFIG_SYS_MAX_FLASH_BANKS
]; /* info for FLASH chips */
35 #define FLASH_WORD_SIZE unsigned long
36 #define FLASH_ID_MASK 0xFFFFFFFF
38 /*-----------------------------------------------------------------------
41 /* stolen from esteem192e/flash.c */
42 ulong
flash_get_size (volatile FLASH_WORD_SIZE
*addr
, flash_info_t
*info
);
44 static int write_word (flash_info_t
*info
, ulong dest
, ulong data
);
45 static void flash_get_offsets (ulong base
, flash_info_t
*info
);
48 /*-----------------------------------------------------------------------
51 unsigned long flash_init (void)
53 unsigned long size_b0
, size_b1
;
56 unsigned long base_b0
, base_b1
;
57 volatile FLASH_WORD_SIZE
* flash_base
;
59 /* Init: no FLASHes known */
60 for (i
=0; i
<CONFIG_SYS_MAX_FLASH_BANKS
; ++i
) {
61 flash_info
[i
].flash_id
= FLASH_UNKNOWN
;
64 /* Static FLASH Bank configuration here */
65 /* Test for 8M Flash first */
66 debug ("\n## Get flash bank 1 size @ 0x%08x\n",FLASH_BASE0_8M_PRELIM
);
67 flash_base
= (volatile FLASH_WORD_SIZE
*)(FLASH_BASE0_8M_PRELIM
);
68 size_b0
= flash_get_size(flash_base
, &flash_info
[0]);
70 if (flash_info
[0].flash_id
== FLASH_UNKNOWN
) {
71 printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
72 size_b0
, size_b0
<<20);
76 if (size_b0
< 8*1024*1024) {
77 /* Not quite 8M, try 4M Flash base address */
78 debug ("\n## Get flash bank 1 size @ 0x%08x\n",FLASH_BASE0_4M_PRELIM
);
79 flash_base
= (volatile FLASH_WORD_SIZE
*)(FLASH_BASE0_4M_PRELIM
);
80 size_b0
= flash_get_size(flash_base
, &flash_info
[0]);
83 if (flash_info
[0].flash_id
== FLASH_UNKNOWN
) {
84 printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
85 size_b0
, size_b0
<<20);
90 if (CONFIG_SYS_MAX_FLASH_BANKS
== 1) {
92 flash_get_offsets ((ulong
)flash_base
, &flash_info
[0]);
94 /* Monitor protection ON by default */
95 (void)flash_protect(FLAG_PROTECT_SET
, CONFIG_SYS_MONITOR_BASE
,
96 CONFIG_SYS_MONITOR_BASE
+CONFIG_SYS_MONITOR_LEN
-1, &flash_info
[0]);
98 flash_info
[0].size
= size_b0
;
102 /* We have 2 banks */
103 size_b1
= flash_get_size(flash_base
, &flash_info
[1]);
105 /* Re-do sizing to get full correct info */
107 mtdcr(ebccfga
, pb0cr
);
108 pbcr
= mfdcr(ebccfgd
);
109 mtdcr(ebccfga
, pb0cr
);
111 pbcr
= (pbcr
& 0x0001ffff) | base_b1
| (((size_b1
/1024/1024)-1)<<17);
112 mtdcr(ebccfgd
, pbcr
);
116 mtdcr(ebccfga
, pb1cr
);
117 pbcr
= mfdcr(ebccfgd
);
118 mtdcr(ebccfga
, pb1cr
);
119 base_b0
= base_b1
- size_b0
;
120 pbcr
= (pbcr
& 0x0001ffff) | base_b0
| (((size_b0
/1024/1024)-1)<<17);
121 mtdcr(ebccfgd
, pbcr
);
124 size_b0
= flash_get_size((volatile FLASH_WORD_SIZE
*)base_b0
, &flash_info
[0]);
125 flash_get_offsets (base_b0
, &flash_info
[0]);
127 /* monitor protection ON by default */
128 (void)flash_protect(FLAG_PROTECT_SET
, CONFIG_SYS_MONITOR_BASE
,
129 CONFIG_SYS_MONITOR_BASE
+CONFIG_SYS_MONITOR_LEN
-1, &flash_info
[0]);
132 /* Re-do sizing to get full correct info */
133 size_b1
= flash_get_size((volatile FLASH_WORD_SIZE
*)base_b1
, &flash_info
[1]);
134 flash_get_offsets (base_b1
, &flash_info
[1]);
136 /* monitor protection ON by default */
137 (void)flash_protect(FLAG_PROTECT_SET
, base_b1
+size_b1
-CONFIG_SYS_MONITOR_LEN
,
138 base_b1
+size_b1
-1, &flash_info
[1]);
140 /* monitor protection OFF by default (one is enough) */
141 (void)flash_protect(FLAG_PROTECT_CLEAR
, base_b0
+size_b0
-CONFIG_SYS_MONITOR_LEN
,
142 base_b0
+size_b0
-1, &flash_info
[0]);
144 flash_info
[1].flash_id
= FLASH_UNKNOWN
;
145 flash_info
[1].sector_count
= -1;
148 flash_info
[0].size
= size_b0
;
149 flash_info
[1].size
= size_b1
;
150 return (size_b0
+ size_b1
);
154 /*-----------------------------------------------------------------------
155 This code is specific to the AM29DL163/AM29DL232 for the QS850/QS823.
158 static void flash_get_offsets (ulong base
, flash_info_t
*info
)
161 long large_sect_size
;
162 long small_sect_size
;
164 /* set up sector start adress table */
165 large_sect_size
= info
->size
/ (info
->sector_count
- 8 + 1);
166 small_sect_size
= large_sect_size
/ 8;
168 if (info
->flash_id
& FLASH_BTYPE
) {
170 /* set sector offsets for bottom boot block type */
171 for (i
= 0; i
< 7; i
++) {
172 info
->start
[i
] = base
;
173 base
+= small_sect_size
;
176 for (; i
< info
->sector_count
; i
++) {
177 info
->start
[i
] = base
;
178 base
+= large_sect_size
;
183 /* set sector offsets for top boot block type */
184 for (i
= 0; i
< (info
->sector_count
- 8); i
++) {
185 info
->start
[i
] = base
;
186 base
+= large_sect_size
;
189 for (; i
< info
->sector_count
; i
++) {
190 info
->start
[i
] = base
;
191 base
+= small_sect_size
;
196 /*-----------------------------------------------------------------------
199 void flash_print_info (flash_info_t
*info
)
203 uchar botboot
[]=", bottom boot sect)\n";
204 uchar topboot
[]=", top boot sector)\n";
206 if (info
->flash_id
== FLASH_UNKNOWN
) {
207 printf ("missing or unknown FLASH type\n");
211 switch (info
->flash_id
& FLASH_VENDMASK
) {
224 case FLASH_MAN_INTEL
:
228 printf ("Unknown Vendor ");
232 if (info
->flash_id
& 0x0001 ) {
238 switch (info
->flash_id
& FLASH_TYPEMASK
) {
240 printf ("AM29LV160B (16 Mbit%s",boottype
);
243 printf ("AM29LV160T (16 Mbit%s",boottype
);
246 printf ("AM29DL163T (16 Mbit%s",boottype
);
249 printf ("AM29DL163B (16 Mbit%s",boottype
);
252 printf ("AM29LV320B (32 Mbit%s",boottype
);
255 printf ("AM29LV320T (32 Mbit%s",boottype
);
258 printf ("AM29DL323T (32 Mbit%s",boottype
);
261 printf ("AM29DL323B (32 Mbit%s",boottype
);
264 printf ("AM29DL322T (32 Mbit%s",boottype
);
267 printf ("Unknown Chip Type\n");
271 printf (" Size: %ld MB in %d Sectors\n",
272 info
->size
>> 20, info
->sector_count
);
274 printf (" Sector Start Addresses:");
275 for (i
=0; i
<info
->sector_count
; ++i
) {
278 printf (" %08lX%s", info
->start
[i
],
279 info
->protect
[i
] ? " (RO)" : " ");
286 /*-----------------------------------------------------------------------
287 * The following code cannot be run from FLASH!
289 ulong
flash_get_size (volatile FLASH_WORD_SIZE
*addr
, flash_info_t
*info
)
292 ulong base
= (ulong
)addr
;
293 FLASH_WORD_SIZE value
;
295 /* Write auto select command: read Manufacturer ID */
298 * Note: if it is an AMD flash and the word at addr[0000]
299 * is 0x00890089 this routine will think it is an Intel
300 * flash device and may(most likely) cause trouble.
303 addr
[0x0000] = 0x00900090;
304 if(addr
[0x0000] != 0x00890089){
305 addr
[0x0555] = 0x00AA00AA;
306 addr
[0x02AA] = 0x00550055;
307 addr
[0x0555] = 0x00900090;
312 case (AMD_MANUFACT
& FLASH_ID_MASK
):
313 info
->flash_id
= FLASH_MAN_AMD
;
315 case (FUJ_MANUFACT
& FLASH_ID_MASK
):
316 info
->flash_id
= FLASH_MAN_FUJ
;
318 case (STM_MANUFACT
& FLASH_ID_MASK
):
319 info
->flash_id
= FLASH_MAN_STM
;
321 case (SST_MANUFACT
& FLASH_ID_MASK
):
322 info
->flash_id
= FLASH_MAN_SST
;
324 case (INTEL_MANUFACT
& FLASH_ID_MASK
):
325 info
->flash_id
= FLASH_MAN_INTEL
;
328 info
->flash_id
= FLASH_UNKNOWN
;
329 info
->sector_count
= 0;
331 return (0); /* no or unknown flash */
334 value
= addr
[1]; /* device ID */
337 case (AMD_ID_LV160T
& FLASH_ID_MASK
):
338 info
->flash_id
+= FLASH_AM160T
;
339 info
->sector_count
= 35;
340 info
->size
= 0x00400000;
343 case (AMD_ID_LV160B
& FLASH_ID_MASK
):
344 info
->flash_id
+= FLASH_AM160B
;
345 info
->sector_count
= 35;
346 info
->size
= 0x00400000;
349 case (AMD_ID_DL163T
& FLASH_ID_MASK
):
350 info
->flash_id
+= FLASH_AMDL163T
;
351 info
->sector_count
= 39;
352 info
->size
= 0x00400000;
355 case (AMD_ID_DL163B
& FLASH_ID_MASK
):
356 info
->flash_id
+= FLASH_AMDL163B
;
357 info
->sector_count
= 39;
358 info
->size
= 0x00400000;
361 case (AMD_ID_DL323T
& FLASH_ID_MASK
):
362 info
->flash_id
+= FLASH_AMDL323T
;
363 info
->sector_count
= 71;
364 info
->size
= 0x00800000;
367 case (AMD_ID_DL323B
& FLASH_ID_MASK
):
368 info
->flash_id
+= FLASH_AMDL323B
;
369 info
->sector_count
= 71;
370 info
->size
= 0x00800000;
373 case (AMD_ID_DL322T
& FLASH_ID_MASK
):
374 info
->flash_id
+= FLASH_AMDL322T
;
375 info
->sector_count
= 71;
376 info
->size
= 0x00800000;
381 info
->flash_id
= FLASH_UNKNOWN
;
382 return (0); /* => no or unknown flash */
385 flash_get_offsets(base
, info
);
387 /* check for protected sectors */
388 for (i
= 0; i
< info
->sector_count
; i
++) {
389 /* read sector protection at sector address, (A7 .. A0) = 0x02 */
390 /* D0 = 1 if protected */
391 addr
= (volatile FLASH_WORD_SIZE
*)(info
->start
[i
]);
392 info
->protect
[i
] = addr
[2] & 1;
396 * Prevent writes to uninitialized FLASH.
398 if (info
->flash_id
!= FLASH_UNKNOWN
) {
399 addr
= (volatile FLASH_WORD_SIZE
*)info
->start
[0];
400 *addr
= (0x00FF00FF & FLASH_ID_MASK
); /* reset bank */
407 /*-----------------------------------------------------------------------
410 int flash_erase (flash_info_t
*info
, int s_first
, int s_last
)
412 volatile FLASH_WORD_SIZE
*addr
=(volatile FLASH_WORD_SIZE
*)(info
->start
[0]);
413 int flag
, prot
, sect
, l_sect
;
414 ulong start
, now
, last
;
417 if ((s_first
< 0) || (s_first
> s_last
)) {
418 if (info
->flash_id
== FLASH_UNKNOWN
) {
419 printf ("- missing\n");
421 printf ("- no sectors to erase\n");
426 if ((info
->flash_id
== FLASH_UNKNOWN
) ||
427 (info
->flash_id
> FLASH_AMD_COMP
) ) {
428 printf ("Can't erase unknown flash type - aborted\n");
433 for (sect
=s_first
; sect
<=s_last
; ++sect
) {
434 if (info
->protect
[sect
]) {
440 printf ("- Warning: %d protected sectors will not be erased!\n",
448 /* Disable interrupts which might cause a timeout here */
449 flag
= disable_interrupts();
450 addr
[0x0555] = 0x00AA00AA;
451 addr
[0x02AA] = 0x00550055;
452 addr
[0x0555] = 0x00800080;
453 addr
[0x0555] = 0x00AA00AA;
454 addr
[0x02AA] = 0x00550055;
455 /* Start erase on unprotected sectors */
456 for (sect
= s_first
; sect
<=s_last
; sect
++) {
457 if (info
->protect
[sect
] == 0) { /* not protected */
458 addr
= (volatile FLASH_WORD_SIZE
*)(info
->start
[sect
]);
459 addr
[0] = (0x00300030 & FLASH_ID_MASK
);
464 /* re-enable interrupts if necessary */
468 /* wait at least 80us - let's wait 1 ms */
472 * We wait for the last triggered sector
477 start
= get_timer (0);
479 addr
= (volatile FLASH_WORD_SIZE
*)(info
->start
[l_sect
]);
480 while ((addr
[0] & (0x00800080&FLASH_ID_MASK
)) !=
481 (0x00800080&FLASH_ID_MASK
) )
483 if ((now
= get_timer(start
)) > CONFIG_SYS_FLASH_ERASE_TOUT
) {
484 printf ("Timeout\n");
487 /* show that we're waiting */
488 if ((now
- last
) > 1000) { /* every second */
495 /* reset to read mode */
496 addr
= (volatile FLASH_WORD_SIZE
*)info
->start
[0];
497 addr
[0] = (0x00F000F0 & FLASH_ID_MASK
); /* reset bank */
503 /*-----------------------------------------------------------------------
504 * Copy memory to flash, returns:
507 * 2 - Flash not erased
510 int write_buff (flash_info_t
*info
, uchar
*src
, ulong addr
, ulong cnt
)
516 wp
= (addr
& ~3); /* get lower word aligned address */
519 * handle unaligned start bytes
521 if ((l
= addr
- wp
) != 0) {
523 for (i
=0, cp
=wp
; i
<l
; ++i
, ++cp
) {
524 data
= (data
<< 8) | (*(uchar
*)cp
);
526 for (; i
<4 && cnt
>0; ++i
) {
527 data
= (data
<< 8) | *src
++;
531 for (; cnt
==0 && i
<4; ++i
, ++cp
) {
532 data
= (data
<< 8) | (*(uchar
*)cp
);
535 if ((rc
= write_word(info
, wp
, data
)) != 0) {
542 * handle word aligned part
546 for (i
=0; i
<4; ++i
) {
547 data
= (data
<< 8) | *src
++;
549 if ((rc
= write_word(info
, wp
, data
)) != 0) {
561 * handle unaligned tail bytes
564 for (i
=0, cp
=wp
; i
<4 && cnt
>0; ++i
, ++cp
) {
565 data
= (data
<< 8) | *src
++;
568 for (; i
<4; ++i
, ++cp
) {
569 data
= (data
<< 8) | (*(uchar
*)cp
);
572 return (write_word(info
, wp
, data
));
575 /*-----------------------------------------------------------------------
576 * Write a word to Flash, returns:
579 * 2 - Flash not erased
581 static int write_word (flash_info_t
*info
, ulong dest
, ulong data
)
583 vu_long
*addr
= (vu_long
*)(info
->start
[0]);
587 /* Check if Flash is (sufficiently) erased */
588 if ((*((vu_long
*)dest
) & data
) != data
) {
592 /* Disable interrupts which might cause a timeout here */
593 flag
= disable_interrupts();
596 addr
[0x0555] = 0x00AA00AA;
597 addr
[0x02AA] = 0x00550055;
598 addr
[0x0555] = 0x00A000A0;
600 *((vu_long
*)dest
) = data
;
602 /* re-enable interrupts if necessary */
606 /* data polling for D7 */
607 start
= get_timer(0);
609 while ((*((vu_long
*)dest
) & 0x00800080) != (data
& 0x00800080)) {
610 if (get_timer(start
) > CONFIG_SYS_FLASH_WRITE_TOUT
) {