flash.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830
  1. /*
  2. * (C) 2000 Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  3. * (C) 2003 August Hoeraendl, Logotronic GmbH
  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. #undef CONFIG_FLASH_16BIT
  24. #include <common.h>
  25. #define FLASH_BANK_SIZE 0x1000000
  26. #define MAIN_SECT_SIZE 0x20000 /* 2x64k = 128k per sector */
  27. flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
  28. /* NOTE - CONFIG_FLASH_16BIT means the CPU interface is 16-bit, it
  29. * has nothing to do with the flash chip being 8-bit or 16-bit.
  30. */
  31. #ifdef CONFIG_FLASH_16BIT
  32. typedef unsigned short FLASH_PORT_WIDTH;
  33. typedef volatile unsigned short FLASH_PORT_WIDTHV;
  34. #define FLASH_ID_MASK 0xFFFF
  35. #else
  36. typedef unsigned long FLASH_PORT_WIDTH;
  37. typedef volatile unsigned long FLASH_PORT_WIDTHV;
  38. #define FLASH_ID_MASK 0xFFFFFFFF
  39. #endif
  40. #define FPW FLASH_PORT_WIDTH
  41. #define FPWV FLASH_PORT_WIDTHV
  42. #define ORMASK(size) ((-size) & OR_AM_MSK)
  43. /*-----------------------------------------------------------------------
  44. * Functions
  45. */
  46. static ulong flash_get_size(FPWV *addr, flash_info_t *info);
  47. static void flash_reset(flash_info_t *info);
  48. static int write_word_intel(flash_info_t *info, FPWV *dest, FPW data);
  49. static int write_word_amd(flash_info_t *info, FPWV *dest, FPW data);
  50. #define write_word(in, de, da) write_word_amd(in, de, da)
  51. static void flash_get_offsets(ulong base, flash_info_t *info);
  52. #ifdef CFG_FLASH_PROTECTION
  53. static void flash_sync_real_protect(flash_info_t *info);
  54. #endif
  55. /*-----------------------------------------------------------------------
  56. * flash_init()
  57. *
  58. * sets up flash_info and returns size of FLASH (bytes)
  59. */
  60. ulong flash_init(void)
  61. {
  62. int i, j;
  63. ulong size = 0;
  64. for (i = 0; i < CFG_MAX_FLASH_BANKS; i++)
  65. {
  66. ulong flashbase = 0;
  67. flash_info[i].flash_id =
  68. (FLASH_MAN_AMD & FLASH_VENDMASK) |
  69. (FLASH_AM640U & FLASH_TYPEMASK);
  70. flash_info[i].size = FLASH_BANK_SIZE;
  71. flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
  72. memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
  73. switch (i)
  74. {
  75. case 0:
  76. flashbase = PHYS_FLASH_1;
  77. break;
  78. case 1:
  79. flashbase = PHYS_FLASH_2;
  80. break;
  81. default:
  82. panic("configured to many flash banks!\n");
  83. break;
  84. }
  85. for (j = 0; j < flash_info[i].sector_count; j++)
  86. {
  87. flash_info[i].start[j] = flashbase + j*MAIN_SECT_SIZE;
  88. }
  89. size += flash_info[i].size;
  90. }
  91. /* Protect monitor and environment sectors
  92. */
  93. flash_protect(FLAG_PROTECT_SET,
  94. CFG_FLASH_BASE,
  95. CFG_FLASH_BASE + _armboot_end_data - _armboot_start,
  96. &flash_info[0]);
  97. flash_protect(FLAG_PROTECT_SET,
  98. CFG_ENV_ADDR,
  99. CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
  100. &flash_info[0]);
  101. return size;
  102. }
  103. /*-----------------------------------------------------------------------
  104. */
  105. static void flash_reset(flash_info_t *info)
  106. {
  107. FPWV *base = (FPWV *)(info->start[0]);
  108. /* Put FLASH back in read mode */
  109. if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL)
  110. *base = (FPW)0x00FF00FF; /* Intel Read Mode */
  111. else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD)
  112. *base = (FPW)0x00F000F0; /* AMD Read Mode */
  113. }
  114. /*-----------------------------------------------------------------------
  115. */
  116. static void flash_get_offsets (ulong base, flash_info_t *info)
  117. {
  118. int i;
  119. /* set up sector start address table */
  120. if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL
  121. && (info->flash_id & FLASH_BTYPE)) {
  122. int bootsect_size; /* number of bytes/boot sector */
  123. int sect_size; /* number of bytes/regular sector */
  124. bootsect_size = 0x00002000 * (sizeof(FPW)/2);
  125. sect_size = 0x00010000 * (sizeof(FPW)/2);
  126. /* set sector offsets for bottom boot block type */
  127. for (i = 0; i < 8; ++i) {
  128. info->start[i] = base + (i * bootsect_size);
  129. }
  130. for (i = 8; i < info->sector_count; i++) {
  131. info->start[i] = base + ((i - 7) * sect_size);
  132. }
  133. }
  134. else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD
  135. && (info->flash_id & FLASH_TYPEMASK) == FLASH_AM640U) {
  136. int sect_size; /* number of bytes/sector */
  137. sect_size = 0x00010000 * (sizeof(FPW)/2);
  138. /* set up sector start address table (uniform sector type) */
  139. for( i = 0; i < info->sector_count; i++ )
  140. info->start[i] = base + (i * sect_size);
  141. }
  142. }
  143. /*-----------------------------------------------------------------------
  144. */
  145. void flash_print_info (flash_info_t *info)
  146. {
  147. int i;
  148. uchar *boottype;
  149. uchar *bootletter;
  150. uchar *fmt;
  151. uchar botbootletter[] = "B";
  152. uchar topbootletter[] = "T";
  153. uchar botboottype[] = "bottom boot sector";
  154. uchar topboottype[] = "top boot sector";
  155. if (info->flash_id == FLASH_UNKNOWN) {
  156. printf ("missing or unknown FLASH type\n");
  157. return;
  158. }
  159. switch (info->flash_id & FLASH_VENDMASK) {
  160. case FLASH_MAN_AMD: printf ("AMD "); break;
  161. case FLASH_MAN_BM: printf ("BRIGHT MICRO "); break;
  162. case FLASH_MAN_FUJ: printf ("FUJITSU "); break;
  163. case FLASH_MAN_SST: printf ("SST "); break;
  164. case FLASH_MAN_STM: printf ("STM "); break;
  165. case FLASH_MAN_INTEL: printf ("INTEL "); break;
  166. default: printf ("Unknown Vendor "); break;
  167. }
  168. /* check for top or bottom boot, if it applies */
  169. if (info->flash_id & FLASH_BTYPE) {
  170. boottype = botboottype;
  171. bootletter = botbootletter;
  172. }
  173. else {
  174. boottype = topboottype;
  175. bootletter = topbootletter;
  176. }
  177. switch (info->flash_id & FLASH_TYPEMASK) {
  178. case FLASH_AM640U:
  179. fmt = "29LV641D (64 Mbit, uniform sectors)\n";
  180. break;
  181. case FLASH_28F800C3B:
  182. case FLASH_28F800C3T:
  183. fmt = "28F800C3%s (8 Mbit, %s)\n";
  184. break;
  185. case FLASH_INTEL800B:
  186. case FLASH_INTEL800T:
  187. fmt = "28F800B3%s (8 Mbit, %s)\n";
  188. break;
  189. case FLASH_28F160C3B:
  190. case FLASH_28F160C3T:
  191. fmt = "28F160C3%s (16 Mbit, %s)\n";
  192. break;
  193. case FLASH_INTEL160B:
  194. case FLASH_INTEL160T:
  195. fmt = "28F160B3%s (16 Mbit, %s)\n";
  196. break;
  197. case FLASH_28F320C3B:
  198. case FLASH_28F320C3T:
  199. fmt = "28F320C3%s (32 Mbit, %s)\n";
  200. break;
  201. case FLASH_INTEL320B:
  202. case FLASH_INTEL320T:
  203. fmt = "28F320B3%s (32 Mbit, %s)\n";
  204. break;
  205. case FLASH_28F640C3B:
  206. case FLASH_28F640C3T:
  207. fmt = "28F640C3%s (64 Mbit, %s)\n";
  208. break;
  209. case FLASH_INTEL640B:
  210. case FLASH_INTEL640T:
  211. fmt = "28F640B3%s (64 Mbit, %s)\n";
  212. break;
  213. default:
  214. fmt = "Unknown Chip Type\n";
  215. break;
  216. }
  217. printf (fmt, bootletter, boottype);
  218. printf (" Size: %ld MB in %d Sectors\n",
  219. info->size >> 20,
  220. info->sector_count);
  221. printf (" Sector Start Addresses:");
  222. for (i=0; i<info->sector_count; ++i) {
  223. if ((i % 5) == 0) {
  224. printf ("\n ");
  225. }
  226. printf (" %08lX%s", info->start[i],
  227. info->protect[i] ? " (RO)" : " ");
  228. }
  229. printf ("\n");
  230. }
  231. /*-----------------------------------------------------------------------
  232. */
  233. /*
  234. * The following code cannot be run from FLASH!
  235. */
  236. ulong flash_get_size (FPWV *addr, flash_info_t *info)
  237. {
  238. /* Write auto select command: read Manufacturer ID */
  239. /* Write auto select command sequence and test FLASH answer */
  240. addr[0x0555] = (FPW)0x00AA00AA; /* for AMD, Intel ignores this */
  241. addr[0x02AA] = (FPW)0x00550055; /* for AMD, Intel ignores this */
  242. addr[0x0555] = (FPW)0x00900090; /* selects Intel or AMD */
  243. /* The manufacturer codes are only 1 byte, so just use 1 byte.
  244. * This works for any bus width and any FLASH device width.
  245. */
  246. switch (addr[0] & 0xff) {
  247. case (uchar)AMD_MANUFACT:
  248. info->flash_id = FLASH_MAN_AMD;
  249. break;
  250. case (uchar)INTEL_MANUFACT:
  251. info->flash_id = FLASH_MAN_INTEL;
  252. break;
  253. default:
  254. info->flash_id = FLASH_UNKNOWN;
  255. info->sector_count = 0;
  256. info->size = 0;
  257. break;
  258. }
  259. /* Check 16 bits or 32 bits of ID so work on 32 or 16 bit bus. */
  260. if (info->flash_id != FLASH_UNKNOWN) switch (addr[1]) {
  261. case (FPW)AMD_ID_LV640U: /* 29LV640 and 29LV641 have same ID */
  262. info->flash_id += FLASH_AM640U;
  263. info->sector_count = 128;
  264. info->size = 0x00800000 * (sizeof(FPW)/2);
  265. break; /* => 8 or 16 MB */
  266. case (FPW)INTEL_ID_28F800C3B:
  267. info->flash_id += FLASH_28F800C3B;
  268. info->sector_count = 23;
  269. info->size = 0x00100000 * (sizeof(FPW)/2);
  270. break; /* => 1 or 2 MB */
  271. case (FPW)INTEL_ID_28F800B3B:
  272. info->flash_id += FLASH_INTEL800B;
  273. info->sector_count = 23;
  274. info->size = 0x00100000 * (sizeof(FPW)/2);
  275. break; /* => 1 or 2 MB */
  276. case (FPW)INTEL_ID_28F160C3B:
  277. info->flash_id += FLASH_28F160C3B;
  278. info->sector_count = 39;
  279. info->size = 0x00200000 * (sizeof(FPW)/2);
  280. break; /* => 2 or 4 MB */
  281. case (FPW)INTEL_ID_28F160B3B:
  282. info->flash_id += FLASH_INTEL160B;
  283. info->sector_count = 39;
  284. info->size = 0x00200000 * (sizeof(FPW)/2);
  285. break; /* => 2 or 4 MB */
  286. case (FPW)INTEL_ID_28F320C3B:
  287. info->flash_id += FLASH_28F320C3B;
  288. info->sector_count = 71;
  289. info->size = 0x00400000 * (sizeof(FPW)/2);
  290. break; /* => 4 or 8 MB */
  291. case (FPW)INTEL_ID_28F320B3B:
  292. info->flash_id += FLASH_INTEL320B;
  293. info->sector_count = 71;
  294. info->size = 0x00400000 * (sizeof(FPW)/2);
  295. break; /* => 4 or 8 MB */
  296. case (FPW)INTEL_ID_28F640C3B:
  297. info->flash_id += FLASH_28F640C3B;
  298. info->sector_count = 135;
  299. info->size = 0x00800000 * (sizeof(FPW)/2);
  300. break; /* => 8 or 16 MB */
  301. case (FPW)INTEL_ID_28F640B3B:
  302. info->flash_id += FLASH_INTEL640B;
  303. info->sector_count = 135;
  304. info->size = 0x00800000 * (sizeof(FPW)/2);
  305. break; /* => 8 or 16 MB */
  306. default:
  307. info->flash_id = FLASH_UNKNOWN;
  308. info->sector_count = 0;
  309. info->size = 0;
  310. return (0); /* => no or unknown flash */
  311. }
  312. flash_get_offsets((ulong)addr, info);
  313. /* Put FLASH back in read mode */
  314. flash_reset(info);
  315. return (info->size);
  316. }
  317. #ifdef CFG_FLASH_PROTECTION
  318. /*-----------------------------------------------------------------------
  319. */
  320. static void flash_sync_real_protect(flash_info_t *info)
  321. {
  322. FPWV *addr = (FPWV *)(info->start[0]);
  323. FPWV *sect;
  324. int i;
  325. switch (info->flash_id & FLASH_TYPEMASK) {
  326. case FLASH_28F800C3B:
  327. case FLASH_28F800C3T:
  328. case FLASH_28F160C3B:
  329. case FLASH_28F160C3T:
  330. case FLASH_28F320C3B:
  331. case FLASH_28F320C3T:
  332. case FLASH_28F640C3B:
  333. case FLASH_28F640C3T:
  334. /* check for protected sectors */
  335. *addr = (FPW)0x00900090;
  336. for (i = 0; i < info->sector_count; i++) {
  337. /* read sector protection at sector address, (A7 .. A0) = 0x02.
  338. * D0 = 1 for each device if protected.
  339. * If at least one device is protected the sector is marked
  340. * protected, but mixed protected and unprotected devices
  341. * within a sector should never happen.
  342. */
  343. sect = (FPWV *)(info->start[i]);
  344. info->protect[i] = (sect[2] & (FPW)(0x00010001)) ? 1 : 0;
  345. }
  346. /* Put FLASH back in read mode */
  347. flash_reset(info);
  348. break;
  349. case FLASH_AM640U:
  350. default:
  351. /* no hardware protect that we support */
  352. break;
  353. }
  354. }
  355. #endif
  356. /*-----------------------------------------------------------------------
  357. */
  358. int flash_erase (flash_info_t *info, int s_first, int s_last)
  359. {
  360. FPWV *addr;
  361. int flag, prot, sect;
  362. int intel = (info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL;
  363. ulong start, now, last;
  364. int rcode = 0;
  365. if ((s_first < 0) || (s_first > s_last)) {
  366. if (info->flash_id == FLASH_UNKNOWN) {
  367. printf ("- missing\n");
  368. } else {
  369. printf ("- no sectors to erase\n");
  370. }
  371. return 1;
  372. }
  373. switch (info->flash_id & FLASH_TYPEMASK) {
  374. case FLASH_INTEL800B:
  375. case FLASH_INTEL160B:
  376. case FLASH_INTEL320B:
  377. case FLASH_INTEL640B:
  378. case FLASH_28F800C3B:
  379. case FLASH_28F160C3B:
  380. case FLASH_28F320C3B:
  381. case FLASH_28F640C3B:
  382. case FLASH_AM640U:
  383. break;
  384. case FLASH_UNKNOWN:
  385. default:
  386. printf ("Can't erase unknown flash type %08lx - aborted\n",
  387. info->flash_id);
  388. return 1;
  389. }
  390. prot = 0;
  391. for (sect=s_first; sect<=s_last; ++sect) {
  392. if (info->protect[sect]) {
  393. prot++;
  394. }
  395. }
  396. if (prot) {
  397. printf ("- Warning: %d protected sectors will not be erased!\n",
  398. prot);
  399. } else {
  400. printf ("\n");
  401. }
  402. start = get_timer(0);
  403. last = start;
  404. /* Start erase on unprotected sectors */
  405. for (sect = s_first; sect<=s_last && rcode == 0; sect++) {
  406. if (info->protect[sect] != 0) /* protected, skip it */
  407. continue;
  408. /* Disable interrupts which might cause a timeout here */
  409. flag = disable_interrupts();
  410. addr = (FPWV *)(info->start[sect]);
  411. if (intel) {
  412. *addr = (FPW)0x00500050; /* clear status register */
  413. *addr = (FPW)0x00200020; /* erase setup */
  414. *addr = (FPW)0x00D000D0; /* erase confirm */
  415. }
  416. else {
  417. /* must be AMD style if not Intel */
  418. FPWV *base; /* first address in bank */
  419. base = (FPWV *)(info->start[0]);
  420. base[0x0555] = (FPW)0x00AA00AA; /* unlock */
  421. base[0x02AA] = (FPW)0x00550055; /* unlock */
  422. base[0x0555] = (FPW)0x00800080; /* erase mode */
  423. base[0x0555] = (FPW)0x00AA00AA; /* unlock */
  424. base[0x02AA] = (FPW)0x00550055; /* unlock */
  425. *addr = (FPW)0x00300030; /* erase sector */
  426. }
  427. /* re-enable interrupts if necessary */
  428. if (flag)
  429. enable_interrupts();
  430. /* wait at least 50us for AMD, 80us for Intel.
  431. * Let's wait 1 ms.
  432. */
  433. udelay (1000);
  434. while ((*addr & (FPW)0x00800080) != (FPW)0x00800080) {
  435. if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
  436. printf ("Timeout\n");
  437. if (intel) {
  438. /* suspend erase */
  439. *addr = (FPW)0x00B000B0;
  440. }
  441. flash_reset(info); /* reset to read mode */
  442. rcode = 1; /* failed */
  443. break;
  444. }
  445. /* show that we're waiting */
  446. if ((now - last) > 1000) { /* every second */
  447. putc ('.');
  448. last = now;
  449. }
  450. }
  451. flash_reset(info); /* reset to read mode */
  452. }
  453. printf (" done\n");
  454. return rcode;
  455. }
  456. /*-----------------------------------------------------------------------
  457. * Copy memory to flash, returns:
  458. * 0 - OK
  459. * 1 - write timeout
  460. * 2 - Flash not erased
  461. */
  462. int bad_write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
  463. {
  464. FPW data = 0; /* 16 or 32 bit word, matches flash bus width on MPC8XX */
  465. int bytes; /* number of bytes to program in current word */
  466. int left; /* number of bytes left to program */
  467. int i, res;
  468. for (left = cnt, res = 0;
  469. left > 0 && res == 0;
  470. addr += sizeof(data), left -= sizeof(data) - bytes) {
  471. bytes = addr & (sizeof(data) - 1);
  472. addr &= ~(sizeof(data) - 1);
  473. /* combine source and destination data so can program
  474. * an entire word of 16 or 32 bits
  475. */
  476. for (i = 0; i < sizeof(data); i++) {
  477. data <<= 8;
  478. if (i < bytes || i - bytes >= left )
  479. data += *((uchar *)addr + i);
  480. else
  481. data += *src++;
  482. }
  483. /* write one word to the flash */
  484. switch (info->flash_id & FLASH_VENDMASK) {
  485. case FLASH_MAN_AMD:
  486. res = write_word_amd(info, (FPWV *)addr, data);
  487. break;
  488. case FLASH_MAN_INTEL:
  489. res = write_word_intel(info, (FPWV *)addr, data);
  490. break;
  491. default:
  492. /* unknown flash type, error! */
  493. printf ("missing or unknown FLASH type\n");
  494. res = 1; /* not really a timeout, but gives error */
  495. break;
  496. }
  497. }
  498. return (res);
  499. }
  500. /**
  501. * write_buf: - Copy memory to flash.
  502. *
  503. * @param info:
  504. * @param src: source of copy transaction
  505. * @param addr: where to copy to
  506. * @param cnt: number of bytes to copy
  507. *
  508. * @return error code
  509. */
  510. int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
  511. {
  512. ulong cp, wp;
  513. FPW data;
  514. int l;
  515. int i, rc;
  516. wp = (addr & ~1); /* get lower word aligned address */
  517. /*
  518. * handle unaligned start bytes
  519. */
  520. if ((l = addr - wp) != 0) {
  521. data = 0;
  522. for (i=0, cp=wp; i<l; ++i, ++cp) {
  523. data = (data >> 8) | (*(uchar *)cp << 8);
  524. }
  525. for (; i<2 && cnt>0; ++i) {
  526. data = (data >> 8) | (*src++ << 8);
  527. --cnt;
  528. ++cp;
  529. }
  530. for (; cnt==0 && i<2; ++i, ++cp) {
  531. data = (data >> 8) | (*(uchar *)cp << 8);
  532. }
  533. if ((rc = write_word(info, wp, data)) != 0) {
  534. return (rc);
  535. }
  536. wp += 2;
  537. }
  538. /*
  539. * handle word aligned part
  540. */
  541. while (cnt >= 2) {
  542. /* data = *((vushort*)src); */
  543. data = *((FPW*)src);
  544. if ((rc = write_word(info, wp, data)) != 0) {
  545. return (rc);
  546. }
  547. src += sizeof(FPW);
  548. wp += sizeof(FPW);
  549. cnt -= sizeof(FPW);
  550. }
  551. if (cnt == 0) return ERR_OK;
  552. /*
  553. * handle unaligned tail bytes
  554. */
  555. data = 0;
  556. for (i=0, cp=wp; i<2 && cnt>0; ++i, ++cp) {
  557. data = (data >> 8) | (*src++ << 8);
  558. --cnt;
  559. }
  560. for (; i<2; ++i, ++cp) {
  561. data = (data >> 8) | (*(uchar *)cp << 8);
  562. }
  563. return write_word(info, wp, data);
  564. }
  565. /*-----------------------------------------------------------------------
  566. * Write a word to Flash for AMD FLASH
  567. * A word is 16 or 32 bits, whichever the bus width of the flash bank
  568. * (not an individual chip) is.
  569. *
  570. * returns:
  571. * 0 - OK
  572. * 1 - write timeout
  573. * 2 - Flash not erased
  574. */
  575. static int write_word_amd (flash_info_t *info, FPWV *dest, FPW data)
  576. {
  577. ulong start;
  578. int flag;
  579. int res = 0; /* result, assume success */
  580. FPWV *base; /* first address in flash bank */
  581. /* Check if Flash is (sufficiently) erased */
  582. if ((*dest & data) != data) {
  583. return (2);
  584. }
  585. base = (FPWV *)(info->start[0]);
  586. /* Disable interrupts which might cause a timeout here */
  587. flag = disable_interrupts();
  588. base[0x0555] = (FPW)0x00AA00AA; /* unlock */
  589. base[0x02AA] = (FPW)0x00550055; /* unlock */
  590. base[0x0555] = (FPW)0x00A000A0; /* selects program mode */
  591. *dest = data; /* start programming the data */
  592. /* re-enable interrupts if necessary */
  593. if (flag)
  594. enable_interrupts();
  595. start = get_timer (0);
  596. /* data polling for D7 */
  597. while (res == 0 && (*dest & (FPW)0x00800080) != (data & (FPW)0x00800080)) {
  598. if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
  599. *dest = (FPW)0x00F000F0; /* reset bank */
  600. res = 1;
  601. }
  602. }
  603. return (res);
  604. }
  605. /*-----------------------------------------------------------------------
  606. * Write a word to Flash for Intel FLASH
  607. * A word is 16 or 32 bits, whichever the bus width of the flash bank
  608. * (not an individual chip) is.
  609. *
  610. * returns:
  611. * 0 - OK
  612. * 1 - write timeout
  613. * 2 - Flash not erased
  614. */
  615. static int write_word_intel (flash_info_t *info, FPWV *dest, FPW data)
  616. {
  617. ulong start;
  618. int flag;
  619. int res = 0; /* result, assume success */
  620. /* Check if Flash is (sufficiently) erased */
  621. if ((*dest & data) != data) {
  622. return (2);
  623. }
  624. /* Disable interrupts which might cause a timeout here */
  625. flag = disable_interrupts();
  626. *dest = (FPW)0x00500050; /* clear status register */
  627. *dest = (FPW)0x00FF00FF; /* make sure in read mode */
  628. *dest = (FPW)0x00400040; /* program setup */
  629. *dest = data; /* start programming the data */
  630. /* re-enable interrupts if necessary */
  631. if (flag)
  632. enable_interrupts();
  633. start = get_timer (0);
  634. while (res == 0 && (*dest & (FPW)0x00800080) != (FPW)0x00800080) {
  635. if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
  636. *dest = (FPW)0x00B000B0; /* Suspend program */
  637. res = 1;
  638. }
  639. }
  640. if (res == 0 && (*dest & (FPW)0x00100010))
  641. res = 1; /* write failed, time out error is close enough */
  642. *dest = (FPW)0x00500050; /* clear status register */
  643. *dest = (FPW)0x00FF00FF; /* make sure in read mode */
  644. return (res);
  645. }
  646. #ifdef CFG_FLASH_PROTECTION
  647. /*-----------------------------------------------------------------------
  648. */
  649. int flash_real_protect (flash_info_t * info, long sector, int prot)
  650. {
  651. int rcode = 0; /* assume success */
  652. FPWV *addr; /* address of sector */
  653. FPW value;
  654. addr = (FPWV *) (info->start[sector]);
  655. switch (info->flash_id & FLASH_TYPEMASK) {
  656. case FLASH_28F800C3B:
  657. case FLASH_28F800C3T:
  658. case FLASH_28F160C3B:
  659. case FLASH_28F160C3T:
  660. case FLASH_28F320C3B:
  661. case FLASH_28F320C3T:
  662. case FLASH_28F640C3B:
  663. case FLASH_28F640C3T:
  664. flash_reset (info); /* make sure in read mode */
  665. *addr = (FPW) 0x00600060L; /* lock command setup */
  666. if (prot)
  667. *addr = (FPW) 0x00010001L; /* lock sector */
  668. else
  669. *addr = (FPW) 0x00D000D0L; /* unlock sector */
  670. flash_reset (info); /* reset to read mode */
  671. /* now see if it really is locked/unlocked as requested */
  672. *addr = (FPW) 0x00900090;
  673. /* read sector protection at sector address, (A7 .. A0) = 0x02.
  674. * D0 = 1 for each device if protected.
  675. * If at least one device is protected the sector is marked
  676. * protected, but return failure. Mixed protected and
  677. * unprotected devices within a sector should never happen.
  678. */
  679. value = addr[2] & (FPW) 0x00010001;
  680. if (value == 0)
  681. info->protect[sector] = 0;
  682. else if (value == (FPW) 0x00010001)
  683. info->protect[sector] = 1;
  684. else {
  685. /* error, mixed protected and unprotected */
  686. rcode = 1;
  687. info->protect[sector] = 1;
  688. }
  689. if (info->protect[sector] != prot)
  690. rcode = 1; /* failed to protect/unprotect as requested */
  691. /* reload all protection bits from hardware for now */
  692. flash_sync_real_protect (info);
  693. break;
  694. case FLASH_AM640U:
  695. default:
  696. /* no hardware protect that we support */
  697. info->protect[sector] = prot;
  698. break;
  699. }
  700. return rcode;
  701. }
  702. #endif