flash.c 19 KB

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