3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
6 * Reinhard Meyer, EMK Elektronik GmbH, r.meyer@emk-elektronik.de
8 * SPDX-License-Identifier: GPL-2.0+
13 flash_info_t flash_info
[CONFIG_SYS_MAX_FLASH_BANKS
]; /* info for FLASH chips */
15 #if defined (CONFIG_TOP860)
16 typedef unsigned short FLASH_PORT_WIDTH
;
17 typedef volatile unsigned short FLASH_PORT_WIDTHV
;
18 #define FLASH_ID_MASK 0xFF
20 #define FPW FLASH_PORT_WIDTH
21 #define FPWV FLASH_PORT_WIDTHV
23 #define FLASH_CYCLE1 0x0555
24 #define FLASH_CYCLE2 0x02aa
27 #define FLASH_ID3 0x0e
28 #define FLASH_ID4 0x0F
31 #if defined (CONFIG_TOP5200) && !defined (CONFIG_LITE5200)
32 typedef unsigned char FLASH_PORT_WIDTH
;
33 typedef volatile unsigned char FLASH_PORT_WIDTHV
;
34 #define FLASH_ID_MASK 0xFF
36 #define FPW FLASH_PORT_WIDTH
37 #define FPWV FLASH_PORT_WIDTHV
39 #define FLASH_CYCLE1 0x0aaa
40 #define FLASH_CYCLE2 0x0555
43 #define FLASH_ID3 0x1c
44 #define FLASH_ID4 0x1E
47 #if defined (CONFIG_TOP5200) && defined (CONFIG_LITE5200)
48 typedef unsigned char FLASH_PORT_WIDTH
;
49 typedef volatile unsigned char FLASH_PORT_WIDTHV
;
50 #define FLASH_ID_MASK 0xFF
52 #define FPW FLASH_PORT_WIDTH
53 #define FPWV FLASH_PORT_WIDTHV
55 #define FLASH_CYCLE1 0x0555
56 #define FLASH_CYCLE2 0x02aa
59 #define FLASH_ID3 0x0E
60 #define FLASH_ID4 0x0F
63 /*-----------------------------------------------------------------------
66 static ulong
flash_get_size(FPWV
*addr
, flash_info_t
*info
);
67 static void flash_reset(flash_info_t
*info
);
68 static int write_word_amd(flash_info_t
*info
, FPWV
*dest
, FPW data
);
69 flash_info_t
*flash_get_info(ulong base
);
71 /*-----------------------------------------------------------------------
74 * sets up flash_info and returns size of FLASH (bytes)
76 unsigned long flash_init (void)
78 unsigned long size
= 0;
80 extern void flash_preinit(void);
81 extern void flash_afterinit(uint
, ulong
, ulong
);
82 ulong flashbase
= CONFIG_SYS_FLASH_BASE
;
86 /* There is only ONE FLASH device */
87 memset(&flash_info
[i
], 0, sizeof(flash_info_t
));
89 flash_get_size((FPW
*)flashbase
, &flash_info
[i
]);
90 size
+= flash_info
[i
].size
;
92 #if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
93 /* monitor protection ON by default */
94 flash_protect(FLAG_PROTECT_SET
,
95 CONFIG_SYS_MONITOR_BASE
,
96 CONFIG_SYS_MONITOR_BASE
+monitor_flash_len
-1,
97 flash_get_info(CONFIG_SYS_MONITOR_BASE
));
100 #ifdef CONFIG_ENV_IS_IN_FLASH
101 /* ENV protection ON by default */
102 flash_protect(FLAG_PROTECT_SET
,
104 CONFIG_ENV_ADDR
+CONFIG_ENV_SIZE
-1,
105 flash_get_info(CONFIG_ENV_ADDR
));
109 flash_afterinit(i
, flash_info
[i
].start
[0], flash_info
[i
].size
);
110 return size
? size
: 1;
113 /*-----------------------------------------------------------------------
115 static void flash_reset(flash_info_t
*info
)
117 FPWV
*base
= (FPWV
*)(info
->start
[0]);
119 /* Put FLASH back in read mode */
120 if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_INTEL
)
121 *base
= (FPW
)0x00FF00FF; /* Intel Read Mode */
122 else if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_AMD
)
123 *base
= (FPW
)0x00F000F0; /* AMD Read Mode */
126 /*-----------------------------------------------------------------------
129 flash_info_t
*flash_get_info(ulong base
)
134 for (i
= 0; i
< CONFIG_SYS_MAX_FLASH_BANKS
; i
++) {
135 info
= & flash_info
[i
];
137 info
->start
[0] <= base
&& base
<= info
->start
[0] + info
->size
- 1)
141 return i
== CONFIG_SYS_MAX_FLASH_BANKS
? 0 : info
;
144 /*-----------------------------------------------------------------------
147 void flash_print_info (flash_info_t
*info
)
153 uchar botbootletter
[] = "B";
154 uchar topbootletter
[] = "T";
155 uchar botboottype
[] = "bottom boot sector";
156 uchar topboottype
[] = "top boot sector";
158 if (info
->flash_id
== FLASH_UNKNOWN
) {
159 printf ("missing or unknown FLASH type\n");
163 switch (info
->flash_id
& FLASH_VENDMASK
) {
164 case FLASH_MAN_AMD
: printf ("AMD "); break;
166 case FLASH_MAN_BM
: printf ("BRIGHT MICRO "); break;
167 case FLASH_MAN_FUJ
: printf ("FUJITSU "); break;
168 case FLASH_MAN_SST
: printf ("SST "); break;
169 case FLASH_MAN_STM
: printf ("STM "); break;
170 case FLASH_MAN_INTEL
: printf ("INTEL "); break;
172 default: printf ("Unknown Vendor "); break;
175 /* check for top or bottom boot, if it applies */
176 if (info
->flash_id
& FLASH_BTYPE
) {
177 boottype
= botboottype
;
178 bootletter
= botbootletter
;
181 boottype
= topboottype
;
182 bootletter
= topbootletter
;
185 switch (info
->flash_id
& FLASH_TYPEMASK
) {
188 fmt
= "29LV160%s (16 Mbit, %s)\n";
191 fmt
= "29LV640M (64 Mbit)\n";
193 case FLASH_AMDLV065D
:
194 fmt
= "29LV065D (64 Mbit)\n";
197 fmt
= "29LV256M (256 Mbit)\n";
200 fmt
= "Unknown Chip Type\n";
204 printf (fmt
, bootletter
, boottype
);
206 printf (" Size: %ld MB in %d Sectors\n",
210 printf (" Sector Start Addresses:");
212 for (i
=0; i
<info
->sector_count
; ++i
) {
215 ulong
*flash
= (unsigned long *) info
->start
[i
];
222 * Check if whole sector is erased
225 (i
!= (info
->sector_count
- 1)) ?
226 (info
->start
[i
+ 1] - info
->start
[i
]) >> 2 :
227 (info
->start
[0] + info
->size
- info
->start
[i
]) >> 2;
230 flash
= (unsigned long *) info
->start
[i
], erased
= 1;
231 (flash
!= (unsigned long *) info
->start
[i
] + size
) && erased
;
234 erased
= *flash
== ~0x0UL
;
236 printf (" %08lX %s %s",
239 info
->protect
[i
] ? "(RO)" : " ");
245 /*-----------------------------------------------------------------------
249 * The following code cannot be run from FLASH!
252 ulong
flash_get_size (FPWV
*addr
, flash_info_t
*info
)
256 /* Write auto select command: read Manufacturer ID */
257 /* Write auto select command sequence and test FLASH answer */
258 addr
[FLASH_CYCLE1
] = (FPW
)0x00AA00AA; /* for AMD, Intel ignores this */
259 addr
[FLASH_CYCLE2
] = (FPW
)0x00550055; /* for AMD, Intel ignores this */
260 addr
[FLASH_CYCLE1
] = (FPW
)0x00900090; /* selects Intel or AMD */
262 /* The manufacturer codes are only 1 byte, so just use 1 byte.
263 * This works for any bus width and any FLASH device width.
266 switch (addr
[FLASH_ID1
] & 0xff) {
268 case (uchar
)AMD_MANUFACT
:
269 info
->flash_id
= FLASH_MAN_AMD
;
273 case (uchar
)INTEL_MANUFACT
:
274 info
->flash_id
= FLASH_MAN_INTEL
;
279 printf ("unknown vendor=%x ", addr
[FLASH_ID1
] & 0xff);
280 info
->flash_id
= FLASH_UNKNOWN
;
281 info
->sector_count
= 0;
286 /* Check 16 bits or 32 bits of ID so work on 32 or 16 bit bus. */
287 if (info
->flash_id
!= FLASH_UNKNOWN
) switch ((FPW
)addr
[FLASH_ID2
]) {
289 case (FPW
)AMD_ID_LV160B
:
290 info
->flash_id
+= FLASH_AM160B
;
291 info
->sector_count
= 35;
292 info
->size
= 0x00200000;
293 info
->start
[0] = (ulong
)addr
;
294 info
->start
[1] = (ulong
)addr
+ 0x4000;
295 info
->start
[2] = (ulong
)addr
+ 0x6000;
296 info
->start
[3] = (ulong
)addr
+ 0x8000;
297 for (i
= 4; i
< info
->sector_count
; i
++)
299 info
->start
[i
] = (ulong
)addr
+ 0x10000 * (i
-3);
303 case (FPW
)AMD_ID_LV065D
:
304 info
->flash_id
+= FLASH_AMDLV065D
;
305 info
->sector_count
= 128;
306 info
->size
= 0x00800000;
307 for (i
= 0; i
< info
->sector_count
; i
++)
309 info
->start
[i
] = (ulong
)addr
+ 0x10000 * i
;
313 case (FPW
)AMD_ID_MIRROR
:
314 /* MIRROR BIT FLASH, read more ID bytes */
315 if ((FPW
)addr
[FLASH_ID3
] == (FPW
)AMD_ID_LV640U_2
&&
316 (FPW
)addr
[FLASH_ID4
] == (FPW
)AMD_ID_LV640U_3
)
318 info
->flash_id
+= FLASH_AMLV640U
;
319 info
->sector_count
= 128;
320 info
->size
= 0x00800000;
321 for (i
= 0; i
< info
->sector_count
; i
++)
323 info
->start
[i
] = (ulong
)addr
+ 0x10000 * i
;
327 if ((FPW
)addr
[FLASH_ID3
] == (FPW
)AMD_ID_LV256U_2
&&
328 (FPW
)addr
[FLASH_ID4
] == (FPW
)AMD_ID_LV256U_3
)
330 /* attention: only the first 16 MB will be used in u-boot */
331 info
->flash_id
+= FLASH_AMLV256U
;
332 info
->sector_count
= 256;
333 info
->size
= 0x01000000;
334 for (i
= 0; i
< info
->sector_count
; i
++)
336 info
->start
[i
] = (ulong
)addr
+ 0x10000 * i
;
341 /* fall thru to here ! */
343 printf ("unknown AMD device=%x %x %x",
344 (FPW
)addr
[FLASH_ID2
],
345 (FPW
)addr
[FLASH_ID3
],
346 (FPW
)addr
[FLASH_ID4
]);
347 info
->flash_id
= FLASH_UNKNOWN
;
348 info
->sector_count
= 0;
349 info
->size
= 0x800000;
353 /* Put FLASH back in read mode */
359 /*-----------------------------------------------------------------------
362 int flash_erase (flash_info_t
*info
, int s_first
, int s_last
)
365 int flag
, prot
, sect
;
366 int intel
= (info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_INTEL
;
367 ulong start
, now
, last
;
370 if ((s_first
< 0) || (s_first
> s_last
)) {
371 if (info
->flash_id
== FLASH_UNKNOWN
) {
372 printf ("- missing\n");
374 printf ("- no sectors to erase\n");
379 switch (info
->flash_id
& FLASH_TYPEMASK
) {
385 printf ("Can't erase unknown flash type %08lx - aborted\n",
391 for (sect
=s_first
; sect
<=s_last
; ++sect
) {
392 if (info
->protect
[sect
]) {
398 printf ("- Warning: %d protected sectors will not be erased!\n",
406 /* Start erase on unprotected sectors */
407 for (sect
= s_first
; sect
<=s_last
&& rcode
== 0; sect
++) {
409 if (info
->protect
[sect
] != 0) /* protected, skip it */
412 /* Disable interrupts which might cause a timeout here */
413 flag
= disable_interrupts();
415 addr
= (FPWV
*)(info
->start
[sect
]);
417 *addr
= (FPW
)0x00500050; /* clear status register */
418 *addr
= (FPW
)0x00200020; /* erase setup */
419 *addr
= (FPW
)0x00D000D0; /* erase confirm */
422 /* must be AMD style if not Intel */
423 FPWV
*base
; /* first address in bank */
425 base
= (FPWV
*)(info
->start
[0]);
426 base
[FLASH_CYCLE1
] = (FPW
)0x00AA00AA; /* unlock */
427 base
[FLASH_CYCLE2
] = (FPW
)0x00550055; /* unlock */
428 base
[FLASH_CYCLE1
] = (FPW
)0x00800080; /* erase mode */
429 base
[FLASH_CYCLE1
] = (FPW
)0x00AA00AA; /* unlock */
430 base
[FLASH_CYCLE2
] = (FPW
)0x00550055; /* unlock */
431 *addr
= (FPW
)0x00300030; /* erase sector */
434 /* re-enable interrupts if necessary */
438 start
= get_timer(0);
440 /* wait at least 50us for AMD, 80us for Intel.
445 while ((*addr
& (FPW
)0x00800080) != (FPW
)0x00800080) {
446 if ((now
= get_timer(start
)) > CONFIG_SYS_FLASH_ERASE_TOUT
) {
447 printf ("Timeout\n");
451 *addr
= (FPW
)0x00B000B0;
454 flash_reset(info
); /* reset to read mode */
455 rcode
= 1; /* failed */
459 /* show that we're waiting */
460 if ((get_timer(last
)) > CONFIG_SYS_HZ
) {/* every second */
466 /* show that we're waiting */
467 if ((get_timer(last
)) > CONFIG_SYS_HZ
) { /* every second */
472 flash_reset(info
); /* reset to read mode */
479 /*-----------------------------------------------------------------------
480 * Copy memory to flash, returns:
483 * 2 - Flash not erased
485 int write_buff (flash_info_t
*info
, uchar
*src
, ulong addr
, ulong cnt
)
487 FPW data
= 0; /* 16 or 32 bit word, matches flash bus width on MPC8XX */
488 int bytes
; /* number of bytes to program in current word */
489 int left
; /* number of bytes left to program */
492 for (left
= cnt
, res
= 0;
493 left
> 0 && res
== 0;
494 addr
+= sizeof(data
), left
-= sizeof(data
) - bytes
) {
496 bytes
= addr
& (sizeof(data
) - 1);
497 addr
&= ~(sizeof(data
) - 1);
499 /* combine source and destination data so can program
500 * an entire word of 16 or 32 bits
502 for (i
= 0; i
< sizeof(data
); i
++) {
504 if (i
< bytes
|| i
- bytes
>= left
)
505 data
+= *((uchar
*)addr
+ i
);
510 /* write one word to the flash */
511 switch (info
->flash_id
& FLASH_VENDMASK
) {
513 res
= write_word_amd(info
, (FPWV
*)addr
, data
);
516 /* unknown flash type, error! */
517 printf ("missing or unknown FLASH type\n");
518 res
= 1; /* not really a timeout, but gives error */
526 /*-----------------------------------------------------------------------
527 * Write a word to Flash for AMD FLASH
528 * A word is 16 or 32 bits, whichever the bus width of the flash bank
529 * (not an individual chip) is.
534 * 2 - Flash not erased
536 static int write_word_amd (flash_info_t
*info
, FPWV
*dest
, FPW data
)
540 int res
= 0; /* result, assume success */
541 FPWV
*base
; /* first address in flash bank */
543 /* Check if Flash is (sufficiently) erased */
544 if ((*dest
& data
) != data
) {
549 base
= (FPWV
*)(info
->start
[0]);
551 /* Disable interrupts which might cause a timeout here */
552 flag
= disable_interrupts();
554 base
[FLASH_CYCLE1
] = (FPW
)0x00AA00AA; /* unlock */
555 base
[FLASH_CYCLE2
] = (FPW
)0x00550055; /* unlock */
556 base
[FLASH_CYCLE1
] = (FPW
)0x00A000A0; /* selects program mode */
558 *dest
= data
; /* start programming the data */
560 /* re-enable interrupts if necessary */
564 start
= get_timer (0);
566 /* data polling for D7 */
567 while (res
== 0 && (*dest
& (FPW
)0x00800080) != (data
& (FPW
)0x00800080)) {
568 if (get_timer(start
) > CONFIG_SYS_FLASH_WRITE_TOUT
) {
569 *dest
= (FPW
)0x00F000F0; /* reset bank */