2 * (C) Copyright 2002, 2003
3 * Daniel Engström, Omicron Ceti AB, daniel@omicron.se
6 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
7 * Alex Zuepke <azu@sysgo.de>
9 * See file CREDITS for list of people who contributed to this
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License as
14 * published by the Free Software Foundation; either version 2 of
15 * the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
31 #include <asm/ic/sc520.h>
33 #define PROBE_BUFFER_SIZE 1024
34 static unsigned char buffer[PROBE_BUFFER_SIZE];
37 #define SC520_MAX_FLASH_BANKS 1
38 #define SC520_FLASH_BANK0_BASE 0x38000000 /* BOOTCS */
39 #define SC520_FLASH_BANKSIZE 0x8000000
41 #define A29LV641DH_SIZE 0x800000
42 #define A29LV641DH_SECTORS 128
44 #define A29LV641MH_SIZE 0x800000
45 #define A29LV641MH_SECTORS 128
47 #define I28F320J3A_SIZE 0x400000
48 #define I28F320J3A_SECTORS 32
50 #define I28F640J3A_SIZE 0x800000
51 #define I28F640J3A_SECTORS 64
53 #define I28F128J3A_SIZE 0x1000000
54 #define I28F128J3A_SECTORS 128
56 flash_info_t flash_info[SC520_MAX_FLASH_BANKS];
62 /*-----------------------------------------------------------------------
66 static u32 _probe_flash(u32 addr, u32 bw, int il)
70 /* First do an unlock cycle for the benefit of
71 * devices that need it */
76 *(volatile u8*)(addr+0x5555) = 0xaa;
77 *(volatile u8*)(addr+0x2aaa) = 0x55;
78 *(volatile u8*)(addr+0x5555) = 0x90;
81 result = *(volatile u8*)addr;
85 result |= *(volatile u8*)(addr+2);
87 /* Return device to data mode */
88 *(volatile u8*)addr = 0xff;
89 *(volatile u8*)(addr+0x5555), 0xf0;
93 *(volatile u16*)(addr+0xaaaa) = 0xaaaa;
94 *(volatile u16*)(addr+0x5554) = 0x5555;
96 /* Issue identification command */
98 *(volatile u16*)(addr+0xaaaa) = 0x9090;
101 result = *(volatile u8*)addr;
105 result |= *(volatile u8*)(addr+2);
107 /* Return device to data mode */
108 *(volatile u16*)addr = 0xffff;
109 *(volatile u16*)(addr+0xaaaa), 0xf0f0;
112 *(volatile u8*)(addr+0xaaaa) = 0x90;
114 result = *(volatile u16*)addr;
118 result |= *(volatile u16*)(addr+2);
120 /* Return device to data mode */
121 *(volatile u8*)addr = 0xff;
122 *(volatile u8*)(addr+0xaaaa), 0xf0;
128 *(volatile u32*)(addr+0x5554) = 0xaaaaaaaa;
129 *(volatile u32*)(addr+0xaaa8) = 0x55555555;
133 /* Issue identification command */
134 *(volatile u8*)(addr+0x5554) = 0x90;
137 result = *(volatile u16*)addr;
141 result |= *(volatile u16*)(addr+4);
143 /* Return device to data mode */
144 *(volatile u8*)addr = 0xff;
145 *(volatile u8*)(addr+0x5554), 0xf0;
149 /* Issue identification command */
150 *(volatile u32*)(addr + 0x5554) = 0x00900090;
153 result = *(volatile u16*)addr;
157 result |= *(volatile u16*)(addr+4);
159 /* Return device to data mode */
160 *(volatile u32*)addr = 0x00ff00ff;
161 *(volatile u32*)(addr+0x5554), 0x00f000f0;
165 /* Issue identification command */
166 *(volatile u32*)(addr+0x5554) = 0x90909090;
169 result = *(volatile u8*)addr;
173 result |= *(volatile u8*)(addr+4);
175 /* Return device to data mode */
176 *(volatile u32*)addr = 0xffffffff;
177 *(volatile u32*)(addr+0x5554), 0xf0f0f0f0;
188 extern int _probe_flash_end;
189 asm ("_probe_flash_end:\n"
192 static int identify_flash(unsigned address, int width)
200 u32 (*_probe_flash_ptr)(u32 a, u32 bw, int il);
202 size = (unsigned)&_probe_flash_end - (unsigned)_probe_flash;
204 if (size > PROBE_BUFFER_SIZE) {
205 printf("_probe_flash() routine too large (%d) %p - %p\n",
206 size, &_probe_flash_end, _probe_flash);
210 memcpy(buffer, _probe_flash, size);
211 _probe_flash_ptr = (void*)buffer;
213 is = disable_interrupts();
214 res = _probe_flash_ptr(address, width, 1);
221 device = res & 0xffff;
227 ulong flash_init(void)
232 for (i = 0; i < SC520_MAX_FLASH_BANKS; i++) {
237 memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
240 flashbase = SC520_FLASH_BANK0_BASE;
243 panic("configured to many flash banks!\n");
246 id = identify_flash(flashbase, 2);
250 flash_info[i].flash_id =
251 (AMD_MANUFACT & FLASH_VENDMASK) |
252 (AMD_ID_LV640U & FLASH_TYPEMASK);
254 flash_info[i].size = A29LV641DH_SIZE;
255 flash_info[i].sector_count = A29LV641DH_SECTORS;
256 sectsize = A29LV641DH_SIZE/A29LV641DH_SECTORS;
257 printf("Bank %d: AMD 29LV641DH\n", i);
262 flash_info[i].flash_id =
263 (AMD_MANUFACT & FLASH_VENDMASK) |
264 (AMD_ID_DL640 & FLASH_TYPEMASK);
266 flash_info[i].size = A29LV641MH_SIZE;
267 flash_info[i].sector_count = A29LV641MH_SECTORS;
268 sectsize = A29LV641MH_SIZE/A29LV641MH_SECTORS;
269 printf("Bank %d: AMD 29LV641MH\n", i);
274 flash_info[i].flash_id =
275 (INTEL_MANUFACT & FLASH_VENDMASK) |
276 (INTEL_ID_28F320J3A & FLASH_TYPEMASK);
278 flash_info[i].size = I28F320J3A_SIZE;
279 flash_info[i].sector_count = I28F320J3A_SECTORS;
280 sectsize = I28F320J3A_SIZE/I28F320J3A_SECTORS;
281 printf("Bank %d: Intel 28F320J3A\n", i);
286 flash_info[i].flash_id =
287 (INTEL_MANUFACT & FLASH_VENDMASK) |
288 (INTEL_ID_28F640J3A & FLASH_TYPEMASK);
290 flash_info[i].size = I28F640J3A_SIZE;
291 flash_info[i].sector_count = I28F640J3A_SECTORS;
292 sectsize = I28F640J3A_SIZE/I28F640J3A_SECTORS;
293 printf("Bank %d: Intel 28F640J3A\n", i);
298 flash_info[i].flash_id =
299 (INTEL_MANUFACT & FLASH_VENDMASK) |
300 (INTEL_ID_28F128J3A & FLASH_TYPEMASK);
302 flash_info[i].size = I28F128J3A_SIZE;
303 flash_info[i].sector_count = I28F128J3A_SECTORS;
304 sectsize = I28F128J3A_SIZE/I28F128J3A_SECTORS;
305 printf("Bank %d: Intel 28F128J3A\n", i);
309 printf("Bank %d have unknown flash %08x\n", i, id);
310 flash_info[i].flash_id = FLASH_UNKNOWN;
314 for (j = 0; j < flash_info[i].sector_count; j++) {
315 flash_info[i].start[j] = flashbase + j * sectsize;
317 size += flash_info[i].size;
319 flash_protect(FLAG_PROTECT_CLEAR,
320 flash_info[i].start[0],
321 flash_info[i].start[0] + flash_info[i].size - 1,
326 * Protect monitor and environment sectors
328 flash_protect(FLAG_PROTECT_SET,
333 flash_protect(FLAG_PROTECT_SET,
335 CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
341 /*-----------------------------------------------------------------------
343 void flash_print_info(flash_info_t *info)
347 switch (info->flash_id & FLASH_VENDMASK) {
348 case (INTEL_MANUFACT & FLASH_VENDMASK):
350 switch (info->flash_id & FLASH_TYPEMASK) {
351 case (INTEL_ID_28F320J3A & FLASH_TYPEMASK):
352 printf("1x I28F320J3A (32Mbit)\n");
354 case (INTEL_ID_28F640J3A & FLASH_TYPEMASK):
355 printf("1x I28F640J3A (64Mbit)\n");
357 case (INTEL_ID_28F128J3A & FLASH_TYPEMASK):
358 printf("1x I28F128J3A (128Mbit)\n");
361 printf("Unknown Chip Type\n");
368 case (AMD_MANUFACT & FLASH_VENDMASK):
370 switch (info->flash_id & FLASH_TYPEMASK) {
371 case (AMD_ID_LV640U & FLASH_TYPEMASK):
372 printf("1x AMD29LV641DH (64Mbit)\n");
374 case (AMD_ID_DL640 & FLASH_TYPEMASK):
375 printf("1x AMD29LV641MH (64Mbit)\n");
378 printf("Unknown Chip Type\n");
385 printf("Unknown Vendor ");
390 printf(" Size: %ld MB in %d Sectors\n",
391 info->size >> 20, info->sector_count);
393 printf(" Sector Start Addresses:");
394 for (i = 0; i < info->sector_count; i++) {
398 printf (" %08lX%s", info->start[i],
399 info->protect[i] ? " (RO)" : " ");
406 /*-----------------------------------------------------------------------
410 static u32 _amd_erase_flash(u32 addr, u32 sector)
415 *(volatile u16*)(addr + 0xaaaa) = 0x00AA;
416 *(volatile u16*)(addr + 0x5554) = 0x0055;
417 *(volatile u16*)(addr + 0xaaaa) = 0x0080;
419 *(volatile u16*)(addr + 0xaaaa) = 0x00AA;
420 *(volatile u16*)(addr + 0x5554) = 0x0055;
421 /* Sector erase command comes last */
422 *(volatile u16*)(addr + sector) = 0x0030;
424 elapsed = *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI); /* dummy read */
426 while (((*(volatile u16*)(addr + sector)) & 0x0080) != 0x0080) {
428 elapsed += *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI);
429 if (elapsed > ((CFG_FLASH_ERASE_TOUT/CFG_HZ) * 1000)) {
430 *(volatile u16*)(addr) = 0x00f0;
435 *(volatile u16*)(addr) = 0x00f0;
440 extern int _amd_erase_flash_end;
441 asm ("_amd_erase_flash_end:\n"
444 /* this needs to be inlined, the SWTMRMMILLI register is reset by each read */
445 #define __udelay(delay) \
450 micro = *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI); \
454 milli += *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI); \
455 micro = *(volatile u16*)(0xfffef000+SC520_SWTMRMICRO); \
457 if ((delay) <= (micro + (milli * 1000))) { \
463 static u32 _intel_erase_flash(u32 addr, u32 sector)
467 *(volatile u16*)(addr + sector) = 0x0050; /* clear status register */
468 *(volatile u16*)(addr + sector) = 0x0020; /* erase setup */
469 *(volatile u16*)(addr + sector) = 0x00D0; /* erase confirm */
472 /* Wait at least 80us - let's wait 1 ms */
476 while (((*(volatile u16*)(addr + sector)) & 0x0080) != 0x0080) {
477 elapsed += *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI);
478 if (elapsed > ((CFG_FLASH_ERASE_TOUT/CFG_HZ) * 1000)) {
479 *(volatile u16*)(addr + sector) = 0x00B0; /* suspend erase */
480 *(volatile u16*)(addr + sector) = 0x00FF; /* reset to read mode */
485 *(volatile u16*)(addr + sector) = 0x00FF; /* reset to read mode */
491 extern int _intel_erase_flash_end;
492 asm ("_intel_erase_flash_end:\n"
495 int flash_erase(flash_info_t *info, int s_first, int s_last)
497 u32 (*_erase_flash_ptr)(u32 a, u32 so);
502 if ((s_first < 0) || (s_first > s_last)) {
503 if (info->flash_id == FLASH_UNKNOWN) {
504 printf("- missing\n");
506 printf("- no sectors to erase\n");
511 if ((info->flash_id & FLASH_VENDMASK) == (AMD_MANUFACT & FLASH_VENDMASK)) {
512 size = (unsigned)&_amd_erase_flash_end - (unsigned)_amd_erase_flash;
514 if (size > PROBE_BUFFER_SIZE) {
515 printf("_amd_erase_flash() routine too large (%d) %p - %p\n",
516 size, &_amd_erase_flash_end, _amd_erase_flash);
520 memcpy(buffer, _amd_erase_flash, size);
521 _erase_flash_ptr = (void*)buffer;
523 } else if ((info->flash_id & FLASH_VENDMASK) == (INTEL_MANUFACT & FLASH_VENDMASK)) {
524 size = (unsigned)&_intel_erase_flash_end - (unsigned)_intel_erase_flash;
526 if (size > PROBE_BUFFER_SIZE) {
527 printf("_intel_erase_flash() routine too large (%d) %p - %p\n",
528 size, &_intel_erase_flash_end, _intel_erase_flash);
532 memcpy(buffer, _intel_erase_flash, size);
533 _erase_flash_ptr = (void*)buffer;
535 printf ("Can't erase unknown flash type - aborted\n");
540 for (sect=s_first; sect<=s_last; ++sect) {
541 if (info->protect[sect]) {
547 printf ("- Warning: %d protected sectors will not be erased!\n", prot);
553 /* Start erase on unprotected sectors */
554 for (sect = s_first; sect<=s_last; sect++) {
556 if (info->protect[sect] == 0) { /* not protected */
560 /* Disable interrupts which might cause a timeout here */
561 flag = disable_interrupts();
563 res = _erase_flash_ptr(info->start[0], info->start[sect]-info->start[0]);
565 /* re-enable interrupts if necessary */
572 printf("Erase timed out, sector %d\n", sect);
584 /*-----------------------------------------------------------------------
585 * Write a word to Flash, returns:
588 * 2 - Flash not erased
590 static int _amd_write_word(unsigned start, unsigned dest, unsigned data)
592 volatile u16 *addr2 = (u16*)start;
593 volatile u16 *dest2 = (u16*)dest;
594 volatile u16 *data2 = (u16*)&data;
598 /* Check if Flash is (sufficiently) erased */
599 if ((*((volatile u16*)dest) & (u16)data) != (u16)data) {
603 for (i = 0; i < 2; i++) {
606 addr2[0x5555] = 0x00AA;
607 addr2[0x2aaa] = 0x0055;
608 addr2[0x5555] = 0x00A0;
610 dest2[i] = (data >> (i*16)) & 0xffff;
612 elapsed = *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI); /* dummy read */
615 /* data polling for D7 */
616 while ((dest2[i] & 0x0080) != (data2[i] & 0x0080)) {
617 elapsed += *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI);
618 if (elapsed > ((CFG_FLASH_WRITE_TOUT/CFG_HZ) * 1000)) {
630 extern int _amd_write_word_end;
631 asm ("_amd_write_word_end:\n"
636 static int _intel_write_word(unsigned start, unsigned dest, unsigned data)
641 /* Check if Flash is (sufficiently) erased */
642 if ((*((volatile u16*)dest) & (u16)data) != (u16)data) {
646 for (i = 0; i < 2; i++) {
648 *(volatile u16*)(dest+2*i) = 0x0040; /* write setup */
649 *(volatile u16*)(dest+2*i) = (data >> (i*16)) & 0xffff;
651 elapsed = *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI); /* dummy read */
654 /* data polling for D7 */
655 while ((*(volatile u16*)dest & 0x0080) != 0x0080) {
656 elapsed += *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI);
657 if (elapsed > ((CFG_FLASH_WRITE_TOUT/CFG_HZ) * 1000)) {
658 *(volatile u16*)dest = 0x00ff;
664 *(volatile u16*)dest = 0x00ff;
671 extern int _intel_write_word_end;
672 asm ("_intel_write_word_end:\n"
676 /*-----------------------------------------------------------------------
677 * Copy memory to flash, returns:
680 * 2 - Flash not erased
681 * 3 - Unsupported flash type
684 int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
689 u32 (*_write_word_ptr)(unsigned start, unsigned dest, unsigned data);
692 if ((info->flash_id & FLASH_VENDMASK) == (AMD_MANUFACT & FLASH_VENDMASK)) {
693 size = (unsigned)&_amd_write_word_end - (unsigned)_amd_write_word;
695 if (size > PROBE_BUFFER_SIZE) {
696 printf("_amd_write_word() routine too large (%d) %p - %p\n",
697 size, &_amd_write_word_end, _amd_write_word);
701 memcpy(buffer, _amd_write_word, size);
702 _write_word_ptr = (void*)buffer;
704 } else if ((info->flash_id & FLASH_VENDMASK) == (INTEL_MANUFACT & FLASH_VENDMASK)) {
705 size = (unsigned)&_intel_write_word_end - (unsigned)_intel_write_word;
707 if (size > PROBE_BUFFER_SIZE) {
708 printf("_intel_write_word() routine too large (%d) %p - %p\n",
709 size, &_intel_write_word_end, _intel_write_word);
713 memcpy(buffer, _intel_write_word, size);
714 _write_word_ptr = (void*)buffer;
716 printf ("Can't program unknown flash type - aborted\n");
721 wp = (addr & ~3); /* get lower word aligned address */
725 * handle unaligned start bytes
727 if ((l = addr - wp) != 0) {
729 for (i=0, cp=wp; i<l; ++i, ++cp) {
730 data |= (*(uchar *)cp) << (8*i);
732 for (; i<4 && cnt>0; ++i) {
733 data |= *src++ << (8*i);
737 for (; cnt==0 && i<4; ++i, ++cp) {
738 data |= (*(uchar *)cp) << (8*i);
741 /* Disable interrupts which might cause a timeout here */
742 flag = disable_interrupts();
744 rc = _write_word_ptr(info->start[0], wp, data);
746 /* re-enable interrupts if necessary */
757 * handle word aligned part
762 for (i=0; i<4; ++i) {
763 data |= *src++ << (8*i);
766 /* Disable interrupts which might cause a timeout here */
767 flag = disable_interrupts();
769 rc = _write_word_ptr(info->start[0], wp, data);
771 /* re-enable interrupts if necessary */
787 * handle unaligned tail bytes
790 for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
791 data |= *src++ << (8*i);
795 for (; i<4; ++i, ++cp) {
796 data |= (*(uchar *)cp) << (8*i);
799 /* Disable interrupts which might cause a timeout here */
800 flag = disable_interrupts();
802 rc = _write_word_ptr(info->start[0], wp, data);
804 /* re-enable interrupts if necessary */