flash.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721
  1. /*
  2. * board/eva/flash.c
  3. *
  4. * (C) Copyright 2002
  5. * Sangmoon Kim, Etin Systems, dogoil@etinsys.com.
  6. *
  7. * See file CREDITS for list of people who contributed to this
  8. * project.
  9. *
  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.
  14. *
  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.
  19. *
  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,
  23. * MA 02111-1307 USA
  24. */
  25. #include <common.h>
  26. #include <asm/processor.h>
  27. #include <asm/pci_io.h>
  28. #include <mpc824x.h>
  29. #include <asm/mmu.h>
  30. int (*do_flash_erase)(flash_info_t*, uint32_t, uint32_t);
  31. int (*write_dword)(flash_info_t*, ulong, uint64_t);
  32. typedef uint64_t cfi_word;
  33. #define cfi_read(flash, addr) *((volatile cfi_word*)(flash->start[0] + addr))
  34. #define cfi_write(flash, val, addr) \
  35. move64((cfi_word*)&val, \
  36. (cfi_word*)(flash->start[0] + addr))
  37. #define CMD(x) ((((cfi_word)x)<<48)|(((cfi_word)x)<<32)|(((cfi_word)x)<<16)|(((cfi_word)x)))
  38. static void write32(unsigned long addr, uint32_t value)
  39. {
  40. *(volatile uint32_t*)(addr) = value;
  41. asm volatile("sync");
  42. }
  43. static uint32_t read32(unsigned long addr)
  44. {
  45. uint32_t value;
  46. value = *(volatile uint32_t*)addr;
  47. asm volatile("sync");
  48. return value;
  49. }
  50. static cfi_word cfi_cmd(flash_info_t *flash, uint8_t cmd, uint32_t addr)
  51. {
  52. uint32_t base = flash->start[0];
  53. uint32_t val=(cmd << 16) | cmd;
  54. addr <<= 3;
  55. write32(base + addr, val);
  56. return addr;
  57. }
  58. static uint16_t cfi_read_query(flash_info_t *flash, uint32_t addr)
  59. {
  60. uint32_t base = flash->start[0];
  61. addr <<= 3;
  62. return (uint16_t)read32(base + addr);
  63. }
  64. flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */
  65. static void move64(uint64_t *src, uint64_t *dest)
  66. {
  67. asm volatile("lfd 0, 0(3)\n\t" /* fpr0 = *scr */
  68. "stfd 0, 0(4)" /* *dest = fpr0 */
  69. : : : "fr0" ); /* Clobbers fr0 */
  70. return;
  71. }
  72. static int cfi_write_dword(flash_info_t *flash, ulong dest, cfi_word data)
  73. {
  74. unsigned long start;
  75. cfi_word status = 0;
  76. status = cfi_read(flash, dest);
  77. data &= status;
  78. cfi_cmd(flash, 0x40, 0);
  79. cfi_write(flash, data, dest);
  80. udelay(10);
  81. start = get_timer (0);
  82. for(;;) {
  83. status = cfi_read(flash, dest);
  84. status &= CMD(0x80);
  85. if(status == CMD(0x80))
  86. break;
  87. if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
  88. cfi_cmd(flash, 0xff, 0);
  89. return 1;
  90. }
  91. udelay(1);
  92. }
  93. cfi_cmd(flash, 0xff, 0);
  94. return 0;
  95. }
  96. static int jedec_write_dword (flash_info_t *flash, ulong dest, cfi_word data)
  97. {
  98. ulong start;
  99. cfi_word status = 0;
  100. status = cfi_read(flash, dest);
  101. if(status != CMD(0xffff)) return 2;
  102. cfi_cmd(flash, 0xaa, 0x555);
  103. cfi_cmd(flash, 0x55, 0x2aa);
  104. cfi_cmd(flash, 0xa0, 0x555);
  105. cfi_write(flash, data, dest);
  106. udelay(10);
  107. start = get_timer (0);
  108. status = ~data;
  109. while(status != data) {
  110. if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT)
  111. return 1;
  112. status = cfi_read(flash, dest);
  113. udelay(1);
  114. }
  115. return 0;
  116. }
  117. static __inline__ unsigned long get_msr(void)
  118. {
  119. unsigned long msr;
  120. __asm__ __volatile__ ("mfmsr %0" : "=r" (msr) :);
  121. return msr;
  122. }
  123. static __inline__ void set_msr(unsigned long msr)
  124. {
  125. __asm__ __volatile__ ("mtmsr %0" : : "r" (msr));
  126. }
  127. int write_buff (flash_info_t *flash, uchar *src, ulong addr, ulong cnt)
  128. {
  129. ulong wp;
  130. int i, s, l, rc;
  131. cfi_word data;
  132. uint8_t *t = (uint8_t*)&data;
  133. unsigned long base = flash->start[0];
  134. uint32_t msr;
  135. if (flash->flash_id == FLASH_UNKNOWN)
  136. return 4;
  137. if (cnt == 0)
  138. return 0;
  139. addr -= base;
  140. msr = get_msr();
  141. set_msr(msr|MSR_FP);
  142. wp = (addr & ~7); /* get lower word aligned address */
  143. if((addr-wp) != 0) {
  144. data = cfi_read(flash, wp);
  145. s = addr & 7;
  146. l = ( cnt < (8-s) ) ? cnt : (8-s);
  147. for(i = 0; i < l; i++)
  148. t[s+i] = *src++;
  149. if ((rc = write_dword(flash, wp, data)) != 0)
  150. goto DONE;
  151. wp += 8;
  152. cnt -= l;
  153. }
  154. while (cnt >= 8) {
  155. for (i = 0; i < 8; i++)
  156. t[i] = *src++;
  157. if ((rc = write_dword(flash, wp, data)) != 0)
  158. goto DONE;
  159. wp += 8;
  160. cnt -= 8;
  161. }
  162. if (cnt == 0) {
  163. rc = 0;
  164. goto DONE;
  165. }
  166. data = cfi_read(flash, wp);
  167. for(i = 0; i < cnt; i++)
  168. t[i] = *src++;
  169. rc = write_dword(flash, wp, data);
  170. DONE:
  171. set_msr(msr);
  172. return rc;
  173. }
  174. static int cfi_erase_oneblock(flash_info_t *flash, uint32_t sect)
  175. {
  176. int sa;
  177. int flag;
  178. ulong start, last, now;
  179. cfi_word status;
  180. flag = disable_interrupts();
  181. sa = (flash->start[sect] - flash->start[0]);
  182. write32(flash->start[sect], 0x00200020);
  183. write32(flash->start[sect], 0x00d000d0);
  184. if (flag)
  185. enable_interrupts();
  186. udelay(1000);
  187. start = get_timer (0);
  188. last = start;
  189. for (;;) {
  190. status = cfi_read(flash, sa);
  191. status &= CMD(0x80);
  192. if (status == CMD(0x80))
  193. break;
  194. if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
  195. cfi_cmd(flash, 0xff, 0);
  196. printf ("Timeout\n");
  197. return ERR_TIMOUT;
  198. }
  199. if ((now - last) > 1000) {
  200. serial_putc ('.');
  201. last = now;
  202. }
  203. udelay(10);
  204. }
  205. cfi_cmd(flash, 0xff, 0);
  206. return ERR_OK;
  207. }
  208. static int cfi_erase(flash_info_t *flash, uint32_t s_first, uint32_t s_last)
  209. {
  210. int sect;
  211. int rc = ERR_OK;
  212. for (sect = s_first; sect <= s_last; sect++) {
  213. if (flash->protect[sect] == 0) {
  214. rc = cfi_erase_oneblock(flash, sect);
  215. if (rc != ERR_OK) break;
  216. }
  217. }
  218. printf (" done\n");
  219. return rc;
  220. }
  221. static int jedec_erase(flash_info_t *flash, uint32_t s_first, uint32_t s_last)
  222. {
  223. int sect;
  224. cfi_word status;
  225. int sa = -1;
  226. int flag;
  227. ulong start, last, now;
  228. flag = disable_interrupts();
  229. cfi_cmd(flash, 0xaa, 0x555);
  230. cfi_cmd(flash, 0x55, 0x2aa);
  231. cfi_cmd(flash, 0x80, 0x555);
  232. cfi_cmd(flash, 0xaa, 0x555);
  233. cfi_cmd(flash, 0x55, 0x2aa);
  234. for ( sect = s_first; sect <= s_last; sect++) {
  235. if (flash->protect[sect] == 0) {
  236. sa = flash->start[sect] - flash->start[0];
  237. write32(flash->start[sect], 0x00300030);
  238. }
  239. }
  240. if (flag)
  241. enable_interrupts();
  242. if (sa < 0)
  243. goto DONE;
  244. udelay (1000);
  245. start = get_timer (0);
  246. last = start;
  247. for(;;) {
  248. status = cfi_read(flash, sa);
  249. if (status == CMD(0xffff))
  250. break;
  251. if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
  252. printf ("Timeout\n");
  253. return ERR_TIMOUT;
  254. }
  255. if ((now - last) > 1000) {
  256. serial_putc ('.');
  257. last = now;
  258. }
  259. udelay(10);
  260. }
  261. DONE:
  262. cfi_cmd(flash, 0xf0, 0);
  263. printf (" done\n");
  264. return ERR_OK;
  265. }
  266. int flash_erase (flash_info_t *flash, int s_first, int s_last)
  267. {
  268. int sect;
  269. int prot;
  270. if ((s_first < 0) || (s_first > s_last)) {
  271. if (flash->flash_id == FLASH_UNKNOWN)
  272. printf ("- missing\n");
  273. else
  274. printf ("- no sectors to erase\n");
  275. return ERR_NOT_ERASED;
  276. }
  277. if (flash->flash_id == FLASH_UNKNOWN) {
  278. printf ("Can't erase unknown flash type - aborted\n");
  279. return ERR_NOT_ERASED;
  280. }
  281. prot = 0;
  282. for (sect = s_first; sect <= s_last; sect++)
  283. if (flash->protect[sect]) prot++;
  284. if (prot)
  285. printf ("- Warning: %d protected sectors will not be erased!\n",
  286. prot);
  287. else
  288. printf ("\n");
  289. return do_flash_erase(flash, s_first, s_last);
  290. }
  291. struct jedec_flash_info {
  292. const uint16_t mfr_id;
  293. const uint16_t dev_id;
  294. const char *name;
  295. const int DevSize;
  296. const int InterfaceDesc;
  297. const int NumEraseRegions;
  298. const ulong regions[4];
  299. };
  300. #define ERASEINFO(size,blocks) (size<<8)|(blocks-1)
  301. #define SIZE_1MiB 20
  302. #define SIZE_2MiB 21
  303. #define SIZE_4MiB 22
  304. static const struct jedec_flash_info jedec_table[] = {
  305. {
  306. mfr_id: (uint16_t)AMD_MANUFACT,
  307. dev_id: (uint16_t)AMD_ID_LV800T,
  308. name: "AMD AM29LV800T",
  309. DevSize: SIZE_1MiB,
  310. NumEraseRegions: 4,
  311. regions: {ERASEINFO(0x10000,15),
  312. ERASEINFO(0x08000,1),
  313. ERASEINFO(0x02000,2),
  314. ERASEINFO(0x04000,1)
  315. }
  316. }, {
  317. mfr_id: (uint16_t)AMD_MANUFACT,
  318. dev_id: (uint16_t)AMD_ID_LV800B,
  319. name: "AMD AM29LV800B",
  320. DevSize: SIZE_1MiB,
  321. NumEraseRegions: 4,
  322. regions: {ERASEINFO(0x10000,15),
  323. ERASEINFO(0x08000,1),
  324. ERASEINFO(0x02000,2),
  325. ERASEINFO(0x04000,1)
  326. }
  327. }, {
  328. mfr_id: (uint16_t)AMD_MANUFACT,
  329. dev_id: (uint16_t)AMD_ID_LV160T,
  330. name: "AMD AM29LV160T",
  331. DevSize: SIZE_2MiB,
  332. NumEraseRegions: 4,
  333. regions: {ERASEINFO(0x10000,31),
  334. ERASEINFO(0x08000,1),
  335. ERASEINFO(0x02000,2),
  336. ERASEINFO(0x04000,1)
  337. }
  338. }, {
  339. mfr_id: (uint16_t)AMD_MANUFACT,
  340. dev_id: (uint16_t)AMD_ID_LV160B,
  341. name: "AMD AM29LV160B",
  342. DevSize: SIZE_2MiB,
  343. NumEraseRegions: 4,
  344. regions: {ERASEINFO(0x04000,1),
  345. ERASEINFO(0x02000,2),
  346. ERASEINFO(0x08000,1),
  347. ERASEINFO(0x10000,31)
  348. }
  349. }, {
  350. mfr_id: (uint16_t)AMD_MANUFACT,
  351. dev_id: (uint16_t)AMD_ID_LV320T,
  352. name: "AMD AM29LV320T",
  353. DevSize: SIZE_4MiB,
  354. NumEraseRegions: 2,
  355. regions: {ERASEINFO(0x10000,63),
  356. ERASEINFO(0x02000,8)
  357. }
  358. }, {
  359. mfr_id: (uint16_t)AMD_MANUFACT,
  360. dev_id: (uint16_t)AMD_ID_LV320B,
  361. name: "AMD AM29LV320B",
  362. DevSize: SIZE_4MiB,
  363. NumEraseRegions: 2,
  364. regions: {ERASEINFO(0x02000,8),
  365. ERASEINFO(0x10000,63)
  366. }
  367. }
  368. };
  369. static ulong cfi_init(uint32_t base, flash_info_t *flash)
  370. {
  371. int sector;
  372. int block;
  373. int block_count;
  374. int offset = 0;
  375. int reverse = 0;
  376. int primary;
  377. int mfr_id;
  378. int dev_id;
  379. flash->start[0] = base;
  380. cfi_cmd(flash, 0xF0, 0);
  381. cfi_cmd(flash, 0x98, 0);
  382. if ( !( cfi_read_query(flash, 0x10) == 'Q' &&
  383. cfi_read_query(flash, 0x11) == 'R' &&
  384. cfi_read_query(flash, 0x12) == 'Y' )) {
  385. cfi_cmd(flash, 0xff, 0);
  386. return 0;
  387. }
  388. flash->size = 1 << cfi_read_query(flash, 0x27);
  389. flash->size *= 4;
  390. block_count = cfi_read_query(flash, 0x2c);
  391. primary = cfi_read_query(flash, 0x15);
  392. if ( cfi_read_query(flash, primary + 4) == 0x30)
  393. reverse = (cfi_read_query(flash, 0x1) & 0x01);
  394. else
  395. reverse = (cfi_read_query(flash, primary+15) == 3);
  396. flash->sector_count = 0;
  397. for ( block = reverse ? block_count - 1 : 0;
  398. reverse ? block >= 0 : block < block_count;
  399. reverse ? block-- : block ++) {
  400. int sector_size =
  401. (cfi_read_query(flash, 0x2d + block*4+2) |
  402. (cfi_read_query(flash, 0x2d + block*4+3) << 8)) << 8;
  403. int sector_count =
  404. (cfi_read_query(flash, 0x2d + block*4+0) |
  405. (cfi_read_query(flash, 0x2d + block*4+1) << 8)) + 1;
  406. for(sector = 0; sector < sector_count; sector++) {
  407. flash->start[flash->sector_count++] = base + offset;
  408. offset += sector_size * 4;
  409. }
  410. }
  411. mfr_id = cfi_read_query(flash, 0x00);
  412. dev_id = cfi_read_query(flash, 0x01);
  413. cfi_cmd(flash, 0xff, 0);
  414. flash->flash_id = (mfr_id << 16) | dev_id;
  415. for (sector = 0; sector < flash->sector_count; sector++) {
  416. write32(flash->start[sector], 0x00600060);
  417. write32(flash->start[sector], 0x00d000d0);
  418. }
  419. cfi_cmd(flash, 0xff, 0);
  420. for (sector = 0; sector < flash->sector_count; sector++)
  421. flash->protect[sector] = 0;
  422. do_flash_erase = cfi_erase;
  423. write_dword = cfi_write_dword;
  424. return flash->size;
  425. }
  426. static ulong jedec_init(unsigned long base, flash_info_t *flash)
  427. {
  428. int i;
  429. int block, block_count;
  430. int sector, offset;
  431. int mfr_id, dev_id;
  432. flash->start[0] = base;
  433. cfi_cmd(flash, 0xF0, 0x000);
  434. cfi_cmd(flash, 0xAA, 0x555);
  435. cfi_cmd(flash, 0x55, 0x2AA);
  436. cfi_cmd(flash, 0x90, 0x555);
  437. mfr_id = cfi_read_query(flash, 0x000);
  438. dev_id = cfi_read_query(flash, 0x0001);
  439. cfi_cmd(flash, 0xf0, 0x000);
  440. for(i=0; i<sizeof(jedec_table)/sizeof(struct jedec_flash_info); i++) {
  441. if((jedec_table[i].mfr_id == mfr_id) &&
  442. (jedec_table[i].dev_id == dev_id)) {
  443. flash->flash_id = (mfr_id << 16) | dev_id;
  444. flash->size = 1 << jedec_table[0].DevSize;
  445. flash->size *= 4;
  446. block_count = jedec_table[i].NumEraseRegions;
  447. offset = 0;
  448. flash->sector_count = 0;
  449. for (block = 0; block < block_count; block++) {
  450. int sector_size = jedec_table[i].regions[block];
  451. int sector_count = (sector_size & 0xff) + 1;
  452. sector_size >>= 8;
  453. for (sector=0; sector<sector_count; sector++) {
  454. flash->start[flash->sector_count++] =
  455. base + offset;
  456. offset += sector_size * 4;
  457. }
  458. }
  459. break;
  460. }
  461. }
  462. for (sector = 0; sector < flash->sector_count; sector++)
  463. flash->protect[sector] = 0;
  464. do_flash_erase = jedec_erase;
  465. write_dword = jedec_write_dword;
  466. return flash->size;
  467. }
  468. inline void mtibat1u(unsigned int x)
  469. {
  470. __asm__ __volatile__ ("mtspr 530, %0" :: "r" (x));
  471. }
  472. inline void mtibat1l(unsigned int x)
  473. {
  474. __asm__ __volatile__ ("mtspr 531, %0" :: "r" (x));
  475. }
  476. inline void mtdbat1u(unsigned int x)
  477. {
  478. __asm__ __volatile__ ("mtspr 538, %0" :: "r" (x));
  479. }
  480. inline void mtdbat1l(unsigned int x)
  481. {
  482. __asm__ __volatile__ ("mtspr 539, %0" :: "r" (x));
  483. }
  484. unsigned long flash_init (void)
  485. {
  486. unsigned long size = 0;
  487. int i;
  488. unsigned int msr;
  489. /* BAT1 */
  490. CONFIG_WRITE_WORD(ERCR3, 0x0C00000C);
  491. CONFIG_WRITE_WORD(ERCR4, 0x0800000C);
  492. msr = get_msr();
  493. set_msr(msr & ~(MSR_IR | MSR_DR));
  494. mtibat1l(0x70000000 | BATL_PP_10 | BATL_CACHEINHIBIT);
  495. mtibat1u(0x70000000 | BATU_BL_256M | BATU_VS | BATU_VP);
  496. mtdbat1l(0x70000000 | BATL_PP_10 | BATL_CACHEINHIBIT);
  497. mtdbat1u(0x70000000 | BATU_BL_256M | BATU_VS | BATU_VP);
  498. set_msr(msr);
  499. for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++)
  500. flash_info[i].flash_id = FLASH_UNKNOWN;
  501. size = cfi_init(FLASH_BASE0_PRELIM, &flash_info[0]);
  502. if (!size)
  503. size = jedec_init(FLASH_BASE0_PRELIM, &flash_info[0]);
  504. if (flash_info[0].flash_id == FLASH_UNKNOWN)
  505. printf ("# Unknown FLASH on Bank 1 - Size = 0x%08lx = %ld MB\n",
  506. size, size<<20);
  507. return size;
  508. }
  509. void flash_print_info (flash_info_t *flash)
  510. {
  511. int i;
  512. int k;
  513. int size;
  514. int erased;
  515. volatile unsigned long *p;
  516. if (flash->flash_id == FLASH_UNKNOWN) {
  517. printf ("missing or unknown FLASH type\n");
  518. flash_init();
  519. }
  520. if (flash->flash_id == FLASH_UNKNOWN) {
  521. printf ("missing or unknown FLASH type\n");
  522. return;
  523. }
  524. switch (((flash->flash_id) >> 16) & 0xff) {
  525. case 0x01:
  526. printf ("AMD ");
  527. break;
  528. case 0x04:
  529. printf("FUJITSU ");
  530. break;
  531. case 0x20:
  532. printf("STM ");
  533. break;
  534. case 0xBF:
  535. printf("SST ");
  536. break;
  537. case 0x89:
  538. case 0xB0:
  539. printf("INTEL ");
  540. break;
  541. default:
  542. printf ("Unknown Vendor ");
  543. break;
  544. }
  545. switch ((flash->flash_id) & 0xffff) {
  546. case (uint16_t)AMD_ID_LV800T:
  547. printf ("AM29LV800T\n");
  548. break;
  549. case (uint16_t)AMD_ID_LV800B:
  550. printf ("AM29LV800B\n");
  551. break;
  552. case (uint16_t)AMD_ID_LV160T:
  553. printf ("AM29LV160T\n");
  554. break;
  555. case (uint16_t)AMD_ID_LV160B:
  556. printf ("AM29LV160B\n");
  557. break;
  558. case (uint16_t)AMD_ID_LV320T:
  559. printf ("AM29LV320T\n");
  560. break;
  561. case (uint16_t)AMD_ID_LV320B:
  562. printf ("AM29LV320B\n");
  563. break;
  564. case (uint16_t)INTEL_ID_28F800C3T:
  565. printf ("28F800C3T\n");
  566. break;
  567. case (uint16_t)INTEL_ID_28F800C3B:
  568. printf ("28F800C3B\n");
  569. break;
  570. case (uint16_t)INTEL_ID_28F160C3T:
  571. printf ("28F160C3T\n");
  572. break;
  573. case (uint16_t)INTEL_ID_28F160C3B:
  574. printf ("28F160C3B\n");
  575. break;
  576. case (uint16_t)INTEL_ID_28F320C3T:
  577. printf ("28F320C3T\n");
  578. break;
  579. case (uint16_t)INTEL_ID_28F320C3B:
  580. printf ("28F320C3B\n");
  581. break;
  582. case (uint16_t)INTEL_ID_28F640C3T:
  583. printf ("28F640C3T\n");
  584. break;
  585. case (uint16_t)INTEL_ID_28F640C3B:
  586. printf ("28F640C3B\n");
  587. break;
  588. default:
  589. printf ("Unknown Chip Type\n");
  590. break;
  591. }
  592. if (flash->size >= (1 << 20)) {
  593. printf (" Size: %ld MB in %d Sectors\n",
  594. flash->size >> 20, flash->sector_count);
  595. } else {
  596. printf (" Size: %ld kB in %d Sectors\n",
  597. flash->size >> 10, flash->sector_count);
  598. }
  599. printf (" Sector Start Addresses:");
  600. for (i = 0; i < flash->sector_count; ++i) {
  601. /* Check if whole sector is erased*/
  602. if (i != (flash->sector_count-1))
  603. size = flash->start[i+1] - flash->start[i];
  604. else
  605. size = flash->start[0] + flash->size - flash->start[i];
  606. erased = 1;
  607. p = (volatile unsigned long *)flash->start[i];
  608. size = size >> 2; /* divide by 4 for longword access */
  609. for (k=0; k<size; k++) {
  610. if (*p++ != 0xffffffff) {
  611. erased = 0;
  612. break;
  613. }
  614. }
  615. if ((i % 5) == 0)
  616. printf ("\n ");
  617. printf (" %08lX%s%s",
  618. flash->start[i],
  619. erased ? " E" : " ",
  620. flash->protect[i] ? "RO " : " ");
  621. }
  622. printf ("\n");
  623. }