6 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
8 * SPDX-License-Identifier: GPL-2.0+
12 #include <asm/ppc4xx.h>
13 #include <asm/u-boot.h>
14 #include <asm/processor.h>
16 flash_info_t flash_info
[CONFIG_SYS_MAX_FLASH_BANKS
]; /* info for FLASH chips */
19 #define FLASH_WORD_SIZE unsigned long
20 #define FLASH_ID_MASK 0xFFFFFFFF
22 /*-----------------------------------------------------------------------
25 /* stolen from esteem192e/flash.c */
26 ulong
flash_get_size (volatile FLASH_WORD_SIZE
*addr
, flash_info_t
*info
);
28 static int write_word (flash_info_t
*info
, ulong dest
, ulong data
);
29 static void flash_get_offsets (ulong base
, flash_info_t
*info
);
32 /*-----------------------------------------------------------------------
35 unsigned long flash_init (void)
37 unsigned long size_b0
, size_b1
;
40 unsigned long base_b0
, base_b1
;
41 volatile FLASH_WORD_SIZE
* flash_base
;
43 /* Init: no FLASHes known */
44 for (i
=0; i
<CONFIG_SYS_MAX_FLASH_BANKS
; ++i
) {
45 flash_info
[i
].flash_id
= FLASH_UNKNOWN
;
48 /* Static FLASH Bank configuration here */
49 /* Test for 8M Flash first */
50 debug ("\n## Get flash bank 1 size @ 0x%08x\n",FLASH_BASE0_8M_PRELIM
);
51 flash_base
= (volatile FLASH_WORD_SIZE
*)(FLASH_BASE0_8M_PRELIM
);
52 size_b0
= flash_get_size(flash_base
, &flash_info
[0]);
54 if (flash_info
[0].flash_id
== FLASH_UNKNOWN
) {
55 printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
56 size_b0
, size_b0
<<20);
60 if (size_b0
< 8*1024*1024) {
61 /* Not quite 8M, try 4M Flash base address */
62 debug ("\n## Get flash bank 1 size @ 0x%08x\n",FLASH_BASE0_4M_PRELIM
);
63 flash_base
= (volatile FLASH_WORD_SIZE
*)(FLASH_BASE0_4M_PRELIM
);
64 size_b0
= flash_get_size(flash_base
, &flash_info
[0]);
67 if (flash_info
[0].flash_id
== FLASH_UNKNOWN
) {
68 printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
69 size_b0
, size_b0
<<20);
74 if (CONFIG_SYS_MAX_FLASH_BANKS
== 1) {
76 flash_get_offsets ((ulong
)flash_base
, &flash_info
[0]);
78 /* Monitor protection ON by default */
79 (void)flash_protect(FLAG_PROTECT_SET
, CONFIG_SYS_MONITOR_BASE
,
80 CONFIG_SYS_MONITOR_BASE
+CONFIG_SYS_MONITOR_LEN
-1, &flash_info
[0]);
82 flash_info
[0].size
= size_b0
;
87 size_b1
= flash_get_size(flash_base
, &flash_info
[1]);
89 /* Re-do sizing to get full correct info */
91 mtdcr(EBC0_CFGADDR
, PB0CR
);
92 pbcr
= mfdcr(EBC0_CFGDATA
);
93 mtdcr(EBC0_CFGADDR
, PB0CR
);
95 pbcr
= (pbcr
& 0x0001ffff) | base_b1
| (((size_b1
/1024/1024)-1)<<17);
96 mtdcr(EBC0_CFGDATA
, pbcr
);
100 mtdcr(EBC0_CFGADDR
, PB1CR
);
101 pbcr
= mfdcr(EBC0_CFGDATA
);
102 mtdcr(EBC0_CFGADDR
, PB1CR
);
103 base_b0
= base_b1
- size_b0
;
104 pbcr
= (pbcr
& 0x0001ffff) | base_b0
| (((size_b0
/1024/1024)-1)<<17);
105 mtdcr(EBC0_CFGDATA
, pbcr
);
108 size_b0
= flash_get_size((volatile FLASH_WORD_SIZE
*)base_b0
, &flash_info
[0]);
109 flash_get_offsets (base_b0
, &flash_info
[0]);
111 /* monitor protection ON by default */
112 (void)flash_protect(FLAG_PROTECT_SET
, CONFIG_SYS_MONITOR_BASE
,
113 CONFIG_SYS_MONITOR_BASE
+CONFIG_SYS_MONITOR_LEN
-1, &flash_info
[0]);
116 /* Re-do sizing to get full correct info */
117 size_b1
= flash_get_size((volatile FLASH_WORD_SIZE
*)base_b1
, &flash_info
[1]);
118 flash_get_offsets (base_b1
, &flash_info
[1]);
120 /* monitor protection ON by default */
121 (void)flash_protect(FLAG_PROTECT_SET
, base_b1
+size_b1
-CONFIG_SYS_MONITOR_LEN
,
122 base_b1
+size_b1
-1, &flash_info
[1]);
124 /* monitor protection OFF by default (one is enough) */
125 (void)flash_protect(FLAG_PROTECT_CLEAR
, base_b0
+size_b0
-CONFIG_SYS_MONITOR_LEN
,
126 base_b0
+size_b0
-1, &flash_info
[0]);
128 flash_info
[1].flash_id
= FLASH_UNKNOWN
;
129 flash_info
[1].sector_count
= -1;
132 flash_info
[0].size
= size_b0
;
133 flash_info
[1].size
= size_b1
;
134 return (size_b0
+ size_b1
);
138 /*-----------------------------------------------------------------------
139 This code is specific to the AM29DL163/AM29DL232 for the QS850/QS823.
142 static void flash_get_offsets (ulong base
, flash_info_t
*info
)
145 long large_sect_size
;
146 long small_sect_size
;
148 /* set up sector start adress table */
149 large_sect_size
= info
->size
/ (info
->sector_count
- 8 + 1);
150 small_sect_size
= large_sect_size
/ 8;
152 if (info
->flash_id
& FLASH_BTYPE
) {
154 /* set sector offsets for bottom boot block type */
155 for (i
= 0; i
< 7; i
++) {
156 info
->start
[i
] = base
;
157 base
+= small_sect_size
;
160 for (; i
< info
->sector_count
; i
++) {
161 info
->start
[i
] = base
;
162 base
+= large_sect_size
;
167 /* set sector offsets for top boot block type */
168 for (i
= 0; i
< (info
->sector_count
- 8); i
++) {
169 info
->start
[i
] = base
;
170 base
+= large_sect_size
;
173 for (; i
< info
->sector_count
; i
++) {
174 info
->start
[i
] = base
;
175 base
+= small_sect_size
;
180 /*-----------------------------------------------------------------------
183 void flash_print_info (flash_info_t
*info
)
187 uchar botboot
[]=", bottom boot sect)\n";
188 uchar topboot
[]=", top boot sector)\n";
190 if (info
->flash_id
== FLASH_UNKNOWN
) {
191 printf ("missing or unknown FLASH type\n");
195 switch (info
->flash_id
& FLASH_VENDMASK
) {
208 case FLASH_MAN_INTEL
:
212 printf ("Unknown Vendor ");
216 if (info
->flash_id
& 0x0001 ) {
222 switch (info
->flash_id
& FLASH_TYPEMASK
) {
224 printf ("AM29LV160B (16 Mbit%s",boottype
);
227 printf ("AM29LV160T (16 Mbit%s",boottype
);
230 printf ("AM29DL163T (16 Mbit%s",boottype
);
233 printf ("AM29DL163B (16 Mbit%s",boottype
);
236 printf ("AM29LV320B (32 Mbit%s",boottype
);
239 printf ("AM29LV320T (32 Mbit%s",boottype
);
242 printf ("AM29DL323T (32 Mbit%s",boottype
);
245 printf ("AM29DL323B (32 Mbit%s",boottype
);
248 printf ("AM29DL322T (32 Mbit%s",boottype
);
251 printf ("Unknown Chip Type\n");
255 printf (" Size: %ld MB in %d Sectors\n",
256 info
->size
>> 20, info
->sector_count
);
258 printf (" Sector Start Addresses:");
259 for (i
=0; i
<info
->sector_count
; ++i
) {
262 printf (" %08lX%s", info
->start
[i
],
263 info
->protect
[i
] ? " (RO)" : " ");
270 /*-----------------------------------------------------------------------
271 * The following code cannot be run from FLASH!
273 ulong
flash_get_size (volatile FLASH_WORD_SIZE
*addr
, flash_info_t
*info
)
276 ulong base
= (ulong
)addr
;
277 FLASH_WORD_SIZE value
;
279 /* Write auto select command: read Manufacturer ID */
282 * Note: if it is an AMD flash and the word at addr[0000]
283 * is 0x00890089 this routine will think it is an Intel
284 * flash device and may(most likely) cause trouble.
287 addr
[0x0000] = 0x00900090;
288 if(addr
[0x0000] != 0x00890089){
289 addr
[0x0555] = 0x00AA00AA;
290 addr
[0x02AA] = 0x00550055;
291 addr
[0x0555] = 0x00900090;
296 case (AMD_MANUFACT
& FLASH_ID_MASK
):
297 info
->flash_id
= FLASH_MAN_AMD
;
299 case (FUJ_MANUFACT
& FLASH_ID_MASK
):
300 info
->flash_id
= FLASH_MAN_FUJ
;
302 case (STM_MANUFACT
& FLASH_ID_MASK
):
303 info
->flash_id
= FLASH_MAN_STM
;
305 case (SST_MANUFACT
& FLASH_ID_MASK
):
306 info
->flash_id
= FLASH_MAN_SST
;
308 case (INTEL_MANUFACT
& FLASH_ID_MASK
):
309 info
->flash_id
= FLASH_MAN_INTEL
;
312 info
->flash_id
= FLASH_UNKNOWN
;
313 info
->sector_count
= 0;
315 return (0); /* no or unknown flash */
318 value
= addr
[1]; /* device ID */
321 case (AMD_ID_LV160T
& FLASH_ID_MASK
):
322 info
->flash_id
+= FLASH_AM160T
;
323 info
->sector_count
= 35;
324 info
->size
= 0x00400000;
327 case (AMD_ID_LV160B
& FLASH_ID_MASK
):
328 info
->flash_id
+= FLASH_AM160B
;
329 info
->sector_count
= 35;
330 info
->size
= 0x00400000;
333 case (AMD_ID_DL163T
& FLASH_ID_MASK
):
334 info
->flash_id
+= FLASH_AMDL163T
;
335 info
->sector_count
= 39;
336 info
->size
= 0x00400000;
339 case (AMD_ID_DL163B
& FLASH_ID_MASK
):
340 info
->flash_id
+= FLASH_AMDL163B
;
341 info
->sector_count
= 39;
342 info
->size
= 0x00400000;
345 case (AMD_ID_DL323T
& FLASH_ID_MASK
):
346 info
->flash_id
+= FLASH_AMDL323T
;
347 info
->sector_count
= 71;
348 info
->size
= 0x00800000;
351 case (AMD_ID_DL323B
& FLASH_ID_MASK
):
352 info
->flash_id
+= FLASH_AMDL323B
;
353 info
->sector_count
= 71;
354 info
->size
= 0x00800000;
357 case (AMD_ID_DL322T
& FLASH_ID_MASK
):
358 info
->flash_id
+= FLASH_AMDL322T
;
359 info
->sector_count
= 71;
360 info
->size
= 0x00800000;
365 info
->flash_id
= FLASH_UNKNOWN
;
366 return (0); /* => no or unknown flash */
369 flash_get_offsets(base
, info
);
371 /* check for protected sectors */
372 for (i
= 0; i
< info
->sector_count
; i
++) {
373 /* read sector protection at sector address, (A7 .. A0) = 0x02 */
374 /* D0 = 1 if protected */
375 addr
= (volatile FLASH_WORD_SIZE
*)(info
->start
[i
]);
376 info
->protect
[i
] = addr
[2] & 1;
380 * Prevent writes to uninitialized FLASH.
382 if (info
->flash_id
!= FLASH_UNKNOWN
) {
383 addr
= (volatile FLASH_WORD_SIZE
*)info
->start
[0];
384 *addr
= (0x00FF00FF & FLASH_ID_MASK
); /* reset bank */
391 /*-----------------------------------------------------------------------
394 int flash_erase (flash_info_t
*info
, int s_first
, int s_last
)
396 volatile FLASH_WORD_SIZE
*addr
=(volatile FLASH_WORD_SIZE
*)(info
->start
[0]);
397 int flag
, prot
, sect
, l_sect
;
398 ulong start
, now
, last
;
401 if ((s_first
< 0) || (s_first
> s_last
)) {
402 if (info
->flash_id
== FLASH_UNKNOWN
) {
403 printf ("- missing\n");
405 printf ("- no sectors to erase\n");
410 if ((info
->flash_id
== FLASH_UNKNOWN
) ||
411 (info
->flash_id
> FLASH_AMD_COMP
) ) {
412 printf ("Can't erase unknown flash type - aborted\n");
417 for (sect
=s_first
; sect
<=s_last
; ++sect
) {
418 if (info
->protect
[sect
]) {
424 printf ("- Warning: %d protected sectors will not be erased!\n",
432 /* Disable interrupts which might cause a timeout here */
433 flag
= disable_interrupts();
434 addr
[0x0555] = 0x00AA00AA;
435 addr
[0x02AA] = 0x00550055;
436 addr
[0x0555] = 0x00800080;
437 addr
[0x0555] = 0x00AA00AA;
438 addr
[0x02AA] = 0x00550055;
439 /* Start erase on unprotected sectors */
440 for (sect
= s_first
; sect
<=s_last
; sect
++) {
441 if (info
->protect
[sect
] == 0) { /* not protected */
442 addr
= (volatile FLASH_WORD_SIZE
*)(info
->start
[sect
]);
443 addr
[0] = (0x00300030 & FLASH_ID_MASK
);
448 /* re-enable interrupts if necessary */
452 /* wait at least 80us - let's wait 1 ms */
456 * We wait for the last triggered sector
461 start
= get_timer (0);
463 addr
= (volatile FLASH_WORD_SIZE
*)(info
->start
[l_sect
]);
464 while ((addr
[0] & (0x00800080&FLASH_ID_MASK
)) !=
465 (0x00800080&FLASH_ID_MASK
) )
467 if ((now
= get_timer(start
)) > CONFIG_SYS_FLASH_ERASE_TOUT
) {
468 printf ("Timeout\n");
471 /* show that we're waiting */
472 if ((now
- last
) > 1000) { /* every second */
479 /* reset to read mode */
480 addr
= (volatile FLASH_WORD_SIZE
*)info
->start
[0];
481 addr
[0] = (0x00F000F0 & FLASH_ID_MASK
); /* reset bank */
487 /*-----------------------------------------------------------------------
488 * Copy memory to flash, returns:
491 * 2 - Flash not erased
494 int write_buff (flash_info_t
*info
, uchar
*src
, ulong addr
, ulong cnt
)
500 wp
= (addr
& ~3); /* get lower word aligned address */
503 * handle unaligned start bytes
505 if ((l
= addr
- wp
) != 0) {
507 for (i
=0, cp
=wp
; i
<l
; ++i
, ++cp
) {
508 data
= (data
<< 8) | (*(uchar
*)cp
);
510 for (; i
<4 && cnt
>0; ++i
) {
511 data
= (data
<< 8) | *src
++;
515 for (; cnt
==0 && i
<4; ++i
, ++cp
) {
516 data
= (data
<< 8) | (*(uchar
*)cp
);
519 if ((rc
= write_word(info
, wp
, data
)) != 0) {
526 * handle word aligned part
530 for (i
=0; i
<4; ++i
) {
531 data
= (data
<< 8) | *src
++;
533 if ((rc
= write_word(info
, wp
, data
)) != 0) {
545 * handle unaligned tail bytes
548 for (i
=0, cp
=wp
; i
<4 && cnt
>0; ++i
, ++cp
) {
549 data
= (data
<< 8) | *src
++;
552 for (; i
<4; ++i
, ++cp
) {
553 data
= (data
<< 8) | (*(uchar
*)cp
);
556 return (write_word(info
, wp
, data
));
559 /*-----------------------------------------------------------------------
560 * Write a word to Flash, returns:
563 * 2 - Flash not erased
565 static int write_word (flash_info_t
*info
, ulong dest
, ulong data
)
567 vu_long
*addr
= (vu_long
*)(info
->start
[0]);
571 /* Check if Flash is (sufficiently) erased */
572 if ((*((vu_long
*)dest
) & data
) != data
) {
576 /* Disable interrupts which might cause a timeout here */
577 flag
= disable_interrupts();
580 addr
[0x0555] = 0x00AA00AA;
581 addr
[0x02AA] = 0x00550055;
582 addr
[0x0555] = 0x00A000A0;
584 *((vu_long
*)dest
) = data
;
586 /* re-enable interrupts if necessary */
590 /* data polling for D7 */
591 start
= get_timer(0);
593 while ((*((vu_long
*)dest
) & 0x00800080) != (data
& 0x00800080)) {
594 if (get_timer(start
) > CONFIG_SYS_FLASH_WRITE_TOUT
) {