flash.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  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[CONFIG_SYS_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 < CONFIG_SYS_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. CONFIG_SYS_FLASH_BASE,
  93. CONFIG_SYS_FLASH_BASE + monitor_flash_len - 1,
  94. &flash_info[0] );
  95. flash_protect ( FLAG_PROTECT_SET,
  96. CONFIG_ENV_ADDR,
  97. CONFIG_ENV_ADDR + CONFIG_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 > CONFIG_SYS_MAX_FLASH_SECT) {
  197. printf ("** ERROR: sector count %d > max (%d) **\n",
  198. info->sector_count, CONFIG_SYS_MAX_FLASH_SECT);
  199. info->sector_count = CONFIG_SYS_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;
  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. /* Disable interrupts which might cause a timeout here */
  238. flag = disable_interrupts ();
  239. /* Start erase on unprotected sectors */
  240. for (sect = s_first; sect <= s_last; sect++) {
  241. if (info->protect[sect] == 0) { /* not protected */
  242. FPWV *addr = (FPWV *) (info->start[sect]);
  243. FPW status;
  244. printf ("Erasing sector %2d ... ", sect);
  245. /* arm simple, non interrupt dependent timer */
  246. start = get_timer(0);
  247. *addr = (FPW) 0x00500050; /* clear status register */
  248. *addr = (FPW) 0x00200020; /* erase setup */
  249. *addr = (FPW) 0x00D000D0; /* erase confirm */
  250. while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
  251. if (get_timer(start) > CONFIG_SYS_FLASH_ERASE_TOUT) {
  252. printf ("Timeout\n");
  253. *addr = (FPW) 0x00B000B0; /* suspend erase */
  254. *addr = (FPW) 0x00FF00FF; /* reset to read mode */
  255. rcode = 1;
  256. break;
  257. }
  258. }
  259. *addr = 0x00500050; /* clear status register cmd. */
  260. *addr = 0x00FF00FF; /* resest to read mode */
  261. printf (" done\n");
  262. }
  263. }
  264. return rcode;
  265. }
  266. /*-----------------------------------------------------------------------
  267. * Copy memory to flash, returns:
  268. * 0 - OK
  269. * 1 - write timeout
  270. * 2 - Flash not erased
  271. * 4 - Flash not identified
  272. */
  273. int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
  274. {
  275. ulong cp, wp;
  276. FPW data;
  277. int count, i, l, rc, port_width;
  278. if (info->flash_id == FLASH_UNKNOWN) {
  279. return 4;
  280. }
  281. /* get lower word aligned address */
  282. #ifdef FLASH_PORT_WIDTH16
  283. wp = (addr & ~1);
  284. port_width = 2;
  285. #else
  286. wp = (addr & ~3);
  287. port_width = 4;
  288. #endif
  289. /*
  290. * handle unaligned start bytes
  291. */
  292. if ((l = addr - wp) != 0) {
  293. data = 0;
  294. for (i = 0, cp = wp; i < l; ++i, ++cp) {
  295. data = (data << 8) | (*(uchar *) cp);
  296. }
  297. for (; i < port_width && cnt > 0; ++i) {
  298. data = (data << 8) | *src++;
  299. --cnt;
  300. ++cp;
  301. }
  302. for (; cnt == 0 && i < port_width; ++i, ++cp) {
  303. data = (data << 8) | (*(uchar *) cp);
  304. }
  305. if ((rc = write_data (info, wp, SWAP (data))) != 0) {
  306. return (rc);
  307. }
  308. wp += port_width;
  309. }
  310. /*
  311. * handle word aligned part
  312. */
  313. count = 0;
  314. while (cnt >= port_width) {
  315. data = 0;
  316. for (i = 0; i < port_width; ++i) {
  317. data = (data << 8) | *src++;
  318. }
  319. if ((rc = write_data (info, wp, SWAP (data))) != 0) {
  320. return (rc);
  321. }
  322. wp += port_width;
  323. cnt -= port_width;
  324. if (count++ > 0x800) {
  325. spin_wheel ();
  326. count = 0;
  327. }
  328. }
  329. if (cnt == 0) {
  330. return (0);
  331. }
  332. /*
  333. * handle unaligned tail bytes
  334. */
  335. data = 0;
  336. for (i = 0, cp = wp; i < port_width && cnt > 0; ++i, ++cp) {
  337. data = (data << 8) | *src++;
  338. --cnt;
  339. }
  340. for (; i < port_width; ++i, ++cp) {
  341. data = (data << 8) | (*(uchar *) cp);
  342. }
  343. return (write_data (info, wp, SWAP (data)));
  344. }
  345. /*-----------------------------------------------------------------------
  346. * Write a word or halfword to Flash, returns:
  347. * 0 - OK
  348. * 1 - write timeout
  349. * 2 - Flash not erased
  350. */
  351. static int write_data (flash_info_t *info, ulong dest, FPW data)
  352. {
  353. FPWV *addr = (FPWV *) dest;
  354. ulong status;
  355. int flag;
  356. ulong start;
  357. /* Check if Flash is (sufficiently) erased */
  358. if ((*addr & data) != data) {
  359. printf ("not erased at %08lx (%lx)\n", (ulong) addr, *addr);
  360. return (2);
  361. }
  362. /* Disable interrupts which might cause a timeout here */
  363. flag = disable_interrupts ();
  364. *addr = (FPW) 0x00400040; /* write setup */
  365. *addr = data;
  366. /* arm simple, non interrupt dependent timer */
  367. start = get_timer(0);
  368. /* wait while polling the status register */
  369. while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
  370. if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
  371. *addr = (FPW) 0x00FF00FF; /* restore read mode */
  372. return (1);
  373. }
  374. }
  375. *addr = (FPW) 0x00FF00FF; /* restore read mode */
  376. return (0);
  377. }
  378. void inline spin_wheel (void)
  379. {
  380. static int p = 0;
  381. static char w[] = "\\/-";
  382. printf ("\010%c", w[p]);
  383. (++p == 3) ? (p = 0) : 0;
  384. }
  385. /*-----------------------------------------------------------------------
  386. * Set/Clear sector's lock bit, returns:
  387. * 0 - OK
  388. * 1 - Error (timeout, voltage problems, etc.)
  389. */
  390. int flash_real_protect(flash_info_t *info, long sector, int prot)
  391. {
  392. int i;
  393. int rc = 0;
  394. vu_long *addr = (vu_long *)(info->start[sector]);
  395. int flag = disable_interrupts();
  396. ulong start;
  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. start = get_timer(0);
  407. while ((*addr & INTEL_FINISHED) != INTEL_FINISHED) {
  408. if (get_timer(start) > CONFIG_SYS_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. start = get_timer(0);
  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(start) > CONFIG_SYS_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. }