flash.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791
  1. /*
  2. * (C) Copyright 2002, 2003
  3. * Daniel Engström, Omicron Ceti AB, daniel@omicron.se
  4. *
  5. * (C) Copyright 2002
  6. * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
  7. * Alex Zuepke <azu@sysgo.de>
  8. *
  9. * See file CREDITS for list of people who contributed to this
  10. * project.
  11. *
  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.
  16. *
  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.
  21. *
  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,
  25. * MA 02111-1307 USA
  26. */
  27. #include <common.h>
  28. #include <asm/io.h>
  29. #include <pci.h>
  30. #include <asm/ic/sc520.h>
  31. #define PROBE_BUFFER_SIZE 1024
  32. static unsigned char buffer[PROBE_BUFFER_SIZE];
  33. #define SC520_MAX_FLASH_BANKS 1
  34. #define SC520_FLASH_BANK0_BASE 0x38000000 /* BOOTCS */
  35. #define SC520_FLASH_BANKSIZE 0x8000000
  36. #define A29LV641DH_SIZE 0x800000
  37. #define A29LV641DH_SECTORS 128
  38. #define A29LV641MH_SIZE 0x800000
  39. #define A29LV641MH_SECTORS 128
  40. #define I28F320J3A_SIZE 0x400000
  41. #define I28F320J3A_SECTORS 32
  42. #define I28F640J3A_SIZE 0x800000
  43. #define I28F640J3A_SECTORS 64
  44. #define I28F128J3A_SIZE 0x1000000
  45. #define I28F128J3A_SECTORS 128
  46. flash_info_t flash_info[SC520_MAX_FLASH_BANKS];
  47. #define READY 1
  48. #define ERR 2
  49. #define TMO 4
  50. /*-----------------------------------------------------------------------
  51. */
  52. static u32 _probe_flash(u32 addr, u32 bw, int il)
  53. {
  54. u32 result=0;
  55. /* First do an unlock cycle for the benefit of
  56. * devices that need it */
  57. switch (bw) {
  58. case 1:
  59. *(volatile u8*)(addr+0x5555) = 0xaa;
  60. *(volatile u8*)(addr+0x2aaa) = 0x55;
  61. *(volatile u8*)(addr+0x5555) = 0x90;
  62. /* Read vendor */
  63. result = *(volatile u8*)addr;
  64. result <<= 16;
  65. /* Read device */
  66. result |= *(volatile u8*)(addr+2);
  67. /* Return device to data mode */
  68. *(volatile u8*)addr = 0xff;
  69. *(volatile u8*)(addr+0x5555), 0xf0;
  70. break;
  71. case 2:
  72. *(volatile u16*)(addr+0xaaaa) = 0xaaaa;
  73. *(volatile u16*)(addr+0x5554) = 0x5555;
  74. /* Issue identification command */
  75. if (il == 2) {
  76. *(volatile u16*)(addr+0xaaaa) = 0x9090;
  77. /* Read vendor */
  78. result = *(volatile u8*)addr;
  79. result <<= 16;
  80. /* Read device */
  81. result |= *(volatile u8*)(addr+2);
  82. /* Return device to data mode */
  83. *(volatile u16*)addr = 0xffff;
  84. *(volatile u16*)(addr+0xaaaa), 0xf0f0;
  85. } else {
  86. *(volatile u8*)(addr+0xaaaa) = 0x90;
  87. /* Read vendor */
  88. result = *(volatile u16*)addr;
  89. result <<= 16;
  90. /* Read device */
  91. result |= *(volatile u16*)(addr+2);
  92. /* Return device to data mode */
  93. *(volatile u8*)addr = 0xff;
  94. *(volatile u8*)(addr+0xaaaa), 0xf0;
  95. }
  96. break;
  97. case 4:
  98. *(volatile u32*)(addr+0x5554) = 0xaaaaaaaa;
  99. *(volatile u32*)(addr+0xaaa8) = 0x55555555;
  100. switch (il) {
  101. case 1:
  102. /* Issue identification command */
  103. *(volatile u8*)(addr+0x5554) = 0x90;
  104. /* Read vendor */
  105. result = *(volatile u16*)addr;
  106. result <<= 16;
  107. /* Read device */
  108. result |= *(volatile u16*)(addr+4);
  109. /* Return device to data mode */
  110. *(volatile u8*)addr = 0xff;
  111. *(volatile u8*)(addr+0x5554), 0xf0;
  112. break;
  113. case 2:
  114. /* Issue identification command */
  115. *(volatile u32*)(addr + 0x5554) = 0x00900090;
  116. /* Read vendor */
  117. result = *(volatile u16*)addr;
  118. result <<= 16;
  119. /* Read device */
  120. result |= *(volatile u16*)(addr+4);
  121. /* Return device to data mode */
  122. *(volatile u32*)addr = 0x00ff00ff;
  123. *(volatile u32*)(addr+0x5554), 0x00f000f0;
  124. break;
  125. case 4:
  126. /* Issue identification command */
  127. *(volatile u32*)(addr+0x5554) = 0x90909090;
  128. /* Read vendor */
  129. result = *(volatile u8*)addr;
  130. result <<= 16;
  131. /* Read device */
  132. result |= *(volatile u8*)(addr+4);
  133. /* Return device to data mode */
  134. *(volatile u32*)addr = 0xffffffff;
  135. *(volatile u32*)(addr+0x5554), 0xf0f0f0f0;
  136. break;
  137. }
  138. break;
  139. }
  140. return result;
  141. }
  142. extern int _probe_flash_end;
  143. asm ("_probe_flash_end:\n"
  144. ".long 0\n");
  145. static int identify_flash(unsigned address, int width)
  146. {
  147. int is;
  148. int device;
  149. int vendor;
  150. int size;
  151. unsigned res;
  152. u32 (*_probe_flash_ptr)(u32 a, u32 bw, int il);
  153. size = (unsigned)&_probe_flash_end - (unsigned)_probe_flash;
  154. if (size > PROBE_BUFFER_SIZE) {
  155. printf("_probe_flash() routine too large (%d) %p - %p\n",
  156. size, &_probe_flash_end, _probe_flash);
  157. return 0;
  158. }
  159. memcpy(buffer, _probe_flash, size);
  160. _probe_flash_ptr = (void*)buffer;
  161. is = disable_interrupts();
  162. res = _probe_flash_ptr(address, width, 1);
  163. if (is) {
  164. enable_interrupts();
  165. }
  166. vendor = res >> 16;
  167. device = res & 0xffff;
  168. return res;
  169. }
  170. ulong flash_init(void)
  171. {
  172. int i, j;
  173. ulong size = 0;
  174. for (i = 0; i < SC520_MAX_FLASH_BANKS; i++) {
  175. unsigned id;
  176. ulong flashbase = 0;
  177. int sectsize = 0;
  178. memset(flash_info[i].protect, 0, CONFIG_SYS_MAX_FLASH_SECT);
  179. switch (i) {
  180. case 0:
  181. flashbase = SC520_FLASH_BANK0_BASE;
  182. break;
  183. default:
  184. panic("configured too many flash banks!\n");
  185. }
  186. id = identify_flash(flashbase, 2);
  187. switch (id) {
  188. case 0x000122d7:
  189. /* 29LV641DH */
  190. flash_info[i].flash_id =
  191. (AMD_MANUFACT & FLASH_VENDMASK) |
  192. (AMD_ID_LV640U & FLASH_TYPEMASK);
  193. flash_info[i].size = A29LV641DH_SIZE;
  194. flash_info[i].sector_count = A29LV641DH_SECTORS;
  195. sectsize = A29LV641DH_SIZE/A29LV641DH_SECTORS;
  196. printf("Bank %d: AMD 29LV641DH\n", i);
  197. break;
  198. case 0x0001227E:
  199. /* 29LV641MH */
  200. flash_info[i].flash_id =
  201. (AMD_MANUFACT & FLASH_VENDMASK) |
  202. (AMD_ID_DL640 & FLASH_TYPEMASK);
  203. flash_info[i].size = A29LV641MH_SIZE;
  204. flash_info[i].sector_count = A29LV641MH_SECTORS;
  205. sectsize = A29LV641MH_SIZE/A29LV641MH_SECTORS;
  206. printf("Bank %d: AMD 29LV641MH\n", i);
  207. break;
  208. case 0x00890016:
  209. /* 28F320J3A */
  210. flash_info[i].flash_id =
  211. (INTEL_MANUFACT & FLASH_VENDMASK) |
  212. (INTEL_ID_28F320J3A & FLASH_TYPEMASK);
  213. flash_info[i].size = I28F320J3A_SIZE;
  214. flash_info[i].sector_count = I28F320J3A_SECTORS;
  215. sectsize = I28F320J3A_SIZE/I28F320J3A_SECTORS;
  216. printf("Bank %d: Intel 28F320J3A\n", i);
  217. break;
  218. case 0x00890017:
  219. /* 28F640J3A */
  220. flash_info[i].flash_id =
  221. (INTEL_MANUFACT & FLASH_VENDMASK) |
  222. (INTEL_ID_28F640J3A & FLASH_TYPEMASK);
  223. flash_info[i].size = I28F640J3A_SIZE;
  224. flash_info[i].sector_count = I28F640J3A_SECTORS;
  225. sectsize = I28F640J3A_SIZE/I28F640J3A_SECTORS;
  226. printf("Bank %d: Intel 28F640J3A\n", i);
  227. break;
  228. case 0x00890018:
  229. /* 28F128J3A */
  230. flash_info[i].flash_id =
  231. (INTEL_MANUFACT & FLASH_VENDMASK) |
  232. (INTEL_ID_28F128J3A & FLASH_TYPEMASK);
  233. flash_info[i].size = I28F128J3A_SIZE;
  234. flash_info[i].sector_count = I28F128J3A_SECTORS;
  235. sectsize = I28F128J3A_SIZE/I28F128J3A_SECTORS;
  236. printf("Bank %d: Intel 28F128J3A\n", i);
  237. break;
  238. default:
  239. printf("Bank %d have unknown flash %08x\n", i, id);
  240. flash_info[i].flash_id = FLASH_UNKNOWN;
  241. continue;
  242. }
  243. for (j = 0; j < flash_info[i].sector_count; j++) {
  244. flash_info[i].start[j] = flashbase + j * sectsize;
  245. }
  246. size += flash_info[i].size;
  247. flash_protect(FLAG_PROTECT_CLEAR,
  248. flash_info[i].start[0],
  249. flash_info[i].start[0] + flash_info[i].size - 1,
  250. &flash_info[i]);
  251. }
  252. /*
  253. * Protect monitor and environment sectors
  254. */
  255. flash_protect(FLAG_PROTECT_SET,
  256. i386boot_start,
  257. i386boot_end,
  258. &flash_info[0]);
  259. #ifdef CONFIG_ENV_ADDR
  260. flash_protect(FLAG_PROTECT_SET,
  261. CONFIG_ENV_ADDR,
  262. CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1,
  263. &flash_info[0]);
  264. #endif
  265. return size;
  266. }
  267. /*-----------------------------------------------------------------------
  268. */
  269. void flash_print_info(flash_info_t *info)
  270. {
  271. int i;
  272. switch (info->flash_id & FLASH_VENDMASK) {
  273. case (INTEL_MANUFACT & FLASH_VENDMASK):
  274. printf("INTEL: ");
  275. switch (info->flash_id & FLASH_TYPEMASK) {
  276. case (INTEL_ID_28F320J3A & FLASH_TYPEMASK):
  277. printf("1x I28F320J3A (32Mbit)\n");
  278. break;
  279. case (INTEL_ID_28F640J3A & FLASH_TYPEMASK):
  280. printf("1x I28F640J3A (64Mbit)\n");
  281. break;
  282. case (INTEL_ID_28F128J3A & FLASH_TYPEMASK):
  283. printf("1x I28F128J3A (128Mbit)\n");
  284. break;
  285. default:
  286. printf("Unknown Chip Type\n");
  287. goto done;
  288. break;
  289. }
  290. break;
  291. case (AMD_MANUFACT & FLASH_VENDMASK):
  292. printf("AMD: ");
  293. switch (info->flash_id & FLASH_TYPEMASK) {
  294. case (AMD_ID_LV640U & FLASH_TYPEMASK):
  295. printf("1x AMD29LV641DH (64Mbit)\n");
  296. break;
  297. case (AMD_ID_DL640 & FLASH_TYPEMASK):
  298. printf("1x AMD29LV641MH (64Mbit)\n");
  299. break;
  300. default:
  301. printf("Unknown Chip Type\n");
  302. goto done;
  303. break;
  304. }
  305. break;
  306. default:
  307. printf("Unknown Vendor ");
  308. break;
  309. }
  310. printf(" Size: %ld MB in %d Sectors\n",
  311. info->size >> 20, info->sector_count);
  312. printf(" Sector Start Addresses:");
  313. for (i = 0; i < info->sector_count; i++) {
  314. if ((i % 5) == 0) {
  315. printf ("\n ");
  316. }
  317. printf (" %08lX%s", info->start[i],
  318. info->protect[i] ? " (RO)" : " ");
  319. }
  320. printf ("\n");
  321. done:
  322. return;
  323. }
  324. /*-----------------------------------------------------------------------
  325. */
  326. static u32 _amd_erase_flash(u32 addr, u32 sector)
  327. {
  328. unsigned elapsed;
  329. /* Issue erase */
  330. *(volatile u16*)(addr + 0xaaaa) = 0x00AA;
  331. *(volatile u16*)(addr + 0x5554) = 0x0055;
  332. *(volatile u16*)(addr + 0xaaaa) = 0x0080;
  333. /* And one unlock */
  334. *(volatile u16*)(addr + 0xaaaa) = 0x00AA;
  335. *(volatile u16*)(addr + 0x5554) = 0x0055;
  336. /* Sector erase command comes last */
  337. *(volatile u16*)(addr + sector) = 0x0030;
  338. elapsed = *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI); /* dummy read */
  339. elapsed = 0;
  340. while (((*(volatile u16*)(addr + sector)) & 0x0080) != 0x0080) {
  341. elapsed += *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI);
  342. if (elapsed > ((CONFIG_SYS_FLASH_ERASE_TOUT/CONFIG_SYS_HZ) * 1000)) {
  343. *(volatile u16*)(addr) = 0x00f0;
  344. return 1;
  345. }
  346. }
  347. *(volatile u16*)(addr) = 0x00f0;
  348. return 0;
  349. }
  350. extern int _amd_erase_flash_end;
  351. asm ("_amd_erase_flash_end:\n"
  352. ".long 0\n");
  353. /* this needs to be inlined, the SWTMRMMILLI register is reset by each read */
  354. #define __udelay(delay) \
  355. { \
  356. unsigned micro; \
  357. unsigned milli=0; \
  358. \
  359. micro = *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI); \
  360. \
  361. for (;;) { \
  362. \
  363. milli += *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI); \
  364. micro = *(volatile u16*)(0xfffef000+SC520_SWTMRMICRO); \
  365. \
  366. if ((delay) <= (micro + (milli * 1000))) { \
  367. break; \
  368. } \
  369. } \
  370. } while (0)
  371. static u32 _intel_erase_flash(u32 addr, u32 sector)
  372. {
  373. unsigned elapsed;
  374. *(volatile u16*)(addr + sector) = 0x0050; /* clear status register */
  375. *(volatile u16*)(addr + sector) = 0x0020; /* erase setup */
  376. *(volatile u16*)(addr + sector) = 0x00D0; /* erase confirm */
  377. /* Wait at least 80us - let's wait 1 ms */
  378. __udelay(1000);
  379. elapsed = 0;
  380. while (((*(volatile u16*)(addr + sector)) & 0x0080) != 0x0080) {
  381. elapsed += *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI);
  382. if (elapsed > ((CONFIG_SYS_FLASH_ERASE_TOUT/CONFIG_SYS_HZ) * 1000)) {
  383. *(volatile u16*)(addr + sector) = 0x00B0; /* suspend erase */
  384. *(volatile u16*)(addr + sector) = 0x00FF; /* reset to read mode */
  385. return 1;
  386. }
  387. }
  388. *(volatile u16*)(addr + sector) = 0x00FF; /* reset to read mode */
  389. return 0;
  390. }
  391. extern int _intel_erase_flash_end;
  392. asm ("_intel_erase_flash_end:\n"
  393. ".long 0\n");
  394. int flash_erase(flash_info_t *info, int s_first, int s_last)
  395. {
  396. u32 (*_erase_flash_ptr)(u32 a, u32 so);
  397. int prot;
  398. int sect;
  399. unsigned size;
  400. if ((s_first < 0) || (s_first > s_last)) {
  401. if (info->flash_id == FLASH_UNKNOWN) {
  402. printf("- missing\n");
  403. } else {
  404. printf("- no sectors to erase\n");
  405. }
  406. return 1;
  407. }
  408. if ((info->flash_id & FLASH_VENDMASK) == (AMD_MANUFACT & FLASH_VENDMASK)) {
  409. size = (unsigned)&_amd_erase_flash_end - (unsigned)_amd_erase_flash;
  410. if (size > PROBE_BUFFER_SIZE) {
  411. printf("_amd_erase_flash() routine too large (%d) %p - %p\n",
  412. size, &_amd_erase_flash_end, _amd_erase_flash);
  413. return 0;
  414. }
  415. memcpy(buffer, _amd_erase_flash, size);
  416. _erase_flash_ptr = (void*)buffer;
  417. } else if ((info->flash_id & FLASH_VENDMASK) == (INTEL_MANUFACT & FLASH_VENDMASK)) {
  418. size = (unsigned)&_intel_erase_flash_end - (unsigned)_intel_erase_flash;
  419. if (size > PROBE_BUFFER_SIZE) {
  420. printf("_intel_erase_flash() routine too large (%d) %p - %p\n",
  421. size, &_intel_erase_flash_end, _intel_erase_flash);
  422. return 0;
  423. }
  424. memcpy(buffer, _intel_erase_flash, size);
  425. _erase_flash_ptr = (void*)buffer;
  426. } else {
  427. printf ("Can't erase unknown flash type - aborted\n");
  428. return 1;
  429. }
  430. prot = 0;
  431. for (sect=s_first; sect<=s_last; ++sect) {
  432. if (info->protect[sect]) {
  433. prot++;
  434. }
  435. }
  436. if (prot) {
  437. printf ("- Warning: %d protected sectors will not be erased!\n", prot);
  438. } else {
  439. printf ("\n");
  440. }
  441. /* Start erase on unprotected sectors */
  442. for (sect = s_first; sect<=s_last; sect++) {
  443. if (info->protect[sect] == 0) { /* not protected */
  444. int res;
  445. int flag;
  446. /* Disable interrupts which might cause a timeout here */
  447. flag = disable_interrupts();
  448. res = _erase_flash_ptr(info->start[0], info->start[sect]-info->start[0]);
  449. /* re-enable interrupts if necessary */
  450. if (flag) {
  451. enable_interrupts();
  452. }
  453. if (res) {
  454. printf("Erase timed out, sector %d\n", sect);
  455. return res;
  456. }
  457. putc('.');
  458. }
  459. }
  460. return 0;
  461. }
  462. /*-----------------------------------------------------------------------
  463. * Write a word to Flash, returns:
  464. * 0 - OK
  465. * 1 - write timeout
  466. * 2 - Flash not erased
  467. */
  468. static int _amd_write_word(unsigned start, unsigned dest, u16 data)
  469. {
  470. volatile u16 *addr2 = (volatile u16*)start;
  471. volatile u16 *dest2 = (volatile u16*)dest;
  472. volatile u16 *data2 = (volatile u16*)&data;
  473. int i;
  474. unsigned elapsed;
  475. /* Check if Flash is (sufficiently) erased */
  476. if ((*((volatile u16*)dest) & (u16)data) != (u16)data) {
  477. return 2;
  478. }
  479. for (i = 0; i < 2; i++) {
  480. addr2[0x5555] = 0x00AA;
  481. addr2[0x2aaa] = 0x0055;
  482. addr2[0x5555] = 0x00A0;
  483. dest2[i] = (data >> (i*16)) & 0xffff;
  484. elapsed = *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI); /* dummy read */
  485. elapsed = 0;
  486. /* data polling for D7 */
  487. while ((dest2[i] & 0x0080) != (data2[i] & 0x0080)) {
  488. elapsed += *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI);
  489. if (elapsed > ((CONFIG_SYS_FLASH_WRITE_TOUT/CONFIG_SYS_HZ) * 1000)) {
  490. addr2[i] = 0x00f0;
  491. return 1;
  492. }
  493. }
  494. }
  495. addr2[i] = 0x00f0;
  496. return 0;
  497. }
  498. extern int _amd_write_word_end;
  499. asm ("_amd_write_word_end:\n"
  500. ".long 0\n");
  501. static int _intel_write_word(unsigned start, unsigned dest, unsigned data)
  502. {
  503. int i;
  504. unsigned elapsed;
  505. /* Check if Flash is (sufficiently) erased */
  506. if ((*((volatile u16*)dest) & (u16)data) != (u16)data) {
  507. return 2;
  508. }
  509. for (i = 0; i < 2; i++) {
  510. *(volatile u16*)(dest+2*i) = 0x0040; /* write setup */
  511. *(volatile u16*)(dest+2*i) = (data >> (i*16)) & 0xffff;
  512. elapsed = *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI); /* dummy read */
  513. elapsed = 0;
  514. /* data polling for D7 */
  515. while ((*(volatile u16*)dest & 0x0080) != 0x0080) {
  516. elapsed += *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI);
  517. if (elapsed > ((CONFIG_SYS_FLASH_WRITE_TOUT/CONFIG_SYS_HZ) * 1000)) {
  518. *(volatile u16*)dest = 0x00ff;
  519. return 1;
  520. }
  521. }
  522. }
  523. *(volatile u16*)dest = 0x00ff;
  524. return 0;
  525. }
  526. extern int _intel_write_word_end;
  527. asm ("_intel_write_word_end:\n"
  528. ".long 0\n");
  529. /*-----------------------------------------------------------------------
  530. * Copy memory to flash, returns:
  531. * 0 - OK
  532. * 1 - write timeout
  533. * 2 - Flash not erased
  534. * 3 - Unsupported flash type
  535. */
  536. int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
  537. {
  538. ulong cp, wp, data;
  539. int i, l, rc;
  540. int flag;
  541. u32 (*_write_word_ptr)(unsigned start, unsigned dest, unsigned data);
  542. unsigned size;
  543. if ((info->flash_id & FLASH_VENDMASK) == (AMD_MANUFACT & FLASH_VENDMASK)) {
  544. size = (unsigned)&_amd_write_word_end - (unsigned)_amd_write_word;
  545. if (size > PROBE_BUFFER_SIZE) {
  546. printf("_amd_write_word() routine too large (%d) %p - %p\n",
  547. size, &_amd_write_word_end, _amd_write_word);
  548. return 0;
  549. }
  550. memcpy(buffer, _amd_write_word, size);
  551. _write_word_ptr = (void*)buffer;
  552. } else if ((info->flash_id & FLASH_VENDMASK) == (INTEL_MANUFACT & FLASH_VENDMASK)) {
  553. size = (unsigned)&_intel_write_word_end - (unsigned)_intel_write_word;
  554. if (size > PROBE_BUFFER_SIZE) {
  555. printf("_intel_write_word() routine too large (%d) %p - %p\n",
  556. size, &_intel_write_word_end, _intel_write_word);
  557. return 0;
  558. }
  559. memcpy(buffer, _intel_write_word, size);
  560. _write_word_ptr = (void*)buffer;
  561. } else {
  562. printf ("Can't program unknown flash type - aborted\n");
  563. return 3;
  564. }
  565. wp = (addr & ~3); /* get lower word aligned address */
  566. /*
  567. * handle unaligned start bytes
  568. */
  569. if ((l = addr - wp) != 0) {
  570. data = 0;
  571. for (i=0, cp=wp; i<l; ++i, ++cp) {
  572. data |= (*(uchar *)cp) << (8*i);
  573. }
  574. for (; i<4 && cnt>0; ++i) {
  575. data |= *src++ << (8*i);
  576. --cnt;
  577. ++cp;
  578. }
  579. for (; cnt==0 && i<4; ++i, ++cp) {
  580. data |= (*(uchar *)cp) << (8*i);
  581. }
  582. /* Disable interrupts which might cause a timeout here */
  583. flag = disable_interrupts();
  584. rc = _write_word_ptr(info->start[0], wp, data);
  585. /* re-enable interrupts if necessary */
  586. if (flag) {
  587. enable_interrupts();
  588. }
  589. if (rc != 0) {
  590. return rc;
  591. }
  592. wp += 4;
  593. }
  594. /*
  595. * handle word aligned part
  596. */
  597. while (cnt >= 4) {
  598. data = 0;
  599. for (i=0; i<4; ++i) {
  600. data |= *src++ << (8*i);
  601. }
  602. /* Disable interrupts which might cause a timeout here */
  603. flag = disable_interrupts();
  604. rc = _write_word_ptr(info->start[0], wp, data);
  605. /* re-enable interrupts if necessary */
  606. if (flag) {
  607. enable_interrupts();
  608. }
  609. if (rc != 0) {
  610. return rc;
  611. }
  612. wp += 4;
  613. cnt -= 4;
  614. }
  615. if (cnt == 0) {
  616. return 0;
  617. }
  618. /*
  619. * handle unaligned tail bytes
  620. */
  621. data = 0;
  622. for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
  623. data |= *src++ << (8*i);
  624. --cnt;
  625. }
  626. for (; i<4; ++i, ++cp) {
  627. data |= (*(uchar *)cp) << (8*i);
  628. }
  629. /* Disable interrupts which might cause a timeout here */
  630. flag = disable_interrupts();
  631. rc = _write_word_ptr(info->start[0], wp, data);
  632. /* re-enable interrupts if necessary */
  633. if (flag) {
  634. enable_interrupts();
  635. }
  636. return rc;
  637. }