3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5 * SPDX-License-Identifier: GPL-2.0+
10 flash_info_t flash_info
[CONFIG_SYS_MAX_FLASH_BANKS
]; /* info for FLASH chips */
12 typedef unsigned short FLASH_PORT_WIDTH
;
13 typedef volatile unsigned short FLASH_PORT_WIDTHV
;
15 #define FLASH_ID_MASK 0x00FF
17 #define FPW FLASH_PORT_WIDTH
18 #define FPWV FLASH_PORT_WIDTHV
20 #define FLASH_CYCLE1 0x0555
21 #define FLASH_CYCLE2 0x0aaa
22 #define FLASH_ID1 0x00
23 #define FLASH_ID2 0x01
24 #define FLASH_ID3 0x0E
25 #define FLASH_ID4 0x0F
27 /*-----------------------------------------------------------------------
30 static ulong
flash_get_size(FPWV
* addr
, flash_info_t
* info
);
31 static void flash_reset(flash_info_t
* info
);
32 static int write_word_amd(flash_info_t
* info
, FPWV
* dest
, FPW data
);
33 static flash_info_t
*flash_get_info(ulong base
);
35 /*-----------------------------------------------------------------------
38 * sets up flash_info and returns size of FLASH (bytes)
40 unsigned long flash_init(void)
42 unsigned long size
= 0;
44 extern void flash_preinit(void);
45 extern void flash_afterinit(uint
, ulong
, ulong
);
47 ulong flashbase
= CONFIG_SYS_FLASH_BASE
;
51 /* There is only ONE FLASH device */
52 memset(&flash_info
[i
], 0, sizeof(flash_info_t
));
53 flash_info
[i
].size
= flash_get_size((FPW
*) flashbase
, &flash_info
[i
]);
54 size
+= flash_info
[i
].size
;
56 #if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
57 /* monitor protection ON by default */
58 flash_protect(FLAG_PROTECT_SET
, CONFIG_SYS_MONITOR_BASE
,
59 CONFIG_SYS_MONITOR_BASE
+ monitor_flash_len
- 1,
60 flash_get_info(CONFIG_SYS_MONITOR_BASE
));
63 #ifdef CONFIG_ENV_IS_IN_FLASH
64 /* ENV protection ON by default */
65 flash_protect(FLAG_PROTECT_SET
, CONFIG_ENV_ADDR
,
66 CONFIG_ENV_ADDR
+ CONFIG_ENV_SIZE
- 1,
67 flash_get_info(CONFIG_ENV_ADDR
));
70 flash_afterinit(i
, flash_info
[i
].start
[0], flash_info
[i
].size
);
71 return size
? size
: 1;
74 /*-----------------------------------------------------------------------
76 static void flash_reset(flash_info_t
* info
) {
77 FPWV
*base
= (FPWV
*) (info
->start
[0]);
79 /* Put FLASH back in read mode */
80 if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_INTEL
) {
81 *base
= (FPW
) 0x00FF00FF; /* Intel Read Mode */
82 } else if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_AMD
) {
83 *base
= (FPW
) 0x00F000F0; /* AMD Read Mode */
87 /*-----------------------------------------------------------------------
90 static flash_info_t
*flash_get_info(ulong base
) {
94 for (i
= 0; i
< CONFIG_SYS_MAX_FLASH_BANKS
; i
++) {
95 info
= &flash_info
[i
];
96 if ((info
->size
) && (info
->start
[0] <= base
)
97 && (base
<= info
->start
[0] + info
->size
- 1)) {
101 return (i
== CONFIG_SYS_MAX_FLASH_BANKS
? 0 : info
);
104 /*-----------------------------------------------------------------------
107 void flash_print_info(flash_info_t
* info
) {
111 if (info
->flash_id
== FLASH_UNKNOWN
) {
112 printf("missing or unknown FLASH type\n");
116 switch (info
->flash_id
& FLASH_VENDMASK
) {
121 printf("Unknown Vendor ");
125 switch (info
->flash_id
& FLASH_TYPEMASK
) {
127 fmt
= "29LV256M (256 Mbit)\n";
130 fmt
= "Unknown Chip Type\n";
135 printf(" Size: %ld MB in %d Sectors\n", info
->size
>> 20,
137 printf(" Sector Start Addresses:");
139 for (i
= 0; i
< info
->sector_count
; ++i
) {
142 ulong
*flash
= (unsigned long *)info
->start
[i
];
149 * Check if whole sector is erased
153 (info
->sector_count
- 1)) ? (info
->start
[i
+ 1] -
154 info
->start
[i
]) >> 2 : (info
->
164 for (flash
= (unsigned long *)info
->start
[i
], erased
= 1;
165 (flash
!= (unsigned long *)info
->start
[i
] + size
)
166 && erased
; flash
++) {
167 erased
= *flash
== ~0x0UL
;
169 printf(" %08lX %s %s", info
->start
[i
], erased
? "E" : " ",
170 info
->protect
[i
] ? "(RO)" : " ");
176 /*-----------------------------------------------------------------------
180 * The following code cannot be run from FLASH!
183 ulong
flash_get_size(FPWV
* addr
, flash_info_t
* info
) {
186 /* Write auto select command: read Manufacturer ID */
187 /* Write auto select command sequence and test FLASH answer */
188 addr
[FLASH_CYCLE1
] = (FPW
) 0x00AA00AA; /* for AMD, Intel ignores this */
189 addr
[FLASH_CYCLE2
] = (FPW
) 0x00550055; /* for AMD, Intel ignores this */
190 addr
[FLASH_CYCLE1
] = (FPW
) 0x00900090; /* selects Intel or AMD */
192 /* The manufacturer codes are only 1 byte, so just use 1 byte. */
193 /* This works for any bus width and any FLASH device width. */
195 switch (addr
[FLASH_ID1
] & 0x00ff) {
196 case (uchar
) AMD_MANUFACT
:
197 info
->flash_id
= FLASH_MAN_AMD
;
200 printf("unknown vendor=%x ", addr
[FLASH_ID1
] & 0xff);
201 info
->flash_id
= FLASH_UNKNOWN
;
202 info
->sector_count
= 0;
207 /* Check 16 bits or 32 bits of ID so work on 32 or 16 bit bus. */
208 if (info
->flash_id
!= FLASH_UNKNOWN
) {
209 switch ((FPW
) addr
[FLASH_ID2
]) {
210 case (FPW
) AMD_ID_MIRROR
:
211 /* MIRROR BIT FLASH, read more ID bytes */
212 if ((FPW
) addr
[FLASH_ID3
] == (FPW
) AMD_ID_LV256U_2
213 && (FPW
) addr
[FLASH_ID4
] == (FPW
) AMD_ID_LV256U_3
) {
214 /* attention: only the first 16 MB will be used in u-boot */
215 info
->flash_id
+= FLASH_AMLV256U
;
216 info
->sector_count
= 512;
217 info
->size
= 0x02000000;
218 for (i
= 0; i
< info
->sector_count
; i
++) {
220 (ulong
) addr
+ 0x10000 * i
;
224 /* fall thru to here ! */
226 printf("unknown AMD device=%x %x %x",
227 (FPW
) addr
[FLASH_ID2
], (FPW
) addr
[FLASH_ID3
],
228 (FPW
) addr
[FLASH_ID4
]);
229 info
->flash_id
= FLASH_UNKNOWN
;
230 info
->sector_count
= 0;
231 info
->size
= 0x800000;
235 /* Put FLASH back in read mode */
241 /*-----------------------------------------------------------------------
244 int flash_erase(flash_info_t
* info
, int s_first
, int s_last
) {
246 int flag
, prot
, sect
;
247 int intel
= (info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_INTEL
;
248 ulong start
, now
, last
;
251 if ((s_first
< 0) || (s_first
> s_last
)) {
252 if (info
->flash_id
== FLASH_UNKNOWN
) {
253 printf("- missing\n");
255 printf("- no sectors to erase\n");
260 switch (info
->flash_id
& FLASH_TYPEMASK
) {
265 printf("Can't erase unknown flash type %08lx - aborted\n",
271 for (sect
= s_first
; sect
<= s_last
; ++sect
) {
272 if (info
->protect
[sect
]) {
278 printf("- Warning: %d protected sectors will not be erased!\n",
286 /* Start erase on unprotected sectors */
287 for (sect
= s_first
; sect
<= s_last
&& rcode
== 0; sect
++) {
288 if (info
->protect
[sect
] != 0) { /* protected, skip it */
291 /* Disable interrupts which might cause a timeout here */
292 flag
= disable_interrupts();
294 addr
= (FPWV
*) (info
->start
[sect
]);
296 *addr
= (FPW
) 0x00500050; /* clear status register */
297 *addr
= (FPW
) 0x00200020; /* erase setup */
298 *addr
= (FPW
) 0x00D000D0; /* erase confirm */
300 /* must be AMD style if not Intel */
301 FPWV
*base
; /* first address in bank */
303 base
= (FPWV
*) (info
->start
[0]);
304 base
[FLASH_CYCLE1
] = (FPW
) 0x00AA00AA; /* unlock */
305 base
[FLASH_CYCLE2
] = (FPW
) 0x00550055; /* unlock */
306 base
[FLASH_CYCLE1
] = (FPW
) 0x00800080; /* erase mode */
307 base
[FLASH_CYCLE1
] = (FPW
) 0x00AA00AA; /* unlock */
308 base
[FLASH_CYCLE2
] = (FPW
) 0x00550055; /* unlock */
309 *addr
= (FPW
) 0x00300030; /* erase sector */
312 /* re-enable interrupts if necessary */
316 start
= get_timer(0);
318 /* wait at least 50us for AMD, 80us for Intel. */
319 /* Let's wait 1 ms. */
322 while ((*addr
& (FPW
) 0x00800080) != (FPW
) 0x00800080) {
323 if ((now
= get_timer(start
)) > CONFIG_SYS_FLASH_ERASE_TOUT
) {
327 *addr
= (FPW
) 0x00B000B0;
329 flash_reset(info
); /* reset to read mode */
330 rcode
= 1; /* failed */
333 /* show that we're waiting */
334 if ((get_timer(last
)) > CONFIG_SYS_HZ
) {
340 /* show that we're waiting */
341 if ((get_timer(last
)) > CONFIG_SYS_HZ
) {
346 flash_reset(info
); /* reset to read mode */
352 /*-----------------------------------------------------------------------
353 * Copy memory to flash, returns:
356 * 2 - Flash not erased
358 int write_buff(flash_info_t
* info
, uchar
* src
, ulong addr
, ulong cnt
)
360 FPW data
= 0; /* 16 or 32 bit word, matches flash bus width on MPC8XX */
361 int bytes
; /* number of bytes to program in current word */
362 int left
; /* number of bytes left to program */
365 for (left
= cnt
, res
= 0;
366 left
> 0 && res
== 0;
367 addr
+= sizeof(data
), left
-= sizeof(data
) - bytes
) {
369 bytes
= addr
& (sizeof(data
) - 1);
370 addr
&= ~(sizeof(data
) - 1);
372 /* combine source and destination data so can program
373 * an entire word of 16 or 32 bits
375 for (i
= 0; i
< sizeof(data
); i
++) {
377 if (i
< bytes
|| i
- bytes
>= left
)
378 data
+= *((uchar
*) addr
+ i
);
383 /* write one word to the flash */
384 switch (info
->flash_id
& FLASH_VENDMASK
) {
386 res
= write_word_amd(info
, (FPWV
*) addr
, data
);
389 /* unknown flash type, error! */
390 printf("missing or unknown FLASH type\n");
391 res
= 1; /* not really a timeout, but gives error */
398 /*-----------------------------------------------------------------------
399 * Write a word to Flash for AMD FLASH
400 * A word is 16 or 32 bits, whichever the bus width of the flash bank
401 * (not an individual chip) is.
406 * 2 - Flash not erased
408 static int write_word_amd(flash_info_t
* info
, FPWV
* dest
, FPW data
) {
411 int res
= 0; /* result, assume success */
412 FPWV
*base
; /* first address in flash bank */
414 /* Check if Flash is (sufficiently) erased */
415 if ((*dest
& data
) != data
) {
419 base
= (FPWV
*) (info
->start
[0]);
421 /* Disable interrupts which might cause a timeout here */
422 flag
= disable_interrupts();
424 base
[FLASH_CYCLE1
] = (FPW
) 0x00AA00AA; /* unlock */
425 base
[FLASH_CYCLE2
] = (FPW
) 0x00550055; /* unlock */
426 base
[FLASH_CYCLE1
] = (FPW
) 0x00A000A0; /* selects program mode */
428 *dest
= data
; /* start programming the data */
430 /* re-enable interrupts if necessary */
434 start
= get_timer(0);
436 /* data polling for D7 */
438 && (*dest
& (FPW
) 0x00800080) != (data
& (FPW
) 0x00800080)) {
439 if (get_timer(start
) > CONFIG_SYS_FLASH_WRITE_TOUT
) {
440 *dest
= (FPW
) 0x00F000F0; /* reset bank */