flash.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  1. /*
  2. * (C) Copyright 2000-2003
  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. /******************************************************************************
  24. ** Notes: AM29LV320DB - 90EI ( 32 Mbit device )
  25. ** Sectors - Eight 8 Kb sector
  26. ** - Sixty three 64 Kb sector
  27. ** Bottom boot sector
  28. ******************************************************************************/
  29. #include <common.h>
  30. #include <mpc8xx.h>
  31. /******************************************************************************
  32. ** Defines
  33. ******************************************************************************/
  34. #ifdef CONFIG_ADDERII
  35. #define ADDR0 0x0555
  36. #define ADDR1 0x02AA
  37. #define FLASH_WORD_SIZE unsigned short
  38. #endif
  39. #if defined( CFG_ENV_IS_IN_FLASH )
  40. # ifndef CFG_ENV_ADDR
  41. # define CFG_ENV_ADDR ( CFG_FLASH_BASE + CFG_ENV_OFFSET )
  42. # endif
  43. # ifndef CFG_ENV_SIZE
  44. # define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
  45. # endif
  46. # ifndef CFG_ENV_SECT_SIZE
  47. # define CFG_ENV_SECT_SIZE CFG_ENV_SIZE
  48. # endif
  49. #endif
  50. /******************************************************************************
  51. ** Global Parameters
  52. ******************************************************************************/
  53. flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
  54. /******************************************************************************
  55. ** Function Prototypes
  56. ******************************************************************************/
  57. static ulong flash_get_size( vu_long *addr, flash_info_t *info );
  58. static int write_word( flash_info_t *info, ulong dest, ulong data );
  59. static void flash_get_offsets( ulong base, flash_info_t *info );
  60. int wait_for_DQ7( flash_info_t *info, int sect );
  61. /******************************************************************************
  62. ** Function : flash_init
  63. ** Param : void
  64. ** Notes : Initializes the Flash Chip
  65. ******************************************************************************/
  66. ulong flash_init (void)
  67. {
  68. ulong size_b0 = -1;
  69. int i;
  70. volatile immap_t *immap = (immap_t *) CFG_IMMR;
  71. volatile memctl8xx_t *memctl = &immap->im_memctl;
  72. /* Set Flash to unknown */
  73. for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
  74. flash_info[i].flash_id = FLASH_UNKNOWN;
  75. }
  76. /* Get the Flash Bank Size */
  77. size_b0 = flash_get_size ((vu_long *) (CFG_FLASH_BASE),
  78. &flash_info[0]);
  79. if (flash_info[0].flash_id == FLASH_UNKNOWN) {
  80. printf ("## UNKNOWN Flash on Bank 0 - Size = 0x%08lx = %ldMB\n",
  81. size_b0, size_b0 >> 20);
  82. }
  83. /* Remap Flash according to size detected */
  84. memctl->memc_or0 = 0xFF800774;
  85. memctl->memc_br0 = CFG_BR0_PRELIM;
  86. /* Setup Flash Sector Offsets */
  87. flash_get_offsets (CFG_FLASH_BASE, &flash_info[0]);
  88. /* Monitor Protection ON - default */
  89. #if ( CFG_MONITOR_BASE >= CFG_FLASH_BASE )
  90. flash_protect (FLAG_PROTECT_SET, CFG_MONITOR_BASE,
  91. (CFG_MONITOR_BASE + monitor_flash_len - 1),
  92. &flash_info[0]);
  93. #endif
  94. /* Protect Environment Variables */
  95. #ifdef CFG_ENV_IS_IN_FLASH
  96. flash_protect (FLAG_PROTECT_SET, CFG_ENV_ADDR,
  97. (CFG_ENV_ADDR + CFG_ENV_SIZE - 1), &flash_info[0]);
  98. #endif
  99. return size_b0;
  100. }
  101. /******************************************************************************
  102. ** Function : flash_get_offsets
  103. ** Param : ulong base, flash_into_t *info
  104. ** Notes :
  105. ******************************************************************************/
  106. static void flash_get_offsets (ulong base, flash_info_t * info)
  107. {
  108. return;
  109. }
  110. /******************************************************************************
  111. ** Function : flash_print_info
  112. ** Param : flash_info_t
  113. ** Notes :
  114. ******************************************************************************/
  115. void flash_print_info (flash_info_t * info)
  116. {
  117. int i;
  118. if (info->flash_id == FLASH_UNKNOWN) {
  119. printf ("Missing or unknown flash type\n");
  120. return;
  121. }
  122. switch (info->flash_id & FLASH_VENDMASK) {
  123. case FLASH_MAN_AMD:
  124. printf ("AMD ");
  125. break;
  126. case FLASH_MAN_FUJ:
  127. printf ("FUJITSU ");
  128. break;
  129. case FLASH_MAN_BM:
  130. printf ("BRIGHT MICRO ");
  131. break;
  132. default:
  133. printf ("Unknown Vendor ");
  134. break;
  135. }
  136. switch (info->flash_id & FLASH_TYPEMASK) {
  137. case FLASH_AM320B:
  138. printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
  139. break;
  140. case FLASH_AM320T:
  141. printf ("AM29LV320T (32 Mbit, top boot sector)\n");
  142. break;
  143. default:
  144. printf ("Unknown Chip Type\n");
  145. break;
  146. }
  147. printf (" Size: %ld MB in %d Sectors\n", info->size >> 20,
  148. info->sector_count);
  149. printf (" Sector Start Addresses:");
  150. for (i = 0; i < info->sector_count; ++i) {
  151. if ((i % 5) == 0) {
  152. printf ("\n ");
  153. }
  154. printf (" %08lX%s",
  155. info->start[i],
  156. info->protect[i] ? " (RO)" : " ");
  157. }
  158. printf ("\n");
  159. return;
  160. }
  161. /******************************************************************************
  162. ** Function : flash_get_size
  163. ** Param : vu_long *addr, flash_info_t *info
  164. ** Notes :
  165. ******************************************************************************/
  166. static ulong flash_get_size (vu_long * addr, flash_info_t * info)
  167. {
  168. short i;
  169. FLASH_WORD_SIZE manu_id, dev_id;
  170. ulong base = (ulong) addr;
  171. volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *) addr;
  172. /* Write Auto Select Command and read Manufacturer's ID and Dev ID */
  173. addr2[ADDR0] = (FLASH_WORD_SIZE) 0xAAAAAAAA;
  174. addr2[ADDR1] = (FLASH_WORD_SIZE) 0x55555555;
  175. addr2[ADDR0] = (FLASH_WORD_SIZE) 0x90909090;
  176. manu_id = addr2[0];
  177. switch (manu_id) {
  178. case (FLASH_WORD_SIZE) AMD_MANUFACT:
  179. info->flash_id = FLASH_MAN_AMD;
  180. break;
  181. default:
  182. info->flash_id = FLASH_UNKNOWN;
  183. info->sector_count = 0;
  184. info->size = 0;
  185. break;
  186. }
  187. /* Read Device Id */
  188. dev_id = addr2[1];
  189. switch (dev_id) {
  190. case (FLASH_WORD_SIZE) AMD_ID_LV320B:
  191. info->flash_id += FLASH_AM320B;
  192. info->sector_count = 71; /* 8 - boot sec + 63 normal */
  193. info->size = 0x400000; /* 4MByte */
  194. break;
  195. default:
  196. info->flash_id = FLASH_UNKNOWN;
  197. break;
  198. }
  199. /* Set up sector start Addresses */
  200. if (info->flash_id & FLASH_BTYPE) {
  201. /* set sector offsets for bottom boot block
  202. ** Eight 8 Kb Boot sectors
  203. ** Sixty Three 64Kb sectors
  204. */
  205. for (i = 0; i < 8; i++) {
  206. info->start[i] = base + (i * 0x00002000);
  207. }
  208. for (i = 8; i < info->sector_count; i++) {
  209. info->start[i] = base + (i * 0x00010000) - 0x00070000;
  210. }
  211. }
  212. /* Reset To read mode */
  213. if (info->flash_id != FLASH_UNKNOWN) {
  214. addr = (ulong *) info->start[0];
  215. *addr = 0xF0F0F0F0;
  216. }
  217. return (info->size);
  218. }
  219. /*******************************************************************************
  220. ** Function : flash_erase
  221. ** Param : flash_info_t *info, int s_first, int s_last
  222. ** Notes :
  223. ******************************************************************************/
  224. int flash_erase (flash_info_t * info, int s_first, int s_last)
  225. {
  226. volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *) (info->start[0]);
  227. volatile FLASH_WORD_SIZE *addr2;
  228. int flag, prot, sect, l_sect;
  229. int i;
  230. if ((s_first < 0) || (s_first > s_last)) {
  231. if (info->flash_id == FLASH_UNKNOWN) {
  232. printf ("- missing\n");
  233. } else {
  234. printf ("- no sectors to erase\n");
  235. }
  236. return 1;
  237. }
  238. if (info->flash_id == FLASH_UNKNOWN) {
  239. printf ("Can't erase unknown flash type - aborted\n");
  240. return 1;
  241. }
  242. prot = 0;
  243. for (sect = s_first; sect <= s_last; ++sect) {
  244. if (info->protect[sect]) {
  245. prot++;
  246. }
  247. }
  248. if (prot) {
  249. printf ("Warning: %d protected sectors will not be erased!\n",
  250. prot);
  251. } else {
  252. printf ("\n");
  253. }
  254. l_sect = -1;
  255. /* Disable interrupts which might cause a timeout here */
  256. flag = disable_interrupts ();
  257. /* Start erase on unprotected sectors */
  258. for (sect = s_first; sect <= s_last; sect++) {
  259. if (info->protect[sect] == 0) { /* not protected */
  260. addr2 = (FLASH_WORD_SIZE *) (info->start[sect]);
  261. if ((info->flash_id & FLASH_VENDMASK) ==
  262. FLASH_MAN_SST) {
  263. addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
  264. addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
  265. addr[ADDR0] = (FLASH_WORD_SIZE) 0x00800080;
  266. addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
  267. addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
  268. addr2[0] = (FLASH_WORD_SIZE) 0x00500050; /* block erase */
  269. for (i = 0; i < 50; i++)
  270. udelay (1000); /* wait 1 ms */
  271. } else {
  272. addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
  273. addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
  274. addr[ADDR0] = (FLASH_WORD_SIZE) 0x00800080;
  275. addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
  276. addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
  277. addr2[0] = (FLASH_WORD_SIZE) 0x00300030; /* sector erase */
  278. }
  279. l_sect = sect;
  280. /*
  281. * Wait for each sector to complete, it's more
  282. * reliable. According to AMD Spec, you must
  283. * issue all erase commands within a specified
  284. * timeout. This has been seen to fail, especially
  285. * if printf()s are included (for debug)!!
  286. */
  287. wait_for_DQ7 (info, sect);
  288. }
  289. }
  290. /* re-enable interrupts if necessary */
  291. if (flag)
  292. enable_interrupts ();
  293. /* wait at least 80us - let's wait 1 ms */
  294. udelay (1000);
  295. /* reset to read mode */
  296. addr = (FLASH_WORD_SIZE *) info->start[0];
  297. addr[0] = (FLASH_WORD_SIZE) 0x00F000F0; /* reset bank */
  298. printf (" done\n");
  299. return 0;
  300. }
  301. int wait_for_DQ7 (flash_info_t * info, int sect)
  302. {
  303. ulong start, now, last;
  304. volatile FLASH_WORD_SIZE *addr =
  305. (FLASH_WORD_SIZE *) (info->start[sect]);
  306. start = get_timer (0);
  307. last = start;
  308. while ((addr[0] & (FLASH_WORD_SIZE) 0x00800080) !=
  309. (FLASH_WORD_SIZE) 0x00800080) {
  310. if ((now = get_timer (start)) > CFG_FLASH_ERASE_TOUT) {
  311. printf ("Timeout\n");
  312. return -1;
  313. }
  314. /* show that we're waiting */
  315. if ((now - last) > 1000) {
  316. putc ('.');
  317. last = now;
  318. }
  319. }
  320. return 0;
  321. }
  322. /******************************************************************************
  323. ** Function : write_buff
  324. ** Param : flash_info_t *info, uchar *src, ulong addr, ulong cnt
  325. ** Notes :
  326. ******************************************************************************/
  327. int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
  328. {
  329. ulong cp, wp, data;
  330. int i, l, rc;
  331. /* get lower word aligned address */
  332. wp = (addr & ~3);
  333. /*
  334. * handle unaligned start bytes
  335. */
  336. if ((l = addr - wp) != 0) {
  337. data = 0;
  338. for (i = 0, cp = wp; i < l; ++i, ++cp) {
  339. data = (data << 8) | (*(uchar *) cp);
  340. }
  341. for (; i < 4 && cnt > 0; ++i) {
  342. data = (data << 8) | *src++;
  343. --cnt;
  344. ++cp;
  345. }
  346. for (; cnt == 0 && i < 4; ++i, ++cp) {
  347. data = (data << 8) | (*(uchar *) cp);
  348. }
  349. if ((rc = write_word (info, wp, data)) != 0) {
  350. return (rc);
  351. }
  352. wp += 4;
  353. }
  354. /*
  355. * handle word aligned part
  356. */
  357. while (cnt >= 4) {
  358. data = 0;
  359. for (i = 0; i < 4; ++i) {
  360. data = (data << 8) | *src++;
  361. }
  362. if ((rc = write_word (info, wp, data)) != 0) {
  363. return (rc);
  364. }
  365. wp += 4;
  366. cnt -= 4;
  367. }
  368. if (cnt == 0) {
  369. return (0);
  370. }
  371. /*
  372. * handle unaligned tail bytes
  373. */
  374. data = 0;
  375. for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
  376. data = (data << 8) | *src++;
  377. --cnt;
  378. }
  379. for (; i < 4; ++i, ++cp) {
  380. data = (data << 8) | (*(uchar *) cp);
  381. }
  382. return (write_word (info, wp, data));
  383. }
  384. /******************************************************************************
  385. ** Function : write_word
  386. ** Param : flash_info_t *info, ulong dest, ulong data
  387. ** Notes :
  388. ******************************************************************************/
  389. static int write_word (flash_info_t * info, ulong dest, ulong data)
  390. {
  391. volatile FLASH_WORD_SIZE *addr2 =
  392. (FLASH_WORD_SIZE *) (info->start[0]);
  393. volatile FLASH_WORD_SIZE *dest2 = (FLASH_WORD_SIZE *) dest;
  394. volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *) & data;
  395. ulong start;
  396. int i;
  397. /* Check if Flash is (sufficiently) erased */
  398. if ((*((volatile FLASH_WORD_SIZE *) dest) &
  399. (FLASH_WORD_SIZE) data) != (FLASH_WORD_SIZE) data) {
  400. return (2);
  401. }
  402. for (i = 0; i < 4 / sizeof (FLASH_WORD_SIZE); i++) {
  403. int flag;
  404. /* Disable interrupts which might cause a timeout here */
  405. flag = disable_interrupts ();
  406. addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
  407. addr2[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
  408. addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00A000A0;
  409. dest2[i] = data2[i];
  410. /* re-enable interrupts if necessary */
  411. if (flag)
  412. enable_interrupts ();
  413. /* data polling for D7 */
  414. start = get_timer (0);
  415. while ((dest2[i] & (FLASH_WORD_SIZE) 0x00800080) !=
  416. (data2[i] & (FLASH_WORD_SIZE) 0x00800080)) {
  417. if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
  418. return (1);
  419. }
  420. }
  421. }
  422. return (0);
  423. }