flash.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813
  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, CFG_MAX_FLASH_SECT);
  179. switch (i) {
  180. case 0:
  181. flashbase = SC520_FLASH_BANK0_BASE;
  182. break;
  183. default:
  184. panic("configured to 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 CFG_ENV_ADDR
  260. flash_protect(FLAG_PROTECT_SET,
  261. CFG_ENV_ADDR,
  262. CFG_ENV_ADDR + CFG_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. }
  323. /*-----------------------------------------------------------------------
  324. */
  325. static u32 _amd_erase_flash(u32 addr, u32 sector)
  326. {
  327. unsigned elapsed;
  328. /* Issue erase */
  329. *(volatile u16*)(addr + 0xaaaa) = 0x00AA;
  330. *(volatile u16*)(addr + 0x5554) = 0x0055;
  331. *(volatile u16*)(addr + 0xaaaa) = 0x0080;
  332. /* And one unlock */
  333. *(volatile u16*)(addr + 0xaaaa) = 0x00AA;
  334. *(volatile u16*)(addr + 0x5554) = 0x0055;
  335. /* Sector erase command comes last */
  336. *(volatile u16*)(addr + sector) = 0x0030;
  337. elapsed = *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI); /* dummy read */
  338. elapsed = 0;
  339. while (((*(volatile u16*)(addr + sector)) & 0x0080) != 0x0080) {
  340. elapsed += *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI);
  341. if (elapsed > ((CFG_FLASH_ERASE_TOUT/CFG_HZ) * 1000)) {
  342. *(volatile u16*)(addr) = 0x00f0;
  343. return 1;
  344. }
  345. }
  346. *(volatile u16*)(addr) = 0x00f0;
  347. return 0;
  348. }
  349. extern int _amd_erase_flash_end;
  350. asm ("_amd_erase_flash_end:\n"
  351. ".long 0\n");
  352. /* this needs to be inlined, the SWTMRMMILLI register is reset by each read */
  353. #define __udelay(delay) \
  354. { \
  355. unsigned micro; \
  356. unsigned milli=0; \
  357. \
  358. micro = *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI); \
  359. \
  360. for (;;) { \
  361. \
  362. milli += *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI); \
  363. micro = *(volatile u16*)(0xfffef000+SC520_SWTMRMICRO); \
  364. \
  365. if ((delay) <= (micro + (milli * 1000))) { \
  366. break; \
  367. } \
  368. } \
  369. } while (0)
  370. static u32 _intel_erase_flash(u32 addr, u32 sector)
  371. {
  372. unsigned elapsed;
  373. *(volatile u16*)(addr + sector) = 0x0050; /* clear status register */
  374. *(volatile u16*)(addr + sector) = 0x0020; /* erase setup */
  375. *(volatile u16*)(addr + sector) = 0x00D0; /* erase confirm */
  376. /* Wait at least 80us - let's wait 1 ms */
  377. __udelay(1000);
  378. elapsed = 0;
  379. while (((*(volatile u16*)(addr + sector)) & 0x0080) != 0x0080) {
  380. elapsed += *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI);
  381. if (elapsed > ((CFG_FLASH_ERASE_TOUT/CFG_HZ) * 1000)) {
  382. *(volatile u16*)(addr + sector) = 0x00B0; /* suspend erase */
  383. *(volatile u16*)(addr + sector) = 0x00FF; /* reset to read mode */
  384. return 1;
  385. }
  386. }
  387. *(volatile u16*)(addr + sector) = 0x00FF; /* reset to read mode */
  388. return 0;
  389. }
  390. extern int _intel_erase_flash_end;
  391. asm ("_intel_erase_flash_end:\n"
  392. ".long 0\n");
  393. int flash_erase(flash_info_t *info, int s_first, int s_last)
  394. {
  395. u32 (*_erase_flash_ptr)(u32 a, u32 so);
  396. int prot;
  397. int sect;
  398. unsigned size;
  399. if ((s_first < 0) || (s_first > s_last)) {
  400. if (info->flash_id == FLASH_UNKNOWN) {
  401. printf("- missing\n");
  402. } else {
  403. printf("- no sectors to erase\n");
  404. }
  405. return 1;
  406. }
  407. if ((info->flash_id & FLASH_VENDMASK) == (AMD_MANUFACT & FLASH_VENDMASK)) {
  408. size = (unsigned)&_amd_erase_flash_end - (unsigned)_amd_erase_flash;
  409. if (size > PROBE_BUFFER_SIZE) {
  410. printf("_amd_erase_flash() routine too large (%d) %p - %p\n",
  411. size, &_amd_erase_flash_end, _amd_erase_flash);
  412. return 0;
  413. }
  414. memcpy(buffer, _amd_erase_flash, size);
  415. _erase_flash_ptr = (void*)buffer;
  416. } else if ((info->flash_id & FLASH_VENDMASK) == (INTEL_MANUFACT & FLASH_VENDMASK)) {
  417. size = (unsigned)&_intel_erase_flash_end - (unsigned)_intel_erase_flash;
  418. if (size > PROBE_BUFFER_SIZE) {
  419. printf("_intel_erase_flash() routine too large (%d) %p - %p\n",
  420. size, &_intel_erase_flash_end, _intel_erase_flash);
  421. return 0;
  422. }
  423. memcpy(buffer, _intel_erase_flash, size);
  424. _erase_flash_ptr = (void*)buffer;
  425. } else {
  426. printf ("Can't erase unknown flash type - aborted\n");
  427. return 1;
  428. }
  429. prot = 0;
  430. for (sect=s_first; sect<=s_last; ++sect) {
  431. if (info->protect[sect]) {
  432. prot++;
  433. }
  434. }
  435. if (prot) {
  436. printf ("- Warning: %d protected sectors will not be erased!\n", prot);
  437. } else {
  438. printf ("\n");
  439. }
  440. /* Start erase on unprotected sectors */
  441. for (sect = s_first; sect<=s_last; sect++) {
  442. if (info->protect[sect] == 0) { /* not protected */
  443. int res;
  444. int flag;
  445. /* Disable interrupts which might cause a timeout here */
  446. flag = disable_interrupts();
  447. res = _erase_flash_ptr(info->start[0], info->start[sect]-info->start[0]);
  448. /* re-enable interrupts if necessary */
  449. if (flag) {
  450. enable_interrupts();
  451. }
  452. if (res) {
  453. printf("Erase timed out, sector %d\n", sect);
  454. return res;
  455. }
  456. putc('.');
  457. }
  458. }
  459. return 0;
  460. }
  461. /*-----------------------------------------------------------------------
  462. * Write a word to Flash, returns:
  463. * 0 - OK
  464. * 1 - write timeout
  465. * 2 - Flash not erased
  466. */
  467. static int _amd_write_word(unsigned start, unsigned dest, unsigned data)
  468. {
  469. volatile u16 *addr2 = (u16*)start;
  470. volatile u16 *dest2 = (u16*)dest;
  471. volatile u16 *data2 = (u16*)&data;
  472. int i;
  473. unsigned elapsed;
  474. /* Check if Flash is (sufficiently) erased */
  475. if ((*((volatile u16*)dest) & (u16)data) != (u16)data) {
  476. return 2;
  477. }
  478. for (i = 0; i < 2; i++) {
  479. addr2[0x5555] = 0x00AA;
  480. addr2[0x2aaa] = 0x0055;
  481. addr2[0x5555] = 0x00A0;
  482. dest2[i] = (data >> (i*16)) & 0xffff;
  483. elapsed = *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI); /* dummy read */
  484. elapsed = 0;
  485. /* data polling for D7 */
  486. while ((dest2[i] & 0x0080) != (data2[i] & 0x0080)) {
  487. elapsed += *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI);
  488. if (elapsed > ((CFG_FLASH_WRITE_TOUT/CFG_HZ) * 1000)) {
  489. addr2[i] = 0x00f0;
  490. return 1;
  491. }
  492. }
  493. }
  494. addr2[i] = 0x00f0;
  495. return 0;
  496. }
  497. extern int _amd_write_word_end;
  498. asm ("_amd_write_word_end:\n"
  499. ".long 0\n");
  500. static int _intel_write_word(unsigned start, unsigned dest, unsigned data)
  501. {
  502. int i;
  503. unsigned elapsed;
  504. /* Check if Flash is (sufficiently) erased */
  505. if ((*((volatile u16*)dest) & (u16)data) != (u16)data) {
  506. return 2;
  507. }
  508. for (i = 0; i < 2; i++) {
  509. *(volatile u16*)(dest+2*i) = 0x0040; /* write setup */
  510. *(volatile u16*)(dest+2*i) = (data >> (i*16)) & 0xffff;
  511. elapsed = *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI); /* dummy read */
  512. elapsed = 0;
  513. /* data polling for D7 */
  514. while ((*(volatile u16*)dest & 0x0080) != 0x0080) {
  515. elapsed += *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI);
  516. if (elapsed > ((CFG_FLASH_WRITE_TOUT/CFG_HZ) * 1000)) {
  517. *(volatile u16*)dest = 0x00ff;
  518. return 1;
  519. }
  520. }
  521. }
  522. *(volatile u16*)dest = 0x00ff;
  523. return 0;
  524. }
  525. extern int _intel_write_word_end;
  526. asm ("_intel_write_word_end:\n"
  527. ".long 0\n");
  528. /*-----------------------------------------------------------------------
  529. * Copy memory to flash, returns:
  530. * 0 - OK
  531. * 1 - write timeout
  532. * 2 - Flash not erased
  533. * 3 - Unsupported flash type
  534. */
  535. int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
  536. {
  537. ulong cp, wp, data;
  538. int i, l, rc;
  539. int flag;
  540. u32 (*_write_word_ptr)(unsigned start, unsigned dest, unsigned data);
  541. unsigned size;
  542. if ((info->flash_id & FLASH_VENDMASK) == (AMD_MANUFACT & FLASH_VENDMASK)) {
  543. size = (unsigned)&_amd_write_word_end - (unsigned)_amd_write_word;
  544. if (size > PROBE_BUFFER_SIZE) {
  545. printf("_amd_write_word() routine too large (%d) %p - %p\n",
  546. size, &_amd_write_word_end, _amd_write_word);
  547. return 0;
  548. }
  549. memcpy(buffer, _amd_write_word, size);
  550. _write_word_ptr = (void*)buffer;
  551. } else if ((info->flash_id & FLASH_VENDMASK) == (INTEL_MANUFACT & FLASH_VENDMASK)) {
  552. size = (unsigned)&_intel_write_word_end - (unsigned)_intel_write_word;
  553. if (size > PROBE_BUFFER_SIZE) {
  554. printf("_intel_write_word() routine too large (%d) %p - %p\n",
  555. size, &_intel_write_word_end, _intel_write_word);
  556. return 0;
  557. }
  558. memcpy(buffer, _intel_write_word, size);
  559. _write_word_ptr = (void*)buffer;
  560. } else {
  561. printf ("Can't program unknown flash type - aborted\n");
  562. return 3;
  563. }
  564. wp = (addr & ~3); /* get lower word aligned address */
  565. /*
  566. * handle unaligned start bytes
  567. */
  568. if ((l = addr - wp) != 0) {
  569. data = 0;
  570. for (i=0, cp=wp; i<l; ++i, ++cp) {
  571. data |= (*(uchar *)cp) << (8*i);
  572. }
  573. for (; i<4 && cnt>0; ++i) {
  574. data |= *src++ << (8*i);
  575. --cnt;
  576. ++cp;
  577. }
  578. for (; cnt==0 && i<4; ++i, ++cp) {
  579. data |= (*(uchar *)cp) << (8*i);
  580. }
  581. /* Disable interrupts which might cause a timeout here */
  582. flag = disable_interrupts();
  583. rc = _write_word_ptr(info->start[0], wp, data);
  584. /* re-enable interrupts if necessary */
  585. if (flag) {
  586. enable_interrupts();
  587. }
  588. if (rc != 0) {
  589. return rc;
  590. }
  591. wp += 4;
  592. }
  593. /*
  594. * handle word aligned part
  595. */
  596. while (cnt >= 4) {
  597. data = 0;
  598. for (i=0; i<4; ++i) {
  599. data |= *src++ << (8*i);
  600. }
  601. /* Disable interrupts which might cause a timeout here */
  602. flag = disable_interrupts();
  603. rc = _write_word_ptr(info->start[0], wp, data);
  604. /* re-enable interrupts if necessary */
  605. if (flag) {
  606. enable_interrupts();
  607. }
  608. if (rc != 0) {
  609. return rc;
  610. }
  611. wp += 4;
  612. cnt -= 4;
  613. }
  614. if (cnt == 0) {
  615. return 0;
  616. }
  617. /*
  618. * handle unaligned tail bytes
  619. */
  620. data = 0;
  621. for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
  622. data |= *src++ << (8*i);
  623. --cnt;
  624. }
  625. for (; i<4; ++i, ++cp) {
  626. data |= (*(uchar *)cp) << (8*i);
  627. }
  628. /* Disable interrupts which might cause a timeout here */
  629. flag = disable_interrupts();
  630. rc = _write_word_ptr(info->start[0], wp, data);
  631. /* re-enable interrupts if necessary */
  632. if (flag) {
  633. enable_interrupts();
  634. }
  635. return rc;
  636. }