flash.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666
  1. /*
  2. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  3. *
  4. * SPDX-License-Identifier: GPL-2.0+
  5. */
  6. #include <common.h>
  7. #include <mpc8xx.h>
  8. #ifndef CONFIG_ENV_ADDR
  9. #define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + CONFIG_ENV_OFFSET)
  10. #endif
  11. flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
  12. /*-----------------------------------------------------------------------
  13. * Functions
  14. */
  15. static int write_word(flash_info_t *info, ulong dest, ulong data);
  16. #ifdef CONFIG_BOOT_8B
  17. static int my_in_8(unsigned char *addr);
  18. static void my_out_8(unsigned char *addr, int val);
  19. #endif
  20. #ifdef CONFIG_BOOT_16B
  21. static int my_in_be16(unsigned short *addr);
  22. static void my_out_be16(unsigned short *addr, int val);
  23. #endif
  24. #ifdef CONFIG_BOOT_32B
  25. static unsigned my_in_be32(unsigned *addr);
  26. static void my_out_be32(unsigned *addr, int val);
  27. #endif
  28. /*-----------------------------------------------------------------------
  29. */
  30. unsigned long flash_init(void)
  31. {
  32. volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
  33. volatile memctl8xx_t *memctl = &immap->im_memctl;
  34. unsigned long size_b0, size_b1;
  35. int i;
  36. size_b0 = 0;
  37. size_b1 = 0;
  38. /* Init: no FLASHes known */
  39. for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i)
  40. flash_info[i].flash_id = FLASH_UNKNOWN;
  41. #ifdef CONFIG_SYS_DOC_BASE
  42. #ifndef CONFIG_FEL8xx_AT
  43. /* 32k bytes */
  44. memctl->memc_or5 = (0xffff8000 | CONFIG_SYS_OR_TIMING_DOC);
  45. memctl->memc_br5 = CONFIG_SYS_DOC_BASE | 0x401;
  46. #else
  47. /* 32k bytes */
  48. memctl->memc_or3 = (0xffff8000 | CONFIG_SYS_OR_TIMING_DOC);
  49. memctl->memc_br3 = CONFIG_SYS_DOC_BASE | 0x401;
  50. #endif
  51. #endif
  52. #if defined(CONFIG_BOOT_8B)
  53. size_b0 = 0x80000; /* 512 K */
  54. flash_info[0].flash_id = FLASH_MAN_AMD | FLASH_AM040;
  55. flash_info[0].sector_count = 8;
  56. flash_info[0].size = 0x00080000;
  57. /* set up sector start address table */
  58. for (i = 0; i < flash_info[0].sector_count; i++)
  59. flash_info[0].start[i] = 0x40000000 + (i * 0x10000);
  60. /* protect all sectors */
  61. for (i = 0; i < flash_info[0].sector_count; i++)
  62. flash_info[0].protect[i] = 0x1;
  63. #elif defined(CONFIG_BOOT_16B)
  64. size_b0 = 0x400000; /* 4MB , assume AMD29LV320B */
  65. flash_info[0].flash_id = FLASH_MAN_AMD | FLASH_AM320B;
  66. flash_info[0].sector_count = 67;
  67. flash_info[0].size = 0x00400000;
  68. /* set up sector start address table */
  69. flash_info[0].start[0] = 0x40000000;
  70. flash_info[0].start[1] = 0x40000000 + 0x4000;
  71. flash_info[0].start[2] = 0x40000000 + 0x6000;
  72. flash_info[0].start[3] = 0x40000000 + 0x8000;
  73. for (i = 4; i < flash_info[0].sector_count; i++) {
  74. flash_info[0].start[i] =
  75. 0x40000000 + 0x10000 + ((i - 4) * 0x10000);
  76. }
  77. /* protect all sectors */
  78. for (i = 0; i < flash_info[0].sector_count; i++)
  79. flash_info[0].protect[i] = 0x1;
  80. #endif
  81. #ifdef CONFIG_BOOT_32B
  82. /* Static FLASH Bank configuration here - FIXME XXX */
  83. size_b0 = flash_get_size((vu_long *) FLASH_BASE0_PRELIM,
  84. &flash_info[0]);
  85. if (flash_info[0].flash_id == FLASH_UNKNOWN) {
  86. printf("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
  87. size_b0, size_b0 << 20);
  88. }
  89. size_b1 = flash_get_size((vu_long *) FLASH_BASE1_PRELIM,
  90. &flash_info[1]);
  91. if (size_b1 > size_b0) {
  92. printf("## ERROR: "
  93. "Bank 1 (0x%08lx = %ld MB) > Bank 0 (0x%08lx = %ld MB)\n",
  94. size_b1, size_b1 << 20, size_b0, size_b0 << 20);
  95. flash_info[0].flash_id = FLASH_UNKNOWN;
  96. flash_info[1].flash_id = FLASH_UNKNOWN;
  97. flash_info[0].sector_count = -1;
  98. flash_info[1].sector_count = -1;
  99. flash_info[0].size = 0;
  100. flash_info[1].size = 0;
  101. return 0;
  102. }
  103. /* Remap FLASH according to real size */
  104. memctl->memc_or0 = CONFIG_SYS_OR_TIMING_FLASH |
  105. (-size_b0 & OR_AM_MSK);
  106. memctl->memc_br0 = (CONFIG_SYS_FLASH_BASE & BR_BA_MSK) |
  107. BR_MS_GPCM | BR_V;
  108. /* Re-do sizing to get full correct info */
  109. size_b0 = flash_get_size((vu_long *) CONFIG_SYS_FLASH_BASE,
  110. &flash_info[0]);
  111. flash_get_offsets(CONFIG_SYS_FLASH_BASE, &flash_info[0]);
  112. #if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
  113. /* monitor protection ON by default */
  114. flash_protect(FLAG_PROTECT_SET,
  115. CONFIG_SYS_MONITOR_BASE,
  116. CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1,
  117. &flash_info[0]);
  118. #endif
  119. #ifdef CONFIG_ENV_IS_IN_FLASH
  120. /* ENV protection ON by default */
  121. flash_protect(FLAG_PROTECT_SET,
  122. CONFIG_ENV_ADDR,
  123. CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, &flash_info[0]);
  124. #endif
  125. if (size_b1) {
  126. memctl->memc_or1 = CONFIG_SYS_OR_TIMING_FLASH |
  127. (-size_b1 & 0xFFFF8000);
  128. memctl->memc_br1 = ((CONFIG_SYS_FLASH_BASE +
  129. size_b0) & BR_BA_MSK) | BR_MS_GPCM | BR_V;
  130. /* Re-do sizing to get full correct info */
  131. size_b1 = flash_get_size((vu_long *)(CONFIG_SYS_FLASH_BASE +
  132. size_b0), &flash_info[1]);
  133. flash_get_offsets(CONFIG_SYS_FLASH_BASE + size_b0,
  134. &flash_info[1]);
  135. #if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
  136. /* monitor protection ON by default */
  137. flash_protect(FLAG_PROTECT_SET,
  138. CONFIG_SYS_MONITOR_BASE,
  139. CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1,
  140. &flash_info[1]);
  141. #endif
  142. #ifdef CONFIG_ENV_IS_IN_FLASH
  143. /* ENV protection ON by default */
  144. flash_protect(FLAG_PROTECT_SET,
  145. CONFIG_ENV_ADDR,
  146. CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1,
  147. &flash_info[1]);
  148. #endif
  149. } else {
  150. memctl->memc_br1 = 0; /* invalidate bank */
  151. flash_info[1].flash_id = FLASH_UNKNOWN;
  152. flash_info[1].sector_count = -1;
  153. }
  154. flash_info[0].size = size_b0;
  155. flash_info[1].size = size_b1;
  156. #endif /* CONFIG_BOOT_32B */
  157. return size_b0 + size_b1;
  158. }
  159. void flash_print_info(flash_info_t *info)
  160. {
  161. int i;
  162. if (info->flash_id == FLASH_UNKNOWN) {
  163. printf("missing or unknown FLASH type\n");
  164. return;
  165. }
  166. switch (info->flash_id & FLASH_VENDMASK) {
  167. case FLASH_MAN_AMD:
  168. printf("AMD ");
  169. break;
  170. case FLASH_MAN_FUJ:
  171. printf("FUJITSU ");
  172. break;
  173. default:
  174. printf("Unknown Vendor ");
  175. break;
  176. }
  177. switch (info->flash_id & FLASH_TYPEMASK) {
  178. case FLASH_AM400B:
  179. printf("AM29LV400B (4 Mbit, bottom boot sect)\n");
  180. break;
  181. case FLASH_AM400T:
  182. printf("AM29LV400T (4 Mbit, top boot sector)\n");
  183. break;
  184. case FLASH_AM800B:
  185. printf("AM29LV800B (8 Mbit, bottom boot sect)\n");
  186. break;
  187. case FLASH_AM800T:
  188. printf("AM29LV800T (8 Mbit, top boot sector)\n");
  189. break;
  190. case FLASH_AM160B:
  191. printf("AM29LV160B (16 Mbit, bottom boot sect)\n");
  192. break;
  193. case FLASH_AM160T:
  194. printf("AM29LV160T (16 Mbit, top boot sector)\n");
  195. break;
  196. case FLASH_AM320B:
  197. printf("AM29LV320B (32 Mbit, bottom boot sect)\n");
  198. break;
  199. case FLASH_AM320T:
  200. printf("AM29LV320T (32 Mbit, top boot sector)\n");
  201. break;
  202. default:
  203. printf("Unknown Chip Type\n");
  204. break;
  205. }
  206. printf(" Size: %ld MB in %d Sectors\n",
  207. info->size >> 20, info->sector_count);
  208. printf(" Sector Start Addresses:");
  209. for (i = 0; i < info->sector_count; ++i) {
  210. if ((i % 5) == 0)
  211. printf("\n ");
  212. printf(" %08lX%s",
  213. info->start[i], info->protect[i] ? " (RO)" : " ");
  214. }
  215. printf("\n");
  216. return;
  217. }
  218. /*
  219. * The following code cannot be run from FLASH!
  220. */
  221. int flash_erase(flash_info_t *info, int s_first, int s_last)
  222. {
  223. vu_long *addr = (vu_long *) (info->start[0]);
  224. int flag, prot, sect, l_sect, in_mid, in_did;
  225. ulong start, now, last;
  226. if ((s_first < 0) || (s_first > s_last)) {
  227. if (info->flash_id == FLASH_UNKNOWN)
  228. printf("- missing\n");
  229. else
  230. printf("- no sectors to erase\n");
  231. return 1;
  232. }
  233. if ((info->flash_id == FLASH_UNKNOWN) ||
  234. (info->flash_id > FLASH_AMD_COMP)) {
  235. printf("Can't erase unknown flash type %08lx - aborted\n",
  236. info->flash_id);
  237. return 1;
  238. }
  239. prot = 0;
  240. for (sect = s_first; sect <= s_last; ++sect) {
  241. if (info->protect[sect])
  242. prot++;
  243. }
  244. if (prot) {
  245. printf("- Warning: %d protected sectors will not be erased!\n",
  246. prot);
  247. } else {
  248. printf("\n");
  249. }
  250. l_sect = -1;
  251. /* Disable interrupts which might cause a timeout here */
  252. flag = disable_interrupts();
  253. #if defined(CONFIG_BOOT_8B)
  254. my_out_8((unsigned char *)((ulong)addr + 0x555), 0xaa);
  255. my_out_8((unsigned char *)((ulong)addr + 0x2aa), 0x55);
  256. my_out_8((unsigned char *)((ulong)addr + 0x555), 0x90);
  257. in_mid = my_in_8((unsigned char *)addr);
  258. in_did = my_in_8((unsigned char *)((ulong)addr + 1));
  259. printf(" man ID=0x%x, dev ID=0x%x.\n", in_mid, in_did);
  260. my_out_8((unsigned char *)addr, 0xf0);
  261. udelay(1);
  262. my_out_8((unsigned char *)((ulong)addr + 0x555), 0xaa);
  263. my_out_8((unsigned char *)((ulong)addr + 0x2aa), 0x55);
  264. my_out_8((unsigned char *)((ulong)addr + 0x555), 0x80);
  265. my_out_8((unsigned char *)((ulong)addr + 0x555), 0xaa);
  266. my_out_8((unsigned char *)((ulong)addr + 0x2aa), 0x55);
  267. /* Start erase on unprotected sectors */
  268. for (sect = s_first; sect <= s_last; sect++) {
  269. if (info->protect[sect] == 0) { /* not protected */
  270. addr = (vu_long *) (info->start[sect]);
  271. /*addr[0] = 0x00300030; */
  272. my_out_8((unsigned char *)((ulong)addr), 0x30);
  273. l_sect = sect;
  274. }
  275. }
  276. #elif defined(CONFIG_BOOT_16B)
  277. my_out_be16((unsigned short *)((ulong)addr + (0xaaa)), 0xaa);
  278. my_out_be16((unsigned short *)((ulong)addr + (0x554)), 0x55);
  279. my_out_be16((unsigned short *)((ulong)addr + (0xaaa)), 0x90);
  280. in_mid = my_in_be16((unsigned short *)addr);
  281. in_did = my_in_be16((unsigned short *)((ulong)addr + 2));
  282. printf(" man ID=0x%x, dev ID=0x%x.\n", in_mid, in_did);
  283. my_out_be16((unsigned short *)addr, 0xf0);
  284. udelay(1);
  285. my_out_be16((unsigned short *)((ulong)addr + 0xaaa), 0xaa);
  286. my_out_be16((unsigned short *)((ulong)addr + 0x554), 0x55);
  287. my_out_be16((unsigned short *)((ulong)addr + 0xaaa), 0x80);
  288. my_out_be16((unsigned short *)((ulong)addr + 0xaaa), 0xaa);
  289. my_out_be16((unsigned short *)((ulong)addr + 0x554), 0x55);
  290. /* Start erase on unprotected sectors */
  291. for (sect = s_first; sect <= s_last; sect++) {
  292. if (info->protect[sect] == 0) { /* not protected */
  293. addr = (vu_long *) (info->start[sect]);
  294. my_out_be16((unsigned short *)((ulong)addr), 0x30);
  295. l_sect = sect;
  296. }
  297. }
  298. #elif defined(CONFIG_BOOT_32B)
  299. my_out_be32((unsigned *)((ulong)addr + 0x1554), 0xaa);
  300. my_out_be32((unsigned *)((ulong)addr + 0xaa8), 0x55);
  301. my_out_be32((unsigned *)((ulong)addr + 0x1554), 0x90);
  302. in_mid = my_in_be32((unsigned *)addr);
  303. in_did = my_in_be32((unsigned *)((ulong)addr + 4));
  304. printf(" man ID=0x%x, dev ID=0x%x.\n", in_mid, in_did);
  305. my_out_be32((unsigned *) addr, 0xf0);
  306. udelay(1);
  307. my_out_be32((unsigned *)((ulong)addr + 0x1554), 0xaa);
  308. my_out_be32((unsigned *)((ulong)addr + 0xaa8), 0x55);
  309. my_out_be32((unsigned *)((ulong)addr + 0x1554), 0x80);
  310. my_out_be32((unsigned *)((ulong)addr + 0x1554), 0xaa);
  311. my_out_be32((unsigned *)((ulong)addr + 0xaa8), 0x55);
  312. /* Start erase on unprotected sectors */
  313. for (sect = s_first; sect <= s_last; sect++) {
  314. if (info->protect[sect] == 0) { /* not protected */
  315. addr = (vu_long *) (info->start[sect]);
  316. my_out_be32((unsigned *)((ulong)addr), 0x00300030);
  317. l_sect = sect;
  318. }
  319. }
  320. #else
  321. #error CONFIG_BOOT_(size)B missing.
  322. #endif
  323. /* re-enable interrupts if necessary */
  324. if (flag)
  325. enable_interrupts();
  326. /* wait at least 80us - let's wait 1 ms */
  327. udelay(1000);
  328. /*
  329. * We wait for the last triggered sector
  330. */
  331. if (l_sect < 0)
  332. goto DONE;
  333. start = get_timer(0);
  334. last = start;
  335. addr = (vu_long *) (info->start[l_sect]);
  336. #if defined(CONFIG_BOOT_8B)
  337. while ((my_in_8((unsigned char *) addr) & 0x80) != 0x80)
  338. #elif defined(CONFIG_BOOT_16B)
  339. while ((my_in_be16((unsigned short *) addr) & 0x0080) != 0x0080)
  340. #elif defined(CONFIG_BOOT_32B)
  341. while ((my_in_be32((unsigned *) addr) & 0x00800080) != 0x00800080)
  342. #else
  343. #error CONFIG_BOOT_(size)B missing.
  344. #endif
  345. {
  346. now = get_timer(start);
  347. if (now > CONFIG_SYS_FLASH_ERASE_TOUT) {
  348. printf("Timeout\n");
  349. return 1;
  350. }
  351. /* show that we're waiting */
  352. if ((now - last) > 1000) { /* every second */
  353. putc('.');
  354. last = now;
  355. }
  356. }
  357. DONE:
  358. /* reset to read mode */
  359. addr = (volatile unsigned long *) info->start[0];
  360. #if defined(CONFIG_BOOT_8B)
  361. my_out_8((unsigned char *) addr, 0xf0);
  362. #elif defined(CONFIG_BOOT_16B)
  363. my_out_be16((unsigned short *) addr, 0x00f0);
  364. #elif defined(CONFIG_BOOT_32B)
  365. my_out_be32((unsigned *) addr, 0x00F000F0); /* reset bank */
  366. #else
  367. #error CONFIG_BOOT_(size)B missing.
  368. #endif
  369. printf(" done\n");
  370. return 0;
  371. }
  372. /*
  373. * Copy memory to flash, returns:
  374. * 0 - OK
  375. * 1 - write timeout
  376. * 2 - Flash not erased
  377. */
  378. int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
  379. {
  380. ulong cp, wp, data;
  381. int i, l, rc;
  382. wp = (addr & ~3); /* get lower word aligned address */
  383. /*
  384. * handle unaligned start bytes
  385. */
  386. l = addr - wp;
  387. if (l != 0) {
  388. data = 0;
  389. for (i = 0, cp = wp; i < l; ++i, ++cp)
  390. data = (data << 8) | (*(uchar *) cp);
  391. for (; i < 4 && cnt > 0; ++i) {
  392. data = (data << 8) | *src++;
  393. --cnt;
  394. ++cp;
  395. }
  396. for (; cnt == 0 && i < 4; ++i, ++cp)
  397. data = (data << 8) | (*(uchar *) cp);
  398. rc = write_word(info, wp, data);
  399. if (rc != 0)
  400. return rc;
  401. wp += 4;
  402. }
  403. /*
  404. * handle word aligned part
  405. */
  406. while (cnt >= 4) {
  407. data = 0;
  408. for (i = 0; i < 4; ++i)
  409. data = (data << 8) | *src++;
  410. rc = write_word(info, wp, data);
  411. if (rc != 0)
  412. return rc;
  413. wp += 4;
  414. cnt -= 4;
  415. }
  416. if (cnt == 0)
  417. return 0;
  418. /*
  419. * handle unaligned tail bytes
  420. */
  421. data = 0;
  422. for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
  423. data = (data << 8) | *src++;
  424. --cnt;
  425. }
  426. for (; i < 4; ++i, ++cp)
  427. data = (data << 8) | (*(uchar *) cp);
  428. return write_word(info, wp, data);
  429. }
  430. /*
  431. * Write a word to Flash, returns:
  432. * 0 - OK
  433. * 1 - write timeout
  434. * 2 - Flash not erased
  435. */
  436. static int write_word(flash_info_t *info, ulong dest, ulong data)
  437. {
  438. ulong addr = (ulong) (info->start[0]);
  439. ulong start;
  440. int flag;
  441. ulong i;
  442. int data_short[2];
  443. /* Check if Flash is (sufficiently) erased */
  444. if (((ulong)*(ulong *)dest & data) != data)
  445. return 2;
  446. /* Disable interrupts which might cause a timeout here */
  447. flag = disable_interrupts();
  448. #if defined(CONFIG_BOOT_8B)
  449. #ifdef DEBUG
  450. {
  451. int in_mid, in_did;
  452. my_out_8((unsigned char *) (addr + 0x555), 0xaa);
  453. my_out_8((unsigned char *) (addr + 0x2aa), 0x55);
  454. my_out_8((unsigned char *) (addr + 0x555), 0x90);
  455. in_mid = my_in_8((unsigned char *) addr);
  456. in_did = my_in_8((unsigned char *) (addr + 1));
  457. printf(" man ID=0x%x, dev ID=0x%x.\n", in_mid, in_did);
  458. my_out_8((unsigned char *) addr, 0xf0);
  459. udelay(1);
  460. }
  461. #endif
  462. {
  463. int data_ch[4];
  464. data_ch[0] = (int) ((data >> 24) & 0xff);
  465. data_ch[1] = (int) ((data >> 16) & 0xff);
  466. data_ch[2] = (int) ((data >> 8) & 0xff);
  467. data_ch[3] = (int) (data & 0xff);
  468. for (i = 0; i < 4; i++) {
  469. my_out_8((unsigned char *) (addr + 0x555), 0xaa);
  470. my_out_8((unsigned char *) (addr + 0x2aa), 0x55);
  471. my_out_8((unsigned char *) (addr + 0x555), 0xa0);
  472. my_out_8((unsigned char *) (dest + i), data_ch[i]);
  473. /* re-enable interrupts if necessary */
  474. if (flag)
  475. enable_interrupts();
  476. start = get_timer(0);
  477. while ((my_in_8((unsigned char *)(dest + i))) !=
  478. (data_ch[i])) {
  479. if (get_timer(start) >
  480. CONFIG_SYS_FLASH_WRITE_TOUT) {
  481. return 1;
  482. }
  483. }
  484. } /* for */
  485. }
  486. #elif defined(CONFIG_BOOT_16B)
  487. data_short[0] = (int) (data >> 16) & 0xffff;
  488. data_short[1] = (int) data & 0xffff;
  489. for (i = 0; i < 2; i++) {
  490. my_out_be16((unsigned short *)((ulong)addr + 0xaaa), 0xaa);
  491. my_out_be16((unsigned short *)((ulong)addr + 0x554), 0x55);
  492. my_out_be16((unsigned short *)((ulong)addr + 0xaaa), 0xa0);
  493. my_out_be16((unsigned short *)(dest + (i * 2)),
  494. data_short[i]);
  495. /* re-enable interrupts if necessary */
  496. if (flag)
  497. enable_interrupts();
  498. start = get_timer(0);
  499. while ((my_in_be16((unsigned short *)(dest + (i * 2)))) !=
  500. (data_short[i])) {
  501. if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT)
  502. return 1;
  503. }
  504. }
  505. #elif defined(CONFIG_BOOT_32B)
  506. addr[0x0555] = 0x00AA00AA;
  507. addr[0x02AA] = 0x00550055;
  508. addr[0x0555] = 0x00A000A0;
  509. *((vu_long *)dest) = data;
  510. /* re-enable interrupts if necessary */
  511. if (flag)
  512. enable_interrupts();
  513. /* data polling for D7 */
  514. start = get_timer(0);
  515. while ((*((vu_long *)dest) & 0x00800080) != (data & 0x00800080)) {
  516. if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT)
  517. return 1;
  518. }
  519. #endif
  520. return 0;
  521. }
  522. #ifdef CONFIG_BOOT_8B
  523. static int my_in_8(unsigned char *addr)
  524. {
  525. int ret;
  526. __asm__ __volatile__("lbz%U1%X1 %0,%1; eieio":"=r"(ret):"m"(*addr));
  527. return ret;
  528. }
  529. static void my_out_8(unsigned char *addr, int val)
  530. {
  531. __asm__ __volatile__("stb%U0%X0 %1,%0; eieio":"=m"(*addr):"r"(val));
  532. }
  533. #endif
  534. #ifdef CONFIG_BOOT_16B
  535. static int my_in_be16(unsigned short *addr)
  536. {
  537. int ret;
  538. __asm__ __volatile__("lhz%U1%X1 %0,%1; eieio":"=r"(ret):"m"(*addr));
  539. return ret;
  540. }
  541. static void my_out_be16(unsigned short *addr, int val)
  542. {
  543. __asm__ __volatile__("sth%U0%X0 %1,%0; eieio":"=m"(*addr):"r"(val));
  544. }
  545. #endif
  546. #ifdef CONFIG_BOOT_32B
  547. static unsigned my_in_be32(unsigned *addr)
  548. {
  549. unsigned ret;
  550. __asm__ __volatile__("lwz%U1%X1 %0,%1; eieio":"=r"(ret):"m"(*addr));
  551. return ret;
  552. }
  553. static void my_out_be32(unsigned *addr, int val)
  554. {
  555. __asm__ __volatile__("stw%U0%X0 %1,%0; eieio":"=m"(*addr):"r"(val));
  556. }
  557. #endif