7 * See file CREDITS for list of people who contributed to this
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
27 #include <asm/processor.h>
28 #include <asm/pci_io.h>
31 int (*do_flash_erase)(flash_info_t*, uint32_t, uint32_t);
32 int (*write_dword)(flash_info_t*, ulong, uint64_t);
34 typedef uint64_t cfi_word;
36 #define cfi_read(flash, addr) *((volatile cfi_word*)(flash->start[0] + addr))
38 #define cfi_write(flash, val, addr) \
39 move64((cfi_word*)&val, \
40 (cfi_word*)(flash->start[0] + addr))
42 #define CMD(x) ((((cfi_word)x)<<48)|(((cfi_word)x)<<32)|(((cfi_word)x)<<16)|(((cfi_word)x)))
44 static void write32(unsigned long addr, uint32_t value)
46 *(volatile uint32_t*)(addr) = value;
50 static uint32_t read32(unsigned long addr)
53 value = *(volatile uint32_t*)addr;
58 static cfi_word cfi_cmd(flash_info_t *flash, uint8_t cmd, uint32_t addr)
60 uint32_t base = flash->start[0];
61 uint32_t val=(cmd << 16) | cmd;
63 write32(base + addr, val);
67 static uint16_t cfi_read_query(flash_info_t *flash, uint32_t addr)
69 uint32_t base = flash->start[0];
71 return (uint16_t)read32(base + addr);
74 flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */
76 static void move64(uint64_t *src, uint64_t *dest)
78 asm volatile("lfd 0, 0(3)\n\t" /* fpr0 = *scr */
79 "stfd 0, 0(4)" /* *dest = fpr0 */
80 : : : "fr0" ); /* Clobbers fr0 */
84 static int cfi_write_dword(flash_info_t *flash, ulong dest, cfi_word data)
89 status = cfi_read(flash, dest);
92 cfi_cmd(flash, 0x40, 0);
93 cfi_write(flash, data, dest);
96 start = get_timer (0);
98 status = cfi_read(flash, dest);
100 if(status == CMD(0x80))
102 if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
103 cfi_cmd(flash, 0xff, 0);
108 cfi_cmd(flash, 0xff, 0);
113 static int jedec_write_dword (flash_info_t *flash, ulong dest, cfi_word data)
118 status = cfi_read(flash, dest);
119 if(status != CMD(0xffff)) return 2;
121 cfi_cmd(flash, 0xaa, 0x555);
122 cfi_cmd(flash, 0x55, 0x2aa);
123 cfi_cmd(flash, 0xa0, 0x555);
125 cfi_write(flash, data, dest);
128 start = get_timer (0);
130 while(status != data) {
131 if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT)
133 status = cfi_read(flash, dest);
139 static __inline__ unsigned long get_msr(void)
142 __asm__ __volatile__ ("mfmsr %0" : "=r" (msr) :);
146 static __inline__ void set_msr(unsigned long msr)
148 __asm__ __volatile__ ("mtmsr %0" : : "r" (msr));
151 int write_buff (flash_info_t *flash, uchar *src, ulong addr, ulong cnt)
156 uint8_t *t = (uint8_t*)&data;
157 unsigned long base = flash->start[0];
160 if (flash->flash_id == FLASH_UNKNOWN)
171 wp = (addr & ~7); /* get lower word aligned address */
174 data = cfi_read(flash, wp);
176 l = ( cnt < (8-s) ) ? cnt : (8-s);
177 for(i = 0; i < l; i++)
179 if ((rc = write_dword(flash, wp, data)) != 0)
186 for (i = 0; i < 8; i++)
188 if ((rc = write_dword(flash, wp, data)) != 0)
199 data = cfi_read(flash, wp);
200 for(i = 0; i < cnt; i++)
202 rc = write_dword(flash, wp, data);
208 static int cfi_erase_oneblock(flash_info_t *flash, uint32_t sect)
212 ulong start, last, now;
215 flag = disable_interrupts();
217 sa = (flash->start[sect] - flash->start[0]);
218 write32(flash->start[sect], 0x00200020);
219 write32(flash->start[sect], 0x00d000d0);
225 start = get_timer (0);
229 status = cfi_read(flash, sa);
231 if (status == CMD(0x80))
233 if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
234 cfi_cmd(flash, 0xff, 0);
235 printf ("Timeout\n");
239 if ((now - last) > 1000) {
245 cfi_cmd(flash, 0xff, 0);
249 static int cfi_erase(flash_info_t *flash, uint32_t s_first, uint32_t s_last)
254 for (sect = s_first; sect <= s_last; sect++) {
255 if (flash->protect[sect] == 0) {
256 rc = cfi_erase_oneblock(flash, sect);
257 if (rc != ERR_OK) break;
264 static int jedec_erase(flash_info_t *flash, uint32_t s_first, uint32_t s_last)
270 ulong start, last, now;
272 flag = disable_interrupts();
274 cfi_cmd(flash, 0xaa, 0x555);
275 cfi_cmd(flash, 0x55, 0x2aa);
276 cfi_cmd(flash, 0x80, 0x555);
277 cfi_cmd(flash, 0xaa, 0x555);
278 cfi_cmd(flash, 0x55, 0x2aa);
279 for ( sect = s_first; sect <= s_last; sect++) {
280 if (flash->protect[sect] == 0) {
281 sa = flash->start[sect] - flash->start[0];
282 write32(flash->start[sect], 0x00300030);
292 start = get_timer (0);
295 status = cfi_read(flash, sa);
296 if (status == CMD(0xffff))
299 if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
300 printf ("Timeout\n");
304 if ((now - last) > 1000) {
311 cfi_cmd(flash, 0xf0, 0);
318 int flash_erase (flash_info_t *flash, int s_first, int s_last)
323 if ((s_first < 0) || (s_first > s_last)) {
324 if (flash->flash_id == FLASH_UNKNOWN)
325 printf ("- missing\n");
327 printf ("- no sectors to erase\n");
328 return ERR_NOT_ERASED;
330 if (flash->flash_id == FLASH_UNKNOWN) {
331 printf ("Can't erase unknown flash type - aborted\n");
332 return ERR_NOT_ERASED;
336 for (sect = s_first; sect <= s_last; sect++)
337 if (flash->protect[sect]) prot++;
340 printf ("- Warning: %d protected sectors will not be erased!\n",
345 return do_flash_erase(flash, s_first, s_last);
348 struct jedec_flash_info {
349 const uint16_t mfr_id;
350 const uint16_t dev_id;
353 const int InterfaceDesc;
354 const int NumEraseRegions;
355 const ulong regions[4];
358 #define ERASEINFO(size,blocks) (size<<8)|(blocks-1)
364 static const struct jedec_flash_info jedec_table[] = {
366 mfr_id: (uint16_t)AMD_MANUFACT,
367 dev_id: (uint16_t)AMD_ID_LV800T,
368 name: "AMD AM29LV800T",
371 regions: {ERASEINFO(0x10000,15),
372 ERASEINFO(0x08000,1),
373 ERASEINFO(0x02000,2),
377 mfr_id: (uint16_t)AMD_MANUFACT,
378 dev_id: (uint16_t)AMD_ID_LV800B,
379 name: "AMD AM29LV800B",
382 regions: {ERASEINFO(0x10000,15),
383 ERASEINFO(0x08000,1),
384 ERASEINFO(0x02000,2),
388 mfr_id: (uint16_t)AMD_MANUFACT,
389 dev_id: (uint16_t)AMD_ID_LV160T,
390 name: "AMD AM29LV160T",
393 regions: {ERASEINFO(0x10000,31),
394 ERASEINFO(0x08000,1),
395 ERASEINFO(0x02000,2),
399 mfr_id: (uint16_t)AMD_MANUFACT,
400 dev_id: (uint16_t)AMD_ID_LV160B,
401 name: "AMD AM29LV160B",
404 regions: {ERASEINFO(0x04000,1),
405 ERASEINFO(0x02000,2),
406 ERASEINFO(0x08000,1),
407 ERASEINFO(0x10000,31)
410 mfr_id: (uint16_t)AMD_MANUFACT,
411 dev_id: (uint16_t)AMD_ID_LV320T,
412 name: "AMD AM29LV320T",
415 regions: {ERASEINFO(0x10000,63),
420 mfr_id: (uint16_t)AMD_MANUFACT,
421 dev_id: (uint16_t)AMD_ID_LV320B,
422 name: "AMD AM29LV320B",
425 regions: {ERASEINFO(0x02000,8),
426 ERASEINFO(0x10000,63)
431 static ulong cfi_init(uint32_t base, flash_info_t *flash)
442 flash->start[0] = base;
443 cfi_cmd(flash, 0xF0, 0);
444 cfi_cmd(flash, 0x98, 0);
445 if ( !( cfi_read_query(flash, 0x10) == 'Q' &&
446 cfi_read_query(flash, 0x11) == 'R' &&
447 cfi_read_query(flash, 0x12) == 'Y' )) {
448 cfi_cmd(flash, 0xff, 0);
452 flash->size = 1 << cfi_read_query(flash, 0x27);
454 block_count = cfi_read_query(flash, 0x2c);
455 primary = cfi_read_query(flash, 0x15);
456 if ( cfi_read_query(flash, primary + 4) == 0x30)
457 reverse = (cfi_read_query(flash, 0x1) & 0x01);
459 reverse = (cfi_read_query(flash, primary+15) == 3);
461 flash->sector_count = 0;
463 for ( block = reverse ? block_count - 1 : 0;
464 reverse ? block >= 0 : block < block_count;
465 reverse ? block-- : block ++) {
467 (cfi_read_query(flash, 0x2d + block*4+2) |
468 (cfi_read_query(flash, 0x2d + block*4+3) << 8)) << 8;
470 (cfi_read_query(flash, 0x2d + block*4+0) |
471 (cfi_read_query(flash, 0x2d + block*4+1) << 8)) + 1;
472 for(sector = 0; sector < sector_count; sector++) {
473 flash->start[flash->sector_count++] = base + offset;
474 offset += sector_size * 4;
477 mfr_id = cfi_read_query(flash, 0x00);
478 dev_id = cfi_read_query(flash, 0x01);
480 cfi_cmd(flash, 0xff, 0);
482 flash->flash_id = (mfr_id << 16) | dev_id;
484 for (sector = 0; sector < flash->sector_count; sector++) {
485 write32(flash->start[sector], 0x00600060);
486 write32(flash->start[sector], 0x00d000d0);
488 cfi_cmd(flash, 0xff, 0);
490 for (sector = 0; sector < flash->sector_count; sector++)
491 flash->protect[sector] = 0;
493 do_flash_erase = cfi_erase;
494 write_dword = cfi_write_dword;
499 static ulong jedec_init(unsigned long base, flash_info_t *flash)
502 int block, block_count;
505 flash->start[0] = base;
506 cfi_cmd(flash, 0xF0, 0x000);
507 cfi_cmd(flash, 0xAA, 0x555);
508 cfi_cmd(flash, 0x55, 0x2AA);
509 cfi_cmd(flash, 0x90, 0x555);
510 mfr_id = cfi_read_query(flash, 0x000);
511 dev_id = cfi_read_query(flash, 0x0001);
512 cfi_cmd(flash, 0xf0, 0x000);
514 for(i=0; i<sizeof(jedec_table)/sizeof(struct jedec_flash_info); i++) {
515 if((jedec_table[i].mfr_id == mfr_id) &&
516 (jedec_table[i].dev_id == dev_id)) {
518 flash->flash_id = (mfr_id << 16) | dev_id;
519 flash->size = 1 << jedec_table[0].DevSize;
521 block_count = jedec_table[i].NumEraseRegions;
523 flash->sector_count = 0;
524 for (block = 0; block < block_count; block++) {
525 int sector_size = jedec_table[i].regions[block];
526 int sector_count = (sector_size & 0xff) + 1;
528 for (sector=0; sector<sector_count; sector++) {
529 flash->start[flash->sector_count++] =
531 offset += sector_size * 4;
538 for (sector = 0; sector < flash->sector_count; sector++)
539 flash->protect[sector] = 0;
541 do_flash_erase = jedec_erase;
542 write_dword = jedec_write_dword;
547 inline void mtibat1u(unsigned int x)
549 __asm__ __volatile__ ("mtspr 530, %0" :: "r" (x));
552 inline void mtibat1l(unsigned int x)
554 __asm__ __volatile__ ("mtspr 531, %0" :: "r" (x));
557 inline void mtdbat1u(unsigned int x)
559 __asm__ __volatile__ ("mtspr 538, %0" :: "r" (x));
562 inline void mtdbat1l(unsigned int x)
564 __asm__ __volatile__ ("mtspr 539, %0" :: "r" (x));
567 unsigned long flash_init (void)
569 unsigned long size = 0;
574 CONFIG_WRITE_WORD(ERCR3, 0x0C00000C);
575 CONFIG_WRITE_WORD(ERCR4, 0x0800000C);
577 set_msr(msr & ~(MSR_IR | MSR_DR));
578 mtibat1l(0x70000000 | BATL_PP_10 | BATL_CACHEINHIBIT);
579 mtibat1u(0x70000000 | BATU_BL_256M | BATU_VS | BATU_VP);
580 mtdbat1l(0x70000000 | BATL_PP_10 | BATL_CACHEINHIBIT);
581 mtdbat1u(0x70000000 | BATU_BL_256M | BATU_VS | BATU_VP);
584 for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++)
585 flash_info[i].flash_id = FLASH_UNKNOWN;
586 size = cfi_init(FLASH_BASE0_PRELIM, &flash_info[0]);
588 size = jedec_init(FLASH_BASE0_PRELIM, &flash_info[0]);
590 if (flash_info[0].flash_id == FLASH_UNKNOWN)
591 printf ("# Unknown FLASH on Bank 1 - Size = 0x%08lx = %ld MB\n",
597 void flash_print_info (flash_info_t *flash)
603 volatile unsigned long *p;
605 if (flash->flash_id == FLASH_UNKNOWN) {
606 printf ("missing or unknown FLASH type\n");
610 if (flash->flash_id == FLASH_UNKNOWN) {
611 printf ("missing or unknown FLASH type\n");
615 switch (((flash->flash_id) >> 16) & 0xff) {
633 printf ("Unknown Vendor ");
637 switch ((flash->flash_id) & 0xffff) {
638 case (uint16_t)AMD_ID_LV800T:
639 printf ("AM29LV800T\n");
641 case (uint16_t)AMD_ID_LV800B:
642 printf ("AM29LV800B\n");
644 case (uint16_t)AMD_ID_LV160T:
645 printf ("AM29LV160T\n");
647 case (uint16_t)AMD_ID_LV160B:
648 printf ("AM29LV160B\n");
650 case (uint16_t)AMD_ID_LV320T:
651 printf ("AM29LV320T\n");
653 case (uint16_t)AMD_ID_LV320B:
654 printf ("AM29LV320B\n");
656 case (uint16_t)INTEL_ID_28F800C3T:
657 printf ("28F800C3T\n");
659 case (uint16_t)INTEL_ID_28F800C3B:
660 printf ("28F800C3B\n");
662 case (uint16_t)INTEL_ID_28F160C3T:
663 printf ("28F160C3T\n");
665 case (uint16_t)INTEL_ID_28F160C3B:
666 printf ("28F160C3B\n");
668 case (uint16_t)INTEL_ID_28F320C3T:
669 printf ("28F320C3T\n");
671 case (uint16_t)INTEL_ID_28F320C3B:
672 printf ("28F320C3B\n");
674 case (uint16_t)INTEL_ID_28F640C3T:
675 printf ("28F640C3T\n");
677 case (uint16_t)INTEL_ID_28F640C3B:
678 printf ("28F640C3B\n");
681 printf ("Unknown Chip Type\n");
685 if (flash->size >= (1 << 20)) {
686 printf (" Size: %ld MB in %d Sectors\n",
687 flash->size >> 20, flash->sector_count);
689 printf (" Size: %ld kB in %d Sectors\n",
690 flash->size >> 10, flash->sector_count);
693 printf (" Sector Start Addresses:");
694 for (i = 0; i < flash->sector_count; ++i) {
695 /* Check if whole sector is erased*/
696 if (i != (flash->sector_count-1))
697 size = flash->start[i+1] - flash->start[i];
699 size = flash->start[0] + flash->size - flash->start[i];
702 p = (volatile unsigned long *)flash->start[i];
703 size = size >> 2; /* divide by 4 for longword access */
704 for (k=0; k<size; k++) {
705 if (*p++ != 0xffffffff) {
714 printf (" %08lX%s%s",
717 flash->protect[i] ? "RO " : " ");