flash.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
  1. /*
  2. * (C) Copyright 2001
  3. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  4. *
  5. * (C) Copyright 2002
  6. * Gregory E. Allen, gallen@arlut.utexas.edu
  7. * Matthew E. Karger, karger@arlut.utexas.edu
  8. * Applied Research Laboratories, The University of Texas at Austin
  9. *
  10. * See file CREDITS for list of people who contributed to this
  11. * project.
  12. *
  13. * This program is free software; you can redistribute it and/or
  14. * modify it under the terms of the GNU General Public License as
  15. * published by the Free Software Foundation; either version 2 of
  16. * the License, or (at your option) any later version.
  17. *
  18. * This program is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU General Public License
  24. * along with this program; if not, write to the Free Software
  25. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  26. * MA 02111-1307 USA
  27. */
  28. #include <common.h>
  29. #include <mpc824x.h>
  30. #include <asm/processor.h>
  31. #define ROM_CS0_START 0xFF800000
  32. #define ROM_CS1_START 0xFF000000
  33. #if defined(CONFIG_ENV_IS_IN_FLASH)
  34. # ifndef CONFIG_ENV_ADDR
  35. # define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + CONFIG_ENV_OFFSET)
  36. # endif
  37. # ifndef CONFIG_ENV_SIZE
  38. # define CONFIG_ENV_SIZE CONFIG_ENV_SECT_SIZE
  39. # endif
  40. # ifndef CONFIG_ENV_SECT_SIZE
  41. # define CONFIG_ENV_SECT_SIZE CONFIG_ENV_SIZE
  42. # endif
  43. #endif
  44. #define FLASH_BANK_SIZE ((uint)(16 * 1024 * 1024)) /* max 16Mbyte */
  45. #define MAIN_SECT_SIZE 0x10000
  46. #define SECT_SIZE_32KB 0x8000
  47. #define SECT_SIZE_8KB 0x2000
  48. flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
  49. static int write_word (flash_info_t * info, ulong dest, ulong data);
  50. #if 0
  51. static void write_via_fpu (vu_long * addr, ulong * data);
  52. #endif
  53. static __inline__ unsigned long get_msr (void);
  54. static __inline__ void set_msr (unsigned long msr);
  55. /*flash command address offsets*/
  56. #define ADDR0 (0x555)
  57. #define ADDR1 (0xAAA)
  58. #define ADDR3 (0x001)
  59. #define FLASH_WORD_SIZE unsigned char
  60. /*---------------------------------------------------------------------*/
  61. /*#define DEBUG_FLASH 1 */
  62. /*---------------------------------------------------------------------*/
  63. unsigned long flash_init (void)
  64. {
  65. int i; /* flash bank counter */
  66. int j; /* flash device sector counter */
  67. int k; /* flash size calculation loop counter */
  68. int N; /* pow(2,N) is flash size, but we don't have <math.h> */
  69. ulong total_size = 0, device_size = 1;
  70. unsigned char manuf_id, device_id;
  71. for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
  72. vu_char *addr = (vu_char *) (CONFIG_SYS_FLASH_BASE + i * FLASH_BANK_SIZE);
  73. addr[0x555] = 0xAA; /* get manuf/device info command */
  74. addr[0x2AA] = 0x55; /* 3-cycle command */
  75. addr[0x555] = 0x90;
  76. manuf_id = addr[0]; /* read back manuf/device info */
  77. device_id = addr[1];
  78. addr[0x55] = 0x98; /* CFI command */
  79. N = addr[0x27]; /* read back device_size = pow(2,N) */
  80. for (k = 0; k < N; k++) /* calculate device_size = pow(2,N) */
  81. device_size *= 2;
  82. flash_info[i].size = device_size;
  83. flash_info[i].sector_count = CONFIG_SYS_MAX_FLASH_SECT;
  84. #if defined DEBUG_FLASH
  85. printf ("manuf_id = %x, device_id = %x\n", manuf_id, device_id);
  86. #endif
  87. /* find out what kind of flash we are using */
  88. if ((manuf_id == (uchar) (AMD_MANUFACT))
  89. && (device_id == AMD_ID_LV033C)) {
  90. flash_info[i].flash_id =
  91. ((FLASH_MAN_AMD & FLASH_VENDMASK) << 16) |
  92. (FLASH_AM033C & FLASH_TYPEMASK);
  93. /* set individual sector start addresses */
  94. for (j = 0; j < flash_info[i].sector_count; j++) {
  95. flash_info[i].start[j] =
  96. (CONFIG_SYS_FLASH_BASE + i * FLASH_BANK_SIZE +
  97. j * MAIN_SECT_SIZE);
  98. }
  99. }
  100. else if ((manuf_id == (uchar) (AMD_MANUFACT)) &&
  101. (device_id == AMD_ID_LV116DT)) {
  102. flash_info[i].flash_id =
  103. ((FLASH_MAN_AMD & FLASH_VENDMASK) << 16) |
  104. (FLASH_AM160T & FLASH_TYPEMASK);
  105. /* set individual sector start addresses */
  106. for (j = 0; j < flash_info[i].sector_count; j++) {
  107. flash_info[i].start[j] =
  108. (CONFIG_SYS_FLASH_BASE + i * FLASH_BANK_SIZE +
  109. j * MAIN_SECT_SIZE);
  110. if (j < (CONFIG_SYS_MAX_FLASH_SECT - 3)) {
  111. flash_info[i].start[j] =
  112. (CONFIG_SYS_FLASH_BASE + i * FLASH_BANK_SIZE +
  113. j * MAIN_SECT_SIZE);
  114. } else if (j == (CONFIG_SYS_MAX_FLASH_SECT - 3)) {
  115. flash_info[i].start[j] =
  116. (flash_info[i].start[j - 1] + SECT_SIZE_32KB);
  117. } else {
  118. flash_info[i].start[j] =
  119. (flash_info[i].start[j - 1] + SECT_SIZE_8KB);
  120. }
  121. }
  122. }
  123. else {
  124. flash_info[i].flash_id = FLASH_UNKNOWN;
  125. addr[0] = 0xFF;
  126. goto Done;
  127. }
  128. #if defined DEBUG_FLASH
  129. printf ("flash_id = 0x%08lX\n", flash_info[i].flash_id);
  130. #endif
  131. addr[0] = 0xFF;
  132. memset (flash_info[i].protect, 0, CONFIG_SYS_MAX_FLASH_SECT);
  133. total_size += flash_info[i].size;
  134. }
  135. /* Protect monitor and environment sectors
  136. */
  137. #if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
  138. flash_protect (FLAG_PROTECT_SET, CONFIG_SYS_MONITOR_BASE,
  139. CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1,
  140. &flash_info[0]);
  141. #endif
  142. #if defined(CONFIG_ENV_IS_IN_FLASH) && defined(CONFIG_ENV_ADDR)
  143. flash_protect (FLAG_PROTECT_SET, CONFIG_ENV_ADDR,
  144. CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, &flash_info[0]);
  145. #endif
  146. Done:
  147. return total_size;
  148. }
  149. /*-----------------------------------------------------------------------
  150. */
  151. void flash_print_info (flash_info_t * info)
  152. {
  153. static const char unk[] = "Unknown";
  154. const char *mfct = unk, *type = unk;
  155. unsigned int i;
  156. if (info->flash_id != FLASH_UNKNOWN) {
  157. switch (info->flash_id & FLASH_VENDMASK) {
  158. case FLASH_MAN_AMD:
  159. mfct = "AMD";
  160. break;
  161. case FLASH_MAN_FUJ:
  162. mfct = "FUJITSU";
  163. break;
  164. case FLASH_MAN_STM:
  165. mfct = "STM";
  166. break;
  167. case FLASH_MAN_SST:
  168. mfct = "SST";
  169. break;
  170. case FLASH_MAN_BM:
  171. mfct = "Bright Microelectonics";
  172. break;
  173. case FLASH_MAN_INTEL:
  174. mfct = "Intel";
  175. break;
  176. }
  177. switch (info->flash_id & FLASH_TYPEMASK) {
  178. case FLASH_AM033C:
  179. type = "AM29LV033C (32 Mbit, uniform sector size)";
  180. break;
  181. case FLASH_AM160T:
  182. type = "AM29LV160T (16 Mbit, top boot sector)";
  183. break;
  184. case FLASH_AM040:
  185. type = "AM29F040B (512K * 8, uniform sector size)";
  186. break;
  187. case FLASH_AM400B:
  188. type = "AM29LV400B (4 Mbit, bottom boot sect)";
  189. break;
  190. case FLASH_AM400T:
  191. type = "AM29LV400T (4 Mbit, top boot sector)";
  192. break;
  193. case FLASH_AM800B:
  194. type = "AM29LV800B (8 Mbit, bottom boot sect)";
  195. break;
  196. case FLASH_AM800T:
  197. type = "AM29LV800T (8 Mbit, top boot sector)";
  198. break;
  199. case FLASH_AM320B:
  200. type = "AM29LV320B (32 Mbit, bottom boot sect)";
  201. break;
  202. case FLASH_AM320T:
  203. type = "AM29LV320T (32 Mbit, top boot sector)";
  204. break;
  205. case FLASH_STM800AB:
  206. type = "M29W800AB (8 Mbit, bottom boot sect)";
  207. break;
  208. case FLASH_SST800A:
  209. type = "SST39LF/VF800 (8 Mbit, uniform sector size)";
  210. break;
  211. case FLASH_SST160A:
  212. type = "SST39LF/VF160 (16 Mbit, uniform sector size)";
  213. break;
  214. }
  215. }
  216. printf ("\n Brand: %s Type: %s\n"
  217. " Size: %lu KB in %d Sectors\n",
  218. mfct, type, info->size >> 10, info->sector_count);
  219. printf (" Sector Start Addresses:");
  220. for (i = 0; i < info->sector_count; i++) {
  221. unsigned long size;
  222. unsigned int erased;
  223. unsigned long *flash = (unsigned long *) info->start[i];
  224. /*
  225. * Check if whole sector is erased
  226. */
  227. size = (i != (info->sector_count - 1)) ?
  228. (info->start[i + 1] - info->start[i]) >> 2 :
  229. (info->start[0] + info->size - info->start[i]) >> 2;
  230. for (flash = (unsigned long *) info->start[i], erased = 1;
  231. (flash != (unsigned long *) info->start[i] + size) && erased;
  232. flash++)
  233. erased = *flash == ~0x0UL;
  234. printf ("%s %08lX %s %s",
  235. (i % 5) ? "" : "\n ",
  236. info->start[i],
  237. erased ? "E" : " ", info->protect[i] ? "RO" : " ");
  238. }
  239. puts ("\n");
  240. return;
  241. }
  242. /*-----------------------------------------------------------------------
  243. */
  244. int flash_erase (flash_info_t * info, int s_first, int s_last)
  245. {
  246. volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *) (info->start[0]);
  247. int flag, prot, sect, l_sect;
  248. ulong start, now, last;
  249. unsigned char sh8b;
  250. if ((s_first < 0) || (s_first > s_last)) {
  251. if (info->flash_id == FLASH_UNKNOWN) {
  252. printf ("- missing\n");
  253. } else {
  254. printf ("- no sectors to erase\n");
  255. }
  256. return 1;
  257. }
  258. if ((info->flash_id == FLASH_UNKNOWN) ||
  259. (info->flash_id > (FLASH_MAN_STM | FLASH_AMD_COMP))) {
  260. printf ("Can't erase unknown flash type - aborted\n");
  261. return 1;
  262. }
  263. prot = 0;
  264. for (sect = s_first; sect <= s_last; ++sect) {
  265. if (info->protect[sect]) {
  266. prot++;
  267. }
  268. }
  269. if (prot) {
  270. printf ("- Warning: %d protected sectors will not be erased!\n",
  271. prot);
  272. } else {
  273. printf ("\n");
  274. }
  275. l_sect = -1;
  276. /* Check the ROM CS */
  277. if ((info->start[0] >= ROM_CS1_START)
  278. && (info->start[0] < ROM_CS0_START))
  279. sh8b = 3;
  280. else
  281. sh8b = 0;
  282. /* Disable interrupts which might cause a timeout here */
  283. flag = disable_interrupts ();
  284. addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE) 0x00AA00AA;
  285. addr[ADDR1 << sh8b] = (FLASH_WORD_SIZE) 0x00550055;
  286. addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE) 0x00800080;
  287. addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE) 0x00AA00AA;
  288. addr[ADDR1 << sh8b] = (FLASH_WORD_SIZE) 0x00550055;
  289. /* Start erase on unprotected sectors */
  290. for (sect = s_first; sect <= s_last; sect++) {
  291. if (info->protect[sect] == 0) { /* not protected */
  292. addr = (FLASH_WORD_SIZE *) (info->start[0] + ((info->
  293. start[sect] -
  294. info->
  295. start[0]) <<
  296. sh8b));
  297. if (info->flash_id & FLASH_MAN_SST) {
  298. addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE) 0x00AA00AA;
  299. addr[ADDR1 << sh8b] = (FLASH_WORD_SIZE) 0x00550055;
  300. addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE) 0x00800080;
  301. addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE) 0x00AA00AA;
  302. addr[ADDR1 << sh8b] = (FLASH_WORD_SIZE) 0x00550055;
  303. addr[0] = (FLASH_WORD_SIZE) 0x00500050; /* block erase */
  304. udelay (30000); /* wait 30 ms */
  305. } else {
  306. addr[0] = (FLASH_WORD_SIZE) 0x00300030; /* sector erase */
  307. }
  308. l_sect = sect;
  309. }
  310. }
  311. /* re-enable interrupts if necessary */
  312. if (flag)
  313. enable_interrupts ();
  314. /* wait at least 80us - let's wait 1 ms */
  315. udelay (1000);
  316. /*
  317. * We wait for the last triggered sector
  318. */
  319. if (l_sect < 0)
  320. goto DONE;
  321. start = get_timer (0);
  322. last = start;
  323. addr = (FLASH_WORD_SIZE *) (info->start[0] + ((info->start[l_sect] -
  324. info->
  325. start[0]) << sh8b));
  326. while ((addr[0] & (FLASH_WORD_SIZE) 0x00800080) !=
  327. (FLASH_WORD_SIZE) 0x00800080) {
  328. if ((now = get_timer (start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
  329. printf ("Timeout\n");
  330. return 1;
  331. }
  332. /* show that we're waiting */
  333. if ((now - last) > 1000) { /* every second */
  334. serial_putc ('.');
  335. last = now;
  336. }
  337. }
  338. DONE:
  339. /* reset to read mode */
  340. addr = (FLASH_WORD_SIZE *) info->start[0];
  341. addr[0] = (FLASH_WORD_SIZE) 0x00F000F0; /* reset bank */
  342. printf (" done\n");
  343. return 0;
  344. }
  345. /*-----------------------------------------------------------------------
  346. * Copy memory to flash, returns:
  347. * 0 - OK
  348. * 1 - write timeout
  349. * 2 - Flash not erased
  350. */
  351. int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
  352. {
  353. ulong cp, wp, data;
  354. int i, l, rc;
  355. wp = (addr & ~3); /* get lower word aligned address */
  356. /*
  357. * handle unaligned start bytes
  358. */
  359. if ((l = addr - wp) != 0) {
  360. data = 0;
  361. for (i = 0, cp = wp; i < l; ++i, ++cp) {
  362. data = (data << 8) | (*(uchar *) cp);
  363. }
  364. for (; i < 4 && cnt > 0; ++i) {
  365. data = (data << 8) | *src++;
  366. --cnt;
  367. ++cp;
  368. }
  369. for (; cnt == 0 && i < 4; ++i, ++cp) {
  370. data = (data << 8) | (*(uchar *) cp);
  371. }
  372. if ((rc = write_word (info, wp, data)) != 0) {
  373. return (rc);
  374. }
  375. wp += 4;
  376. }
  377. /*
  378. * handle word aligned part
  379. */
  380. while (cnt >= 4) {
  381. data = 0;
  382. for (i = 0; i < 4; ++i) {
  383. data = (data << 8) | *src++;
  384. }
  385. if ((rc = write_word (info, wp, data)) != 0) {
  386. return (rc);
  387. }
  388. wp += 4;
  389. cnt -= 4;
  390. }
  391. if (cnt == 0) {
  392. return (0);
  393. }
  394. /*
  395. * handle unaligned tail bytes
  396. */
  397. data = 0;
  398. for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
  399. data = (data << 8) | *src++;
  400. --cnt;
  401. }
  402. for (; i < 4; ++i, ++cp) {
  403. data = (data << 8) | (*(uchar *) cp);
  404. }
  405. return (write_word (info, wp, data));
  406. }
  407. /*-----------------------------------------------------------------------
  408. * Write a word to Flash, returns:
  409. * 0 - OK
  410. * 1 - write timeout
  411. * 2 - Flash not erased
  412. */
  413. static int write_word (flash_info_t * info, ulong dest, ulong data)
  414. {
  415. volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *) info->start[0];
  416. volatile FLASH_WORD_SIZE *dest2;
  417. volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *) & data;
  418. ulong start;
  419. int flag;
  420. int i;
  421. unsigned char sh8b;
  422. /* Check the ROM CS */
  423. if ((info->start[0] >= ROM_CS1_START)
  424. && (info->start[0] < ROM_CS0_START))
  425. sh8b = 3;
  426. else
  427. sh8b = 0;
  428. dest2 = (FLASH_WORD_SIZE *) (((dest - info->start[0]) << sh8b) +
  429. info->start[0]);
  430. /* Check if Flash is (sufficiently) erased */
  431. if ((*dest2 & (FLASH_WORD_SIZE) data) != (FLASH_WORD_SIZE) data) {
  432. return (2);
  433. }
  434. /* Disable interrupts which might cause a timeout here */
  435. flag = disable_interrupts ();
  436. for (i = 0; i < 4 / sizeof (FLASH_WORD_SIZE); i++) {
  437. addr2[ADDR0 << sh8b] = (FLASH_WORD_SIZE) 0x00AA00AA;
  438. addr2[ADDR1 << sh8b] = (FLASH_WORD_SIZE) 0x00550055;
  439. addr2[ADDR0 << sh8b] = (FLASH_WORD_SIZE) 0x00A000A0;
  440. dest2[i << sh8b] = data2[i];
  441. /* re-enable interrupts if necessary */
  442. if (flag)
  443. enable_interrupts ();
  444. /* data polling for D7 */
  445. start = get_timer (0);
  446. while ((dest2[i << sh8b] & (FLASH_WORD_SIZE) 0x00800080) !=
  447. (data2[i] & (FLASH_WORD_SIZE) 0x00800080)) {
  448. if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
  449. return (1);
  450. }
  451. }
  452. }
  453. return (0);
  454. }
  455. /*-----------------------------------------------------------------------
  456. */
  457. #if 0
  458. static void write_via_fpu (vu_long * addr, ulong * data)
  459. {
  460. __asm__ __volatile__ ("lfd 1, 0(%0)"::"r" (data));
  461. __asm__ __volatile__ ("stfd 1, 0(%0)"::"r" (addr));
  462. }
  463. #endif
  464. /*-----------------------------------------------------------------------
  465. */
  466. static __inline__ unsigned long get_msr (void)
  467. {
  468. unsigned long msr;
  469. __asm__ __volatile__ ("mfmsr %0":"=r" (msr):);
  470. return msr;
  471. }
  472. static __inline__ void set_msr (unsigned long msr)
  473. {
  474. __asm__ __volatile__ ("mtmsr %0"::"r" (msr));
  475. }