flash.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797
  1. /*
  2. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  3. *
  4. * See file CREDITS for list of people who contributed to this
  5. * project.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation; either version 2 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  20. * MA 02111-1307 USA
  21. */
  22. #include <common.h>
  23. #include <mpc8xx.h>
  24. #ifndef CONFIG_ENV_ADDR
  25. #define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + CONFIG_ENV_OFFSET)
  26. #endif
  27. flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */
  28. /*-----------------------------------------------------------------------
  29. * Functions
  30. */
  31. static int write_word (flash_info_t *info, ulong dest, ulong data);
  32. #if 0
  33. static ulong flash_get_size (vu_long *addr, flash_info_t *info);
  34. static void flash_get_offsets (ulong base, flash_info_t *info);
  35. #endif
  36. #ifdef CONFIG_BOOT_8B
  37. static int my_in_8( unsigned char *addr);
  38. static void my_out_8( unsigned char *addr, int val);
  39. #endif
  40. #ifdef CONFIG_BOOT_16B
  41. static int my_in_be16( unsigned short *addr);
  42. static void my_out_be16( unsigned short *addr, int val);
  43. #endif
  44. #ifdef CONFIG_BOOT_32B
  45. static unsigned my_in_be32( unsigned *addr);
  46. static void my_out_be32( unsigned *addr, int val);
  47. #endif
  48. /*-----------------------------------------------------------------------
  49. */
  50. unsigned long flash_init (void)
  51. {
  52. volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
  53. volatile memctl8xx_t *memctl = &immap->im_memctl;
  54. unsigned long size_b0, size_b1;
  55. int i;
  56. size_b0=0;
  57. size_b1=0;
  58. /* Init: no FLASHes known */
  59. for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
  60. flash_info[i].flash_id = FLASH_UNKNOWN;
  61. }
  62. #ifdef CONFIG_SYS_DOC_BASE
  63. #ifndef CONFIG_FEL8xx_AT
  64. memctl->memc_or5 = (0xffff8000 | CONFIG_SYS_OR_TIMING_DOC ); /* 32k bytes */
  65. memctl->memc_br5 = CONFIG_SYS_DOC_BASE | 0x401;
  66. #else
  67. memctl->memc_or3 = (0xffff8000 | CONFIG_SYS_OR_TIMING_DOC ); /* 32k bytes */
  68. memctl->memc_br3 = CONFIG_SYS_DOC_BASE | 0x401;
  69. #endif
  70. #endif
  71. #if defined( CONFIG_BOOT_8B)
  72. /* memctl->memc_or0 = 0xfff80ff4; /###* 4MB bytes */
  73. /* memctl->memc_br0 = 0x40000401; */
  74. size_b0 = 0x80000; /* 512 K */
  75. flash_info[0].flash_id = FLASH_MAN_AMD | FLASH_AM040;
  76. flash_info[0].sector_count = 8;
  77. flash_info[0].size = 0x00080000;
  78. /* set up sector start address table */
  79. for (i = 0; i < flash_info[0].sector_count; i++)
  80. flash_info[0].start[i] = 0x40000000 + (i * 0x10000);
  81. /* protect all sectors */
  82. for (i = 0; i < flash_info[0].sector_count; i++)
  83. flash_info[0].protect[i] = 0x1;
  84. #elif defined (CONFIG_BOOT_16B)
  85. /* memctl->memc_or0 = 0xfff80ff4; /###* 4MB bytes */
  86. /* memctl->memc_br0 = 0x40000401; */
  87. size_b0 = 0x400000; /* 4MB , assume AMD29LV320B */
  88. flash_info[0].flash_id = FLASH_MAN_AMD | FLASH_AM320B;
  89. flash_info[0].sector_count = 67;
  90. flash_info[0].size = 0x00400000;
  91. /* set up sector start address table */
  92. flash_info[0].start[0] = 0x40000000 ;
  93. flash_info[0].start[1] = 0x40000000 + 0x4000;
  94. flash_info[0].start[2] = 0x40000000 + 0x6000;
  95. flash_info[0].start[3] = 0x40000000 + 0x8000;
  96. for (i = 4; i < flash_info[0].sector_count; i++)
  97. flash_info[0].start[i] = 0x40000000 + 0x10000 + ((i-4) * 0x10000);
  98. /* protect all sectors */
  99. for (i = 0; i < flash_info[0].sector_count; i++)
  100. flash_info[0].protect[i] = 0x1;
  101. #endif
  102. #ifdef CONFIG_BOOT_32B
  103. /* Static FLASH Bank configuration here - FIXME XXX */
  104. size_b0 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]);
  105. if (flash_info[0].flash_id == FLASH_UNKNOWN) {
  106. printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
  107. size_b0, size_b0<<20);
  108. }
  109. size_b1 = flash_get_size((vu_long *)FLASH_BASE1_PRELIM, &flash_info[1]);
  110. if (size_b1 > size_b0) {
  111. printf ("## ERROR: "
  112. "Bank 1 (0x%08lx = %ld MB) > Bank 0 (0x%08lx = %ld MB)\n",
  113. size_b1, size_b1<<20,
  114. size_b0, size_b0<<20
  115. );
  116. flash_info[0].flash_id = FLASH_UNKNOWN;
  117. flash_info[1].flash_id = FLASH_UNKNOWN;
  118. flash_info[0].sector_count = -1;
  119. flash_info[1].sector_count = -1;
  120. flash_info[0].size = 0;
  121. flash_info[1].size = 0;
  122. return (0);
  123. }
  124. /* Remap FLASH according to real size */
  125. memctl->memc_or0 = CONFIG_SYS_OR_TIMING_FLASH | (-size_b0 & OR_AM_MSK);
  126. memctl->memc_br0 = (CONFIG_SYS_FLASH_BASE & BR_BA_MSK) | BR_MS_GPCM | BR_V;
  127. /* Re-do sizing to get full correct info */
  128. size_b0 = flash_get_size((vu_long *)CONFIG_SYS_FLASH_BASE, &flash_info[0]);
  129. flash_get_offsets (CONFIG_SYS_FLASH_BASE, &flash_info[0]);
  130. #if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
  131. /* monitor protection ON by default */
  132. flash_protect(FLAG_PROTECT_SET,
  133. CONFIG_SYS_MONITOR_BASE,
  134. CONFIG_SYS_MONITOR_BASE+monitor_flash_len-1,
  135. &flash_info[0]);
  136. #endif
  137. #ifdef CONFIG_ENV_IS_IN_FLASH
  138. /* ENV protection ON by default */
  139. flash_protect(FLAG_PROTECT_SET,
  140. CONFIG_ENV_ADDR,
  141. CONFIG_ENV_ADDR+CONFIG_ENV_SIZE-1,
  142. &flash_info[0]);
  143. #endif
  144. if (size_b1) {
  145. memctl->memc_or1 = CONFIG_SYS_OR_TIMING_FLASH | (-size_b1 & 0xFFFF8000);
  146. memctl->memc_br1 = ((CONFIG_SYS_FLASH_BASE + size_b0) & BR_BA_MSK) |
  147. BR_MS_GPCM | BR_V;
  148. /* Re-do sizing to get full correct info */
  149. size_b1 = flash_get_size((vu_long *)(CONFIG_SYS_FLASH_BASE + size_b0),
  150. &flash_info[1]);
  151. flash_get_offsets (CONFIG_SYS_FLASH_BASE + size_b0, &flash_info[1]);
  152. #if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
  153. /* monitor protection ON by default */
  154. flash_protect(FLAG_PROTECT_SET,
  155. CONFIG_SYS_MONITOR_BASE,
  156. CONFIG_SYS_MONITOR_BASE+monitor_flash_len-1,
  157. &flash_info[1]);
  158. #endif
  159. #ifdef CONFIG_ENV_IS_IN_FLASH
  160. /* ENV protection ON by default */
  161. flash_protect(FLAG_PROTECT_SET,
  162. CONFIG_ENV_ADDR,
  163. CONFIG_ENV_ADDR+CONFIG_ENV_SIZE-1,
  164. &flash_info[1]);
  165. #endif
  166. } else {
  167. memctl->memc_br1 = 0; /* invalidate bank */
  168. flash_info[1].flash_id = FLASH_UNKNOWN;
  169. flash_info[1].sector_count = -1;
  170. }
  171. flash_info[0].size = size_b0;
  172. flash_info[1].size = size_b1;
  173. #endif /* CONFIG_BOOT_32B */
  174. return (size_b0 + size_b1);
  175. }
  176. #if 0
  177. /*-----------------------------------------------------------------------
  178. */
  179. static void flash_get_offsets (ulong base, flash_info_t *info)
  180. {
  181. int i;
  182. /* set up sector start address table */
  183. if (info->flash_id & FLASH_BTYPE) {
  184. /* set sector offsets for bottom boot block type */
  185. info->start[0] = base + 0x00000000;
  186. info->start[1] = base + 0x00008000;
  187. info->start[2] = base + 0x0000C000;
  188. info->start[3] = base + 0x00010000;
  189. for (i = 4; i < info->sector_count; i++) {
  190. info->start[i] = base + (i * 0x00020000) - 0x00060000;
  191. }
  192. } else {
  193. /* set sector offsets for top boot block type */
  194. i = info->sector_count - 1;
  195. info->start[i--] = base + info->size - 0x00008000;
  196. info->start[i--] = base + info->size - 0x0000C000;
  197. info->start[i--] = base + info->size - 0x00010000;
  198. for (; i >= 0; i--) {
  199. info->start[i] = base + i * 0x00020000;
  200. }
  201. }
  202. }
  203. #endif
  204. /*-----------------------------------------------------------------------
  205. */
  206. void flash_print_info (flash_info_t *info)
  207. {
  208. int i;
  209. if (info->flash_id == FLASH_UNKNOWN) {
  210. printf ("missing or unknown FLASH type\n");
  211. return;
  212. }
  213. switch (info->flash_id & FLASH_VENDMASK) {
  214. case FLASH_MAN_AMD: printf ("AMD "); break;
  215. case FLASH_MAN_FUJ: printf ("FUJITSU "); break;
  216. default: printf ("Unknown Vendor "); break;
  217. }
  218. switch (info->flash_id & FLASH_TYPEMASK) {
  219. case FLASH_AM400B: printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
  220. break;
  221. case FLASH_AM400T: printf ("AM29LV400T (4 Mbit, top boot sector)\n");
  222. break;
  223. case FLASH_AM800B: printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
  224. break;
  225. case FLASH_AM800T: printf ("AM29LV800T (8 Mbit, top boot sector)\n");
  226. break;
  227. case FLASH_AM160B: printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
  228. break;
  229. case FLASH_AM160T: printf ("AM29LV160T (16 Mbit, top boot sector)\n");
  230. break;
  231. case FLASH_AM320B: printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
  232. break;
  233. case FLASH_AM320T: printf ("AM29LV320T (32 Mbit, top boot sector)\n");
  234. break;
  235. default: printf ("Unknown Chip Type\n");
  236. break;
  237. }
  238. printf (" Size: %ld MB in %d Sectors\n",
  239. info->size >> 20, info->sector_count);
  240. printf (" Sector Start Addresses:");
  241. for (i=0; i<info->sector_count; ++i) {
  242. if ((i % 5) == 0)
  243. printf ("\n ");
  244. printf (" %08lX%s",
  245. info->start[i],
  246. info->protect[i] ? " (RO)" : " "
  247. );
  248. }
  249. printf ("\n");
  250. return;
  251. }
  252. /*-----------------------------------------------------------------------
  253. */
  254. /*-----------------------------------------------------------------------
  255. */
  256. /*
  257. * The following code cannot be run from FLASH!
  258. */
  259. #if 0
  260. static ulong flash_get_size (vu_long *addr, flash_info_t *info)
  261. {
  262. short i;
  263. ulong value;
  264. ulong base = (ulong)addr;
  265. /* Write auto select command: read Manufacturer ID */
  266. addr[0x0555] = 0x00AA00AA;
  267. addr[0x02AA] = 0x00550055;
  268. addr[0x0555] = 0x00900090;
  269. value = addr[0];
  270. switch (value) {
  271. case AMD_MANUFACT:
  272. info->flash_id = FLASH_MAN_AMD;
  273. break;
  274. case FUJ_MANUFACT:
  275. info->flash_id = FLASH_MAN_FUJ;
  276. break;
  277. default:
  278. info->flash_id = FLASH_UNKNOWN;
  279. info->sector_count = 0;
  280. info->size = 0;
  281. return (0); /* no or unknown flash */
  282. }
  283. value = addr[1]; /* device ID */
  284. switch (value) {
  285. case AMD_ID_LV400T:
  286. info->flash_id += FLASH_AM400T;
  287. info->sector_count = 11;
  288. info->size = 0x00100000;
  289. break; /* => 1 MB */
  290. case AMD_ID_LV400B:
  291. info->flash_id += FLASH_AM400B;
  292. info->sector_count = 11;
  293. info->size = 0x00100000;
  294. break; /* => 1 MB */
  295. case AMD_ID_LV800T:
  296. info->flash_id += FLASH_AM800T;
  297. info->sector_count = 19;
  298. info->size = 0x00200000;
  299. break; /* => 2 MB */
  300. case AMD_ID_LV800B:
  301. info->flash_id += FLASH_AM800B;
  302. info->sector_count = 19;
  303. info->size = 0x00200000;
  304. break; /* => 2 MB */
  305. case AMD_ID_LV160T:
  306. info->flash_id += FLASH_AM160T;
  307. info->sector_count = 35;
  308. info->size = 0x00400000;
  309. break; /* => 4 MB */
  310. case AMD_ID_LV160B:
  311. info->flash_id += FLASH_AM160B;
  312. info->sector_count = 35;
  313. info->size = 0x00400000;
  314. break; /* => 4 MB */
  315. #if 0 /* enable when device IDs are available */
  316. case AMD_ID_LV320T:
  317. info->flash_id += FLASH_AM320T;
  318. info->sector_count = 67;
  319. info->size = 0x00800000;
  320. break; /* => 8 MB */
  321. case AMD_ID_LV320B:
  322. info->flash_id += FLASH_AM320B;
  323. info->sector_count = 67;
  324. info->size = 0x00800000;
  325. break; /* => 8 MB */
  326. #endif
  327. default:
  328. info->flash_id = FLASH_UNKNOWN;
  329. return (0); /* => no or unknown flash */
  330. }
  331. /* set up sector start address table */
  332. if (info->flash_id & FLASH_BTYPE) {
  333. /* set sector offsets for bottom boot block type */
  334. info->start[0] = base + 0x00000000;
  335. info->start[1] = base + 0x00008000;
  336. info->start[2] = base + 0x0000C000;
  337. info->start[3] = base + 0x00010000;
  338. for (i = 4; i < info->sector_count; i++) {
  339. info->start[i] = base + (i * 0x00020000) - 0x00060000;
  340. }
  341. } else {
  342. /* set sector offsets for top boot block type */
  343. i = info->sector_count - 1;
  344. info->start[i--] = base + info->size - 0x00008000;
  345. info->start[i--] = base + info->size - 0x0000C000;
  346. info->start[i--] = base + info->size - 0x00010000;
  347. for (; i >= 0; i--) {
  348. info->start[i] = base + i * 0x00020000;
  349. }
  350. }
  351. /* check for protected sectors */
  352. for (i = 0; i < info->sector_count; i++) {
  353. /* read sector protection at sector address, (A7 .. A0) = 0x02 */
  354. /* D0 = 1 if protected */
  355. addr = (volatile unsigned long *)(info->start[i]);
  356. info->protect[i] = addr[2] & 1;
  357. }
  358. /*
  359. * Prevent writes to uninitialized FLASH.
  360. */
  361. if (info->flash_id != FLASH_UNKNOWN) {
  362. addr = (volatile unsigned long *)info->start[0];
  363. *addr = 0x00F000F0; /* reset bank */
  364. }
  365. return (info->size);
  366. }
  367. #endif
  368. /*-----------------------------------------------------------------------
  369. */
  370. int flash_erase (flash_info_t *info, int s_first, int s_last)
  371. {
  372. vu_long *addr = (vu_long*)(info->start[0]);
  373. int flag, prot, sect, l_sect,in_mid,in_did;
  374. ulong start, now, last;
  375. if ((s_first < 0) || (s_first > s_last)) {
  376. if (info->flash_id == FLASH_UNKNOWN) {
  377. printf ("- missing\n");
  378. } else {
  379. printf ("- no sectors to erase\n");
  380. }
  381. return 1;
  382. }
  383. if ((info->flash_id == FLASH_UNKNOWN) ||
  384. (info->flash_id > FLASH_AMD_COMP)) {
  385. printf ("Can't erase unknown flash type %08lx - aborted\n",
  386. info->flash_id);
  387. return 1;
  388. }
  389. prot = 0;
  390. for (sect=s_first; sect<=s_last; ++sect) {
  391. if (info->protect[sect]) {
  392. prot++;
  393. }
  394. }
  395. if (prot) {
  396. printf ("- Warning: %d protected sectors will not be erased!\n",
  397. prot);
  398. } else {
  399. printf ("\n");
  400. }
  401. l_sect = -1;
  402. /* Disable interrupts which might cause a timeout here */
  403. flag = disable_interrupts();
  404. #if defined (CONFIG_BOOT_8B )
  405. my_out_8( (unsigned char * ) ((ulong)addr+0x555) , 0xaa );
  406. my_out_8( (unsigned char * ) ((ulong)addr+0x2aa) , 0x55 );
  407. my_out_8( (unsigned char * ) ((ulong)addr+0x555) , 0x90 );
  408. in_mid=my_in_8( (unsigned char * ) addr );
  409. in_did=my_in_8( (unsigned char * ) ((ulong)addr+1) );
  410. printf(" man ID=0x%x, dev ID=0x%x.\n",in_mid,in_did );
  411. my_out_8( (unsigned char *)addr, 0xf0);
  412. udelay(1);
  413. my_out_8( (unsigned char *) ((ulong)addr+0x555),0xaa );
  414. my_out_8( (unsigned char *) ((ulong)addr+0x2aa),0x55 );
  415. my_out_8( (unsigned char *) ((ulong)addr+0x555),0x80 );
  416. my_out_8( (unsigned char *) ((ulong)addr+0x555),0xaa );
  417. my_out_8( (unsigned char *) ((ulong)addr+0x2aa),0x55 );
  418. /* Start erase on unprotected sectors */
  419. for (sect = s_first; sect<=s_last; sect++) {
  420. if (info->protect[sect] == 0) { /* not protected */
  421. addr = (vu_long*)(info->start[sect]);
  422. /*addr[0] = 0x00300030; */
  423. my_out_8( (unsigned char *) ((ulong)addr),0x30 );
  424. l_sect = sect;
  425. }
  426. }
  427. #elif defined(CONFIG_BOOT_16B )
  428. my_out_be16( (unsigned short * ) ((ulong)addr+ (0xaaa)) , 0xaa );
  429. my_out_be16( (unsigned short * ) ((ulong)addr+ (0x554)) , 0x55 );
  430. my_out_be16( (unsigned short * ) ((ulong)addr+ (0xaaa)) , 0x90 );
  431. in_mid=my_in_be16( (unsigned short * ) addr );
  432. in_did=my_in_be16 ( (unsigned short * ) ((ulong)addr+2) );
  433. printf(" man ID=0x%x, dev ID=0x%x.\n",in_mid,in_did );
  434. my_out_be16( (unsigned short *)addr, 0xf0);
  435. udelay(1);
  436. my_out_be16( (unsigned short *) ((ulong)addr+ 0xaaa),0xaa );
  437. my_out_be16( (unsigned short *) ((ulong)addr+0x554),0x55 );
  438. my_out_be16( (unsigned short *) ((ulong)addr+0xaaa),0x80 );
  439. my_out_be16( (unsigned short *) ((ulong)addr+0xaaa),0xaa );
  440. my_out_be16( (unsigned short *) ((ulong)addr+0x554),0x55 );
  441. /* Start erase on unprotected sectors */
  442. for (sect = s_first; sect<=s_last; sect++) {
  443. if (info->protect[sect] == 0) { /* not protected */
  444. addr = (vu_long*)(info->start[sect]);
  445. my_out_be16( (unsigned short *) ((ulong)addr),0x30 );
  446. l_sect = sect;
  447. }
  448. }
  449. #elif defined(CONFIG_BOOT_32B)
  450. my_out_be32( (unsigned * ) ((ulong)addr+0x1554) , 0xaa );
  451. my_out_be32( (unsigned * ) ((ulong)addr+0xaa8) , 0x55 );
  452. my_out_be32( (unsigned *) ((ulong)addr+0x1554) , 0x90 );
  453. in_mid=my_in_be32( (unsigned * ) addr );
  454. in_did=my_in_be32( (unsigned * ) ((ulong)addr+4) );
  455. printf(" man ID=0x%x, dev ID=0x%x.\n",in_mid,in_did );
  456. my_out_be32( (unsigned *)addr, 0xf0);
  457. udelay(1);
  458. my_out_be32( (unsigned *) ((ulong)addr+0x1554),0xaa );
  459. my_out_be32( (unsigned *) ((ulong)addr+0xaa8),0x55 );
  460. my_out_be32( (unsigned *) ((ulong)addr+0x1554),0x80 );
  461. my_out_be32( (unsigned *) ((ulong)addr+0x1554),0xaa );
  462. my_out_be32( (unsigned *) ((ulong)addr+0xaa8),0x55 );
  463. /* Start erase on unprotected sectors */
  464. for (sect = s_first; sect<=s_last; sect++) {
  465. if (info->protect[sect] == 0) { /* not protected */
  466. addr = (vu_long*)(info->start[sect]);
  467. my_out_be32( (unsigned *) ((ulong)addr),0x00300030 );
  468. l_sect = sect;
  469. }
  470. }
  471. #else
  472. # error CONFIG_BOOT_(size)B missing.
  473. #endif
  474. /* re-enable interrupts if necessary */
  475. if (flag)
  476. enable_interrupts();
  477. /* wait at least 80us - let's wait 1 ms */
  478. udelay (1000);
  479. /*
  480. * We wait for the last triggered sector
  481. */
  482. if (l_sect < 0)
  483. goto DONE;
  484. start = get_timer (0);
  485. last = start;
  486. addr = (vu_long*)(info->start[l_sect]);
  487. #if defined (CONFIG_BOOT_8B)
  488. while ( (my_in_8((unsigned char *)addr) & 0x80) != 0x80 )
  489. #elif defined(CONFIG_BOOT_16B )
  490. while ( (my_in_be16((unsigned short *)addr) & 0x0080) != 0x0080 )
  491. #elif defined(CONFIG_BOOT_32B)
  492. while ( (my_in_be32((unsigned *)addr) & 0x00800080) != 0x00800080 )
  493. #else
  494. # error CONFIG_BOOT_(size)B missing.
  495. #endif
  496. {
  497. if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
  498. printf ("Timeout\n");
  499. return 1;
  500. }
  501. /* show that we're waiting */
  502. if ((now - last) > 1000) { /* every second */
  503. putc ('.');
  504. last = now;
  505. }
  506. }
  507. DONE:
  508. /* reset to read mode */
  509. addr = (volatile unsigned long *)info->start[0];
  510. #if defined (CONFIG_BOOT_8B)
  511. my_out_8( (unsigned char *)addr, 0xf0);
  512. #elif defined(CONFIG_BOOT_16B )
  513. my_out_be16( (unsigned short * ) addr , 0x00f0 );
  514. #elif defined(CONFIG_BOOT_32B)
  515. my_out_be32 ( (unsigned *)addr, 0x00F000F0 ); /* reset bank */
  516. #else
  517. # error CONFIG_BOOT_(size)B missing.
  518. #endif
  519. printf (" done\n");
  520. return 0;
  521. }
  522. /*-----------------------------------------------------------------------
  523. * Copy memory to flash, returns:
  524. * 0 - OK
  525. * 1 - write timeout
  526. * 2 - Flash not erased
  527. */
  528. int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
  529. {
  530. ulong cp, wp, data;
  531. int i, l, rc;
  532. wp = (addr & ~3); /* get lower word aligned address */
  533. /*
  534. * handle unaligned start bytes
  535. */
  536. if ((l = addr - wp) != 0) {
  537. data = 0;
  538. for (i=0, cp=wp; i<l; ++i, ++cp) {
  539. data = (data << 8) | (*(uchar *)cp);
  540. }
  541. for (; i<4 && cnt>0; ++i) {
  542. data = (data << 8) | *src++;
  543. --cnt;
  544. ++cp;
  545. }
  546. for (; cnt==0 && i<4; ++i, ++cp) {
  547. data = (data << 8) | (*(uchar *)cp);
  548. }
  549. if ((rc = write_word(info, wp, data)) != 0) {
  550. return (rc);
  551. }
  552. wp += 4;
  553. }
  554. /*
  555. * handle word aligned part
  556. */
  557. while (cnt >= 4) {
  558. data = 0;
  559. for (i=0; i<4; ++i) {
  560. data = (data << 8) | *src++;
  561. }
  562. if ((rc = write_word(info, wp, data)) != 0) {
  563. return (rc);
  564. }
  565. wp += 4;
  566. cnt -= 4;
  567. }
  568. if (cnt == 0) {
  569. return (0);
  570. }
  571. /*
  572. * handle unaligned tail bytes
  573. */
  574. data = 0;
  575. for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
  576. data = (data << 8) | *src++;
  577. --cnt;
  578. }
  579. for (; i<4; ++i, ++cp) {
  580. data = (data << 8) | (*(uchar *)cp);
  581. }
  582. return (write_word(info, wp, data));
  583. }
  584. /*-----------------------------------------------------------------------
  585. * Write a word to Flash, returns:
  586. * 0 - OK
  587. * 1 - write timeout
  588. * 2 - Flash not erased
  589. */
  590. static int write_word (flash_info_t *info, ulong dest, ulong data)
  591. {
  592. ulong addr = (ulong)(info->start[0]);
  593. ulong start,last;
  594. int flag;
  595. ulong i;
  596. int data_short[2];
  597. /* Check if Flash is (sufficiently) erased */
  598. if ( ((ulong) *(ulong *)dest & data) != data ) {
  599. return (2);
  600. }
  601. /* Disable interrupts which might cause a timeout here */
  602. flag = disable_interrupts();
  603. #if defined(CONFIG_BOOT_8B)
  604. #ifdef DEBUG
  605. {
  606. int in_mid,in_did;
  607. my_out_8( (unsigned char * ) (addr+0x555) , 0xaa );
  608. my_out_8( (unsigned char * ) (addr+0x2aa) , 0x55 );
  609. my_out_8( (unsigned char * ) (addr+0x555) , 0x90 );
  610. in_mid=my_in_8( (unsigned char * ) addr );
  611. in_did=my_in_8( (unsigned char * ) (addr+1) );
  612. printf(" man ID=0x%x, dev ID=0x%x.\n",in_mid,in_did );
  613. my_out_8( (unsigned char *)addr, 0xf0);
  614. udelay(1);
  615. }
  616. #endif
  617. {
  618. int data_ch[4];
  619. data_ch[0]=(int ) ((data>>24) & 0xff);
  620. data_ch[1]=(int ) ((data>>16) &0xff );
  621. data_ch[2]=(int ) ((data >>8) & 0xff);
  622. data_ch[3]=(int ) (data & 0xff);
  623. for (i=0;i<4;i++ ){
  624. my_out_8( (unsigned char *) (addr+0x555),0xaa);
  625. my_out_8((unsigned char *) (addr+0x2aa),0x55);
  626. my_out_8( (unsigned char *) (addr+0x555),0xa0);
  627. my_out_8((unsigned char *) (dest+i) ,data_ch[i]);
  628. /* re-enable interrupts if necessary */
  629. if (flag)
  630. enable_interrupts();
  631. start = get_timer (0);
  632. last = start;
  633. while( ( my_in_8((unsigned char *) (dest+i)) ) != ( data_ch[i] ) ) {
  634. if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT ) {
  635. return 1;
  636. }
  637. }
  638. }/* for */
  639. }
  640. #elif defined( CONFIG_BOOT_16B)
  641. data_short[0]=(int) (data>>16) & 0xffff;
  642. data_short[1]=(int ) data & 0xffff ;
  643. for (i=0;i<2;i++ ){
  644. my_out_be16( (unsigned short *) ((ulong)addr+ 0xaaa),0xaa );
  645. my_out_be16( (unsigned short *) ((ulong)addr+ 0x554),0x55 );
  646. my_out_be16( (unsigned short *) ((ulong)addr+ 0xaaa),0xa0 );
  647. my_out_be16( (unsigned short *) (dest+(i*2)) ,data_short[i]);
  648. /* re-enable interrupts if necessary */
  649. if (flag)
  650. enable_interrupts();
  651. start = get_timer (0);
  652. last = start;
  653. while( ( my_in_be16((unsigned short *) (dest+(i*2))) ) != ( data_short[i] ) ) {
  654. if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT ) {
  655. return 1;
  656. }
  657. }
  658. }
  659. #elif defined( CONFIG_BOOT_32B)
  660. addr[0x0555] = 0x00AA00AA;
  661. addr[0x02AA] = 0x00550055;
  662. addr[0x0555] = 0x00A000A0;
  663. *((vu_long *)dest) = data;
  664. /* re-enable interrupts if necessary */
  665. if (flag)
  666. enable_interrupts();
  667. /* data polling for D7 */
  668. start = get_timer (0);
  669. while ((*((vu_long *)dest) & 0x00800080) != (data & 0x00800080)) {
  670. if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
  671. return (1);
  672. }
  673. }
  674. #endif
  675. return (0);
  676. }
  677. #ifdef CONFIG_BOOT_8B
  678. static int my_in_8 ( unsigned char *addr)
  679. {
  680. int ret;
  681. __asm__ __volatile__("lbz%U1%X1 %0,%1; eieio" : "=r" (ret) : "m" (*addr));
  682. return ret;
  683. }
  684. static void my_out_8 ( unsigned char *addr, int val)
  685. {
  686. __asm__ __volatile__("stb%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));
  687. }
  688. #endif
  689. #ifdef CONFIG_BOOT_16B
  690. static int my_in_be16( unsigned short *addr)
  691. {
  692. int ret;
  693. __asm__ __volatile__("lhz%U1%X1 %0,%1; eieio" : "=r" (ret) : "m" (*addr));
  694. return ret;
  695. }
  696. static void my_out_be16( unsigned short *addr, int val)
  697. {
  698. __asm__ __volatile__("sth%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));
  699. }
  700. #endif
  701. #ifdef CONFIG_BOOT_32B
  702. static unsigned my_in_be32( unsigned *addr)
  703. {
  704. unsigned ret;
  705. __asm__ __volatile__("lwz%U1%X1 %0,%1; eieio" : "=r" (ret) : "m" (*addr));
  706. return ret;
  707. }
  708. static void my_out_be32( unsigned *addr, int val)
  709. {
  710. __asm__ __volatile__("stw%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));
  711. }
  712. #endif