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 */