flash.c 13 KB

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