flash.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  1. /*
  2. * (C) Copyright 2000, 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. /*
  24. * Modified 4/5/2001
  25. * Wait for completion of each sector erase command issued
  26. * 4/5/2001
  27. * Chris Hallinan - DS4.COM, Inc. - clh@net1plus.com
  28. */
  29. /*
  30. * Modified 3/7/2001
  31. * - adapted for pip405, Denis Peter, MPL AG Switzerland
  32. * TODO:
  33. * clean-up
  34. */
  35. #include <common.h>
  36. #include <ppc4xx.h>
  37. #include <asm/processor.h>
  38. #include "common_util.h"
  39. flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
  40. /*-----------------------------------------------------------------------
  41. * Functions
  42. */
  43. static ulong flash_get_size (vu_long *addr, flash_info_t *info);
  44. static int write_word (flash_info_t *info, ulong dest, ulong data);
  45. void unlock_intel_sectors(flash_info_t *info,ulong addr,ulong cnt);
  46. #ifdef CONFIG_PIP405
  47. #define ADDR0 0x5555
  48. #define ADDR1 0x2aaa
  49. #define FLASH_WORD_SIZE unsigned short
  50. #endif
  51. #ifdef CONFIG_MIP405
  52. #define ADDR0 0x5555
  53. #define ADDR1 0x2aaa
  54. #define FLASH_WORD_SIZE unsigned short
  55. #endif
  56. #define FALSE 0
  57. #define TRUE 1
  58. /*-----------------------------------------------------------------------
  59. */
  60. unsigned long flash_init (void)
  61. {
  62. unsigned long size_b0, size_b1;
  63. int i;
  64. /* Since we are relocated, we can set-up the CS finally */
  65. setup_cs_reloc();
  66. /* get and display boot mode */
  67. i=get_boot_mode();
  68. if(i & BOOT_PCI)
  69. printf("(PCI Boot %s Map) ",(i & BOOT_MPS) ?
  70. "MPS" : "Flash");
  71. else
  72. printf("(%s Boot) ",(i & BOOT_MPS) ?
  73. "MPS" : "Flash");
  74. /* Init: no FLASHes known */
  75. for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
  76. flash_info[i].flash_id = FLASH_UNKNOWN;
  77. }
  78. /* Static FLASH Bank configuration here - FIXME XXX */
  79. size_b0 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]);
  80. if (flash_info[0].flash_id == FLASH_UNKNOWN) {
  81. printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
  82. size_b0, size_b0<<20);
  83. }
  84. /* protect the bootloader */
  85. /* Monitor protection ON by default */
  86. #if CFG_MONITOR_BASE >= CFG_FLASH_BASE
  87. flash_protect(FLAG_PROTECT_SET,
  88. CFG_MONITOR_BASE,
  89. CFG_MONITOR_BASE+monitor_flash_len-1,
  90. &flash_info[0]);
  91. #endif
  92. /* protect reset vector */
  93. flash_info[0].protect[flash_info[0].sector_count-1] = 1;
  94. size_b1 = 0 ;
  95. flash_info[0].size = size_b0;
  96. #if 0
  97. /* include this if you want to test if
  98. the relocation has be done ok.
  99. This will disable both Chipselects */
  100. mtdcr (ebccfga, pb0cr);
  101. mtdcr (ebccfgd, 0L);
  102. mtdcr (ebccfga, pb1cr);
  103. mtdcr (ebccfgd, 0L);
  104. printf("CS0 & CS1 switched off for test\n");
  105. #endif
  106. return (size_b0);
  107. }
  108. /*-----------------------------------------------------------------------
  109. */
  110. void flash_print_info (flash_info_t *info)
  111. {
  112. int i;
  113. int k;
  114. int size;
  115. int erased;
  116. volatile unsigned long *flash;
  117. if (info->flash_id == FLASH_UNKNOWN) {
  118. printf ("missing or unknown FLASH type\n");
  119. return;
  120. }
  121. switch (info->flash_id & FLASH_VENDMASK) {
  122. case FLASH_MAN_AMD: printf ("AMD "); break;
  123. case FLASH_MAN_FUJ: printf ("FUJITSU "); break;
  124. case FLASH_MAN_SST: printf ("SST "); break;
  125. case FLASH_MAN_INTEL: printf ("Intel "); break;
  126. default: printf ("Unknown Vendor "); break;
  127. }
  128. switch (info->flash_id & FLASH_TYPEMASK) {
  129. case FLASH_AM040: printf ("AM29F040 (512 Kbit, uniform sector size)\n");
  130. break;
  131. case FLASH_AM400B: printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
  132. break;
  133. case FLASH_AM400T: printf ("AM29LV400T (4 Mbit, top boot sector)\n");
  134. break;
  135. case FLASH_AM800B: printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
  136. break;
  137. case FLASH_AM800T: printf ("AM29LV800T (8 Mbit, top boot sector)\n");
  138. break;
  139. case FLASH_AM160B: printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
  140. break;
  141. case FLASH_AM160T: printf ("AM29LV160T (16 Mbit, top boot sector)\n");
  142. break;
  143. case FLASH_AM320B: printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
  144. break;
  145. case FLASH_AM320T: printf ("AM29LV320T (32 Mbit, top boot sector)\n");
  146. break;
  147. case FLASH_SST800A: printf ("SST39LF/VF800 (8 Mbit, uniform sector size)\n");
  148. break;
  149. case FLASH_SST160A: printf ("SST39LF/VF160 (16 Mbit, uniform sector size)\n");
  150. break;
  151. case FLASH_INTEL320T: printf ("TE28F320C3 (32 Mbit, top sector size)\n");
  152. break;
  153. default: printf ("Unknown Chip Type\n");
  154. break;
  155. }
  156. printf (" Size: %ld KB in %d Sectors\n",
  157. info->size >> 10, info->sector_count);
  158. printf (" Sector Start Addresses:");
  159. for (i=0; i<info->sector_count; ++i) {
  160. /*
  161. * Check if whole sector is erased
  162. */
  163. if (i != (info->sector_count-1))
  164. size = info->start[i+1] - info->start[i];
  165. else
  166. size = info->start[0] + info->size - info->start[i];
  167. erased = 1;
  168. flash = (volatile unsigned long *)info->start[i];
  169. size = size >> 2; /* divide by 4 for longword access */
  170. for (k=0; k<size; k++) {
  171. if (*flash++ != 0xffffffff) {
  172. erased = 0;
  173. break;
  174. }
  175. }
  176. if ((i % 5) == 0)
  177. printf ("\n ");
  178. printf (" %08lX%s%s",
  179. info->start[i],
  180. erased ? " E" : " ",
  181. info->protect[i] ? "RO " : " ");
  182. }
  183. printf ("\n");
  184. }
  185. /*-----------------------------------------------------------------------
  186. */
  187. /*-----------------------------------------------------------------------
  188. */
  189. /*
  190. * The following code cannot be run from FLASH!
  191. */
  192. static ulong flash_get_size (vu_long *addr, flash_info_t *info)
  193. {
  194. short i;
  195. FLASH_WORD_SIZE value;
  196. ulong base = (ulong)addr;
  197. volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)addr;
  198. /* Write auto select command: read Manufacturer ID */
  199. addr2[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
  200. addr2[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
  201. addr2[ADDR0] = (FLASH_WORD_SIZE)0x00900090;
  202. value = addr2[0];
  203. /* printf("flash_get_size value: %x\n",value); */
  204. switch (value) {
  205. case (FLASH_WORD_SIZE)AMD_MANUFACT:
  206. info->flash_id = FLASH_MAN_AMD;
  207. break;
  208. case (FLASH_WORD_SIZE)FUJ_MANUFACT:
  209. info->flash_id = FLASH_MAN_FUJ;
  210. break;
  211. case (FLASH_WORD_SIZE)INTEL_MANUFACT:
  212. info->flash_id = FLASH_MAN_INTEL;
  213. break;
  214. case (FLASH_WORD_SIZE)SST_MANUFACT:
  215. info->flash_id = FLASH_MAN_SST;
  216. break;
  217. default:
  218. info->flash_id = FLASH_UNKNOWN;
  219. info->sector_count = 0;
  220. info->size = 0;
  221. return (0); /* no or unknown flash */
  222. }
  223. value = addr2[1]; /* device ID */
  224. /* printf("Device value %x\n",value); */
  225. switch (value) {
  226. case (FLASH_WORD_SIZE)AMD_ID_F040B:
  227. info->flash_id += FLASH_AM040;
  228. info->sector_count = 8;
  229. info->size = 0x0080000; /* => 512 ko */
  230. break;
  231. case (FLASH_WORD_SIZE)AMD_ID_LV400T:
  232. info->flash_id += FLASH_AM400T;
  233. info->sector_count = 11;
  234. info->size = 0x00080000;
  235. break; /* => 0.5 MB */
  236. case (FLASH_WORD_SIZE)AMD_ID_LV400B:
  237. info->flash_id += FLASH_AM400B;
  238. info->sector_count = 11;
  239. info->size = 0x00080000;
  240. break; /* => 0.5 MB */
  241. case (FLASH_WORD_SIZE)AMD_ID_LV800T:
  242. info->flash_id += FLASH_AM800T;
  243. info->sector_count = 19;
  244. info->size = 0x00100000;
  245. break; /* => 1 MB */
  246. case (FLASH_WORD_SIZE)AMD_ID_LV800B:
  247. info->flash_id += FLASH_AM800B;
  248. info->sector_count = 19;
  249. info->size = 0x00100000;
  250. break; /* => 1 MB */
  251. case (FLASH_WORD_SIZE)AMD_ID_LV160T:
  252. info->flash_id += FLASH_AM160T;
  253. info->sector_count = 35;
  254. info->size = 0x00200000;
  255. break; /* => 2 MB */
  256. case (FLASH_WORD_SIZE)AMD_ID_LV160B:
  257. info->flash_id += FLASH_AM160B;
  258. info->sector_count = 35;
  259. info->size = 0x00200000;
  260. break; /* => 2 MB */
  261. #if 0 /* enable when device IDs are available */
  262. case (FLASH_WORD_SIZE)AMD_ID_LV320T:
  263. info->flash_id += FLASH_AM320T;
  264. info->sector_count = 67;
  265. info->size = 0x00400000;
  266. break; /* => 4 MB */
  267. case (FLASH_WORD_SIZE)AMD_ID_LV320B:
  268. info->flash_id += FLASH_AM320B;
  269. info->sector_count = 67;
  270. info->size = 0x00400000;
  271. break; /* => 4 MB */
  272. #endif
  273. case (FLASH_WORD_SIZE)SST_ID_xF800A:
  274. info->flash_id += FLASH_SST800A;
  275. info->sector_count = 16;
  276. info->size = 0x00100000;
  277. break; /* => 1 MB */
  278. case (FLASH_WORD_SIZE)INTEL_ID_28F320C3T:
  279. info->flash_id += FLASH_INTEL320T;
  280. info->sector_count = 71;
  281. info->size = 0x00400000;
  282. break; /* => 4 MB */
  283. case (FLASH_WORD_SIZE)SST_ID_xF160A:
  284. info->flash_id += FLASH_SST160A;
  285. info->sector_count = 32;
  286. info->size = 0x00200000;
  287. break; /* => 2 MB */
  288. default:
  289. info->flash_id = FLASH_UNKNOWN;
  290. return (0); /* => no or unknown flash */
  291. }
  292. /* set up sector start address table */
  293. if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
  294. (info->flash_id == FLASH_AM040)){
  295. for (i = 0; i < info->sector_count; i++)
  296. info->start[i] = base + (i * 0x00010000);
  297. }
  298. else {
  299. if (info->flash_id & FLASH_BTYPE) {
  300. /* set sector offsets for bottom boot block type */
  301. info->start[0] = base + 0x00000000;
  302. info->start[1] = base + 0x00004000;
  303. info->start[2] = base + 0x00006000;
  304. info->start[3] = base + 0x00008000;
  305. for (i = 4; i < info->sector_count; i++)
  306. info->start[i] = base + (i * 0x00010000) - 0x00030000;
  307. }
  308. else {
  309. /* set sector offsets for top boot block type */
  310. i = info->sector_count - 1;
  311. if(info->sector_count==71) {
  312. info->start[i--] = base + info->size - 0x00002000;
  313. info->start[i--] = base + info->size - 0x00004000;
  314. info->start[i--] = base + info->size - 0x00006000;
  315. info->start[i--] = base + info->size - 0x00008000;
  316. info->start[i--] = base + info->size - 0x0000A000;
  317. info->start[i--] = base + info->size - 0x0000C000;
  318. info->start[i--] = base + info->size - 0x0000E000;
  319. for (; i >= 0; i--)
  320. info->start[i] = base + i * 0x000010000;
  321. }
  322. else {
  323. info->start[i--] = base + info->size - 0x00004000;
  324. info->start[i--] = base + info->size - 0x00006000;
  325. info->start[i--] = base + info->size - 0x00008000;
  326. for (; i >= 0; i--)
  327. info->start[i] = base + i * 0x00010000;
  328. }
  329. }
  330. }
  331. /* check for protected sectors */
  332. for (i = 0; i < info->sector_count; i++) {
  333. /* read sector protection at sector address, (A7 .. A0) = 0x02 */
  334. /* D0 = 1 if protected */
  335. addr2 = (volatile FLASH_WORD_SIZE *)(info->start[i]);
  336. if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL)
  337. info->protect[i] = 0;
  338. else
  339. info->protect[i] = addr2[2] & 1;
  340. }
  341. /*
  342. * Prevent writes to uninitialized FLASH.
  343. */
  344. if (info->flash_id != FLASH_UNKNOWN) {
  345. addr2 = (FLASH_WORD_SIZE *)info->start[0];
  346. *addr2 = (FLASH_WORD_SIZE)0x00F000F0; /* reset bank */
  347. }
  348. return (info->size);
  349. }
  350. int wait_for_DQ7(flash_info_t *info, int sect)
  351. {
  352. ulong start, now, last;
  353. volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[sect]);
  354. start = get_timer (0);
  355. last = start;
  356. while ((addr[0] & (FLASH_WORD_SIZE)0x00800080) != (FLASH_WORD_SIZE)0x00800080) {
  357. if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
  358. printf ("Timeout\n");
  359. return -1;
  360. }
  361. /* show that we're waiting */
  362. if ((now - last) > 1000) { /* every second */
  363. putc ('.');
  364. last = now;
  365. }
  366. }
  367. return 0;
  368. }
  369. int intel_wait_for_DQ7(flash_info_t *info, int sect)
  370. {
  371. ulong start, now, last;
  372. volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[sect]);
  373. start = get_timer (0);
  374. last = start;
  375. while ((addr[0] & (FLASH_WORD_SIZE)0x00800080) != (FLASH_WORD_SIZE)0x00800080) {
  376. if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
  377. printf ("Timeout\n");
  378. return -1;
  379. }
  380. /* show that we're waiting */
  381. if ((now - last) > 1000) { /* every second */
  382. putc ('.');
  383. last = now;
  384. }
  385. }
  386. addr[0]=(FLASH_WORD_SIZE)0x00500050;
  387. return 0;
  388. }
  389. /*-----------------------------------------------------------------------
  390. */
  391. int flash_erase (flash_info_t *info, int s_first, int s_last)
  392. {
  393. volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[0]);
  394. volatile FLASH_WORD_SIZE *addr2;
  395. int flag, prot, sect, l_sect;
  396. int i;
  397. if ((s_first < 0) || (s_first > s_last)) {
  398. if (info->flash_id == FLASH_UNKNOWN) {
  399. printf ("- missing\n");
  400. } else {
  401. printf ("- no sectors to erase\n");
  402. }
  403. return 1;
  404. }
  405. if (info->flash_id == FLASH_UNKNOWN) {
  406. printf ("Can't erase unknown flash type - aborted\n");
  407. return 1;
  408. }
  409. prot = 0;
  410. for (sect=s_first; sect<=s_last; ++sect) {
  411. if (info->protect[sect]) {
  412. prot++;
  413. }
  414. }
  415. if (prot) {
  416. printf ("- Warning: %d protected sectors will not be erased!\n",
  417. prot);
  418. } else {
  419. printf ("\n");
  420. }
  421. l_sect = -1;
  422. /* Disable interrupts which might cause a timeout here */
  423. flag = disable_interrupts();
  424. /* Start erase on unprotected sectors */
  425. for (sect = s_first; sect<=s_last; sect++) {
  426. if (info->protect[sect] == 0) { /* not protected */
  427. addr2 = (FLASH_WORD_SIZE *)(info->start[sect]);
  428. /* printf("Erasing sector %p\n", addr2); */ /* CLH */
  429. if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) {
  430. addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
  431. addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
  432. addr[ADDR0] = (FLASH_WORD_SIZE)0x00800080;
  433. addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
  434. addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
  435. addr2[0] = (FLASH_WORD_SIZE)0x00500050; /* block erase */
  436. for (i=0; i<50; i++)
  437. udelay(1000); /* wait 1 ms */
  438. wait_for_DQ7(info, sect);
  439. }
  440. else {
  441. if((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL){
  442. addr2[0] = (FLASH_WORD_SIZE)0x00600060; /* unlock sector */
  443. addr2[0] = (FLASH_WORD_SIZE)0x00D000D0; /* sector erase */
  444. intel_wait_for_DQ7(info, sect);
  445. addr2[0] = (FLASH_WORD_SIZE)0x00200020; /* sector erase */
  446. addr2[0] = (FLASH_WORD_SIZE)0x00D000D0; /* sector erase */
  447. intel_wait_for_DQ7(info, sect);
  448. }
  449. else {
  450. addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
  451. addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
  452. addr[ADDR0] = (FLASH_WORD_SIZE)0x00800080;
  453. addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
  454. addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
  455. addr2[0] = (FLASH_WORD_SIZE)0x00300030; /* sector erase */
  456. wait_for_DQ7(info, sect);
  457. }
  458. }
  459. l_sect = sect;
  460. /*
  461. * Wait for each sector to complete, it's more
  462. * reliable. According to AMD Spec, you must
  463. * issue all erase commands within a specified
  464. * timeout. This has been seen to fail, especially
  465. * if printf()s are included (for debug)!!
  466. */
  467. /* wait_for_DQ7(info, sect); */
  468. }
  469. }
  470. /* re-enable interrupts if necessary */
  471. if (flag)
  472. enable_interrupts();
  473. /* wait at least 80us - let's wait 1 ms */
  474. udelay (1000);
  475. #if 0
  476. /*
  477. * We wait for the last triggered sector
  478. */
  479. if (l_sect < 0)
  480. goto DONE;
  481. wait_for_DQ7(info, l_sect);
  482. DONE:
  483. #endif
  484. /* reset to read mode */
  485. addr = (FLASH_WORD_SIZE *)info->start[0];
  486. addr[0] = (FLASH_WORD_SIZE)0x00F000F0; /* reset bank */
  487. printf (" done\n");
  488. return 0;
  489. }
  490. void unlock_intel_sectors(flash_info_t *info,ulong addr,ulong cnt)
  491. {
  492. int i;
  493. volatile FLASH_WORD_SIZE *addr2;
  494. long c;
  495. c= (long)cnt;
  496. for(i=info->sector_count-1;i>0;i--)
  497. {
  498. if(addr>=info->start[i])
  499. break;
  500. }
  501. do {
  502. addr2 = (FLASH_WORD_SIZE *)(info->start[i]);
  503. addr2[0] = (FLASH_WORD_SIZE)0x00600060; /* unlock sector setup */
  504. addr2[0] = (FLASH_WORD_SIZE)0x00D000D0; /* unlock sector */
  505. intel_wait_for_DQ7(info, i);
  506. i++;
  507. c-=(info->start[i]-info->start[i-1]);
  508. }while(c>0);
  509. }
  510. /*-----------------------------------------------------------------------
  511. * Copy memory to flash, returns:
  512. * 0 - OK
  513. * 1 - write timeout
  514. * 2 - Flash not erased
  515. */
  516. int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
  517. {
  518. ulong cp, wp, data;
  519. int i, l, rc;
  520. if((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL){
  521. unlock_intel_sectors(info,addr,cnt);
  522. }
  523. wp = (addr & ~3); /* get lower word aligned address */
  524. /*
  525. * handle unaligned start bytes
  526. */
  527. if ((l = addr - wp) != 0) {
  528. data = 0;
  529. for (i=0, cp=wp; i<l; ++i, ++cp) {
  530. data = (data << 8) | (*(uchar *)cp);
  531. }
  532. for (; i<4 && cnt>0; ++i) {
  533. data = (data << 8) | *src++;
  534. --cnt;
  535. ++cp;
  536. }
  537. for (; cnt==0 && i<4; ++i, ++cp) {
  538. data = (data << 8) | (*(uchar *)cp);
  539. }
  540. if ((rc = write_word(info, wp, data)) != 0) {
  541. return (rc);
  542. }
  543. wp += 4;
  544. }
  545. /*
  546. * handle word aligned part
  547. */
  548. while (cnt >= 4) {
  549. data = 0;
  550. for (i=0; i<4; ++i) {
  551. data = (data << 8) | *src++;
  552. }
  553. if ((rc = write_word(info, wp, data)) != 0) {
  554. return (rc);
  555. }
  556. wp += 4;
  557. if((wp % 0x10000)==0)
  558. printf("."); /* show Progress */
  559. cnt -= 4;
  560. }
  561. if (cnt == 0) {
  562. return (0);
  563. }
  564. /*
  565. * handle unaligned tail bytes
  566. */
  567. data = 0;
  568. for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
  569. data = (data << 8) | *src++;
  570. --cnt;
  571. }
  572. for (; i<4; ++i, ++cp) {
  573. data = (data << 8) | (*(uchar *)cp);
  574. }
  575. rc=write_word(info, wp, data);
  576. return rc;
  577. }
  578. /*-----------------------------------------------------------------------
  579. * Write a word to Flash, returns:
  580. * 0 - OK
  581. * 1 - write timeout
  582. * 2 - Flash not erased
  583. */
  584. static FLASH_WORD_SIZE *read_val = (FLASH_WORD_SIZE *)0x200000;
  585. static int write_word (flash_info_t *info, ulong dest, ulong data)
  586. {
  587. volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)(info->start[0]);
  588. volatile FLASH_WORD_SIZE *dest2 = (FLASH_WORD_SIZE *)dest;
  589. volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *)&data;
  590. ulong start;
  591. int flag;
  592. int i;
  593. /* Check if Flash is (sufficiently) erased */
  594. if ((*((volatile FLASH_WORD_SIZE *)dest) &
  595. (FLASH_WORD_SIZE)data) != (FLASH_WORD_SIZE)data) {
  596. return (2);
  597. }
  598. /* Disable interrupts which might cause a timeout here */
  599. flag = disable_interrupts();
  600. for (i=0; i<4/sizeof(FLASH_WORD_SIZE); i++)
  601. {
  602. if((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL){
  603. /* intel style writting */
  604. dest2[i] = (FLASH_WORD_SIZE)0x00500050;
  605. dest2[i] = (FLASH_WORD_SIZE)0x00400040;
  606. *read_val++ = data2[i];
  607. dest2[i] = data2[i];
  608. if (flag)
  609. enable_interrupts();
  610. /* data polling for D7 */
  611. start = get_timer (0);
  612. udelay(10);
  613. while ((dest2[i] & (FLASH_WORD_SIZE)0x00800080) != (FLASH_WORD_SIZE)0x00800080)
  614. {
  615. if (get_timer(start) > CFG_FLASH_WRITE_TOUT)
  616. return (1);
  617. }
  618. dest2[i] = (FLASH_WORD_SIZE)0x00FF00FF; /* return to read mode */
  619. udelay(10);
  620. dest2[i] = (FLASH_WORD_SIZE)0x00FF00FF; /* return to read mode */
  621. if(dest2[i]!=data2[i])
  622. printf("Error at %p 0x%04X != 0x%04X\n",&dest2[i],dest2[i],data2[i]);
  623. }
  624. else {
  625. addr2[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
  626. addr2[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
  627. addr2[ADDR0] = (FLASH_WORD_SIZE)0x00A000A0;
  628. dest2[i] = data2[i];
  629. /* re-enable interrupts if necessary */
  630. if (flag)
  631. enable_interrupts();
  632. /* data polling for D7 */
  633. start = get_timer (0);
  634. while ((dest2[i] & (FLASH_WORD_SIZE)0x00800080) !=
  635. (data2[i] & (FLASH_WORD_SIZE)0x00800080)) {
  636. if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
  637. return (1);
  638. }
  639. }
  640. }
  641. }
  642. return (0);
  643. }
  644. /*-----------------------------------------------------------------------
  645. */