2 * (C) Copyright 2002-2004
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5 * (C) Copyright 2002 Jun Gu <jung@artesyncp.com>
6 * Add support for Am29F016D and dynamic switch setting.
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 * Wait for completion of each sector erase command issued
31 * Chris Hallinan - DS4.COM, Inc. - clh@net1plus.com
35 * Ported to XPedite1000, 1/2 mb boot flash only
36 * Travis B. Sawyer, <travis.sawyer@sandburst.com>
41 #include <asm/processor.h>
45 #define DEBUGF(x...) printf(x)
50 #define BOOT_SMALL_FLASH 32 /* 00100000 */
51 #define FLASH_ONBD_N 2 /* 00000010 */
52 #define FLASH_SRAM_SEL 1 /* 00000001 */
54 #define BOOT_SMALL_FLASH_VAL 4
55 #define FLASH_ONBD_N_VAL 2
56 #define FLASH_SRAM_SEL_VAL 1
58 flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
60 unsigned long flash_addr_table[512][CFG_MAX_FLASH_BANKS] = {
65 /*-----------------------------------------------------------------------
68 static ulong flash_get_size(vu_long * addr, flash_info_t * info);
69 static int write_word(flash_info_t * info, ulong dest, ulong data);
73 #define FLASH_WORD_SIZE unsigned short
75 /*-----------------------------------------------------------------------
78 unsigned long flash_init(void)
80 unsigned long total_b = 0;
81 unsigned long size_b[CFG_MAX_FLASH_BANKS];
82 unsigned short index = 0;
86 DEBUGF("FLASH: Index: %d\n", index);
88 /* Init: no FLASHes known */
89 for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
90 flash_info[i].flash_id = FLASH_UNKNOWN;
91 flash_info[i].sector_count = -1;
92 flash_info[i].size = 0;
94 /* check whether the address is 0 */
95 if (flash_addr_table[index][i] == 0) {
99 /* call flash_get_size() to initialize sector address */
100 size_b[i] = flash_get_size((vu_long *)
101 flash_addr_table[index][i],
103 flash_info[i].size = size_b[i];
104 if (flash_info[i].flash_id == FLASH_UNKNOWN) {
106 ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n",
107 i, size_b[i], size_b[i] << 20);
108 flash_info[i].sector_count = -1;
109 flash_info[i].size = 0;
112 total_b += flash_info[i].size;
115 /* FLASH protect Monitor */
116 flash_protect(FLAG_PROTECT_SET,
117 CFG_MONITOR_BASE, 0xFFFFFFFF, &flash_info[0]);
122 /*-----------------------------------------------------------------------
124 void flash_print_info(flash_info_t * info)
130 volatile unsigned long *flash;
132 if (info->flash_id == FLASH_UNKNOWN) {
133 printf("missing or unknown FLASH type\n");
137 switch (info->flash_id & FLASH_VENDMASK) {
148 printf("Unknown Vendor ");
152 switch (info->flash_id & FLASH_TYPEMASK) {
154 printf("AM29F016D (16 Mbit, uniform sector size)\n");
157 printf("AM29F040 (512 Kbit, uniform sector size)\n");
160 printf("AM29LV400B (4 Mbit, bottom boot sect)\n");
163 printf("AM29LV400T (4 Mbit, top boot sector)\n");
166 printf("AM29LV800B (8 Mbit, bottom boot sect)\n");
169 printf("AM29LV800T (8 Mbit, top boot sector)\n");
172 printf("AM29LV160B (16 Mbit, bottom boot sect)\n");
175 printf("AM29LV160T (16 Mbit, top boot sector)\n");
178 printf("AM29LV320B (32 Mbit, bottom boot sect)\n");
181 printf("AM29LV320T (32 Mbit, top boot sector)\n");
184 printf("SST39LF/VF800 (8 Mbit, uniform sector size)\n");
187 printf("SST39LF/VF160 (16 Mbit, uniform sector size)\n");
190 printf("Unknown Chip Type\n");
194 printf(" Size: %ld KB in %d Sectors\n",
195 info->size >> 10, info->sector_count);
197 printf(" Sector Start Addresses:");
198 for (i = 0; i < info->sector_count; ++i) {
200 * Check if whole sector is erased
202 if (i != (info->sector_count - 1))
203 size = info->start[i + 1] - info->start[i];
205 size = info->start[0] + info->size - info->start[i];
207 flash = (volatile unsigned long *)info->start[i];
208 size = size >> 2; /* divide by 4 for longword access */
209 for (k = 0; k < size; k++) {
210 if (*flash++ != 0xffffffff) {
220 erased ? " E" : " ", info->protect[i] ? "RO " : " ");
226 /*-----------------------------------------------------------------------
229 /*-----------------------------------------------------------------------
233 * The following code cannot be run from FLASH!
235 static ulong flash_get_size(vu_long * addr, flash_info_t * info)
238 FLASH_WORD_SIZE value;
239 ulong base = (ulong) addr;
240 volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *) addr;
242 DEBUGF("FLASH ADDR: %08x\n", (unsigned)addr);
244 /* Write auto select command: read Manufacturer ID */
246 *(FLASH_WORD_SIZE *) ((int)addr + ADDR0) = (FLASH_WORD_SIZE) 0x00AA;
248 *(FLASH_WORD_SIZE *) ((int)addr + ADDR1) = (FLASH_WORD_SIZE) 0x0055;
250 *(FLASH_WORD_SIZE *) ((int)addr + ADDR0) = (FLASH_WORD_SIZE) 0x0090;
255 DEBUGF("FLASH MANUFACT: %x\n", value);
258 case (FLASH_WORD_SIZE) AMD_MANUFACT:
259 info->flash_id = FLASH_MAN_AMD;
261 case (FLASH_WORD_SIZE) FUJ_MANUFACT:
262 info->flash_id = FLASH_MAN_FUJ;
264 case (FLASH_WORD_SIZE) SST_MANUFACT:
265 info->flash_id = FLASH_MAN_SST;
267 case (FLASH_WORD_SIZE) STM_MANUFACT:
268 info->flash_id = FLASH_MAN_STM;
271 info->flash_id = FLASH_UNKNOWN;
272 info->sector_count = 0;
274 return (0); /* no or unknown flash */
278 value = addr2[0]; /* device ID */
279 debug("\ndev_code=%x\n", value);
281 value = addr2[1]; /* device ID */
284 DEBUGF("\nFLASH DEVICEID: %x\n", value);
287 info->sector_count = CFG_MAX_FLASH_SECT;
288 info->size = 0x02000000;
290 /* set up sector start address table */
291 for (i = 0; i < info->sector_count; i++) {
292 info->start[i] = (int)base + (i * 0x00020000);
293 info->protect[i] = 0;
296 *(FLASH_WORD_SIZE *) ((int)addr) = (FLASH_WORD_SIZE) 0x00F0; /* reset bank */
301 int wait_for_DQ7(flash_info_t * info, int sect)
303 ulong start, now, last;
304 volatile FLASH_WORD_SIZE *addr =
305 (FLASH_WORD_SIZE *) (info->start[sect]);
307 start = get_timer(0);
309 while ((addr[0] & (FLASH_WORD_SIZE) 0x00800080) !=
310 (FLASH_WORD_SIZE) 0x00800080) {
311 if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
315 /* show that we're waiting */
316 if ((now - last) > 1000) { /* every second */
324 /*-----------------------------------------------------------------------
327 int flash_erase(flash_info_t * info, int s_first, int s_last)
329 volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *) (info->start[0]);
330 volatile FLASH_WORD_SIZE *addr2;
331 int flag, prot, sect, l_sect;
334 if ((s_first < 0) || (s_first > s_last)) {
335 if (info->flash_id == FLASH_UNKNOWN) {
336 printf("- missing\n");
338 printf("- no sectors to erase\n");
343 if (info->flash_id == FLASH_UNKNOWN) {
344 printf("Can't erase unknown flash type - aborted\n");
349 for (sect = s_first; sect <= s_last; ++sect) {
350 if (info->protect[sect]) {
356 printf("- Warning: %d protected sectors will not be erased!\n",
364 /* Disable interrupts which might cause a timeout here */
365 flag = disable_interrupts();
367 /* Start erase on unprotected sectors */
368 for (sect = s_first; sect <= s_last; sect++) {
369 if (info->protect[sect] == 0) { /* not protected */
370 addr2 = (FLASH_WORD_SIZE *) (info->start[sect]);
371 printf("Erasing sector %p\n", addr2);
372 *(FLASH_WORD_SIZE *) ((int)addr + ADDR0) =
373 (FLASH_WORD_SIZE) 0x00AA;
376 *(FLASH_WORD_SIZE *) ((int)addr + ADDR1) =
377 (FLASH_WORD_SIZE) 0x0055;
380 *(FLASH_WORD_SIZE *) ((int)addr + ADDR0) =
381 (FLASH_WORD_SIZE) 0x0080;
384 *(FLASH_WORD_SIZE *) ((int)addr + ADDR0) =
385 (FLASH_WORD_SIZE) 0x00AA;
388 *(FLASH_WORD_SIZE *) ((int)addr + ADDR1) =
389 (FLASH_WORD_SIZE) 0x0055;
392 addr2[0] = (FLASH_WORD_SIZE) 0x00300030; /* sector erase */
398 * Wait for each sector to complete, it's more
399 * reliable. According to AMD Spec, you must
400 * issue all erase commands within a specified
401 * timeout. This has been seen to fail, especially
402 * if printf()s are included (for debug)!!
404 wait_for_DQ7(info, sect);
408 /* re-enable interrupts if necessary */
412 /* wait at least 80us - let's wait 1 ms */
417 * We wait for the last triggered sector
421 wait_for_DQ7(info, l_sect);
425 /* reset to read mode */
426 addr = (FLASH_WORD_SIZE *) info->start[0];
427 addr[0] = (FLASH_WORD_SIZE) 0x00F000F0; /* reset bank */
433 /*-----------------------------------------------------------------------
434 * Copy memory to flash, returns:
437 * 2 - Flash not erased
439 int write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt)
443 ulong status_value = 0;
445 wp = (addr & ~3); /* get lower word aligned address */
448 * handle unaligned start bytes
450 if ((l = addr - wp) != 0) {
452 for (i = 0, cp = wp; i < l; ++i, ++cp) {
453 data = (data << 8) | (*(uchar *) cp);
455 for (; i < 4 && cnt > 0; ++i) {
456 data = (data << 8) | *src++;
460 for (; cnt == 0 && i < 4; ++i, ++cp) {
461 data = (data << 8) | (*(uchar *) cp);
464 if ((rc = write_word(info, wp, data)) != 0) {
471 * handle word aligned part
475 /*print status if needed */
476 if ((wp >= (status_value + 0x20000))
477 && (status_value < 0xFFFE0000)) {
479 printf("writing to sector 0x%X\n", status_value);
483 for (i = 0; i < 4; ++i) {
484 data = (data << 8) | *src++;
486 if ((rc = write_word(info, wp, data)) != 0) {
498 * handle unaligned tail bytes
501 for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
502 data = (data << 8) | *src++;
505 for (; i < 4; ++i, ++cp) {
506 data = (data << 8) | (*(uchar *) cp);
509 return (write_word(info, wp, data));
512 /*-----------------------------------------------------------------------
513 * Write a word to Flash, returns:
516 * 2 - Flash not erased
518 static int write_word(flash_info_t * info, ulong dest, ulong data)
520 volatile vu_long *addr2 = (vu_long *) (info->start[0]);
521 volatile FLASH_WORD_SIZE *dest2 = (FLASH_WORD_SIZE *) dest;
522 volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *) & data;
526 /* Check if Flash is (sufficiently) erased */
527 if ((*((volatile FLASH_WORD_SIZE *)dest) &
528 (FLASH_WORD_SIZE) data) != (FLASH_WORD_SIZE) data) {
532 for (i = 0; i < 4 / sizeof(FLASH_WORD_SIZE); i++) {
535 /* Disable interrupts which might cause a timeout here */
536 flag = disable_interrupts();
538 *(FLASH_WORD_SIZE *) ((int)addr2 + ADDR0) =
539 (FLASH_WORD_SIZE) 0x00AA;
542 *(FLASH_WORD_SIZE *) ((int)addr2 + ADDR1) =
543 (FLASH_WORD_SIZE) 0x0055;
546 *(FLASH_WORD_SIZE *) ((int)addr2 + ADDR0) =
547 (FLASH_WORD_SIZE) 0x00A0;
553 /* re-enable interrupts if necessary */
557 /* data polling for D7 */
558 start = get_timer(0);
559 while ((dest2[i] & (FLASH_WORD_SIZE) 0x00800080) !=
560 (data2[i] & (FLASH_WORD_SIZE) 0x00800080)) {
562 if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
571 /*-----------------------------------------------------------------------