flash.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648
  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. #include <common.h>
  24. #include <board/cogent/flash.h>
  25. flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
  26. #if defined(CONFIG_ENV_IS_IN_FLASH)
  27. # ifndef CFG_ENV_ADDR
  28. # define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_ENV_OFFSET)
  29. # endif
  30. # ifndef CFG_ENV_SIZE
  31. # define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
  32. # endif
  33. # ifndef CFG_ENV_SECT_SIZE
  34. # define CFG_ENV_SECT_SIZE CFG_ENV_SIZE
  35. # endif
  36. #endif
  37. /*-----------------------------------------------------------------------
  38. * Functions
  39. */
  40. static int write_word (flash_info_t *info, ulong dest, ulong data);
  41. /*-----------------------------------------------------------------------
  42. */
  43. #if defined(CONFIG_CMA302)
  44. /*
  45. * probe for the existence of flash at address "addr"
  46. * 0 = yes, 1 = bad Manufacturer's Id, 2 = bad Device Id
  47. */
  48. static int
  49. c302f_probe_word(c302f_addr_t addr)
  50. {
  51. /* reset the flash */
  52. *addr = C302F_BNK_CMD_RST;
  53. /* check the manufacturer id */
  54. *addr = C302F_BNK_CMD_RD_ID;
  55. if (*C302F_BNK_ADDR_MAN(addr) != C302F_BNK_RD_ID_MAN)
  56. return 1;
  57. /* check the device id */
  58. *addr = C302F_BNK_CMD_RD_ID;
  59. if (*C302F_BNK_ADDR_DEV(addr) != C302F_BNK_RD_ID_DEV)
  60. return 2;
  61. #ifdef FLASH_DEBUG
  62. {
  63. int i;
  64. printf("\nMaster Lock Config = 0x%08lx\n",
  65. *C302F_BNK_ADDR_CFGM(addr));
  66. for (i = 0; i < C302F_BNK_NBLOCKS; i++)
  67. printf("Block %2d Lock Config = 0x%08lx\n",
  68. i, *C302F_BNK_ADDR_CFG(i, addr));
  69. }
  70. #endif
  71. /* reset the flash again */
  72. *addr = C302F_BNK_CMD_RST;
  73. return 0;
  74. }
  75. /*
  76. * probe for Cogent CMA302 flash module at address "base" and store
  77. * info for any found into flash_info entry "fip". Must find at least
  78. * one bank.
  79. */
  80. static void
  81. c302f_probe(flash_info_t *fip, c302f_addr_t base)
  82. {
  83. c302f_addr_t addr, eaddr;
  84. int nbanks;
  85. fip->size = 0L;
  86. fip->sector_count = 0;
  87. addr = base;
  88. eaddr = C302F_BNK_ADDR_BASE(addr, C302F_MAX_BANKS);
  89. nbanks = 0;
  90. while (addr < eaddr) {
  91. c302f_addr_t addrw, eaddrw, addrb;
  92. int i, osc, nsc;
  93. addrw = addr;
  94. eaddrw = C302F_BNK_ADDR_NEXT_WORD(addrw);
  95. while (addrw < eaddrw)
  96. if (c302f_probe_word(addrw++) != 0)
  97. goto out;
  98. /* bank exists - append info for this bank to *fip */
  99. fip->flash_id = FLASH_MAN_INTEL|FLASH_28F008S5;
  100. fip->size += C302F_BNK_SIZE;
  101. osc = fip->sector_count;
  102. fip->sector_count += C302F_BNK_NBLOCKS;
  103. if ((nsc = fip->sector_count) >= CFG_MAX_FLASH_SECT)
  104. panic("Too many sectors in flash at address 0x%08lx\n",
  105. (unsigned long)base);
  106. addrb = addr;
  107. for (i = osc; i < nsc; i++) {
  108. fip->start[i] = (ulong)addrb;
  109. fip->protect[i] = 0;
  110. addrb = C302F_BNK_ADDR_NEXT_BLK(addrb);
  111. }
  112. addr = C302F_BNK_ADDR_NEXT_BNK(addr);
  113. nbanks++;
  114. }
  115. out:
  116. if (nbanks == 0)
  117. panic("ERROR: no flash found at address 0x%08lx\n",
  118. (unsigned long)base);
  119. }
  120. static void
  121. c302f_reset(flash_info_t *info, int sect)
  122. {
  123. c302f_addr_t addrw, eaddrw;
  124. addrw = (c302f_addr_t)info->start[sect];
  125. eaddrw = C302F_BNK_ADDR_NEXT_WORD(addrw);
  126. while (addrw < eaddrw) {
  127. #ifdef FLASH_DEBUG
  128. printf(" writing reset cmd to addr 0x%08lx\n",
  129. (unsigned long)addrw);
  130. #endif
  131. *addrw = C302F_BNK_CMD_RST;
  132. addrw++;
  133. }
  134. }
  135. static void
  136. c302f_erase_init(flash_info_t *info, int sect)
  137. {
  138. c302f_addr_t addrw, saddrw, eaddrw;
  139. int flag;
  140. #ifdef FLASH_DEBUG
  141. printf("0x%08lx C302F_BNK_CMD_PROG\n", C302F_BNK_CMD_PROG);
  142. printf("0x%08lx C302F_BNK_CMD_ERASE1\n", C302F_BNK_CMD_ERASE1);
  143. printf("0x%08lx C302F_BNK_CMD_ERASE2\n", C302F_BNK_CMD_ERASE2);
  144. printf("0x%08lx C302F_BNK_CMD_CLR_STAT\n", C302F_BNK_CMD_CLR_STAT);
  145. printf("0x%08lx C302F_BNK_CMD_RST\n", C302F_BNK_CMD_RST);
  146. printf("0x%08lx C302F_BNK_STAT_RDY\n", C302F_BNK_STAT_RDY);
  147. printf("0x%08lx C302F_BNK_STAT_ERR\n", C302F_BNK_STAT_ERR);
  148. #endif
  149. saddrw = (c302f_addr_t)info->start[sect];
  150. eaddrw = C302F_BNK_ADDR_NEXT_WORD(saddrw);
  151. #ifdef FLASH_DEBUG
  152. printf("erasing sector %d, start addr = 0x%08lx "
  153. "(bank next word addr = 0x%08lx)\n", sect,
  154. (unsigned long)saddrw, (unsigned long)eaddrw);
  155. #endif
  156. /* Disable intrs which might cause a timeout here */
  157. flag = disable_interrupts();
  158. for (addrw = saddrw; addrw < eaddrw; addrw++) {
  159. #ifdef FLASH_DEBUG
  160. printf(" writing erase cmd to addr 0x%08lx\n",
  161. (unsigned long)addrw);
  162. #endif
  163. *addrw = C302F_BNK_CMD_ERASE1;
  164. *addrw = C302F_BNK_CMD_ERASE2;
  165. }
  166. /* re-enable interrupts if necessary */
  167. if (flag)
  168. enable_interrupts();
  169. }
  170. static int
  171. c302f_erase_poll(flash_info_t *info, int sect)
  172. {
  173. c302f_addr_t addrw, saddrw, eaddrw;
  174. int sectdone, haderr;
  175. saddrw = (c302f_addr_t)info->start[sect];
  176. eaddrw = C302F_BNK_ADDR_NEXT_WORD(saddrw);
  177. sectdone = 1;
  178. haderr = 0;
  179. for (addrw = saddrw; addrw < eaddrw; addrw++) {
  180. c302f_word_t stat = *addrw;
  181. #ifdef FLASH_DEBUG
  182. printf(" checking status at addr "
  183. "0x%08lx [0x%08lx]\n",
  184. (unsigned long)addrw, stat);
  185. #endif
  186. if ((stat & C302F_BNK_STAT_RDY) != C302F_BNK_STAT_RDY)
  187. sectdone = 0;
  188. else if ((stat & C302F_BNK_STAT_ERR) != 0) {
  189. printf(" failed on sector %d "
  190. "(stat = 0x%08lx) at "
  191. "address 0x%08lx\n",
  192. sect, stat,
  193. (unsigned long)addrw);
  194. *addrw = C302F_BNK_CMD_CLR_STAT;
  195. haderr = 1;
  196. }
  197. }
  198. if (haderr)
  199. return (-1);
  200. else
  201. return (sectdone);
  202. }
  203. static int
  204. c302f_write_word(c302f_addr_t addr, c302f_word_t value)
  205. {
  206. c302f_word_t stat;
  207. ulong start;
  208. int flag, retval;
  209. /* Disable interrupts which might cause a timeout here */
  210. flag = disable_interrupts();
  211. *addr = C302F_BNK_CMD_PROG;
  212. *addr = value;
  213. /* re-enable interrupts if necessary */
  214. if (flag)
  215. enable_interrupts();
  216. retval = 0;
  217. /* data polling for D7 */
  218. start = get_timer (0);
  219. do {
  220. if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
  221. retval = 1;
  222. goto done;
  223. }
  224. stat = *addr;
  225. } while ((stat & C302F_BNK_STAT_RDY) != C302F_BNK_STAT_RDY);
  226. if ((stat & C302F_BNK_STAT_ERR) != 0) {
  227. printf("flash program failed (stat = 0x%08lx) "
  228. "at address 0x%08lx\n", (ulong)stat, (ulong)addr);
  229. *addr = C302F_BNK_CMD_CLR_STAT;
  230. retval = 3;
  231. }
  232. done:
  233. /* reset to read mode */
  234. *addr = C302F_BNK_CMD_RST;
  235. return (retval);
  236. }
  237. #endif /* CONFIG_CMA302 */
  238. unsigned long
  239. flash_init(void)
  240. {
  241. unsigned long total;
  242. int i;
  243. flash_info_t *fip;
  244. /* Init: no FLASHes known */
  245. for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
  246. flash_info[i].flash_id = FLASH_UNKNOWN;
  247. }
  248. fip = &flash_info[0];
  249. total = 0L;
  250. #if defined(CONFIG_CMA302)
  251. c302f_probe(fip, (c302f_addr_t)CFG_FLASH_BASE);
  252. total += fip->size;
  253. fip++;
  254. #endif
  255. #if (CMA_MB_CAPS & CMA_MB_CAP_FLASH)
  256. /* not yet ...
  257. cmbf_probe(fip, (cmbf_addr_t)CMA_MB_FLASH_BASE);
  258. total += fip->size;
  259. fip++;
  260. */
  261. #endif
  262. /*
  263. * protect monitor and environment sectors
  264. */
  265. #if CFG_MONITOR_BASE == CFG_FLASH_BASE
  266. flash_protect(FLAG_PROTECT_SET,
  267. CFG_MONITOR_BASE,
  268. CFG_MONITOR_BASE+monitor_flash_len-1,
  269. &flash_info[0]);
  270. #endif
  271. #ifdef CONFIG_ENV_IS_IN_FLASH
  272. /* ENV protection ON by default */
  273. flash_protect(FLAG_PROTECT_SET,
  274. CFG_ENV_ADDR,
  275. CFG_ENV_ADDR+CFG_ENV_SECT_SIZE-1,
  276. &flash_info[0]);
  277. #endif
  278. return total;
  279. }
  280. /*-----------------------------------------------------------------------
  281. */
  282. void
  283. flash_print_info(flash_info_t *info)
  284. {
  285. int i;
  286. if (info->flash_id == FLASH_UNKNOWN) {
  287. printf ("missing or unknown FLASH type\n");
  288. return;
  289. }
  290. switch (info->flash_id & FLASH_VENDMASK) {
  291. case FLASH_MAN_INTEL: printf ("INTEL "); break;
  292. default: printf ("Unknown Vendor "); break;
  293. }
  294. switch (info->flash_id & FLASH_TYPEMASK) {
  295. case FLASH_28F008S5: printf ("28F008S5\n");
  296. break;
  297. default: printf ("Unknown Chip Type\n");
  298. break;
  299. }
  300. printf (" Size: %ld MB in %d Sectors\n",
  301. info->size >> 20, info->sector_count);
  302. printf (" Sector Start Addresses:");
  303. for (i=0; i<info->sector_count; ++i) {
  304. if ((i % 4) == 0)
  305. printf ("\n ");
  306. printf (" %2d - %08lX%s", i,
  307. info->start[i],
  308. info->protect[i] ? " (RO)" : " "
  309. );
  310. }
  311. printf ("\n");
  312. return;
  313. }
  314. /*-----------------------------------------------------------------------
  315. */
  316. /*-----------------------------------------------------------------------
  317. */
  318. /*
  319. * The following code cannot be run from FLASH!
  320. */
  321. int
  322. flash_erase(flash_info_t *info, int s_first, int s_last)
  323. {
  324. int prot, sect, haderr;
  325. ulong start, now, last;
  326. void (*erase_init)(flash_info_t *, int);
  327. int (*erase_poll)(flash_info_t *, int);
  328. void (*reset)(flash_info_t *, int);
  329. int rcode = 0;
  330. #ifdef FLASH_DEBUG
  331. printf("\nflash_erase: erase %d sectors (%d to %d incl.) from\n"
  332. " Bank # %d: ", s_last - s_first + 1, s_first, s_last,
  333. (info - flash_info) + 1);
  334. flash_print_info(info);
  335. #endif
  336. if ((s_first < 0) || (s_first > s_last)) {
  337. if (info->flash_id == FLASH_UNKNOWN) {
  338. printf ("- missing\n");
  339. } else {
  340. printf ("- no sectors to erase\n");
  341. }
  342. return 1;
  343. }
  344. switch (info->flash_id) {
  345. #if defined(CONFIG_CMA302)
  346. case FLASH_MAN_INTEL|FLASH_28F008S5:
  347. erase_init = c302f_erase_init;
  348. erase_poll = c302f_erase_poll;
  349. reset = c302f_reset;
  350. break;
  351. #endif
  352. #if (CMA_MB_CAPS & CMA_MB_CAP_FLASH)
  353. case FLASH_MAN_INTEL|FLASH_28F800_B:
  354. case FLASH_MAN_AMD|FLASH_AM29F800B:
  355. /* not yet ...
  356. erase_init = cmbf_erase_init;
  357. erase_poll = cmbf_erase_poll;
  358. reset = cmbf_reset;
  359. break;
  360. */
  361. #endif
  362. default:
  363. printf ("Flash type %08lx not supported - aborted\n",
  364. info->flash_id);
  365. return 1;
  366. }
  367. prot = 0;
  368. for (sect=s_first; sect<=s_last; ++sect) {
  369. if (info->protect[sect]) {
  370. prot++;
  371. }
  372. }
  373. if (prot) {
  374. printf("- Warning: %d protected sector%s will not be erased!\n",
  375. prot, (prot > 1 ? "s" : ""));
  376. }
  377. start = get_timer (0);
  378. last = 0;
  379. haderr = 0;
  380. for (sect = s_first; sect <= s_last; sect++) {
  381. if (info->protect[sect] == 0) { /* not protected */
  382. ulong estart;
  383. int sectdone;
  384. (*erase_init)(info, sect);
  385. /* wait at least 80us - let's wait 1 ms */
  386. udelay (1000);
  387. estart = get_timer(start);
  388. do {
  389. now = get_timer(start);
  390. if (now - estart > CFG_FLASH_ERASE_TOUT) {
  391. printf ("Timeout (sect %d)\n", sect);
  392. haderr = 1;
  393. break;
  394. }
  395. #ifndef FLASH_DEBUG
  396. /* show that we're waiting */
  397. if ((now - last) > 1000) { /* every second */
  398. putc ('.');
  399. last = now;
  400. }
  401. #endif
  402. sectdone = (*erase_poll)(info, sect);
  403. if (sectdone < 0) {
  404. haderr = 1;
  405. break;
  406. }
  407. } while (!sectdone);
  408. if (haderr)
  409. break;
  410. }
  411. }
  412. if (haderr > 0) {
  413. printf (" failed\n");
  414. rcode = 1;
  415. }
  416. else
  417. printf (" done\n");
  418. /* reset to read mode */
  419. for (sect = s_first; sect <= s_last; sect++) {
  420. if (info->protect[sect] == 0) { /* not protected */
  421. (*reset)(info, sect);
  422. }
  423. }
  424. return rcode;
  425. }
  426. /*-----------------------------------------------------------------------
  427. * Copy memory to flash, returns:
  428. * 0 - OK
  429. * 1 - write timeout
  430. * 2 - Flash not erased
  431. * 3 - write error
  432. */
  433. int
  434. write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
  435. {
  436. ulong cp, wp, data;
  437. int i, l, rc;
  438. ulong start, now, last;
  439. wp = (addr & ~3); /* get lower word aligned address */
  440. /*
  441. * handle unaligned start bytes
  442. */
  443. if ((l = addr - wp) != 0) {
  444. data = 0;
  445. for (i=0, cp=wp; i<l; ++i, ++cp) {
  446. data = (data << 8) | (*(uchar *)cp);
  447. }
  448. for (; i<4 && cnt>0; ++i) {
  449. data = (data << 8) | *src++;
  450. --cnt;
  451. ++cp;
  452. }
  453. for (; cnt==0 && i<4; ++i, ++cp) {
  454. data = (data << 8) | (*(uchar *)cp);
  455. }
  456. if ((rc = write_word(info, wp, data)) != 0) {
  457. return (rc);
  458. }
  459. wp += 4;
  460. }
  461. /*
  462. * handle word aligned part
  463. */
  464. start = get_timer (0);
  465. last = 0;
  466. while (cnt >= 4) {
  467. data = 0;
  468. for (i=0; i<4; ++i) {
  469. data = (data << 8) | *src++;
  470. }
  471. if ((rc = write_word(info, wp, data)) != 0) {
  472. return (rc);
  473. }
  474. wp += 4;
  475. cnt -= 4;
  476. /* show that we're waiting */
  477. now = get_timer(start);
  478. if ((now - last) > 1000) { /* every second */
  479. putc ('.');
  480. last = now;
  481. }
  482. }
  483. if (cnt == 0) {
  484. return (0);
  485. }
  486. /*
  487. * handle unaligned tail bytes
  488. */
  489. data = 0;
  490. for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
  491. data = (data << 8) | *src++;
  492. --cnt;
  493. }
  494. for (; i<4; ++i, ++cp) {
  495. data = (data << 8) | (*(uchar *)cp);
  496. }
  497. return (write_word(info, wp, data));
  498. }
  499. /*-----------------------------------------------------------------------
  500. * Write a word to Flash, returns:
  501. * 0 - OK
  502. * 1 - write timeout
  503. * 2 - Flash not erased
  504. * 3 - write error
  505. */
  506. static int
  507. write_word(flash_info_t *info, ulong dest, ulong data)
  508. {
  509. int retval;
  510. /* Check if Flash is (sufficiently) erased */
  511. if ((*(ulong *)dest & data) != data) {
  512. return (2);
  513. }
  514. switch (info->flash_id) {
  515. #if defined(CONFIG_CMA302)
  516. case FLASH_MAN_INTEL|FLASH_28F008S5:
  517. retval = c302f_write_word((c302f_addr_t)dest, (c302f_word_t)data);
  518. break;
  519. #endif
  520. #if (CMA_MB_CAPS & CMA_MB_CAP_FLASH)
  521. case FLASH_MAN_INTEL|FLASH_28F800_B:
  522. case FLASH_MAN_AMD|FLASH_AM29F800B:
  523. /* not yet ...
  524. retval = cmbf_write_word((cmbf_addr_t)dest, (cmbf_word_t)data);
  525. */
  526. retval = 3;
  527. break;
  528. #endif
  529. default:
  530. printf ("Flash type %08lx not supported - aborted\n",
  531. info->flash_id);
  532. retval = 3;
  533. break;
  534. }
  535. return (retval);
  536. }
  537. /*-----------------------------------------------------------------------
  538. */