flash.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
  1. /*
  2. * (C) Copyright 2001
  3. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  4. *
  5. * See file CREDITS for list of people who contributed to this
  6. * project.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21. * MA 02111-1307 USA
  22. */
  23. #include <common.h>
  24. #include <mpc8xx.h>
  25. #if defined(CONFIG_ENV_IS_IN_FLASH)
  26. # ifndef CONFIG_ENV_ADDR
  27. # define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + CONFIG_ENV_OFFSET)
  28. # endif
  29. # ifndef CONFIG_ENV_SIZE
  30. # define CONFIG_ENV_SIZE CONFIG_ENV_SECT_SIZE
  31. # endif
  32. # ifndef CONFIG_ENV_SECT_SIZE
  33. # define CONFIG_ENV_SECT_SIZE CONFIG_ENV_SIZE
  34. # endif
  35. #endif
  36. /*---------------------------------------------------------------------*/
  37. #undef DEBUG_FLASH
  38. #ifdef DEBUG_FLASH
  39. #define DEBUGF(fmt,args...) printf(fmt ,##args)
  40. #else
  41. #define DEBUGF(fmt,args...)
  42. #endif
  43. /*---------------------------------------------------------------------*/
  44. flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */
  45. /*-----------------------------------------------------------------------
  46. * Functions
  47. */
  48. static ulong flash_get_size (vu_long *addr, flash_info_t *info);
  49. static int write_data (flash_info_t *info, ulong dest, ulong data);
  50. static void flash_get_offsets (ulong base, flash_info_t *info);
  51. /*-----------------------------------------------------------------------
  52. *
  53. * The PCU E uses an address map where flash banks are aligned top
  54. * down, so that the "first" flash bank ends at top of memory, and
  55. * the monitor entry point is at address (0xFFF00100). The second
  56. * flash bank is mapped immediately below bank 0.
  57. *
  58. * This is NOT in conformance to the "official" memory map!
  59. *
  60. */
  61. #define PCU_MONITOR_BASE ( (flash_info[0].start[0] + flash_info[0].size - 1) \
  62. - (0xFFFFFFFF - CONFIG_SYS_MONITOR_BASE) )
  63. /*-----------------------------------------------------------------------
  64. */
  65. unsigned long flash_init (void)
  66. {
  67. volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
  68. volatile memctl8xx_t *memctl = &immap->im_memctl;
  69. unsigned long base, size_b0, size_b1;
  70. int i;
  71. /* Init: no FLASHes known */
  72. for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
  73. flash_info[i].flash_id = FLASH_UNKNOWN;
  74. }
  75. /* Static FLASH Bank configuration here - FIXME XXX */
  76. /*
  77. * Warning:
  78. *
  79. * Since the PCU E memory map assigns flash banks top down,
  80. * we swap the numbering later if both banks are equipped,
  81. * so they look like a contiguous area of memory.
  82. */
  83. DEBUGF("\n## Get flash bank 1 size @ 0x%08x\n",FLASH_BASE0_PRELIM);
  84. size_b0 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]);
  85. if (flash_info[0].flash_id == FLASH_UNKNOWN) {
  86. printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
  87. size_b0, size_b0<<20);
  88. }
  89. DEBUGF("## Get flash bank 2 size @ 0x%08x\n",FLASH_BASE6_PRELIM);
  90. size_b1 = flash_get_size((vu_long *)FLASH_BASE6_PRELIM, &flash_info[1]);
  91. DEBUGF("## Prelim. Flash bank sizes: %08lx + 0x%08lx\n", size_b0, size_b1);
  92. if (size_b1 > size_b0) {
  93. printf ("## ERROR: "
  94. "Bank 1 (0x%08lx = %ld MB) > Bank 0 (0x%08lx = %ld MB)\n",
  95. size_b1, size_b1<<20,
  96. size_b0, size_b0<<20
  97. );
  98. flash_info[0].flash_id = FLASH_UNKNOWN;
  99. flash_info[1].flash_id = FLASH_UNKNOWN;
  100. flash_info[0].sector_count = -1;
  101. flash_info[1].sector_count = -1;
  102. flash_info[0].size = 0;
  103. flash_info[1].size = 0;
  104. return (0);
  105. }
  106. DEBUGF ("## Before remap: "
  107. "BR0: 0x%08x OR0: 0x%08x "
  108. "BR6: 0x%08x OR6: 0x%08x\n",
  109. memctl->memc_br0, memctl->memc_or0,
  110. memctl->memc_br6, memctl->memc_or6);
  111. /* Remap FLASH according to real size */
  112. base = 0 - size_b0;
  113. memctl->memc_or0 = CONFIG_SYS_OR_TIMING_FLASH | (-size_b0 & 0xFFFF8000);
  114. memctl->memc_br0 = (base & BR_BA_MSK) | BR_PS_16 | BR_MS_GPCM | BR_V;
  115. DEBUGF("## BR0: 0x%08x OR0: 0x%08x\n",
  116. memctl->memc_br0, memctl->memc_or0);
  117. /* Re-do sizing to get full correct info */
  118. size_b0 = flash_get_size((vu_long *)base, &flash_info[0]);
  119. base = 0 - size_b0;
  120. flash_info[0].size = size_b0;
  121. flash_get_offsets (base, &flash_info[0]);
  122. /* monitor protection ON by default */
  123. flash_protect(FLAG_PROTECT_SET,
  124. PCU_MONITOR_BASE,
  125. PCU_MONITOR_BASE+monitor_flash_len-1,
  126. &flash_info[0]);
  127. #ifdef CONFIG_ENV_IS_IN_FLASH
  128. /* ENV protection ON by default */
  129. flash_protect(FLAG_PROTECT_SET,
  130. CONFIG_ENV_ADDR,
  131. CONFIG_ENV_ADDR+CONFIG_ENV_SECT_SIZE-1,
  132. &flash_info[0]);
  133. #endif
  134. if (size_b1) {
  135. flash_info_t tmp_info;
  136. memctl->memc_or6 = CONFIG_SYS_OR_TIMING_FLASH | (-size_b1 & 0xFFFF8000);
  137. memctl->memc_br6 = ((base - size_b1) & BR_BA_MSK) |
  138. BR_PS_16 | BR_MS_GPCM | BR_V;
  139. DEBUGF("## New BR6: 0x%08x OR6: 0x%08x\n",
  140. memctl->memc_br6, memctl->memc_or6);
  141. /* Re-do sizing to get full correct info */
  142. size_b1 = flash_get_size((vu_long *)(base - size_b1),
  143. &flash_info[1]);
  144. base -= size_b1;
  145. flash_get_offsets (base, &flash_info[1]);
  146. flash_info[1].size = size_b1;
  147. #ifdef CONFIG_ENV_IS_IN_FLASH
  148. /* ENV protection ON by default */
  149. flash_protect(FLAG_PROTECT_SET,
  150. CONFIG_ENV_ADDR,
  151. CONFIG_ENV_ADDR+CONFIG_ENV_SECT_SIZE-1,
  152. &flash_info[1]);
  153. #endif
  154. /*
  155. * Swap bank numbers so that addresses are in ascending order
  156. */
  157. tmp_info = flash_info[0];
  158. flash_info[0] = flash_info[1];
  159. flash_info[1] = tmp_info;
  160. } else {
  161. memctl->memc_br1 = 0; /* invalidate bank */
  162. flash_info[1].flash_id = FLASH_UNKNOWN;
  163. flash_info[1].sector_count = -1;
  164. }
  165. DEBUGF("## Final Flash bank sizes: %08lx + 0x%08lx\n",size_b0,size_b1);
  166. return (size_b0 + size_b1);
  167. }
  168. /*-----------------------------------------------------------------------
  169. */
  170. static void flash_get_offsets (ulong base, flash_info_t *info)
  171. {
  172. int i;
  173. short n;
  174. if (info->flash_id == FLASH_UNKNOWN) {
  175. return;
  176. }
  177. if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_AMD) {
  178. return;
  179. }
  180. switch (info->flash_id & FLASH_TYPEMASK) {
  181. case FLASH_AMDL322T:
  182. case FLASH_AMDL323T:
  183. case FLASH_AMDL324T:
  184. /* set sector offsets for top boot block type */
  185. base += info->size;
  186. i = info->sector_count;
  187. for (n=0; n<8; ++n) { /* 8 x 8k boot sectors */
  188. base -= 8 << 10;
  189. --i;
  190. info->start[i] = base;
  191. }
  192. while (i > 0) { /* 64k regular sectors */
  193. base -= 64 << 10;
  194. --i;
  195. info->start[i] = base;
  196. }
  197. return;
  198. case FLASH_AMDL322B:
  199. case FLASH_AMDL323B:
  200. case FLASH_AMDL324B:
  201. /* set sector offsets for bottom boot block type */
  202. for (i=0; i<8; ++i) { /* 8 x 8k boot sectors */
  203. info->start[i] = base;
  204. base += 8 << 10;
  205. }
  206. while (base < info->size) { /* 64k regular sectors */
  207. info->start[i] = base;
  208. base += 64 << 10;
  209. ++i;
  210. }
  211. return;
  212. case FLASH_AMDL640:
  213. /* set sector offsets for dual boot block type */
  214. for (i=0; i<8; ++i) { /* 8 x 8k boot sectors */
  215. info->start[i] = base;
  216. base += 8 << 10;
  217. }
  218. n = info->sector_count - 8;
  219. while (i < n) { /* 64k regular sectors */
  220. info->start[i] = base;
  221. base += 64 << 10;
  222. ++i;
  223. }
  224. while (i < info->sector_count) { /* 8 x 8k boot sectors */
  225. info->start[i] = base;
  226. base += 8 << 10;
  227. ++i;
  228. }
  229. return;
  230. default:
  231. return;
  232. }
  233. /* NOTREACHED */
  234. }
  235. /*-----------------------------------------------------------------------
  236. */
  237. void flash_print_info (flash_info_t *info)
  238. {
  239. int i;
  240. if (info->flash_id == FLASH_UNKNOWN) {
  241. printf ("missing or unknown FLASH type\n");
  242. return;
  243. }
  244. switch (info->flash_id & FLASH_VENDMASK) {
  245. case FLASH_MAN_AMD: printf ("AMD "); break;
  246. case FLASH_MAN_FUJ: printf ("FUJITSU "); break;
  247. default: printf ("Unknown Vendor "); break;
  248. }
  249. switch (info->flash_id & FLASH_TYPEMASK) {
  250. case FLASH_AMDL322B: printf ("AM29DL322B (32 Mbit, bottom boot sect)\n");
  251. break;
  252. case FLASH_AMDL322T: printf ("AM29DL322T (32 Mbit, top boot sector)\n");
  253. break;
  254. case FLASH_AMDL323B: printf ("AM29DL323B (32 Mbit, bottom boot sect)\n");
  255. break;
  256. case FLASH_AMDL323T: printf ("AM29DL323T (32 Mbit, top boot sector)\n");
  257. break;
  258. case FLASH_AMDL324B: printf ("AM29DL324B (32 Mbit, bottom boot sect)\n");
  259. break;
  260. case FLASH_AMDL324T: printf ("AM29DL324T (32 Mbit, top boot sector)\n");
  261. break;
  262. case FLASH_AMDL640: printf ("AM29DL640D (64 Mbit, dual boot sector)\n");
  263. break;
  264. default: printf ("Unknown Chip Type 0x%lX\n",
  265. info->flash_id);
  266. break;
  267. }
  268. printf (" Size: %ld MB in %d Sectors\n",
  269. info->size >> 20, info->sector_count);
  270. printf (" Sector Start Addresses:");
  271. for (i=0; i<info->sector_count; ++i) {
  272. if ((i % 5) == 0)
  273. printf ("\n ");
  274. printf (" %08lX%s",
  275. info->start[i],
  276. info->protect[i] ? " (RO)" : " "
  277. );
  278. }
  279. printf ("\n");
  280. return;
  281. }
  282. /*-----------------------------------------------------------------------
  283. */
  284. /*-----------------------------------------------------------------------
  285. */
  286. /*
  287. * The following code cannot be run from FLASH!
  288. */
  289. static ulong flash_get_size (vu_long *addr, flash_info_t *info)
  290. {
  291. short i;
  292. ushort value;
  293. vu_short *saddr = (vu_short *)addr;
  294. /* Write auto select command: read Manufacturer ID */
  295. saddr[0x0555] = 0x00AA;
  296. saddr[0x02AA] = 0x0055;
  297. saddr[0x0555] = 0x0090;
  298. value = saddr[0];
  299. DEBUGF("Manuf. ID @ 0x%08lx: 0x%04x\n", (ulong)addr, value);
  300. switch (value) {
  301. case (AMD_MANUFACT & 0xFFFF):
  302. info->flash_id = FLASH_MAN_AMD;
  303. break;
  304. case (FUJ_MANUFACT & 0xFFFF):
  305. info->flash_id = FLASH_MAN_FUJ;
  306. break;
  307. default:
  308. DEBUGF("Unknown Manufacturer ID\n");
  309. info->flash_id = FLASH_UNKNOWN;
  310. info->sector_count = 0;
  311. info->size = 0;
  312. return (0); /* no or unknown flash */
  313. }
  314. value = saddr[1]; /* device ID */
  315. DEBUGF("Device ID @ 0x%08lx: 0x%04x\n", (ulong)(&addr[1]), value);
  316. switch (value) {
  317. case (AMD_ID_DL322T & 0xFFFF):
  318. info->flash_id += FLASH_AMDL322T;
  319. info->sector_count = 71;
  320. info->size = 0x00400000;
  321. break; /* => 8 MB */
  322. case (AMD_ID_DL322B & 0xFFFF):
  323. info->flash_id += FLASH_AMDL322B;
  324. info->sector_count = 71;
  325. info->size = 0x00400000;
  326. break; /* => 8 MB */
  327. case (AMD_ID_DL323T & 0xFFFF):
  328. info->flash_id += FLASH_AMDL323T;
  329. info->sector_count = 71;
  330. info->size = 0x00400000;
  331. break; /* => 8 MB */
  332. case (AMD_ID_DL323B & 0xFFFF):
  333. info->flash_id += FLASH_AMDL323B;
  334. info->sector_count = 71;
  335. info->size = 0x00400000;
  336. break; /* => 8 MB */
  337. case (AMD_ID_DL324T & 0xFFFF):
  338. info->flash_id += FLASH_AMDL324T;
  339. info->sector_count = 71;
  340. info->size = 0x00400000;
  341. break; /* => 8 MB */
  342. case (AMD_ID_DL324B & 0xFFFF):
  343. info->flash_id += FLASH_AMDL324B;
  344. info->sector_count = 71;
  345. info->size = 0x00400000;
  346. break; /* => 8 MB */
  347. case (AMD_ID_DL640 & 0xFFFF):
  348. info->flash_id += FLASH_AMDL640;
  349. info->sector_count = 142;
  350. info->size = 0x00800000;
  351. break;
  352. default:
  353. DEBUGF("Unknown Device ID\n");
  354. info->flash_id = FLASH_UNKNOWN;
  355. return (0); /* => no or unknown flash */
  356. }
  357. flash_get_offsets ((ulong)addr, info);
  358. /* check for protected sectors */
  359. for (i = 0; i < info->sector_count; i++) {
  360. #if 0
  361. /* read sector protection at sector address, (A7 .. A0) = 0x02 */
  362. /* D0 = 1 if protected */
  363. saddr = (vu_short *)(info->start[i]);
  364. info->protect[i] = saddr[2] & 1;
  365. #else
  366. info->protect[i] =0;
  367. #endif
  368. }
  369. if (info->sector_count > CONFIG_SYS_MAX_FLASH_SECT) {
  370. printf ("** ERROR: sector count %d > max (%d) **\n",
  371. info->sector_count, CONFIG_SYS_MAX_FLASH_SECT);
  372. info->sector_count = CONFIG_SYS_MAX_FLASH_SECT;
  373. }
  374. saddr = (vu_short *)info->start[0];
  375. *saddr = 0x00F0; /* restore read mode */
  376. return (info->size);
  377. }
  378. /*-----------------------------------------------------------------------
  379. */
  380. int flash_erase (flash_info_t *info, int s_first, int s_last)
  381. {
  382. vu_short *addr = (vu_short*)(info->start[0]);
  383. int flag, prot, sect, l_sect;
  384. ulong start, now, last;
  385. if ((s_first < 0) || (s_first > s_last)) {
  386. if (info->flash_id == FLASH_UNKNOWN) {
  387. printf ("- missing\n");
  388. } else {
  389. printf ("- no sectors to erase\n");
  390. }
  391. return 1;
  392. }
  393. if ((info->flash_id == FLASH_UNKNOWN) ||
  394. (info->flash_id > FLASH_AMD_COMP)) {
  395. printf ("Can't erase unknown flash type %08lx - aborted\n",
  396. info->flash_id);
  397. return 1;
  398. }
  399. prot = 0;
  400. for (sect=s_first; sect<=s_last; ++sect) {
  401. if (info->protect[sect]) {
  402. prot++;
  403. }
  404. }
  405. if (prot) {
  406. printf ("- Warning: %d protected sectors will not be erased!\n",
  407. prot);
  408. } else {
  409. printf ("\n");
  410. }
  411. l_sect = -1;
  412. /* Disable interrupts which might cause a timeout here */
  413. flag = disable_interrupts();
  414. addr[0x0555] = 0x00AA;
  415. addr[0x02AA] = 0x0055;
  416. addr[0x0555] = 0x0080;
  417. addr[0x0555] = 0x00AA;
  418. addr[0x02AA] = 0x0055;
  419. /* Start erase on unprotected sectors */
  420. for (sect = s_first; sect<=s_last; sect++) {
  421. if (info->protect[sect] == 0) { /* not protected */
  422. addr = (vu_short*)(info->start[sect]);
  423. addr[0] = 0x0030;
  424. l_sect = sect;
  425. }
  426. }
  427. /* re-enable interrupts if necessary */
  428. if (flag)
  429. enable_interrupts();
  430. /* wait at least 80us - let's wait 1 ms */
  431. udelay (1000);
  432. /*
  433. * We wait for the last triggered sector
  434. */
  435. if (l_sect < 0)
  436. goto DONE;
  437. start = get_timer (0);
  438. last = start;
  439. addr = (vu_short*)(info->start[l_sect]);
  440. while ((addr[0] & 0x0080) != 0x0080) {
  441. if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
  442. printf ("Timeout\n");
  443. return 1;
  444. }
  445. /* show that we're waiting */
  446. if ((now - last) > 1000) { /* every second */
  447. putc ('.');
  448. last = now;
  449. }
  450. }
  451. DONE:
  452. /* reset to read mode */
  453. addr = (vu_short *)info->start[0];
  454. addr[0] = 0x00F0; /* reset bank */
  455. printf (" done\n");
  456. return 0;
  457. }
  458. /*-----------------------------------------------------------------------
  459. * Copy memory to flash, returns:
  460. * 0 - OK
  461. * 1 - write timeout
  462. * 2 - Flash not erased
  463. */
  464. #define FLASH_WIDTH 2 /* flash bus width in bytes */
  465. int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
  466. {
  467. ulong cp, wp, data;
  468. int i, l, rc;
  469. wp = (addr & ~(FLASH_WIDTH-1)); /* get lower FLASH_WIDTH aligned address */
  470. /*
  471. * handle unaligned start bytes
  472. */
  473. if ((l = addr - wp) != 0) {
  474. data = 0;
  475. for (i=0, cp=wp; i<l; ++i, ++cp) {
  476. data = (data << 8) | (*(uchar *)cp);
  477. }
  478. for (; i<FLASH_WIDTH && cnt>0; ++i) {
  479. data = (data << 8) | *src++;
  480. --cnt;
  481. ++cp;
  482. }
  483. for (; cnt==0 && i<FLASH_WIDTH; ++i, ++cp) {
  484. data = (data << 8) | (*(uchar *)cp);
  485. }
  486. if ((rc = write_data(info, wp, data)) != 0) {
  487. return (rc);
  488. }
  489. wp += FLASH_WIDTH;
  490. }
  491. /*
  492. * handle FLASH_WIDTH aligned part
  493. */
  494. while (cnt >= FLASH_WIDTH) {
  495. data = 0;
  496. for (i=0; i<FLASH_WIDTH; ++i) {
  497. data = (data << 8) | *src++;
  498. }
  499. if ((rc = write_data(info, wp, data)) != 0) {
  500. return (rc);
  501. }
  502. wp += FLASH_WIDTH;
  503. cnt -= FLASH_WIDTH;
  504. }
  505. if (cnt == 0) {
  506. return (0);
  507. }
  508. /*
  509. * handle unaligned tail bytes
  510. */
  511. data = 0;
  512. for (i=0, cp=wp; i<FLASH_WIDTH && cnt>0; ++i, ++cp) {
  513. data = (data << 8) | *src++;
  514. --cnt;
  515. }
  516. for (; i<FLASH_WIDTH; ++i, ++cp) {
  517. data = (data << 8) | (*(uchar *)cp);
  518. }
  519. return (write_data(info, wp, data));
  520. }
  521. /*-----------------------------------------------------------------------
  522. * Write a word to Flash, returns:
  523. * 0 - OK
  524. * 1 - write timeout
  525. * 2 - Flash not erased
  526. */
  527. static int write_data (flash_info_t *info, ulong dest, ulong data)
  528. {
  529. vu_short *addr = (vu_short*)(info->start[0]);
  530. vu_short *sdest = (vu_short *)dest;
  531. ushort sdata = (ushort)data;
  532. ushort sval;
  533. ulong start, passed;
  534. int flag, rc;
  535. /* Check if Flash is (sufficiently) erased */
  536. if ((*sdest & sdata) != sdata) {
  537. return (2);
  538. }
  539. /* Disable interrupts which might cause a timeout here */
  540. flag = disable_interrupts();
  541. addr[0x0555] = 0x00AA;
  542. addr[0x02AA] = 0x0055;
  543. addr[0x0555] = 0x00A0;
  544. #ifdef WORKAROUND_FOR_BROKEN_HARDWARE
  545. /* work around the timeout bugs */
  546. udelay(20);
  547. #endif
  548. *sdest = sdata;
  549. /* re-enable interrupts if necessary */
  550. if (flag)
  551. enable_interrupts();
  552. rc = 0;
  553. /* data polling for D7 */
  554. start = get_timer (0);
  555. for (passed=0; passed < CONFIG_SYS_FLASH_WRITE_TOUT; passed=get_timer(start)) {
  556. sval = *sdest;
  557. if ((sval & 0x0080) == (sdata & 0x0080))
  558. break;
  559. if ((sval & 0x0020) == 0) /* DQ5: Timeout? */
  560. continue;
  561. sval = *sdest;
  562. if ((sval & 0x0080) != (sdata & 0x0080))
  563. rc = 1;
  564. break;
  565. }
  566. if (rc) {
  567. DEBUGF ("Program cycle failed @ addr 0x%08lX: val %04X data %04X\n",
  568. dest, sval, sdata);
  569. }
  570. if (passed >= CONFIG_SYS_FLASH_WRITE_TOUT) {
  571. DEBUGF ("Timeout @ addr 0x%08lX: val %04X data %04X\n",
  572. dest, sval, sdata);
  573. rc = 1;
  574. }
  575. /* reset to read mode */
  576. addr = (vu_short *)info->start[0];
  577. addr[0] = 0x00F0; /* reset bank */
  578. return (rc);
  579. }
  580. /*-----------------------------------------------------------------------
  581. */