flash.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. /*
  2. * flash.c
  3. * -------
  4. *
  5. * Flash programming routines for the Wind River PPMC 74xx/7xx
  6. * based on flash.c from the TQM8260 board.
  7. *
  8. * By Richard Danter (richard.danter@windriver.com)
  9. * Copyright (C) 2005 Wind River Systems
  10. */
  11. #include <common.h>
  12. #include <asm/processor.h>
  13. #include <74xx_7xx.h>
  14. #define DWORD unsigned long long
  15. /* Local function prototypes */
  16. static int write_dword (flash_info_t* info, ulong dest, unsigned char *pdata);
  17. static void write_via_fpu (volatile DWORD* addr, DWORD* data);
  18. flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
  19. /*-----------------------------------------------------------------------
  20. */
  21. void flash_reset (void)
  22. {
  23. unsigned long msr;
  24. DWORD cmd_reset = 0x00F000F000F000F0LL;
  25. if (flash_info[0].flash_id != FLASH_UNKNOWN) {
  26. msr = get_msr ();
  27. set_msr (msr | MSR_FP);
  28. write_via_fpu ((DWORD*)flash_info[0].start[0], &cmd_reset );
  29. set_msr (msr);
  30. }
  31. }
  32. /*-----------------------------------------------------------------------
  33. */
  34. ulong flash_get_size (ulong baseaddr, flash_info_t * info)
  35. {
  36. int i;
  37. unsigned long msr;
  38. DWORD flashtest;
  39. DWORD cmd_select[3] = { 0x00AA00AA00AA00AALL, 0x0055005500550055LL,
  40. 0x0090009000900090LL };
  41. /* Enable FPU */
  42. msr = get_msr ();
  43. set_msr (msr | MSR_FP);
  44. /* Write auto-select command sequence */
  45. write_via_fpu ((DWORD*)(baseaddr + (0x0555 << 3)), &cmd_select[0] );
  46. write_via_fpu ((DWORD*)(baseaddr + (0x02AA << 3)), &cmd_select[1] );
  47. write_via_fpu ((DWORD*)(baseaddr + (0x0555 << 3)), &cmd_select[2] );
  48. /* Restore FPU */
  49. set_msr (msr);
  50. /* Read manufacturer ID */
  51. flashtest = *(volatile DWORD*)baseaddr;
  52. switch ((int)flashtest) {
  53. case AMD_MANUFACT:
  54. info->flash_id = FLASH_MAN_AMD;
  55. break;
  56. case FUJ_MANUFACT:
  57. info->flash_id = FLASH_MAN_FUJ;
  58. break;
  59. default:
  60. /* No, faulty or unknown flash */
  61. info->flash_id = FLASH_UNKNOWN;
  62. info->sector_count = 0;
  63. info->size = 0;
  64. return (0);
  65. }
  66. /* Read device ID */
  67. flashtest = *(volatile DWORD*)(baseaddr + 8);
  68. switch ((long)flashtest) {
  69. case AMD_ID_LV800T:
  70. info->flash_id += FLASH_AM800T;
  71. info->sector_count = 19;
  72. info->size = 0x00400000;
  73. break;
  74. case AMD_ID_LV800B:
  75. info->flash_id += FLASH_AM800B;
  76. info->sector_count = 19;
  77. info->size = 0x00400000;
  78. break;
  79. case AMD_ID_LV160T:
  80. info->flash_id += FLASH_AM160T;
  81. info->sector_count = 35;
  82. info->size = 0x00800000;
  83. break;
  84. case AMD_ID_LV160B:
  85. info->flash_id += FLASH_AM160B;
  86. info->sector_count = 35;
  87. info->size = 0x00800000;
  88. break;
  89. case AMD_ID_DL322T:
  90. info->flash_id += FLASH_AMDL322T;
  91. info->sector_count = 71;
  92. info->size = 0x01000000;
  93. break;
  94. case AMD_ID_DL322B:
  95. info->flash_id += FLASH_AMDL322B;
  96. info->sector_count = 71;
  97. info->size = 0x01000000;
  98. break;
  99. case AMD_ID_DL323T:
  100. info->flash_id += FLASH_AMDL323T;
  101. info->sector_count = 71;
  102. info->size = 0x01000000;
  103. break;
  104. case AMD_ID_DL323B:
  105. info->flash_id += FLASH_AMDL323B;
  106. info->sector_count = 71;
  107. info->size = 0x01000000;
  108. break;
  109. case AMD_ID_LV640U:
  110. info->flash_id += FLASH_AM640U;
  111. info->sector_count = 128;
  112. info->size = 0x02000000;
  113. break;
  114. default:
  115. /* Unknown flash type */
  116. info->flash_id = FLASH_UNKNOWN;
  117. return (0);
  118. }
  119. if ((long)flashtest == AMD_ID_LV640U) {
  120. /* set up sector start adress table (uniform sector type) */
  121. for (i = 0; i < info->sector_count; i++)
  122. info->start[i] = baseaddr + (i * 0x00040000);
  123. } else if (info->flash_id & FLASH_BTYPE) {
  124. /* set up sector start adress table (bottom sector type) */
  125. info->start[0] = baseaddr + 0x00000000;
  126. info->start[1] = baseaddr + 0x00010000;
  127. info->start[2] = baseaddr + 0x00018000;
  128. info->start[3] = baseaddr + 0x00020000;
  129. for (i = 4; i < info->sector_count; i++) {
  130. info->start[i] = baseaddr + (i * 0x00040000) - 0x000C0000;
  131. }
  132. } else {
  133. /* set up sector start adress table (top sector type) */
  134. i = info->sector_count - 1;
  135. info->start[i--] = baseaddr + info->size - 0x00010000;
  136. info->start[i--] = baseaddr + info->size - 0x00018000;
  137. info->start[i--] = baseaddr + info->size - 0x00020000;
  138. for (; i >= 0; i--) {
  139. info->start[i] = baseaddr + i * 0x00040000;
  140. }
  141. }
  142. /* check for protected sectors */
  143. for (i = 0; i < info->sector_count; i++) {
  144. /* read sector protection at sector address, (A7 .. A0) = 0x02 */
  145. if (*(volatile DWORD*)(info->start[i] + 16) & 0x0001000100010001LL) {
  146. info->protect[i] = 1; /* D0 = 1 if protected */
  147. } else {
  148. info->protect[i] = 0;
  149. }
  150. }
  151. flash_reset ();
  152. return (info->size);
  153. }
  154. /*-----------------------------------------------------------------------
  155. */
  156. unsigned long flash_init (void)
  157. {
  158. unsigned long size_b0 = 0;
  159. int i;
  160. /* Init: no FLASHes known */
  161. for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
  162. flash_info[i].flash_id = FLASH_UNKNOWN;
  163. }
  164. /* Static FLASH Bank configuration here (only one bank) */
  165. size_b0 = flash_get_size (CFG_FLASH_BASE, &flash_info[0]);
  166. if (flash_info[0].flash_id == FLASH_UNKNOWN || size_b0 == 0) {
  167. printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
  168. size_b0, size_b0 >> 20);
  169. }
  170. /*
  171. * protect monitor and environment sectors
  172. */
  173. #if CFG_MONITOR_BASE >= CFG_FLASH_BASE
  174. flash_protect (FLAG_PROTECT_SET,
  175. CFG_MONITOR_BASE,
  176. CFG_MONITOR_BASE + monitor_flash_len - 1, &flash_info[0]);
  177. #endif
  178. #if defined(CONFIG_ENV_IS_IN_FLASH) && defined(CFG_ENV_ADDR)
  179. # ifndef CFG_ENV_SIZE
  180. # define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
  181. # endif
  182. flash_protect (FLAG_PROTECT_SET,
  183. CFG_ENV_ADDR,
  184. CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
  185. #endif
  186. return (size_b0);
  187. }
  188. /*-----------------------------------------------------------------------
  189. */
  190. void flash_print_info (flash_info_t * info)
  191. {
  192. int i;
  193. if (info->flash_id == FLASH_UNKNOWN) {
  194. printf ("missing or unknown FLASH type\n");
  195. return;
  196. }
  197. switch (info->flash_id & FLASH_VENDMASK) {
  198. case FLASH_MAN_AMD:
  199. printf ("AMD ");
  200. break;
  201. case FLASH_MAN_FUJ:
  202. printf ("FUJITSU ");
  203. break;
  204. default:
  205. printf ("Unknown Vendor ");
  206. break;
  207. }
  208. switch (info->flash_id & FLASH_TYPEMASK) {
  209. case FLASH_AM800T:
  210. printf ("29LV800T (8 M, top sector)\n");
  211. break;
  212. case FLASH_AM800B:
  213. printf ("29LV800T (8 M, bottom sector)\n");
  214. break;
  215. case FLASH_AM160T:
  216. printf ("29LV160T (16 M, top sector)\n");
  217. break;
  218. case FLASH_AM160B:
  219. printf ("29LV160B (16 M, bottom sector)\n");
  220. break;
  221. case FLASH_AMDL322T:
  222. printf ("29DL322T (32 M, top sector)\n");
  223. break;
  224. case FLASH_AMDL322B:
  225. printf ("29DL322B (32 M, bottom sector)\n");
  226. break;
  227. case FLASH_AMDL323T:
  228. printf ("29DL323T (32 M, top sector)\n");
  229. break;
  230. case FLASH_AMDL323B:
  231. printf ("29DL323B (32 M, bottom sector)\n");
  232. break;
  233. case FLASH_AM640U:
  234. printf ("29LV640D (64 M, uniform sector)\n");
  235. break;
  236. default:
  237. printf ("Unknown Chip Type\n");
  238. break;
  239. }
  240. printf (" Size: %ld MB in %d Sectors\n",
  241. info->size >> 20, info->sector_count);
  242. printf (" Sector Start Addresses:");
  243. for (i = 0; i < info->sector_count; ++i) {
  244. if ((i % 5) == 0)
  245. printf ("\n ");
  246. printf (" %08lX%s",
  247. info->start[i],
  248. info->protect[i] ? " (RO)" : " "
  249. );
  250. }
  251. printf ("\n");
  252. return;
  253. }
  254. /*-----------------------------------------------------------------------
  255. */
  256. int flash_erase (flash_info_t * info, int s_first, int s_last)
  257. {
  258. int flag, prot, sect, l_sect;
  259. ulong start, now, last;
  260. unsigned long msr;
  261. DWORD cmd_erase[6] = { 0x00AA00AA00AA00AALL, 0x0055005500550055LL,
  262. 0x0080008000800080LL, 0x00AA00AA00AA00AALL,
  263. 0x0055005500550055LL, 0x0030003000300030LL };
  264. if ((s_first < 0) || (s_first > s_last)) {
  265. if (info->flash_id == FLASH_UNKNOWN) {
  266. printf ("- missing\n");
  267. } else {
  268. printf ("- no sectors to erase\n");
  269. }
  270. return 1;
  271. }
  272. prot = 0;
  273. for (sect = s_first; sect <= s_last; sect++) {
  274. if (info->protect[sect])
  275. prot++;
  276. }
  277. if (prot) {
  278. printf ("- Warning: %d protected sectors will not be erased!\n",
  279. prot);
  280. } else {
  281. printf ("\n");
  282. }
  283. l_sect = -1;
  284. /* Enable FPU */
  285. msr = get_msr();
  286. set_msr ( msr | MSR_FP );
  287. /* Disable interrupts which might cause a timeout here */
  288. flag = disable_interrupts ();
  289. write_via_fpu ((DWORD*)(info->start[0] + (0x0555 << 3)), &cmd_erase[0] );
  290. write_via_fpu ((DWORD*)(info->start[0] + (0x02AA << 3)), &cmd_erase[1] );
  291. write_via_fpu ((DWORD*)(info->start[0] + (0x0555 << 3)), &cmd_erase[2] );
  292. write_via_fpu ((DWORD*)(info->start[0] + (0x0555 << 3)), &cmd_erase[3] );
  293. write_via_fpu ((DWORD*)(info->start[0] + (0x02AA << 3)), &cmd_erase[4] );
  294. udelay (1000);
  295. /* Start erase on unprotected sectors */
  296. for (sect = s_first; sect <= s_last; sect++) {
  297. if (info->protect[sect] == 0) { /* not protected */
  298. write_via_fpu ((DWORD*)info->start[sect], &cmd_erase[5] );
  299. l_sect = sect;
  300. }
  301. }
  302. /* re-enable interrupts if necessary */
  303. if (flag)
  304. enable_interrupts ();
  305. /* Restore FPU */
  306. set_msr (msr);
  307. /* wait at least 80us - let's wait 1 ms */
  308. udelay (1000);
  309. /*
  310. * We wait for the last triggered sector
  311. */
  312. if (l_sect < 0)
  313. goto DONE;
  314. start = get_timer (0);
  315. last = start;
  316. while ((*(volatile DWORD*)info->start[l_sect] & 0x0080008000800080LL )
  317. != 0x0080008000800080LL )
  318. {
  319. if ((now = get_timer (start)) > CFG_FLASH_ERASE_TOUT) {
  320. printf ("Timeout\n");
  321. return 1;
  322. }
  323. /* show that we're waiting */
  324. if ((now - last) > 1000) { /* every second */
  325. serial_putc ('.');
  326. last = now;
  327. }
  328. }
  329. DONE:
  330. /* reset to read mode */
  331. flash_reset ();
  332. printf (" done\n");
  333. return 0;
  334. }
  335. /*-----------------------------------------------------------------------
  336. * Copy memory to flash, returns:
  337. * 0 - OK
  338. * 1 - write timeout
  339. * 2 - Flash not erased
  340. */
  341. int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
  342. {
  343. ulong dp;
  344. static unsigned char bb[8];
  345. int i, l, rc, cc = cnt;
  346. dp = (addr & ~7); /* get lower dword aligned address */
  347. /*
  348. * handle unaligned start bytes
  349. */
  350. if ((l = addr - dp) != 0) {
  351. for (i = 0; i < 8; i++)
  352. bb[i] = (i < l || (i - l) >= cc) ? *(char*)(dp + i) : *src++;
  353. if ((rc = write_dword (info, dp, bb)) != 0) {
  354. return (rc);
  355. }
  356. dp += 8;
  357. cc -= 8 - l;
  358. }
  359. /*
  360. * handle word aligned part
  361. */
  362. while (cc >= 8) {
  363. if ((rc = write_dword (info, dp, src)) != 0) {
  364. return (rc);
  365. }
  366. dp += 8;
  367. src += 8;
  368. cc -= 8;
  369. }
  370. if (cc <= 0) {
  371. return (0);
  372. }
  373. /*
  374. * handle unaligned tail bytes
  375. */
  376. for (i = 0; i < 8; i++) {
  377. bb[i] = (i < cc) ? *src++ : *(char*)(dp + i);
  378. }
  379. return (write_dword (info, dp, bb));
  380. }
  381. /*-----------------------------------------------------------------------
  382. * Write a dword to Flash, returns:
  383. * 0 - OK
  384. * 1 - write timeout
  385. * 2 - Flash not erased
  386. */
  387. static int write_dword (flash_info_t * info, ulong dest, unsigned char *pdata)
  388. {
  389. ulong start;
  390. unsigned long msr;
  391. int flag, i;
  392. DWORD data;
  393. DWORD cmd_write[3] = { 0x00AA00AA00AA00AALL, 0x0055005500550055LL,
  394. 0x00A000A000A000A0LL };
  395. for (data = 0, i = 0; i < 8; i++)
  396. data = (data << 8) + *pdata++;
  397. /* Check if Flash is (sufficiently) erased */
  398. if ((*(DWORD*)dest & data) != data) {
  399. return (2);
  400. }
  401. /* Enable FPU */
  402. msr = get_msr();
  403. set_msr( msr | MSR_FP );
  404. /* Disable interrupts which might cause a timeout here */
  405. flag = disable_interrupts ();
  406. write_via_fpu ((DWORD*)(info->start[0] + (0x0555 << 3)), &cmd_write[0] );
  407. write_via_fpu ((DWORD*)(info->start[0] + (0x02AA << 3)), &cmd_write[1] );
  408. write_via_fpu ((DWORD*)(info->start[0] + (0x0555 << 3)), &cmd_write[2] );
  409. write_via_fpu ((DWORD*)dest, &data );
  410. /* re-enable interrupts if necessary */
  411. if (flag)
  412. enable_interrupts ();
  413. /* Restore FPU */
  414. set_msr(msr);
  415. /* data polling for D7 */
  416. start = get_timer (0);
  417. while (*(volatile DWORD*)dest != data ) {
  418. if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
  419. return (1);
  420. }
  421. }
  422. return (0);
  423. }
  424. /*-----------------------------------------------------------------------
  425. */
  426. static void write_via_fpu (volatile DWORD* addr, DWORD* data)
  427. {
  428. __asm__ __volatile__ ("lfd 1, 0(%0)"::"r" (data));
  429. __asm__ __volatile__ ("stfd 1, 0(%0)"::"r" (addr));
  430. __asm__ __volatile__ ("eieio");
  431. }