flash.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536
  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) __swab16(x)
  36. #else
  37. #define FLASH_PORT_WIDTH ulong
  38. #define FLASH_PORT_WIDTHV vu_long
  39. #define SWAP(x) __swab32(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. for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
  74. switch (i) {
  75. case 0:
  76. flash_get_size ((FPW *) PHYS_FLASH_1, &flash_info[i]);
  77. flash_get_offsets (PHYS_FLASH_1, &flash_info[i]);
  78. break;
  79. case 1:
  80. flash_get_size ((FPW *) PHYS_FLASH_2, &flash_info[i]);
  81. flash_get_offsets (PHYS_FLASH_2, &flash_info[i]);
  82. break;
  83. default:
  84. panic ("configured to many flash banks!\n");
  85. break;
  86. }
  87. size += flash_info[i].size;
  88. }
  89. /* Protect monitor and environment sectors
  90. */
  91. flash_protect ( FLAG_PROTECT_SET,
  92. CFG_FLASH_BASE,
  93. CFG_FLASH_BASE + monitor_flash_len - 1,
  94. &flash_info[0] );
  95. flash_protect ( FLAG_PROTECT_SET,
  96. CFG_ENV_ADDR,
  97. CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0] );
  98. return size;
  99. }
  100. /*-----------------------------------------------------------------------
  101. */
  102. static void flash_get_offsets (ulong base, flash_info_t *info)
  103. {
  104. int i;
  105. if (info->flash_id == FLASH_UNKNOWN) {
  106. return;
  107. }
  108. if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
  109. for (i = 0; i < info->sector_count; i++) {
  110. info->start[i] = base + (i * PHYS_FLASH_SECT_SIZE);
  111. info->protect[i] = 0;
  112. }
  113. }
  114. }
  115. /*-----------------------------------------------------------------------
  116. */
  117. void flash_print_info (flash_info_t *info)
  118. {
  119. int i;
  120. if (info->flash_id == FLASH_UNKNOWN) {
  121. printf ("missing or unknown FLASH type\n");
  122. return;
  123. }
  124. switch (info->flash_id & FLASH_VENDMASK) {
  125. case FLASH_MAN_INTEL:
  126. printf ("INTEL ");
  127. break;
  128. default:
  129. printf ("Unknown Vendor ");
  130. break;
  131. }
  132. switch (info->flash_id & FLASH_TYPEMASK) {
  133. case FLASH_28F128J3A:
  134. printf ("28F128J3A\n");
  135. break;
  136. case FLASH_28F640J3A:
  137. printf ("28F640J3A\n");
  138. break;
  139. default:
  140. printf ("Unknown Chip Type\n");
  141. break;
  142. }
  143. printf (" Size: %ld MB in %d Sectors\n",
  144. info->size >> 20, info->sector_count);
  145. printf (" Sector Start Addresses:");
  146. for (i = 0; i < info->sector_count; ++i) {
  147. if ((i % 5) == 0)
  148. printf ("\n ");
  149. printf (" %08lX%s",
  150. info->start[i],
  151. info->protect[i] ? " (RO)" : " ");
  152. }
  153. printf ("\n");
  154. return;
  155. }
  156. /*
  157. * The following code cannot be run from FLASH!
  158. */
  159. static ulong flash_get_size (FPW *addr, flash_info_t *info)
  160. {
  161. volatile FPW value;
  162. /* Write auto select command: read Manufacturer ID */
  163. addr[0x5555] = (FPW) 0x00AA00AA;
  164. addr[0x2AAA] = (FPW) 0x00550055;
  165. addr[0x5555] = (FPW) 0x00900090;
  166. mb ();
  167. value = addr[0];
  168. switch (value) {
  169. case (FPW) INTEL_MANUFACT:
  170. info->flash_id = FLASH_MAN_INTEL;
  171. break;
  172. default:
  173. info->flash_id = FLASH_UNKNOWN;
  174. info->sector_count = 0;
  175. info->size = 0;
  176. addr[0] = (FPW) 0x00FF00FF; /* restore read mode */
  177. return (0); /* no or unknown flash */
  178. }
  179. mb ();
  180. value = addr[1]; /* device ID */
  181. switch (value) {
  182. case (FPW) INTEL_ID_28F128J3A:
  183. info->flash_id += FLASH_28F128J3A;
  184. info->sector_count = 128;
  185. info->size = 0x02000000;
  186. break; /* => 32 MB */
  187. case (FPW) INTEL_ID_28F640J3A:
  188. info->flash_id += FLASH_28F640J3A;
  189. info->sector_count = 64;
  190. info->size = 0x01000000;
  191. break; /* => 16 MB */
  192. default:
  193. info->flash_id = FLASH_UNKNOWN;
  194. break;
  195. }
  196. if (info->sector_count > CFG_MAX_FLASH_SECT) {
  197. printf ("** ERROR: sector count %d > max (%d) **\n",
  198. info->sector_count, CFG_MAX_FLASH_SECT);
  199. info->sector_count = CFG_MAX_FLASH_SECT;
  200. }
  201. addr[0] = (FPW) 0x00FF00FF; /* restore read mode */
  202. return (info->size);
  203. }
  204. /*-----------------------------------------------------------------------
  205. */
  206. int flash_erase (flash_info_t *info, int s_first, int s_last)
  207. {
  208. int flag, prot, sect;
  209. ulong type, start, last;
  210. int rcode = 0;
  211. if ((s_first < 0) || (s_first > s_last)) {
  212. if (info->flash_id == FLASH_UNKNOWN) {
  213. printf ("- missing\n");
  214. } else {
  215. printf ("- no sectors to erase\n");
  216. }
  217. return 1;
  218. }
  219. type = (info->flash_id & FLASH_VENDMASK);
  220. if ((type != FLASH_MAN_INTEL)) {
  221. printf ("Can't erase unknown flash type %08lx - aborted\n",
  222. info->flash_id);
  223. return 1;
  224. }
  225. prot = 0;
  226. for (sect = s_first; sect <= s_last; ++sect) {
  227. if (info->protect[sect]) {
  228. prot++;
  229. }
  230. }
  231. if (prot) {
  232. printf ("- Warning: %d protected sectors will not be erased!\n",
  233. prot);
  234. } else {
  235. printf ("\n");
  236. }
  237. start = get_timer (0);
  238. last = start;
  239. /* Disable interrupts which might cause a timeout here */
  240. flag = disable_interrupts ();
  241. /* Start erase on unprotected sectors */
  242. for (sect = s_first; sect <= s_last; sect++) {
  243. if (info->protect[sect] == 0) { /* not protected */
  244. FPWV *addr = (FPWV *) (info->start[sect]);
  245. FPW status;
  246. printf ("Erasing sector %2d ... ", sect);
  247. /* arm simple, non interrupt dependent timer */
  248. reset_timer_masked ();
  249. *addr = (FPW) 0x00500050; /* clear status register */
  250. *addr = (FPW) 0x00200020; /* erase setup */
  251. *addr = (FPW) 0x00D000D0; /* erase confirm */
  252. while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
  253. if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) {
  254. printf ("Timeout\n");
  255. *addr = (FPW) 0x00B000B0; /* suspend erase */
  256. *addr = (FPW) 0x00FF00FF; /* reset to read mode */
  257. rcode = 1;
  258. break;
  259. }
  260. }
  261. *addr = 0x00500050; /* clear status register cmd. */
  262. *addr = 0x00FF00FF; /* resest to read mode */
  263. printf (" done\n");
  264. }
  265. }
  266. return rcode;
  267. }
  268. /*-----------------------------------------------------------------------
  269. * Copy memory to flash, returns:
  270. * 0 - OK
  271. * 1 - write timeout
  272. * 2 - Flash not erased
  273. * 4 - Flash not identified
  274. */
  275. int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
  276. {
  277. ulong cp, wp;
  278. FPW data;
  279. int count, i, l, rc, port_width;
  280. if (info->flash_id == FLASH_UNKNOWN) {
  281. return 4;
  282. }
  283. /* get lower word aligned address */
  284. #ifdef FLASH_PORT_WIDTH16
  285. wp = (addr & ~1);
  286. port_width = 2;
  287. #else
  288. wp = (addr & ~3);
  289. port_width = 4;
  290. #endif
  291. /*
  292. * handle unaligned start bytes
  293. */
  294. if ((l = addr - wp) != 0) {
  295. data = 0;
  296. for (i = 0, cp = wp; i < l; ++i, ++cp) {
  297. data = (data << 8) | (*(uchar *) cp);
  298. }
  299. for (; i < port_width && cnt > 0; ++i) {
  300. data = (data << 8) | *src++;
  301. --cnt;
  302. ++cp;
  303. }
  304. for (; cnt == 0 && i < port_width; ++i, ++cp) {
  305. data = (data << 8) | (*(uchar *) cp);
  306. }
  307. if ((rc = write_data (info, wp, SWAP (data))) != 0) {
  308. return (rc);
  309. }
  310. wp += port_width;
  311. }
  312. /*
  313. * handle word aligned part
  314. */
  315. count = 0;
  316. while (cnt >= port_width) {
  317. data = 0;
  318. for (i = 0; i < port_width; ++i) {
  319. data = (data << 8) | *src++;
  320. }
  321. if ((rc = write_data (info, wp, SWAP (data))) != 0) {
  322. return (rc);
  323. }
  324. wp += port_width;
  325. cnt -= port_width;
  326. if (count++ > 0x800) {
  327. spin_wheel ();
  328. count = 0;
  329. }
  330. }
  331. if (cnt == 0) {
  332. return (0);
  333. }
  334. /*
  335. * handle unaligned tail bytes
  336. */
  337. data = 0;
  338. for (i = 0, cp = wp; i < port_width && cnt > 0; ++i, ++cp) {
  339. data = (data << 8) | *src++;
  340. --cnt;
  341. }
  342. for (; i < port_width; ++i, ++cp) {
  343. data = (data << 8) | (*(uchar *) cp);
  344. }
  345. return (write_data (info, wp, SWAP (data)));
  346. }
  347. /*-----------------------------------------------------------------------
  348. * Write a word or halfword to Flash, returns:
  349. * 0 - OK
  350. * 1 - write timeout
  351. * 2 - Flash not erased
  352. */
  353. static int write_data (flash_info_t *info, ulong dest, FPW data)
  354. {
  355. FPWV *addr = (FPWV *) dest;
  356. ulong status;
  357. int flag;
  358. /* Check if Flash is (sufficiently) erased */
  359. if ((*addr & data) != data) {
  360. printf ("not erased at %08lx (%lx)\n", (ulong) addr, *addr);
  361. return (2);
  362. }
  363. /* Disable interrupts which might cause a timeout here */
  364. flag = disable_interrupts ();
  365. *addr = (FPW) 0x00400040; /* write setup */
  366. *addr = data;
  367. /* arm simple, non interrupt dependent timer */
  368. reset_timer_masked ();
  369. /* wait while polling the status register */
  370. while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
  371. if (get_timer_masked () > CFG_FLASH_WRITE_TOUT) {
  372. *addr = (FPW) 0x00FF00FF; /* restore read mode */
  373. return (1);
  374. }
  375. }
  376. *addr = (FPW) 0x00FF00FF; /* restore read mode */
  377. return (0);
  378. }
  379. void inline spin_wheel (void)
  380. {
  381. static int p = 0;
  382. static char w[] = "\\/-";
  383. printf ("\010%c", w[p]);
  384. (++p == 3) ? (p = 0) : 0;
  385. }
  386. /*-----------------------------------------------------------------------
  387. * Set/Clear sector's lock bit, returns:
  388. * 0 - OK
  389. * 1 - Error (timeout, voltage problems, etc.)
  390. */
  391. int flash_real_protect(flash_info_t *info, long sector, int prot)
  392. {
  393. int i;
  394. int rc = 0;
  395. vu_long *addr = (vu_long *)(info->start[sector]);
  396. int flag = disable_interrupts();
  397. *addr = INTEL_CLEAR; /* Clear status register */
  398. if (prot) { /* Set sector lock bit */
  399. *addr = INTEL_LOCKBIT; /* Sector lock bit */
  400. *addr = INTEL_PROTECT; /* set */
  401. }
  402. else { /* Clear sector lock bit */
  403. *addr = INTEL_LOCKBIT; /* All sectors lock bits */
  404. *addr = INTEL_CONFIRM; /* clear */
  405. }
  406. reset_timer_masked ();
  407. while ((*addr & INTEL_FINISHED) != INTEL_FINISHED) {
  408. if (get_timer_masked () > CFG_FLASH_UNLOCK_TOUT) {
  409. printf("Flash lock bit operation timed out\n");
  410. rc = 1;
  411. break;
  412. }
  413. }
  414. if (*addr != INTEL_OK) {
  415. printf("Flash lock bit operation failed at %08X, CSR=%08X\n",
  416. (uint)addr, (uint)*addr);
  417. rc = 1;
  418. }
  419. if (!rc)
  420. info->protect[sector] = prot;
  421. /*
  422. * Clear lock bit command clears all sectors lock bits, so
  423. * we have to restore lock bits of protected sectors.
  424. */
  425. if (!prot)
  426. {
  427. for (i = 0; i < info->sector_count; i++)
  428. {
  429. if (info->protect[i])
  430. {
  431. reset_timer_masked ();
  432. addr = (vu_long *)(info->start[i]);
  433. *addr = INTEL_LOCKBIT; /* Sector lock bit */
  434. *addr = INTEL_PROTECT; /* set */
  435. while ((*addr & INTEL_FINISHED) != INTEL_FINISHED)
  436. {
  437. if (get_timer_masked () > CFG_FLASH_UNLOCK_TOUT)
  438. {
  439. printf("Flash lock bit operation timed out\n");
  440. rc = 1;
  441. break;
  442. }
  443. }
  444. }
  445. }
  446. }
  447. if (flag)
  448. enable_interrupts();
  449. *addr = INTEL_RESET; /* Reset to read array mode */
  450. return rc;
  451. }