flash.c 22 KB

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