flash.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616
  1. /*
  2. * (C) Copyright 2003
  3. * MuLogic B.V.
  4. *
  5. * (C) Copyright 2001
  6. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  7. *
  8. * See file CREDITS for list of people who contributed to this
  9. * project.
  10. *
  11. * This program is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU General Public License as
  13. * published by the Free Software Foundation; either version 2 of
  14. * the License, or (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program; if not, write to the Free Software
  23. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  24. * MA 02111-1307 USA
  25. */
  26. #include <common.h>
  27. #include <ppc4xx.h>
  28. #include <asm/u-boot.h>
  29. #include <asm/processor.h>
  30. flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
  31. #define FLASH_WORD_SIZE unsigned long
  32. #define FLASH_ID_MASK 0xFFFFFFFF
  33. /*-----------------------------------------------------------------------
  34. * Functions
  35. */
  36. /* stolen from esteem192e/flash.c */
  37. ulong flash_get_size (volatile FLASH_WORD_SIZE *addr, flash_info_t *info);
  38. static int write_word (flash_info_t *info, ulong dest, ulong data);
  39. static void flash_get_offsets (ulong base, flash_info_t *info);
  40. /*-----------------------------------------------------------------------
  41. */
  42. unsigned long flash_init (void)
  43. {
  44. unsigned long size_b0, size_b1;
  45. int i;
  46. uint pbcr;
  47. unsigned long base_b0, base_b1;
  48. volatile FLASH_WORD_SIZE* flash_base;
  49. /* Init: no FLASHes known */
  50. for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
  51. flash_info[i].flash_id = FLASH_UNKNOWN;
  52. }
  53. /* Static FLASH Bank configuration here */
  54. /* Test for 8M Flash first */
  55. debug ("\n## Get flash bank 1 size @ 0x%08x\n",FLASH_BASE0_8M_PRELIM);
  56. flash_base = (volatile FLASH_WORD_SIZE*)(FLASH_BASE0_8M_PRELIM);
  57. size_b0 = flash_get_size(flash_base, &flash_info[0]);
  58. if (flash_info[0].flash_id == FLASH_UNKNOWN) {
  59. printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
  60. size_b0, size_b0<<20);
  61. return 0;
  62. }
  63. if (size_b0 < 8*1024*1024) {
  64. /* Not quite 8M, try 4M Flash base address */
  65. debug ("\n## Get flash bank 1 size @ 0x%08x\n",FLASH_BASE0_4M_PRELIM);
  66. flash_base = (volatile FLASH_WORD_SIZE*)(FLASH_BASE0_4M_PRELIM);
  67. size_b0 = flash_get_size(flash_base, &flash_info[0]);
  68. }
  69. if (flash_info[0].flash_id == FLASH_UNKNOWN) {
  70. printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
  71. size_b0, size_b0<<20);
  72. return 0;
  73. }
  74. /* Only one bank */
  75. if (CFG_MAX_FLASH_BANKS == 1) {
  76. /* Setup offsets */
  77. flash_get_offsets ((ulong)flash_base, &flash_info[0]);
  78. /* Monitor protection ON by default */
  79. (void)flash_protect(FLAG_PROTECT_SET, CFG_MONITOR_BASE,
  80. CFG_MONITOR_BASE+CFG_MONITOR_LEN-1, &flash_info[0]);
  81. size_b1 = 0 ;
  82. flash_info[0].size = size_b0;
  83. return(size_b0);
  84. }
  85. /* We have 2 banks */
  86. size_b1 = flash_get_size(flash_base, &flash_info[1]);
  87. /* Re-do sizing to get full correct info */
  88. if (size_b1) {
  89. mtdcr(ebccfga, pb0cr);
  90. pbcr = mfdcr(ebccfgd);
  91. mtdcr(ebccfga, pb0cr);
  92. base_b1 = -size_b1;
  93. pbcr = (pbcr & 0x0001ffff) | base_b1 | (((size_b1/1024/1024)-1)<<17);
  94. mtdcr(ebccfgd, pbcr);
  95. }
  96. if (size_b0) {
  97. mtdcr(ebccfga, pb1cr);
  98. pbcr = mfdcr(ebccfgd);
  99. mtdcr(ebccfga, pb1cr);
  100. base_b0 = base_b1 - size_b0;
  101. pbcr = (pbcr & 0x0001ffff) | base_b0 | (((size_b0/1024/1024)-1)<<17);
  102. mtdcr(ebccfgd, pbcr);
  103. }
  104. size_b0 = flash_get_size((volatile FLASH_WORD_SIZE *)base_b0, &flash_info[0]);
  105. flash_get_offsets (base_b0, &flash_info[0]);
  106. /* monitor protection ON by default */
  107. (void)flash_protect(FLAG_PROTECT_SET, CFG_MONITOR_BASE,
  108. CFG_MONITOR_BASE+CFG_MONITOR_LEN-1, &flash_info[0]);
  109. if (size_b1) {
  110. /* Re-do sizing to get full correct info */
  111. size_b1 = flash_get_size((volatile FLASH_WORD_SIZE *)base_b1, &flash_info[1]);
  112. flash_get_offsets (base_b1, &flash_info[1]);
  113. /* monitor protection ON by default */
  114. (void)flash_protect(FLAG_PROTECT_SET, base_b1+size_b1-CFG_MONITOR_LEN,
  115. base_b1+size_b1-1, &flash_info[1]);
  116. /* monitor protection OFF by default (one is enough) */
  117. (void)flash_protect(FLAG_PROTECT_CLEAR, base_b0+size_b0-CFG_MONITOR_LEN,
  118. base_b0+size_b0-1, &flash_info[0]);
  119. } else {
  120. flash_info[1].flash_id = FLASH_UNKNOWN;
  121. flash_info[1].sector_count = -1;
  122. }
  123. flash_info[0].size = size_b0;
  124. flash_info[1].size = size_b1;
  125. return (size_b0 + size_b1);
  126. }
  127. /*-----------------------------------------------------------------------
  128. This code is specific to the AM29DL163/AM29DL232 for the QS850/QS823.
  129. */
  130. static void flash_get_offsets (ulong base, flash_info_t *info)
  131. {
  132. int i;
  133. long large_sect_size;
  134. long small_sect_size;
  135. /* set up sector start adress table */
  136. large_sect_size = info->size / (info->sector_count - 8 + 1);
  137. small_sect_size = large_sect_size / 8;
  138. if (info->flash_id & FLASH_BTYPE) {
  139. /* set sector offsets for bottom boot block type */
  140. for (i = 0; i < 7; i++) {
  141. info->start[i] = base;
  142. base += small_sect_size;
  143. }
  144. for (; i < info->sector_count; i++) {
  145. info->start[i] = base;
  146. base += large_sect_size;
  147. }
  148. }
  149. else
  150. {
  151. /* set sector offsets for top boot block type */
  152. for (i = 0; i < (info->sector_count - 8); i++) {
  153. info->start[i] = base;
  154. base += large_sect_size;
  155. }
  156. for (; i < info->sector_count; i++) {
  157. info->start[i] = base;
  158. base += small_sect_size;
  159. }
  160. }
  161. }
  162. /*-----------------------------------------------------------------------
  163. */
  164. void flash_print_info (flash_info_t *info)
  165. {
  166. int i;
  167. uchar *boottype;
  168. uchar botboot[]=", bottom boot sect)\n";
  169. uchar topboot[]=", top boot sector)\n";
  170. if (info->flash_id == FLASH_UNKNOWN) {
  171. printf ("missing or unknown FLASH type\n");
  172. return;
  173. }
  174. switch (info->flash_id & FLASH_VENDMASK) {
  175. case FLASH_MAN_AMD:
  176. printf ("AMD ");
  177. break;
  178. case FLASH_MAN_FUJ:
  179. printf ("FUJITSU ");
  180. break;
  181. case FLASH_MAN_SST:
  182. printf ("SST ");
  183. break;
  184. case FLASH_MAN_STM:
  185. printf ("STM ");
  186. break;
  187. case FLASH_MAN_INTEL:
  188. printf ("INTEL ");
  189. break;
  190. default:
  191. printf ("Unknown Vendor ");
  192. break;
  193. }
  194. if (info->flash_id & 0x0001 ) {
  195. boottype = botboot;
  196. } else {
  197. boottype = topboot;
  198. }
  199. switch (info->flash_id & FLASH_TYPEMASK) {
  200. case FLASH_AM160B:
  201. printf ("AM29LV160B (16 Mbit%s",boottype);
  202. break;
  203. case FLASH_AM160T:
  204. printf ("AM29LV160T (16 Mbit%s",boottype);
  205. break;
  206. case FLASH_AMDL163T:
  207. printf ("AM29DL163T (16 Mbit%s",boottype);
  208. break;
  209. case FLASH_AMDL163B:
  210. printf ("AM29DL163B (16 Mbit%s",boottype);
  211. break;
  212. case FLASH_AM320B:
  213. printf ("AM29LV320B (32 Mbit%s",boottype);
  214. break;
  215. case FLASH_AM320T:
  216. printf ("AM29LV320T (32 Mbit%s",boottype);
  217. break;
  218. case FLASH_AMDL323T:
  219. printf ("AM29DL323T (32 Mbit%s",boottype);
  220. break;
  221. case FLASH_AMDL323B:
  222. printf ("AM29DL323B (32 Mbit%s",boottype);
  223. break;
  224. case FLASH_AMDL322T:
  225. printf ("AM29DL322T (32 Mbit%s",boottype);
  226. break;
  227. default:
  228. printf ("Unknown Chip Type\n");
  229. break;
  230. }
  231. printf (" Size: %ld MB in %d Sectors\n",
  232. info->size >> 20, info->sector_count);
  233. printf (" Sector Start Addresses:");
  234. for (i=0; i<info->sector_count; ++i) {
  235. if ((i % 5) == 0)
  236. printf ("\n ");
  237. printf (" %08lX%s", info->start[i],
  238. info->protect[i] ? " (RO)" : " ");
  239. }
  240. printf ("\n");
  241. return;
  242. }
  243. /*-----------------------------------------------------------------------
  244. * The following code cannot be run from FLASH!
  245. */
  246. ulong flash_get_size (volatile FLASH_WORD_SIZE *addr, flash_info_t *info)
  247. {
  248. short i;
  249. ulong base = (ulong)addr;
  250. FLASH_WORD_SIZE value;
  251. /* Write auto select command: read Manufacturer ID */
  252. /*
  253. * Note: if it is an AMD flash and the word at addr[0000]
  254. * is 0x00890089 this routine will think it is an Intel
  255. * flash device and may(most likely) cause trouble.
  256. */
  257. addr[0x0000] = 0x00900090;
  258. if(addr[0x0000] != 0x00890089){
  259. addr[0x0555] = 0x00AA00AA;
  260. addr[0x02AA] = 0x00550055;
  261. addr[0x0555] = 0x00900090;
  262. }
  263. value = addr[0];
  264. switch (value) {
  265. case (AMD_MANUFACT & FLASH_ID_MASK):
  266. info->flash_id = FLASH_MAN_AMD;
  267. break;
  268. case (FUJ_MANUFACT & FLASH_ID_MASK):
  269. info->flash_id = FLASH_MAN_FUJ;
  270. break;
  271. case (STM_MANUFACT & FLASH_ID_MASK):
  272. info->flash_id = FLASH_MAN_STM;
  273. break;
  274. case (SST_MANUFACT & FLASH_ID_MASK):
  275. info->flash_id = FLASH_MAN_SST;
  276. break;
  277. case (INTEL_MANUFACT & FLASH_ID_MASK):
  278. info->flash_id = FLASH_MAN_INTEL;
  279. break;
  280. default:
  281. info->flash_id = FLASH_UNKNOWN;
  282. info->sector_count = 0;
  283. info->size = 0;
  284. return (0); /* no or unknown flash */
  285. }
  286. value = addr[1]; /* device ID */
  287. switch (value) {
  288. case (AMD_ID_LV160T & FLASH_ID_MASK):
  289. info->flash_id += FLASH_AM160T;
  290. info->sector_count = 35;
  291. info->size = 0x00400000;
  292. break; /* => 4 MB */
  293. case (AMD_ID_LV160B & FLASH_ID_MASK):
  294. info->flash_id += FLASH_AM160B;
  295. info->sector_count = 35;
  296. info->size = 0x00400000;
  297. break; /* => 4 MB */
  298. case (AMD_ID_DL163T & FLASH_ID_MASK):
  299. info->flash_id += FLASH_AMDL163T;
  300. info->sector_count = 39;
  301. info->size = 0x00400000;
  302. break; /* => 4 MB */
  303. case (AMD_ID_DL163B & FLASH_ID_MASK):
  304. info->flash_id += FLASH_AMDL163B;
  305. info->sector_count = 39;
  306. info->size = 0x00400000;
  307. break; /* => 4 MB */
  308. case (AMD_ID_DL323T & FLASH_ID_MASK):
  309. info->flash_id += FLASH_AMDL323T;
  310. info->sector_count = 71;
  311. info->size = 0x00800000;
  312. break; /* => 8 MB */
  313. case (AMD_ID_DL323B & FLASH_ID_MASK):
  314. info->flash_id += FLASH_AMDL323B;
  315. info->sector_count = 71;
  316. info->size = 0x00800000;
  317. break; /* => 8 MB */
  318. case (AMD_ID_DL322T & FLASH_ID_MASK):
  319. info->flash_id += FLASH_AMDL322T;
  320. info->sector_count = 71;
  321. info->size = 0x00800000;
  322. break; /* => 8 MB */
  323. default:
  324. /* FIXME*/
  325. info->flash_id = FLASH_UNKNOWN;
  326. return (0); /* => no or unknown flash */
  327. }
  328. flash_get_offsets(base, info);
  329. /* check for protected sectors */
  330. for (i = 0; i < info->sector_count; i++) {
  331. /* read sector protection at sector address, (A7 .. A0) = 0x02 */
  332. /* D0 = 1 if protected */
  333. addr = (volatile FLASH_WORD_SIZE *)(info->start[i]);
  334. info->protect[i] = addr[2] & 1;
  335. }
  336. /*
  337. * Prevent writes to uninitialized FLASH.
  338. */
  339. if (info->flash_id != FLASH_UNKNOWN) {
  340. addr = (volatile FLASH_WORD_SIZE *)info->start[0];
  341. *addr = (0x00FF00FF & FLASH_ID_MASK); /* reset bank */
  342. }
  343. return (info->size);
  344. }
  345. /*-----------------------------------------------------------------------
  346. */
  347. int flash_erase (flash_info_t *info, int s_first, int s_last)
  348. {
  349. volatile FLASH_WORD_SIZE *addr=(volatile FLASH_WORD_SIZE*)(info->start[0]);
  350. int flag, prot, sect, l_sect;
  351. ulong start, now, last;
  352. int rcode = 0;
  353. if ((s_first < 0) || (s_first > s_last)) {
  354. if (info->flash_id == FLASH_UNKNOWN) {
  355. printf ("- missing\n");
  356. } else {
  357. printf ("- no sectors to erase\n");
  358. }
  359. return 1;
  360. }
  361. if ((info->flash_id == FLASH_UNKNOWN) ||
  362. (info->flash_id > FLASH_AMD_COMP) ) {
  363. printf ("Can't erase unknown flash type - aborted\n");
  364. return 1;
  365. }
  366. prot = 0;
  367. for (sect=s_first; sect<=s_last; ++sect) {
  368. if (info->protect[sect]) {
  369. prot++;
  370. }
  371. }
  372. if (prot) {
  373. printf ("- Warning: %d protected sectors will not be erased!\n",
  374. prot);
  375. } else {
  376. printf ("\n");
  377. }
  378. l_sect = -1;
  379. /* Disable interrupts which might cause a timeout here */
  380. flag = disable_interrupts();
  381. addr[0x0555] = 0x00AA00AA;
  382. addr[0x02AA] = 0x00550055;
  383. addr[0x0555] = 0x00800080;
  384. addr[0x0555] = 0x00AA00AA;
  385. addr[0x02AA] = 0x00550055;
  386. /* Start erase on unprotected sectors */
  387. for (sect = s_first; sect<=s_last; sect++) {
  388. if (info->protect[sect] == 0) { /* not protected */
  389. addr = (volatile FLASH_WORD_SIZE *)(info->start[sect]);
  390. addr[0] = (0x00300030 & FLASH_ID_MASK);
  391. l_sect = sect;
  392. }
  393. }
  394. /* re-enable interrupts if necessary */
  395. if (flag)
  396. enable_interrupts();
  397. /* wait at least 80us - let's wait 1 ms */
  398. udelay (1000);
  399. /*
  400. * We wait for the last triggered sector
  401. */
  402. if (l_sect < 0)
  403. goto DONE;
  404. start = get_timer (0);
  405. last = start;
  406. addr = (volatile FLASH_WORD_SIZE*)(info->start[l_sect]);
  407. while ((addr[0] & (0x00800080&FLASH_ID_MASK)) !=
  408. (0x00800080&FLASH_ID_MASK) )
  409. {
  410. if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
  411. printf ("Timeout\n");
  412. return 1;
  413. }
  414. /* show that we're waiting */
  415. if ((now - last) > 1000) { /* every second */
  416. serial_putc ('.');
  417. last = now;
  418. }
  419. }
  420. DONE:
  421. /* reset to read mode */
  422. addr = (volatile FLASH_WORD_SIZE *)info->start[0];
  423. addr[0] = (0x00F000F0 & FLASH_ID_MASK); /* reset bank */
  424. printf (" done\n");
  425. return rcode;
  426. }
  427. /*-----------------------------------------------------------------------
  428. * Copy memory to flash, returns:
  429. * 0 - OK
  430. * 1 - write timeout
  431. * 2 - Flash not erased
  432. */
  433. int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
  434. {
  435. ulong cp, wp, data;
  436. int l;
  437. int i, rc;
  438. wp = (addr & ~3); /* get lower word aligned address */
  439. /*
  440. * handle unaligned start bytes
  441. */
  442. if ((l = addr - wp) != 0) {
  443. data = 0;
  444. for (i=0, cp=wp; i<l; ++i, ++cp) {
  445. data = (data << 8) | (*(uchar *)cp);
  446. }
  447. for (; i<4 && cnt>0; ++i) {
  448. data = (data << 8) | *src++;
  449. --cnt;
  450. ++cp;
  451. }
  452. for (; cnt==0 && i<4; ++i, ++cp) {
  453. data = (data << 8) | (*(uchar *)cp);
  454. }
  455. if ((rc = write_word(info, wp, data)) != 0) {
  456. return (rc);
  457. }
  458. wp += 4;
  459. }
  460. /*
  461. * handle word aligned part
  462. */
  463. while (cnt >= 4) {
  464. data = 0;
  465. for (i=0; i<4; ++i) {
  466. data = (data << 8) | *src++;
  467. }
  468. if ((rc = write_word(info, wp, data)) != 0) {
  469. return (rc);
  470. }
  471. wp += 4;
  472. cnt -= 4;
  473. }
  474. if (cnt == 0) {
  475. return (0);
  476. }
  477. /*
  478. * handle unaligned tail bytes
  479. */
  480. data = 0;
  481. for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
  482. data = (data << 8) | *src++;
  483. --cnt;
  484. }
  485. for (; i<4; ++i, ++cp) {
  486. data = (data << 8) | (*(uchar *)cp);
  487. }
  488. return (write_word(info, wp, data));
  489. }
  490. /*-----------------------------------------------------------------------
  491. * Write a word to Flash, returns:
  492. * 0 - OK
  493. * 1 - write timeout
  494. * 2 - Flash not erased
  495. */
  496. static int write_word (flash_info_t *info, ulong dest, ulong data)
  497. {
  498. vu_long *addr = (vu_long*)(info->start[0]);
  499. ulong start;
  500. int flag;
  501. /* Check if Flash is (sufficiently) erased */
  502. if ((*((vu_long *)dest) & data) != data) {
  503. return (2);
  504. }
  505. /* Disable interrupts which might cause a timeout here */
  506. flag = disable_interrupts();
  507. /* AMD stuff */
  508. addr[0x0555] = 0x00AA00AA;
  509. addr[0x02AA] = 0x00550055;
  510. addr[0x0555] = 0x00A000A0;
  511. *((vu_long *)dest) = data;
  512. /* re-enable interrupts if necessary */
  513. if (flag)
  514. enable_interrupts();
  515. /* data polling for D7 */
  516. start = get_timer(0);
  517. while ((*((vu_long *)dest) & 0x00800080) != (data & 0x00800080)) {
  518. if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
  519. return (1);
  520. }
  521. }
  522. return (0);
  523. }