flash.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506
  1. /*
  2. * (C) Copyright 2000
  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. * Hacked for the Hymod board by Murray.Jensen@csiro.au, 20-Oct-00
  24. */
  25. #include <common.h>
  26. #include <mpc8260.h>
  27. #include <board/hymod/flash.h>
  28. flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
  29. /*-----------------------------------------------------------------------
  30. * Protection Flags:
  31. */
  32. #define FLAG_PROTECT_SET 0x01
  33. #define FLAG_PROTECT_CLEAR 0x02
  34. /*-----------------------------------------------------------------------
  35. */
  36. /*
  37. * probe for flash bank at address "base" and store info about it
  38. * in the flash_info entry "fip". Fatal error if nothing there.
  39. */
  40. static void
  41. bank_probe (flash_info_t *fip, bank_addr_t base)
  42. {
  43. bank_addr_t addr;
  44. bank_word_t word;
  45. int i;
  46. /* reset the flash */
  47. *base = BANK_CMD_RST;
  48. /* check the manufacturer id - must be intel */
  49. *base = BANK_CMD_RD_ID;
  50. word = *BANK_REG_MAN_CODE (base);
  51. *base = BANK_CMD_RST;
  52. if (word != BANK_FILL_WORD (INTEL_MANUFACT&0xff))
  53. panic ("\nbad manufacturer's code (0x%08lx) at addr 0x%08lx",
  54. (unsigned long)word, (unsigned long)base);
  55. /* check the device id */
  56. *base = BANK_CMD_RD_ID;
  57. word = *BANK_REG_DEV_CODE (base);
  58. *base = BANK_CMD_RST;
  59. switch (word) {
  60. case BANK_FILL_WORD (INTEL_ID_28F320J5&0xff):
  61. fip->flash_id = FLASH_MAN_INTEL | FLASH_28F320J5;
  62. fip->sector_count = 32;
  63. break;
  64. case BANK_FILL_WORD (INTEL_ID_28F640J5&0xff):
  65. fip->flash_id = FLASH_MAN_INTEL | FLASH_28F640J5;
  66. fip->sector_count = 64;
  67. break;
  68. case BANK_FILL_WORD (INTEL_ID_28F320J3A&0xff):
  69. fip->flash_id = FLASH_MAN_INTEL | FLASH_28F320J3A;
  70. fip->sector_count = 32;
  71. break;
  72. case BANK_FILL_WORD (INTEL_ID_28F640J3A&0xff):
  73. fip->flash_id = FLASH_MAN_INTEL | FLASH_28F640J3A;
  74. fip->sector_count = 64;
  75. break;
  76. case BANK_FILL_WORD (INTEL_ID_28F128J3A&0xff):
  77. fip->flash_id = FLASH_MAN_INTEL | FLASH_28F128J3A;
  78. fip->sector_count = 128;
  79. break;
  80. default:
  81. panic ("\nbad device code (0x%08lx) at addr 0x%08lx",
  82. (unsigned long)word, (unsigned long)base);
  83. }
  84. if (fip->sector_count >= CFG_MAX_FLASH_SECT)
  85. panic ("\ntoo many sectors (%d) in flash at address 0x%08lx",
  86. fip->sector_count, (unsigned long)base);
  87. addr = base;
  88. for (i = 0; i < fip->sector_count; i++) {
  89. fip->start[i] = (unsigned long)addr;
  90. fip->protect[i] = 0;
  91. addr = BANK_ADDR_NEXT_BLK (addr);
  92. }
  93. fip->size = (bank_size_t)addr - (bank_size_t)base;
  94. }
  95. static void
  96. bank_reset (flash_info_t *info, int sect)
  97. {
  98. bank_addr_t addr = (bank_addr_t)info->start[sect];
  99. #ifdef FLASH_DEBUG
  100. printf ("writing reset cmd to addr 0x%08lx\n", (unsigned long)addr);
  101. #endif
  102. *addr = BANK_CMD_RST;
  103. }
  104. static void
  105. bank_erase_init (flash_info_t *info, int sect)
  106. {
  107. bank_addr_t addr = (bank_addr_t)info->start[sect];
  108. int flag;
  109. #ifdef FLASH_DEBUG
  110. printf ("erasing sector %d, addr = 0x%08lx\n",
  111. sect, (unsigned long)addr);
  112. #endif
  113. /* Disable intrs which might cause a timeout here */
  114. flag = disable_interrupts ();
  115. #ifdef FLASH_DEBUG
  116. printf ("writing erase cmd to addr 0x%08lx\n", (unsigned long)addr);
  117. #endif
  118. *addr = BANK_CMD_ERASE1;
  119. *addr = BANK_CMD_ERASE2;
  120. /* re-enable interrupts if necessary */
  121. if (flag)
  122. enable_interrupts ();
  123. }
  124. static int
  125. bank_erase_poll (flash_info_t *info, int sect)
  126. {
  127. bank_addr_t addr = (bank_addr_t)info->start[sect];
  128. bank_word_t stat = *addr;
  129. #ifdef FLASH_DEBUG
  130. printf ("checking status at addr 0x%08lx [0x%08lx]\n",
  131. (unsigned long)addr, (unsigned long)stat);
  132. #endif
  133. if ((stat & BANK_STAT_RDY) == BANK_STAT_RDY) {
  134. if ((stat & BANK_STAT_ERR) != 0) {
  135. printf ("failed on sector %d [0x%08lx] at "
  136. "address 0x%08lx\n", sect,
  137. (unsigned long)stat, (unsigned long)addr);
  138. *addr = BANK_CMD_CLR_STAT;
  139. return (-1);
  140. }
  141. else
  142. return (1);
  143. }
  144. else
  145. return (0);
  146. }
  147. static int
  148. bank_write_word (bank_addr_t addr, bank_word_t value)
  149. {
  150. bank_word_t stat;
  151. ulong start;
  152. int flag, retval;
  153. /* Disable interrupts which might cause a timeout here */
  154. flag = disable_interrupts ();
  155. *addr = BANK_CMD_PROG;
  156. *addr = value;
  157. /* re-enable interrupts if necessary */
  158. if (flag)
  159. enable_interrupts ();
  160. retval = 0;
  161. /* data polling for D7 */
  162. start = get_timer (0);
  163. do {
  164. if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
  165. retval = 1;
  166. goto done;
  167. }
  168. stat = *addr;
  169. } while ((stat & BANK_STAT_RDY) != BANK_STAT_RDY);
  170. if ((stat & BANK_STAT_ERR) != 0) {
  171. printf ("flash program failed [0x%08lx] at address 0x%08lx\n",
  172. (unsigned long)stat, (unsigned long)addr);
  173. *addr = BANK_CMD_CLR_STAT;
  174. retval = 3;
  175. }
  176. done:
  177. /* reset to read mode */
  178. *addr = BANK_CMD_RST;
  179. return (retval);
  180. }
  181. /*-----------------------------------------------------------------------
  182. */
  183. unsigned long
  184. flash_init (void)
  185. {
  186. int i;
  187. /* Init: no FLASHes known */
  188. for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
  189. flash_info[i].flash_id = FLASH_UNKNOWN;
  190. }
  191. bank_probe (&flash_info[0], (bank_addr_t)CFG_FLASH_BASE);
  192. /*
  193. * protect monitor and environment sectors
  194. */
  195. #if CFG_MONITOR_BASE == CFG_FLASH_BASE
  196. (void)flash_protect (FLAG_PROTECT_SET,
  197. CFG_MONITOR_BASE,
  198. CFG_MONITOR_BASE+monitor_flash_len-1,
  199. &flash_info[0]);
  200. #endif
  201. #if defined(CFG_FLASH_ENV_ADDR)
  202. (void)flash_protect (FLAG_PROTECT_SET,
  203. CFG_FLASH_ENV_ADDR,
  204. #if defined(CFG_FLASH_ENV_BUF)
  205. CFG_FLASH_ENV_ADDR + CFG_FLASH_ENV_BUF - 1,
  206. #else
  207. CFG_FLASH_ENV_ADDR + CFG_FLASH_ENV_SIZE - 1,
  208. #endif
  209. &flash_info[0]);
  210. #endif
  211. return flash_info[0].size;
  212. }
  213. /*-----------------------------------------------------------------------
  214. */
  215. void
  216. flash_print_info (flash_info_t *info)
  217. {
  218. int i;
  219. if (info->flash_id == FLASH_UNKNOWN) {
  220. printf ("missing or unknown FLASH type\n");
  221. return;
  222. }
  223. switch (info->flash_id & FLASH_VENDMASK) {
  224. case FLASH_MAN_INTEL: printf ("INTEL "); break;
  225. default: printf ("Unknown Vendor "); break;
  226. }
  227. switch (info->flash_id & FLASH_TYPEMASK) {
  228. case FLASH_28F320J5: printf ("28F320J5 (32 Mbit, 2 x 16bit)\n");
  229. break;
  230. case FLASH_28F640J5: printf ("28F640J5 (64 Mbit, 2 x 16bit)\n");
  231. break;
  232. case FLASH_28F320J3A: printf ("28F320J3A (32 Mbit, 2 x 16bit)\n");
  233. break;
  234. case FLASH_28F640J3A: printf ("28F640J3A (64 Mbit, 2 x 16bit)\n");
  235. break;
  236. case FLASH_28F128J3A: printf ("28F320J3A (128 Mbit, 2 x 16bit)\n");
  237. break;
  238. default: printf ("Unknown Chip Type\n");
  239. break;
  240. }
  241. printf (" Size: %ld MB in %d Sectors\n",
  242. info->size >> 20, info->sector_count);
  243. printf (" Sector Start Addresses:");
  244. for (i=0; i<info->sector_count; ++i) {
  245. if ((i % 5) == 0)
  246. printf ("\n ");
  247. printf (" %08lX%s",
  248. info->start[i],
  249. info->protect[i] ? " (RO)" : " "
  250. );
  251. }
  252. printf ("\n");
  253. return;
  254. }
  255. /*
  256. * The following code cannot be run from FLASH!
  257. */
  258. /*-----------------------------------------------------------------------
  259. */
  260. int
  261. flash_erase (flash_info_t *info, int s_first, int s_last)
  262. {
  263. int prot, sect, haderr;
  264. ulong start, now, last;
  265. int rcode = 0;
  266. #ifdef FLASH_DEBUG
  267. printf ("\nflash_erase: erase %d sectors (%d to %d incl.) from\n"
  268. " Bank # %d: ", s_last - s_first + 1, s_first, s_last,
  269. (info - flash_info) + 1);
  270. flash_print_info (info);
  271. #endif
  272. if ((s_first < 0) || (s_first > s_last)) {
  273. if (info->flash_id == FLASH_UNKNOWN) {
  274. printf ("- missing\n");
  275. } else {
  276. printf ("- no sectors to erase\n");
  277. }
  278. return 1;
  279. }
  280. prot = 0;
  281. for (sect = s_first; sect <= s_last; ++sect) {
  282. if (info->protect[sect]) {
  283. prot++;
  284. }
  285. }
  286. if (prot) {
  287. printf ("- Warning: %d protected sector%s will not be erased\n",
  288. prot, (prot > 1 ? "s" : ""));
  289. }
  290. start = get_timer (0);
  291. last = 0;
  292. haderr = 0;
  293. for (sect = s_first; sect <= s_last; sect++) {
  294. if (info->protect[sect] == 0) { /* not protected */
  295. ulong estart;
  296. int sectdone;
  297. bank_erase_init (info, sect);
  298. /* wait at least 80us - let's wait 1 ms */
  299. udelay (1000);
  300. estart = get_timer (start);
  301. do {
  302. now = get_timer (start);
  303. if (now - estart > CFG_FLASH_ERASE_TOUT) {
  304. printf ("Timeout (sect %d)\n", sect);
  305. haderr = 1;
  306. rcode = 1;
  307. break;
  308. }
  309. #ifndef FLASH_DEBUG
  310. /* show that we're waiting */
  311. if ((now - last) > 1000) { /* every second */
  312. putc ('.');
  313. last = now;
  314. }
  315. #endif
  316. sectdone = bank_erase_poll (info, sect);
  317. if (sectdone < 0) {
  318. haderr = 1;
  319. rcode = 1;
  320. break;
  321. }
  322. } while (!sectdone);
  323. if (haderr)
  324. break;
  325. }
  326. }
  327. if (haderr > 0)
  328. printf (" failed\n");
  329. else
  330. printf (" done\n");
  331. /* reset to read mode */
  332. for (sect = s_first; sect <= s_last; sect++) {
  333. if (info->protect[sect] == 0) { /* not protected */
  334. bank_reset (info, sect);
  335. }
  336. }
  337. return rcode;
  338. }
  339. /*-----------------------------------------------------------------------
  340. * Write a word to Flash, returns:
  341. * 0 - OK
  342. * 1 - write timeout
  343. * 2 - Flash not erased
  344. * 3 - Program failed
  345. */
  346. static int
  347. write_word (flash_info_t *info, ulong dest, ulong data)
  348. {
  349. /* Check if Flash is (sufficiently) erased */
  350. if ((*(ulong *)dest & data) != data)
  351. return (2);
  352. return (bank_write_word ((bank_addr_t)dest, (bank_word_t)data));
  353. }
  354. /*-----------------------------------------------------------------------
  355. * Copy memory to flash, returns:
  356. * 0 - OK
  357. * 1 - write timeout
  358. * 2 - Flash not erased
  359. * 3 - Program failed
  360. */
  361. int
  362. write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
  363. {
  364. ulong cp, wp, data;
  365. int i, l, rc;
  366. wp = (addr & ~3); /* get lower word aligned address */
  367. /*
  368. * handle unaligned start bytes
  369. */
  370. if ((l = addr - wp) != 0) {
  371. data = 0;
  372. for (i=0, cp=wp; i<l; ++i, ++cp) {
  373. data = (data << 8) | (*(uchar *)cp);
  374. }
  375. for (; i<4 && cnt>0; ++i) {
  376. data = (data << 8) | *src++;
  377. --cnt;
  378. ++cp;
  379. }
  380. for (; cnt==0 && i<4; ++i, ++cp) {
  381. data = (data << 8) | (*(uchar *)cp);
  382. }
  383. if ((rc = write_word (info, wp, data)) != 0) {
  384. return (rc);
  385. }
  386. wp += 4;
  387. }
  388. /*
  389. * handle word aligned part
  390. */
  391. while (cnt >= 4) {
  392. data = 0;
  393. for (i=0; i<4; ++i) {
  394. data = (data << 8) | *src++;
  395. }
  396. if ((rc = write_word (info, wp, data)) != 0) {
  397. return (rc);
  398. }
  399. wp += 4;
  400. cnt -= 4;
  401. }
  402. if (cnt == 0) {
  403. return (0);
  404. }
  405. /*
  406. * handle unaligned tail bytes
  407. */
  408. data = 0;
  409. for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
  410. data = (data << 8) | *src++;
  411. --cnt;
  412. }
  413. for (; i<4; ++i, ++cp) {
  414. data = (data << 8) | (*(uchar *)cp);
  415. }
  416. return (write_word (info, wp, data));
  417. }
  418. /*-----------------------------------------------------------------------
  419. */