flash.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  1. /*
  2. * (C) Copyright 2001
  3. * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
  4. *
  5. * (C) Copyright 2001-2004
  6. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  7. *
  8. * See file CREDITS for list of people who contributed to this
  9. * project.
  10. *
  11. * This program is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU General Public License as
  13. * published by the Free Software Foundation; either version 2 of
  14. * the License, or (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program; if not, write to the Free Software
  23. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  24. * MA 02111-1307 USA
  25. */
  26. #include <common.h>
  27. #include <linux/byteorder/swab.h>
  28. flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
  29. /* Board support for 1 or 2 flash devices */
  30. #define FLASH_PORT_WIDTH32
  31. #undef FLASH_PORT_WIDTH16
  32. #ifdef FLASH_PORT_WIDTH16
  33. #define FLASH_PORT_WIDTH ushort
  34. #define FLASH_PORT_WIDTHV vu_short
  35. #define SWAP(x) (x)
  36. #else
  37. #define FLASH_PORT_WIDTH ulong
  38. #define FLASH_PORT_WIDTHV vu_long
  39. #define SWAP(x) (x)
  40. #endif
  41. /* Intel-compatible flash ID */
  42. #define INTEL_COMPAT 0x00890089
  43. #define INTEL_ALT 0x00B000B0
  44. /* Intel-compatible flash commands */
  45. #define INTEL_PROGRAM 0x00100010
  46. #define INTEL_ERASE 0x00200020
  47. #define INTEL_CLEAR 0x00500050
  48. #define INTEL_LOCKBIT 0x00600060
  49. #define INTEL_PROTECT 0x00010001
  50. #define INTEL_STATUS 0x00700070
  51. #define INTEL_READID 0x00900090
  52. #define INTEL_CONFIRM 0x00D000D0
  53. #define INTEL_RESET 0xFFFFFFFF
  54. /* Intel-compatible flash status bits */
  55. #define INTEL_FINISHED 0x00800080
  56. #define INTEL_OK 0x00800080
  57. #define FPW FLASH_PORT_WIDTH
  58. #define FPWV FLASH_PORT_WIDTHV
  59. #define mb() __asm__ __volatile__ ("" : : : "memory")
  60. /*-----------------------------------------------------------------------
  61. * Functions
  62. */
  63. static ulong flash_get_size (FPW *addr, flash_info_t *info);
  64. static int write_data (flash_info_t *info, ulong dest, FPW data);
  65. static void flash_get_offsets (ulong base, flash_info_t *info);
  66. void inline spin_wheel (void);
  67. /*-----------------------------------------------------------------------
  68. */
  69. unsigned long flash_init (void)
  70. {
  71. int i;
  72. ulong size = 0;
  73. extern void flash_preinit(void);
  74. extern void flash_afterinit(ulong, ulong);
  75. ulong flashbase = CFG_FLASH_BASE;
  76. flash_preinit();
  77. for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
  78. switch (i) {
  79. case 0:
  80. memset(&flash_info[i], 0, sizeof(flash_info_t));
  81. flash_get_size ((FPW *) flashbase, &flash_info[i]);
  82. flash_get_offsets (flash_info[i].start[0], &flash_info[i]);
  83. break;
  84. default:
  85. panic ("configured to many flash banks!\n");
  86. break;
  87. }
  88. size += flash_info[i].size;
  89. }
  90. /* Protect monitor and environment sectors
  91. */
  92. #if CFG_MONITOR_BASE >= CFG_FLASH_BASE
  93. #ifndef CONFIG_BOOT_ROM
  94. flash_protect ( FLAG_PROTECT_SET,
  95. CFG_MONITOR_BASE,
  96. CFG_MONITOR_BASE + monitor_flash_len - 1,
  97. &flash_info[0] );
  98. #endif
  99. #endif
  100. #ifdef CFG_ENV_IS_IN_FLASH
  101. flash_protect ( FLAG_PROTECT_SET,
  102. CFG_ENV_ADDR,
  103. CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0] );
  104. #endif
  105. flash_afterinit(flash_info[0].start[0], flash_info[0].size);
  106. return size;
  107. }
  108. /*-----------------------------------------------------------------------
  109. */
  110. static void flash_get_offsets (ulong base, flash_info_t *info)
  111. {
  112. int i;
  113. if (info->flash_id == FLASH_UNKNOWN) {
  114. return;
  115. }
  116. if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
  117. for (i = 0; i < info->sector_count; i++) {
  118. info->start[i] = base + (i * PHYS_FLASH_SECT_SIZE);
  119. info->protect[i] = 0;
  120. }
  121. }
  122. }
  123. /*-----------------------------------------------------------------------
  124. */
  125. void flash_print_info (flash_info_t *info)
  126. {
  127. int i;
  128. if (info->flash_id == FLASH_UNKNOWN) {
  129. printf ("missing or unknown FLASH type\n");
  130. return;
  131. }
  132. switch (info->flash_id & FLASH_VENDMASK) {
  133. case FLASH_MAN_INTEL:
  134. printf ("INTEL ");
  135. break;
  136. default:
  137. printf ("Unknown Vendor ");
  138. break;
  139. }
  140. switch (info->flash_id & FLASH_TYPEMASK) {
  141. case FLASH_28F128J3A:
  142. printf ("28F128J3A\n");
  143. break;
  144. case FLASH_28F640J3A:
  145. printf ("28F640J3A\n");
  146. break;
  147. case FLASH_28F320J3A:
  148. printf ("28F320J3A\n");
  149. break;
  150. default:
  151. printf ("Unknown Chip Type\n");
  152. break;
  153. }
  154. printf (" Size: %ld MB in %d Sectors\n",
  155. info->size >> 20, info->sector_count);
  156. printf (" Sector Start Addresses:");
  157. for (i = 0; i < info->sector_count; ++i) {
  158. if ((i % 5) == 0)
  159. printf ("\n ");
  160. printf (" %08lX%s",
  161. info->start[i],
  162. info->protect[i] ? " (RO)" : " ");
  163. }
  164. printf ("\n");
  165. return;
  166. }
  167. /*
  168. * The following code cannot be run from FLASH!
  169. */
  170. static ulong flash_get_size (FPW *addr, flash_info_t *info)
  171. {
  172. volatile FPW value;
  173. /* Write auto select command: read Manufacturer ID */
  174. addr[0x5555] = (FPW) 0x00AA00AA;
  175. addr[0x2AAA] = (FPW) 0x00550055;
  176. addr[0x5555] = (FPW) 0x00900090;
  177. mb ();
  178. udelay(100);
  179. value = addr[0];
  180. switch (value) {
  181. case (FPW) INTEL_MANUFACT:
  182. info->flash_id = FLASH_MAN_INTEL;
  183. break;
  184. default:
  185. info->flash_id = FLASH_UNKNOWN;
  186. info->sector_count = 0;
  187. info->size = 0;
  188. addr[0] = (FPW) 0x00FF00FF; /* restore read mode */
  189. return (0); /* no or unknown flash */
  190. }
  191. mb ();
  192. value = addr[1]; /* device ID */
  193. switch (value) {
  194. case (FPW) INTEL_ID_28F128J3A:
  195. info->flash_id += FLASH_28F128J3A;
  196. info->sector_count = 128;
  197. info->size = 0x02000000;
  198. info->start[0] = CFG_FLASH_BASE;
  199. break; /* => 32 MB */
  200. case (FPW) INTEL_ID_28F640J3A:
  201. info->flash_id += FLASH_28F640J3A;
  202. info->sector_count = 64;
  203. info->size = 0x01000000;
  204. info->start[0] = CFG_FLASH_BASE + 0x01000000;
  205. break; /* => 16 MB */
  206. case (FPW) INTEL_ID_28F320J3A:
  207. info->flash_id += FLASH_28F320J3A;
  208. info->sector_count = 32;
  209. info->size = 0x800000;
  210. info->start[0] = CFG_FLASH_BASE + 0x01800000;
  211. break; /* => 8 MB */
  212. default:
  213. info->flash_id = FLASH_UNKNOWN;
  214. break;
  215. }
  216. if (info->sector_count > CFG_MAX_FLASH_SECT) {
  217. printf ("** ERROR: sector count %d > max (%d) **\n",
  218. info->sector_count, CFG_MAX_FLASH_SECT);
  219. info->sector_count = CFG_MAX_FLASH_SECT;
  220. }
  221. addr[0] = (FPW) 0x00FF00FF; /* restore read mode */
  222. return (info->size);
  223. }
  224. /*-----------------------------------------------------------------------
  225. */
  226. int flash_erase (flash_info_t *info, int s_first, int s_last)
  227. {
  228. int flag, prot, sect;
  229. ulong type, start, last;
  230. int rcode = 0;
  231. if ((s_first < 0) || (s_first > s_last)) {
  232. if (info->flash_id == FLASH_UNKNOWN) {
  233. printf ("- missing\n");
  234. } else {
  235. printf ("- no sectors to erase\n");
  236. }
  237. return 1;
  238. }
  239. type = (info->flash_id & FLASH_VENDMASK);
  240. if ((type != FLASH_MAN_INTEL)) {
  241. printf ("Can't erase unknown flash type %08lx - aborted\n",
  242. info->flash_id);
  243. return 1;
  244. }
  245. prot = 0;
  246. for (sect = s_first; sect <= s_last; ++sect) {
  247. if (info->protect[sect]) {
  248. prot++;
  249. }
  250. }
  251. if (prot) {
  252. printf ("- Warning: %d protected sectors will not be erased!\n",
  253. prot);
  254. } else {
  255. printf ("\n");
  256. }
  257. start = get_timer (0);
  258. last = start;
  259. /* Disable interrupts which might cause a timeout here */
  260. flag = disable_interrupts ();
  261. /* Start erase on unprotected sectors */
  262. for (sect = s_first; sect <= s_last; sect++) {
  263. if (info->protect[sect] == 0) { /* not protected */
  264. FPWV *addr = (FPWV *) (info->start[sect]);
  265. FPW status;
  266. printf ("Erasing sector %2d ... ", sect);
  267. /* arm simple, non interrupt dependent timer */
  268. start = get_timer(0);
  269. *addr = (FPW) 0x00500050; /* clear status register */
  270. *addr = (FPW) 0x00200020; /* erase setup */
  271. *addr = (FPW) 0x00D000D0; /* erase confirm */
  272. while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
  273. if (get_timer(start) > CFG_FLASH_ERASE_TOUT) {
  274. printf ("Timeout\n");
  275. *addr = (FPW) 0x00B000B0; /* suspend erase */
  276. *addr = (FPW) 0x00FF00FF; /* reset to read mode */
  277. rcode = 1;
  278. break;
  279. }
  280. }
  281. *addr = 0x00500050; /* clear status register cmd. */
  282. *addr = 0x00FF00FF; /* resest to read mode */
  283. printf (" done\n");
  284. }
  285. }
  286. return rcode;
  287. }
  288. /*-----------------------------------------------------------------------
  289. * Copy memory to flash, returns:
  290. * 0 - OK
  291. * 1 - write timeout
  292. * 2 - Flash not erased
  293. * 4 - Flash not identified
  294. */
  295. int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
  296. {
  297. ulong cp, wp;
  298. FPW data;
  299. int count, i, l, rc, port_width;
  300. if (info->flash_id == FLASH_UNKNOWN) {
  301. return 4;
  302. }
  303. /* get lower word aligned address */
  304. #ifdef FLASH_PORT_WIDTH16
  305. wp = (addr & ~1);
  306. port_width = 2;
  307. #else
  308. wp = (addr & ~3);
  309. port_width = 4;
  310. #endif
  311. /*
  312. * handle unaligned start bytes
  313. */
  314. if ((l = addr - wp) != 0) {
  315. data = 0;
  316. for (i = 0, cp = wp; i < l; ++i, ++cp) {
  317. data = (data << 8) | (*(uchar *) cp);
  318. }
  319. for (; i < port_width && cnt > 0; ++i) {
  320. data = (data << 8) | *src++;
  321. --cnt;
  322. ++cp;
  323. }
  324. for (; cnt == 0 && i < port_width; ++i, ++cp) {
  325. data = (data << 8) | (*(uchar *) cp);
  326. }
  327. if ((rc = write_data (info, wp, SWAP (data))) != 0) {
  328. return (rc);
  329. }
  330. wp += port_width;
  331. }
  332. /*
  333. * handle word aligned part
  334. */
  335. count = 0;
  336. while (cnt >= port_width) {
  337. data = 0;
  338. for (i = 0; i < port_width; ++i) {
  339. data = (data << 8) | *src++;
  340. }
  341. if ((rc = write_data (info, wp, SWAP (data))) != 0) {
  342. return (rc);
  343. }
  344. wp += port_width;
  345. cnt -= port_width;
  346. if (count++ > 0x800) {
  347. spin_wheel ();
  348. count = 0;
  349. }
  350. }
  351. if (cnt == 0) {
  352. return (0);
  353. }
  354. /*
  355. * handle unaligned tail bytes
  356. */
  357. data = 0;
  358. for (i = 0, cp = wp; i < port_width && cnt > 0; ++i, ++cp) {
  359. data = (data << 8) | *src++;
  360. --cnt;
  361. }
  362. for (; i < port_width; ++i, ++cp) {
  363. data = (data << 8) | (*(uchar *) cp);
  364. }
  365. return (write_data (info, wp, SWAP (data)));
  366. }
  367. /*-----------------------------------------------------------------------
  368. * Write a word or halfword to Flash, returns:
  369. * 0 - OK
  370. * 1 - write timeout
  371. * 2 - Flash not erased
  372. */
  373. static int write_data (flash_info_t *info, ulong dest, FPW data)
  374. {
  375. FPWV *addr = (FPWV *) dest;
  376. ulong status;
  377. ulong start;
  378. int flag;
  379. /* Check if Flash is (sufficiently) erased */
  380. if ((*addr & data) != data) {
  381. printf ("not erased at %08lx (%lx)\n", (ulong) addr, *addr);
  382. return (2);
  383. }
  384. /* Disable interrupts which might cause a timeout here */
  385. flag = disable_interrupts ();
  386. *addr = (FPW) 0x00400040; /* write setup */
  387. *addr = data;
  388. /* arm simple, non interrupt dependent timer */
  389. start = get_timer(0);
  390. /* wait while polling the status register */
  391. while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
  392. if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
  393. *addr = (FPW) 0x00FF00FF; /* restore read mode */
  394. return (1);
  395. }
  396. }
  397. *addr = (FPW) 0x00FF00FF; /* restore read mode */
  398. return (0);
  399. }
  400. void inline spin_wheel (void)
  401. {
  402. static int p = 0;
  403. static char w[] = "\\/-";
  404. printf ("\010%c", w[p]);
  405. (++p == 3) ? (p = 0) : 0;
  406. }
  407. /*-----------------------------------------------------------------------
  408. * Set/Clear sector's lock bit, returns:
  409. * 0 - OK
  410. * 1 - Error (timeout, voltage problems, etc.)
  411. */
  412. int flash_real_protect(flash_info_t *info, long sector, int prot)
  413. {
  414. ulong start;
  415. int i;
  416. int rc = 0;
  417. vu_long *addr = (vu_long *)(info->start[sector]);
  418. int flag = disable_interrupts();
  419. *addr = INTEL_CLEAR; /* Clear status register */
  420. if (prot) { /* Set sector lock bit */
  421. *addr = INTEL_LOCKBIT; /* Sector lock bit */
  422. *addr = INTEL_PROTECT; /* set */
  423. }
  424. else { /* Clear sector lock bit */
  425. *addr = INTEL_LOCKBIT; /* All sectors lock bits */
  426. *addr = INTEL_CONFIRM; /* clear */
  427. }
  428. start = get_timer(0);
  429. while ((*addr & INTEL_FINISHED) != INTEL_FINISHED) {
  430. if (get_timer(start) > CFG_FLASH_UNLOCK_TOUT) {
  431. printf("Flash lock bit operation timed out\n");
  432. rc = 1;
  433. break;
  434. }
  435. }
  436. if (*addr != INTEL_OK) {
  437. printf("Flash lock bit operation failed at %08X, CSR=%08X\n",
  438. (uint)addr, (uint)*addr);
  439. rc = 1;
  440. }
  441. if (!rc)
  442. info->protect[sector] = prot;
  443. /*
  444. * Clear lock bit command clears all sectors lock bits, so
  445. * we have to restore lock bits of protected sectors.
  446. */
  447. if (!prot)
  448. {
  449. for (i = 0; i < info->sector_count; i++)
  450. {
  451. if (info->protect[i])
  452. {
  453. start = get_timer(0);
  454. addr = (vu_long *)(info->start[i]);
  455. *addr = INTEL_LOCKBIT; /* Sector lock bit */
  456. *addr = INTEL_PROTECT; /* set */
  457. while ((*addr & INTEL_FINISHED) != INTEL_FINISHED)
  458. {
  459. if (get_timer(start) > CFG_FLASH_UNLOCK_TOUT)
  460. {
  461. printf("Flash lock bit operation timed out\n");
  462. rc = 1;
  463. break;
  464. }
  465. }
  466. }
  467. }
  468. }
  469. if (flag)
  470. enable_interrupts();
  471. *addr = INTEL_RESET; /* Reset to read array mode */
  472. return rc;
  473. }