flash.c 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135
  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. flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */
  26. #ifdef CONFIG_FLASH_16BIT
  27. #define FLASH_WORD_SIZE unsigned short
  28. #define FLASH_ID_MASK 0xFFFF
  29. #else
  30. #define FLASH_WORD_SIZE unsigned long
  31. #define FLASH_ID_MASK 0xFFFFFFFF
  32. #endif
  33. /*-----------------------------------------------------------------------
  34. * Functions
  35. */
  36. ulong flash_get_size (volatile FLASH_WORD_SIZE * addr, flash_info_t * info);
  37. #ifndef CONFIG_FLASH_16BIT
  38. static int write_word (flash_info_t * info, ulong dest, ulong data);
  39. #else
  40. static int write_short (flash_info_t * info, ulong dest, ushort data);
  41. #endif
  42. /*int flash_write (uchar *, ulong, ulong); */
  43. /*flash_info_t *addr2info (ulong); */
  44. static void flash_get_offsets (ulong base, flash_info_t * info);
  45. /*-----------------------------------------------------------------------
  46. */
  47. unsigned long flash_init (void)
  48. {
  49. volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
  50. volatile memctl8xx_t *memctl = &immap->im_memctl;
  51. unsigned long size_b0, size_b1;
  52. int i;
  53. /* Init: no FLASHes known */
  54. for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
  55. flash_info[i].flash_id = FLASH_UNKNOWN;
  56. }
  57. /* Static FLASH Bank configuration here - FIXME XXX */
  58. size_b0 =
  59. flash_get_size ((volatile FLASH_WORD_SIZE *)
  60. FLASH_BASE0_PRELIM, &flash_info[0]);
  61. if (flash_info[0].flash_id == FLASH_UNKNOWN) {
  62. printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n", size_b0, size_b0 << 20);
  63. }
  64. size_b1 =
  65. flash_get_size ((volatile FLASH_WORD_SIZE *)
  66. FLASH_BASE1_PRELIM, &flash_info[1]);
  67. if (size_b1 > size_b0) {
  68. printf ("## ERROR: "
  69. "Bank 1 (0x%08lx = %ld MB) > Bank 0 (0x%08lx = %ld MB)\n",
  70. size_b1, size_b1 << 20, size_b0, size_b0 << 20);
  71. flash_info[0].flash_id = FLASH_UNKNOWN;
  72. flash_info[1].flash_id = FLASH_UNKNOWN;
  73. flash_info[0].sector_count = -1;
  74. flash_info[1].sector_count = -1;
  75. flash_info[0].size = 0;
  76. flash_info[1].size = 0;
  77. return (0);
  78. }
  79. /* Remap FLASH according to real size */
  80. memctl->memc_or0 = CONFIG_SYS_OR_TIMING_FLASH | (-size_b0 & 0xFFFF8000);
  81. memctl->memc_br0 = CONFIG_SYS_FLASH_BASE | 0x00000801; /* (CONFIG_SYS_FLASH_BASE & BR_BA_MSK) | BR_MS_GPCM | BR_V; */
  82. /* Re-do sizing to get full correct info */
  83. size_b0 = flash_get_size ((volatile FLASH_WORD_SIZE *) CONFIG_SYS_FLASH_BASE,
  84. &flash_info[0]);
  85. flash_get_offsets (CONFIG_SYS_FLASH_BASE, &flash_info[0]);
  86. #if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
  87. /* monitor protection ON by default */
  88. (void) flash_protect (FLAG_PROTECT_SET,
  89. CONFIG_SYS_MONITOR_BASE,
  90. CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1,
  91. &flash_info[0]);
  92. #endif
  93. if (size_b1) {
  94. memctl->memc_or1 =
  95. CONFIG_SYS_OR_TIMING_FLASH | (-size_b1 & 0xFFFF8000);
  96. memctl->memc_br1 =
  97. (CONFIG_SYS_FLASH_BASE | 0x00000801) + (size_b0 & BR_BA_MSK);
  98. /*((CONFIG_SYS_FLASH_BASE + size_b0) & BR_BA_MSK) |
  99. BR_MS_GPCM | BR_V; */
  100. /* Re-do sizing to get full correct info */
  101. size_b1 =
  102. flash_get_size ((volatile FLASH_WORD_SIZE
  103. *) (CONFIG_SYS_FLASH_BASE + size_b0),
  104. &flash_info[1]);
  105. flash_get_offsets (CONFIG_SYS_FLASH_BASE + size_b0, &flash_info[1]);
  106. #if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
  107. /* monitor protection ON by default */
  108. (void) flash_protect (FLAG_PROTECT_SET,
  109. CONFIG_SYS_MONITOR_BASE,
  110. CONFIG_SYS_MONITOR_BASE + monitor_flash_len -
  111. 1, &flash_info[1]);
  112. #endif
  113. } else {
  114. memctl->memc_br1 = 0; /* invalidate bank */
  115. flash_info[1].flash_id = FLASH_UNKNOWN;
  116. flash_info[1].sector_count = -1;
  117. }
  118. flash_info[0].size = size_b0;
  119. flash_info[1].size = size_b1;
  120. return (size_b0 + size_b1);
  121. }
  122. /*-----------------------------------------------------------------------
  123. */
  124. static void flash_get_offsets (ulong base, flash_info_t * info)
  125. {
  126. int i;
  127. /* set up sector start adress table */
  128. if (info->flash_id & FLASH_BTYPE) {
  129. if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
  130. #ifndef CONFIG_FLASH_16BIT
  131. /* set sector offsets for bottom boot block type */
  132. info->start[0] = base + 0x00000000;
  133. info->start[1] = base + 0x00004000;
  134. info->start[2] = base + 0x00008000;
  135. info->start[3] = base + 0x0000C000;
  136. info->start[4] = base + 0x00010000;
  137. info->start[5] = base + 0x00014000;
  138. info->start[6] = base + 0x00018000;
  139. info->start[7] = base + 0x0001C000;
  140. for (i = 8; i < info->sector_count; i++) {
  141. info->start[i] =
  142. base + (i * 0x00020000) - 0x000E0000;
  143. }
  144. } else {
  145. /* set sector offsets for bottom boot block type */
  146. info->start[0] = base + 0x00000000;
  147. info->start[1] = base + 0x00008000;
  148. info->start[2] = base + 0x0000C000;
  149. info->start[3] = base + 0x00010000;
  150. for (i = 4; i < info->sector_count; i++) {
  151. info->start[i] =
  152. base + (i * 0x00020000) - 0x00060000;
  153. }
  154. }
  155. #else
  156. /* set sector offsets for bottom boot block type */
  157. info->start[0] = base + 0x00000000;
  158. info->start[1] = base + 0x00002000;
  159. info->start[2] = base + 0x00004000;
  160. info->start[3] = base + 0x00006000;
  161. info->start[4] = base + 0x00008000;
  162. info->start[5] = base + 0x0000A000;
  163. info->start[6] = base + 0x0000C000;
  164. info->start[7] = base + 0x0000E000;
  165. for (i = 8; i < info->sector_count; i++) {
  166. info->start[i] =
  167. base + (i * 0x00010000) - 0x00070000;
  168. }
  169. } else {
  170. /* set sector offsets for bottom boot block type */
  171. info->start[0] = base + 0x00000000;
  172. info->start[1] = base + 0x00004000;
  173. info->start[2] = base + 0x00006000;
  174. info->start[3] = base + 0x00008000;
  175. for (i = 4; i < info->sector_count; i++) {
  176. info->start[i] =
  177. base + (i * 0x00010000) - 0x00030000;
  178. }
  179. }
  180. #endif
  181. } else {
  182. /* set sector offsets for top boot block type */
  183. i = info->sector_count - 1;
  184. if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
  185. #ifndef CONFIG_FLASH_16BIT
  186. info->start[i--] = base + info->size - 0x00004000;
  187. info->start[i--] = base + info->size - 0x00008000;
  188. info->start[i--] = base + info->size - 0x0000C000;
  189. info->start[i--] = base + info->size - 0x00010000;
  190. info->start[i--] = base + info->size - 0x00014000;
  191. info->start[i--] = base + info->size - 0x00018000;
  192. info->start[i--] = base + info->size - 0x0001C000;
  193. for (; i >= 0; i--) {
  194. info->start[i] = base + i * 0x00020000;
  195. }
  196. } else {
  197. info->start[i--] = base + info->size - 0x00008000;
  198. info->start[i--] = base + info->size - 0x0000C000;
  199. info->start[i--] = base + info->size - 0x00010000;
  200. for (; i >= 0; i--) {
  201. info->start[i] = base + i * 0x00020000;
  202. }
  203. }
  204. #else
  205. info->start[i--] = base + info->size - 0x00002000;
  206. info->start[i--] = base + info->size - 0x00004000;
  207. info->start[i--] = base + info->size - 0x00006000;
  208. info->start[i--] = base + info->size - 0x00008000;
  209. info->start[i--] = base + info->size - 0x0000A000;
  210. info->start[i--] = base + info->size - 0x0000C000;
  211. info->start[i--] = base + info->size - 0x0000E000;
  212. for (; i >= 0; i--) {
  213. info->start[i] = base + i * 0x00010000;
  214. }
  215. } else {
  216. info->start[i--] = base + info->size - 0x00004000;
  217. info->start[i--] = base + info->size - 0x00006000;
  218. info->start[i--] = base + info->size - 0x00008000;
  219. for (; i >= 0; i--) {
  220. info->start[i] = base + i * 0x00010000;
  221. }
  222. }
  223. #endif
  224. }
  225. }
  226. /*-----------------------------------------------------------------------
  227. */
  228. void flash_print_info (flash_info_t * info)
  229. {
  230. int i;
  231. uchar *boottype;
  232. uchar botboot[] = ", bottom boot sect)\n";
  233. uchar topboot[] = ", top boot sector)\n";
  234. if (info->flash_id == FLASH_UNKNOWN) {
  235. printf ("missing or unknown FLASH type\n");
  236. return;
  237. }
  238. switch (info->flash_id & FLASH_VENDMASK) {
  239. case FLASH_MAN_AMD:
  240. printf ("AMD ");
  241. break;
  242. case FLASH_MAN_FUJ:
  243. printf ("FUJITSU ");
  244. break;
  245. case FLASH_MAN_SST:
  246. printf ("SST ");
  247. break;
  248. case FLASH_MAN_STM:
  249. printf ("STM ");
  250. break;
  251. case FLASH_MAN_INTEL:
  252. printf ("INTEL ");
  253. break;
  254. default:
  255. printf ("Unknown Vendor ");
  256. break;
  257. }
  258. if (info->flash_id & 0x0001) {
  259. boottype = botboot;
  260. } else {
  261. boottype = topboot;
  262. }
  263. switch (info->flash_id & FLASH_TYPEMASK) {
  264. case FLASH_AM400B:
  265. printf ("AM29LV400B (4 Mbit%s", boottype);
  266. break;
  267. case FLASH_AM400T:
  268. printf ("AM29LV400T (4 Mbit%s", boottype);
  269. break;
  270. case FLASH_AM800B:
  271. printf ("AM29LV800B (8 Mbit%s", boottype);
  272. break;
  273. case FLASH_AM800T:
  274. printf ("AM29LV800T (8 Mbit%s", boottype);
  275. break;
  276. case FLASH_AM160B:
  277. printf ("AM29LV160B (16 Mbit%s", boottype);
  278. break;
  279. case FLASH_AM160T:
  280. printf ("AM29LV160T (16 Mbit%s", boottype);
  281. break;
  282. case FLASH_AM320B:
  283. printf ("AM29LV320B (32 Mbit%s", boottype);
  284. break;
  285. case FLASH_AM320T:
  286. printf ("AM29LV320T (32 Mbit%s", boottype);
  287. break;
  288. case FLASH_INTEL800B:
  289. printf ("INTEL28F800B (8 Mbit%s", boottype);
  290. break;
  291. case FLASH_INTEL800T:
  292. printf ("INTEL28F800T (8 Mbit%s", boottype);
  293. break;
  294. case FLASH_INTEL160B:
  295. printf ("INTEL28F160B (16 Mbit%s", boottype);
  296. break;
  297. case FLASH_INTEL160T:
  298. printf ("INTEL28F160T (16 Mbit%s", boottype);
  299. break;
  300. case FLASH_INTEL320B:
  301. printf ("INTEL28F320B (32 Mbit%s", boottype);
  302. break;
  303. case FLASH_INTEL320T:
  304. printf ("INTEL28F320T (32 Mbit%s", boottype);
  305. break;
  306. #if 0 /* enable when devices are available */
  307. case FLASH_INTEL640B:
  308. printf ("INTEL28F640B (64 Mbit%s", boottype);
  309. break;
  310. case FLASH_INTEL640T:
  311. printf ("INTEL28F640T (64 Mbit%s", boottype);
  312. break;
  313. #endif
  314. default:
  315. printf ("Unknown Chip Type\n");
  316. break;
  317. }
  318. printf (" Size: %ld MB in %d Sectors\n",
  319. info->size >> 20, info->sector_count);
  320. printf (" Sector Start Addresses:");
  321. for (i = 0; i < info->sector_count; ++i) {
  322. if ((i % 5) == 0)
  323. printf ("\n ");
  324. printf (" %08lX%s",
  325. info->start[i], info->protect[i] ? " (RO)" : " ");
  326. }
  327. printf ("\n");
  328. return;
  329. }
  330. /*-----------------------------------------------------------------------
  331. */
  332. /*-----------------------------------------------------------------------
  333. */
  334. /*
  335. * The following code cannot be run from FLASH!
  336. */
  337. ulong flash_get_size (volatile FLASH_WORD_SIZE * addr, flash_info_t * info)
  338. {
  339. short i;
  340. ulong base = (ulong) addr;
  341. FLASH_WORD_SIZE value;
  342. /* Write auto select command: read Manufacturer ID */
  343. #ifndef CONFIG_FLASH_16BIT
  344. /*
  345. * Note: if it is an AMD flash and the word at addr[0000]
  346. * is 0x00890089 this routine will think it is an Intel
  347. * flash device and may(most likely) cause trouble.
  348. */
  349. addr[0x0000] = 0x00900090;
  350. if (addr[0x0000] != 0x00890089) {
  351. addr[0x0555] = 0x00AA00AA;
  352. addr[0x02AA] = 0x00550055;
  353. addr[0x0555] = 0x00900090;
  354. #else
  355. /*
  356. * Note: if it is an AMD flash and the word at addr[0000]
  357. * is 0x0089 this routine will think it is an Intel
  358. * flash device and may(most likely) cause trouble.
  359. */
  360. addr[0x0000] = 0x0090;
  361. if (addr[0x0000] != 0x0089) {
  362. addr[0x0555] = 0x00AA;
  363. addr[0x02AA] = 0x0055;
  364. addr[0x0555] = 0x0090;
  365. #endif
  366. }
  367. value = addr[0];
  368. switch (value) {
  369. case (AMD_MANUFACT & FLASH_ID_MASK):
  370. info->flash_id = FLASH_MAN_AMD;
  371. break;
  372. case (FUJ_MANUFACT & FLASH_ID_MASK):
  373. info->flash_id = FLASH_MAN_FUJ;
  374. break;
  375. case (STM_MANUFACT & FLASH_ID_MASK):
  376. info->flash_id = FLASH_MAN_STM;
  377. break;
  378. case (SST_MANUFACT & FLASH_ID_MASK):
  379. info->flash_id = FLASH_MAN_SST;
  380. break;
  381. case (INTEL_MANUFACT & FLASH_ID_MASK):
  382. info->flash_id = FLASH_MAN_INTEL;
  383. break;
  384. default:
  385. info->flash_id = FLASH_UNKNOWN;
  386. info->sector_count = 0;
  387. info->size = 0;
  388. return (0); /* no or unknown flash */
  389. }
  390. value = addr[1]; /* device ID */
  391. switch (value) {
  392. case (AMD_ID_LV400T & FLASH_ID_MASK):
  393. info->flash_id += FLASH_AM400T;
  394. info->sector_count = 11;
  395. info->size = 0x00100000;
  396. break; /* => 1 MB */
  397. case (AMD_ID_LV400B & FLASH_ID_MASK):
  398. info->flash_id += FLASH_AM400B;
  399. info->sector_count = 11;
  400. info->size = 0x00100000;
  401. break; /* => 1 MB */
  402. case (AMD_ID_LV800T & FLASH_ID_MASK):
  403. info->flash_id += FLASH_AM800T;
  404. info->sector_count = 19;
  405. info->size = 0x00200000;
  406. break; /* => 2 MB */
  407. case (AMD_ID_LV800B & FLASH_ID_MASK):
  408. info->flash_id += FLASH_AM800B;
  409. info->sector_count = 19;
  410. info->size = 0x00200000;
  411. break; /* => 2 MB */
  412. case (AMD_ID_LV160T & FLASH_ID_MASK):
  413. info->flash_id += FLASH_AM160T;
  414. info->sector_count = 35;
  415. info->size = 0x00400000;
  416. break; /* => 4 MB */
  417. case (AMD_ID_LV160B & FLASH_ID_MASK):
  418. info->flash_id += FLASH_AM160B;
  419. info->sector_count = 35;
  420. info->size = 0x00400000;
  421. break; /* => 4 MB */
  422. #if 0 /* enable when device IDs are available */
  423. case (AMD_ID_LV320T & FLASH_ID_MASK):
  424. info->flash_id += FLASH_AM320T;
  425. info->sector_count = 67;
  426. info->size = 0x00800000;
  427. break; /* => 8 MB */
  428. case (AMD_ID_LV320B & FLASH_ID_MASK):
  429. info->flash_id += FLASH_AM320B;
  430. info->sector_count = 67;
  431. info->size = 0x00800000;
  432. break; /* => 8 MB */
  433. #endif
  434. case (INTEL_ID_28F800B3T & FLASH_ID_MASK):
  435. info->flash_id += FLASH_INTEL800T;
  436. info->sector_count = 23;
  437. info->size = 0x00200000;
  438. break; /* => 2 MB */
  439. case (INTEL_ID_28F800B3B & FLASH_ID_MASK):
  440. info->flash_id += FLASH_INTEL800B;
  441. info->sector_count = 23;
  442. info->size = 0x00200000;
  443. break; /* => 2 MB */
  444. case (INTEL_ID_28F160B3T & FLASH_ID_MASK):
  445. info->flash_id += FLASH_INTEL160T;
  446. info->sector_count = 39;
  447. info->size = 0x00400000;
  448. break; /* => 4 MB */
  449. case (INTEL_ID_28F160B3B & FLASH_ID_MASK):
  450. info->flash_id += FLASH_INTEL160B;
  451. info->sector_count = 39;
  452. info->size = 0x00400000;
  453. break; /* => 4 MB */
  454. case (INTEL_ID_28F320B3T & FLASH_ID_MASK):
  455. info->flash_id += FLASH_INTEL320T;
  456. info->sector_count = 71;
  457. info->size = 0x00800000;
  458. break; /* => 8 MB */
  459. case (INTEL_ID_28F320B3B & FLASH_ID_MASK):
  460. info->flash_id += FLASH_AM320B;
  461. info->sector_count = 71;
  462. info->size = 0x00800000;
  463. break; /* => 8 MB */
  464. #if 0 /* enable when devices are available */
  465. case (INTEL_ID_28F320B3T & FLASH_ID_MASK):
  466. info->flash_id += FLASH_INTEL320T;
  467. info->sector_count = 135;
  468. info->size = 0x01000000;
  469. break; /* => 16 MB */
  470. case (INTEL_ID_28F320B3B & FLASH_ID_MASK):
  471. info->flash_id += FLASH_AM320B;
  472. info->sector_count = 135;
  473. info->size = 0x01000000;
  474. break; /* => 16 MB */
  475. #endif
  476. default:
  477. info->flash_id = FLASH_UNKNOWN;
  478. return (0); /* => no or unknown flash */
  479. }
  480. /* set up sector start adress table */
  481. if (info->flash_id & FLASH_BTYPE) {
  482. if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
  483. #ifndef CONFIG_FLASH_16BIT
  484. /* set sector offsets for bottom boot block type */
  485. info->start[0] = base + 0x00000000;
  486. info->start[1] = base + 0x00004000;
  487. info->start[2] = base + 0x00008000;
  488. info->start[3] = base + 0x0000C000;
  489. info->start[4] = base + 0x00010000;
  490. info->start[5] = base + 0x00014000;
  491. info->start[6] = base + 0x00018000;
  492. info->start[7] = base + 0x0001C000;
  493. for (i = 8; i < info->sector_count; i++) {
  494. info->start[i] =
  495. base + (i * 0x00020000) - 0x000E0000;
  496. }
  497. } else {
  498. /* set sector offsets for bottom boot block type */
  499. info->start[0] = base + 0x00000000;
  500. info->start[1] = base + 0x00008000;
  501. info->start[2] = base + 0x0000C000;
  502. info->start[3] = base + 0x00010000;
  503. for (i = 4; i < info->sector_count; i++) {
  504. info->start[i] =
  505. base + (i * 0x00020000) - 0x00060000;
  506. }
  507. }
  508. #else
  509. /* set sector offsets for bottom boot block type */
  510. info->start[0] = base + 0x00000000;
  511. info->start[1] = base + 0x00002000;
  512. info->start[2] = base + 0x00004000;
  513. info->start[3] = base + 0x00006000;
  514. info->start[4] = base + 0x00008000;
  515. info->start[5] = base + 0x0000A000;
  516. info->start[6] = base + 0x0000C000;
  517. info->start[7] = base + 0x0000E000;
  518. for (i = 8; i < info->sector_count; i++) {
  519. info->start[i] =
  520. base + (i * 0x00010000) - 0x00070000;
  521. }
  522. } else {
  523. /* set sector offsets for bottom boot block type */
  524. info->start[0] = base + 0x00000000;
  525. info->start[1] = base + 0x00004000;
  526. info->start[2] = base + 0x00006000;
  527. info->start[3] = base + 0x00008000;
  528. for (i = 4; i < info->sector_count; i++) {
  529. info->start[i] =
  530. base + (i * 0x00010000) - 0x00030000;
  531. }
  532. }
  533. #endif
  534. } else {
  535. /* set sector offsets for top boot block type */
  536. i = info->sector_count - 1;
  537. if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
  538. #ifndef CONFIG_FLASH_16BIT
  539. info->start[i--] = base + info->size - 0x00004000;
  540. info->start[i--] = base + info->size - 0x00008000;
  541. info->start[i--] = base + info->size - 0x0000C000;
  542. info->start[i--] = base + info->size - 0x00010000;
  543. info->start[i--] = base + info->size - 0x00014000;
  544. info->start[i--] = base + info->size - 0x00018000;
  545. info->start[i--] = base + info->size - 0x0001C000;
  546. for (; i >= 0; i--) {
  547. info->start[i] = base + i * 0x00020000;
  548. }
  549. } else {
  550. info->start[i--] = base + info->size - 0x00008000;
  551. info->start[i--] = base + info->size - 0x0000C000;
  552. info->start[i--] = base + info->size - 0x00010000;
  553. for (; i >= 0; i--) {
  554. info->start[i] = base + i * 0x00020000;
  555. }
  556. }
  557. #else
  558. info->start[i--] = base + info->size - 0x00002000;
  559. info->start[i--] = base + info->size - 0x00004000;
  560. info->start[i--] = base + info->size - 0x00006000;
  561. info->start[i--] = base + info->size - 0x00008000;
  562. info->start[i--] = base + info->size - 0x0000A000;
  563. info->start[i--] = base + info->size - 0x0000C000;
  564. info->start[i--] = base + info->size - 0x0000E000;
  565. for (; i >= 0; i--) {
  566. info->start[i] = base + i * 0x00010000;
  567. }
  568. } else {
  569. info->start[i--] = base + info->size - 0x00004000;
  570. info->start[i--] = base + info->size - 0x00006000;
  571. info->start[i--] = base + info->size - 0x00008000;
  572. for (; i >= 0; i--) {
  573. info->start[i] = base + i * 0x00010000;
  574. }
  575. }
  576. #endif
  577. }
  578. /* check for protected sectors */
  579. for (i = 0; i < info->sector_count; i++) {
  580. /* read sector protection at sector address, (A7 .. A0) = 0x02 */
  581. /* D0 = 1 if protected */
  582. addr = (volatile FLASH_WORD_SIZE *) (info->start[i]);
  583. info->protect[i] = addr[2] & 1;
  584. }
  585. /*
  586. * Prevent writes to uninitialized FLASH.
  587. */
  588. if (info->flash_id != FLASH_UNKNOWN) {
  589. addr = (volatile FLASH_WORD_SIZE *) info->start[0];
  590. if ((info->flash_id & 0xFF00) == FLASH_MAN_INTEL) {
  591. *addr = (0x00F000F0 & FLASH_ID_MASK); /* reset bank */
  592. } else {
  593. *addr = (0x00FF00FF & FLASH_ID_MASK); /* reset bank */
  594. }
  595. }
  596. return (info->size);
  597. }
  598. /*-----------------------------------------------------------------------
  599. */
  600. int flash_erase (flash_info_t * info, int s_first, int s_last)
  601. {
  602. volatile FLASH_WORD_SIZE *addr =
  603. (volatile FLASH_WORD_SIZE *) (info->start[0]);
  604. int flag, prot, sect, l_sect, barf;
  605. ulong start, now, last;
  606. int rcode = 0;
  607. if ((s_first < 0) || (s_first > s_last)) {
  608. if (info->flash_id == FLASH_UNKNOWN) {
  609. printf ("- missing\n");
  610. } else {
  611. printf ("- no sectors to erase\n");
  612. }
  613. return 1;
  614. }
  615. if ((info->flash_id == FLASH_UNKNOWN) ||
  616. ((info->flash_id > FLASH_AMD_COMP) &&
  617. ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL))) {
  618. printf ("Can't erase unknown flash type - aborted\n");
  619. return 1;
  620. }
  621. prot = 0;
  622. for (sect = s_first; sect <= s_last; ++sect) {
  623. if (info->protect[sect]) {
  624. prot++;
  625. }
  626. }
  627. if (prot) {
  628. printf ("- Warning: %d protected sectors will not be erased!\n", prot);
  629. } else {
  630. printf ("\n");
  631. }
  632. l_sect = -1;
  633. /* Disable interrupts which might cause a timeout here */
  634. flag = disable_interrupts ();
  635. if (info->flash_id < FLASH_AMD_COMP) {
  636. #ifndef CONFIG_FLASH_16BIT
  637. addr[0x0555] = 0x00AA00AA;
  638. addr[0x02AA] = 0x00550055;
  639. addr[0x0555] = 0x00800080;
  640. addr[0x0555] = 0x00AA00AA;
  641. addr[0x02AA] = 0x00550055;
  642. #else
  643. addr[0x0555] = 0x00AA;
  644. addr[0x02AA] = 0x0055;
  645. addr[0x0555] = 0x0080;
  646. addr[0x0555] = 0x00AA;
  647. addr[0x02AA] = 0x0055;
  648. #endif
  649. /* Start erase on unprotected sectors */
  650. for (sect = s_first; sect <= s_last; sect++) {
  651. if (info->protect[sect] == 0) { /* not protected */
  652. addr = (volatile FLASH_WORD_SIZE *) (info->start[sect]);
  653. addr[0] = (0x00300030 & FLASH_ID_MASK);
  654. l_sect = sect;
  655. }
  656. }
  657. /* re-enable interrupts if necessary */
  658. if (flag)
  659. enable_interrupts ();
  660. /* wait at least 80us - let's wait 1 ms */
  661. udelay (1000);
  662. /*
  663. * We wait for the last triggered sector
  664. */
  665. if (l_sect < 0)
  666. goto DONE;
  667. start = get_timer (0);
  668. last = start;
  669. addr = (volatile FLASH_WORD_SIZE *) (info->start[l_sect]);
  670. while ((addr[0] & (0x00800080 & FLASH_ID_MASK)) !=
  671. (0x00800080 & FLASH_ID_MASK)) {
  672. if ((now = get_timer (start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
  673. printf ("Timeout\n");
  674. return 1;
  675. }
  676. /* show that we're waiting */
  677. if ((now - last) > 1000) { /* every second */
  678. serial_putc ('.');
  679. last = now;
  680. }
  681. }
  682. DONE:
  683. /* reset to read mode */
  684. addr = (volatile FLASH_WORD_SIZE *) info->start[0];
  685. addr[0] = (0x00F000F0 & FLASH_ID_MASK); /* reset bank */
  686. } else {
  687. for (sect = s_first; sect <= s_last; sect++) {
  688. if (info->protect[sect] == 0) { /* not protected */
  689. barf = 0;
  690. #ifndef CONFIG_FLASH_16BIT
  691. addr = (vu_long *) (info->start[sect]);
  692. addr[0] = 0x00200020;
  693. addr[0] = 0x00D000D0;
  694. while (!(addr[0] & 0x00800080)); /* wait for error or finish */
  695. if (addr[0] & 0x003A003A) { /* check for error */
  696. barf = addr[0] & 0x003A0000;
  697. if (barf) {
  698. barf >>= 16;
  699. } else {
  700. barf = addr[0] & 0x0000003A;
  701. }
  702. }
  703. #else
  704. addr = (vu_short *) (info->start[sect]);
  705. addr[0] = 0x0020;
  706. addr[0] = 0x00D0;
  707. while (!(addr[0] & 0x0080)); /* wait for error or finish */
  708. if (addr[0] & 0x003A) /* check for error */
  709. barf = addr[0] & 0x003A;
  710. #endif
  711. if (barf) {
  712. printf ("\nFlash error in sector at %lx\n", (unsigned long) addr);
  713. if (barf & 0x0002)
  714. printf ("Block locked, not erased.\n");
  715. if ((barf & 0x0030) == 0x0030)
  716. printf ("Command Sequence error.\n");
  717. if ((barf & 0x0030) == 0x0020)
  718. printf ("Block Erase error.\n");
  719. if (barf & 0x0008)
  720. printf ("Vpp Low error.\n");
  721. rcode = 1;
  722. } else
  723. printf (".");
  724. l_sect = sect;
  725. }
  726. addr = (volatile FLASH_WORD_SIZE *) info->start[0];
  727. addr[0] = (0x00FF00FF & FLASH_ID_MASK); /* reset bank */
  728. }
  729. }
  730. printf (" done\n");
  731. return rcode;
  732. }
  733. /*-----------------------------------------------------------------------
  734. */
  735. /*-----------------------------------------------------------------------
  736. * Copy memory to flash, returns:
  737. * 0 - OK
  738. * 1 - write timeout
  739. * 2 - Flash not erased
  740. */
  741. int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
  742. {
  743. #ifndef CONFIG_FLASH_16BIT
  744. ulong cp, wp, data;
  745. int l;
  746. #else
  747. ulong cp, wp;
  748. ushort data;
  749. #endif
  750. int i, rc;
  751. #ifndef CONFIG_FLASH_16BIT
  752. wp = (addr & ~3); /* get lower word aligned address */
  753. /*
  754. * handle unaligned start bytes
  755. */
  756. if ((l = addr - wp) != 0) {
  757. data = 0;
  758. for (i = 0, cp = wp; i < l; ++i, ++cp) {
  759. data = (data << 8) | (*(uchar *) cp);
  760. }
  761. for (; i < 4 && cnt > 0; ++i) {
  762. data = (data << 8) | *src++;
  763. --cnt;
  764. ++cp;
  765. }
  766. for (; cnt == 0 && i < 4; ++i, ++cp) {
  767. data = (data << 8) | (*(uchar *) cp);
  768. }
  769. if ((rc = write_word (info, wp, data)) != 0) {
  770. return (rc);
  771. }
  772. wp += 4;
  773. }
  774. /*
  775. * handle word aligned part
  776. */
  777. while (cnt >= 4) {
  778. data = 0;
  779. for (i = 0; i < 4; ++i) {
  780. data = (data << 8) | *src++;
  781. }
  782. if ((rc = write_word (info, wp, data)) != 0) {
  783. return (rc);
  784. }
  785. wp += 4;
  786. cnt -= 4;
  787. }
  788. if (cnt == 0) {
  789. return (0);
  790. }
  791. /*
  792. * handle unaligned tail bytes
  793. */
  794. data = 0;
  795. for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
  796. data = (data << 8) | *src++;
  797. --cnt;
  798. }
  799. for (; i < 4; ++i, ++cp) {
  800. data = (data << 8) | (*(uchar *) cp);
  801. }
  802. return (write_word (info, wp, data));
  803. #else
  804. wp = (addr & ~1); /* get lower word aligned address */
  805. /*
  806. * handle unaligned start byte
  807. */
  808. if (addr - wp) {
  809. data = 0;
  810. data = (data << 8) | *src++;
  811. --cnt;
  812. if ((rc = write_short (info, wp, data)) != 0) {
  813. return (rc);
  814. }
  815. wp += 2;
  816. }
  817. /*
  818. * handle word aligned part
  819. */
  820. /* l = 0; used for debuging */
  821. while (cnt >= 2) {
  822. data = 0;
  823. for (i = 0; i < 2; ++i) {
  824. data = (data << 8) | *src++;
  825. }
  826. /* if(!l){
  827. printf("%x",data);
  828. l = 1;
  829. } used for debuging */
  830. if ((rc = write_short (info, wp, data)) != 0) {
  831. return (rc);
  832. }
  833. wp += 2;
  834. cnt -= 2;
  835. }
  836. if (cnt == 0) {
  837. return (0);
  838. }
  839. /*
  840. * handle unaligned tail bytes
  841. */
  842. data = 0;
  843. for (i = 0, cp = wp; i < 2 && cnt > 0; ++i, ++cp) {
  844. data = (data << 8) | *src++;
  845. --cnt;
  846. }
  847. for (; i < 2; ++i, ++cp) {
  848. data = (data << 8) | (*(uchar *) cp);
  849. }
  850. return (write_short (info, wp, data));
  851. #endif
  852. }
  853. /*-----------------------------------------------------------------------
  854. * Write a word to Flash, returns:
  855. * 0 - OK
  856. * 1 - write timeout
  857. * 2 - Flash not erased
  858. */
  859. #ifndef CONFIG_FLASH_16BIT
  860. static int write_word (flash_info_t * info, ulong dest, ulong data)
  861. {
  862. vu_long *addr = (vu_long *) (info->start[0]);
  863. ulong start, barf;
  864. int flag;
  865. /* Check if Flash is (sufficiently) erased */
  866. if ((*((vu_long *) dest) & data) != data) {
  867. return (2);
  868. }
  869. /* Disable interrupts which might cause a timeout here */
  870. flag = disable_interrupts ();
  871. if (info->flash_id > FLASH_AMD_COMP) {
  872. /* AMD stuff */
  873. addr[0x0555] = 0x00AA00AA;
  874. addr[0x02AA] = 0x00550055;
  875. addr[0x0555] = 0x00A000A0;
  876. } else {
  877. /* intel stuff */
  878. *addr = 0x00400040;
  879. }
  880. *((vu_long *) dest) = data;
  881. /* re-enable interrupts if necessary */
  882. if (flag)
  883. enable_interrupts ();
  884. /* data polling for D7 */
  885. start = get_timer (0);
  886. if (info->flash_id > FLASH_AMD_COMP) {
  887. while ((*((vu_long *) dest) & 0x00800080) !=
  888. (data & 0x00800080)) {
  889. if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
  890. return (1);
  891. }
  892. }
  893. } else {
  894. while (!(addr[0] & 0x00800080)) { /* wait for error or finish */
  895. if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
  896. return (1);
  897. }
  898. if (addr[0] & 0x003A003A) { /* check for error */
  899. barf = addr[0] & 0x003A0000;
  900. if (barf) {
  901. barf >>= 16;
  902. } else {
  903. barf = addr[0] & 0x0000003A;
  904. }
  905. printf ("\nFlash write error at address %lx\n", (unsigned long) dest);
  906. if (barf & 0x0002)
  907. printf ("Block locked, not erased.\n");
  908. if (barf & 0x0010)
  909. printf ("Programming error.\n");
  910. if (barf & 0x0008)
  911. printf ("Vpp Low error.\n");
  912. return (2);
  913. }
  914. }
  915. return (0);
  916. }
  917. #else
  918. static int write_short (flash_info_t * info, ulong dest, ushort data)
  919. {
  920. vu_short *addr = (vu_short *) (info->start[0]);
  921. ulong start, barf;
  922. int flag;
  923. /* Check if Flash is (sufficiently) erased */
  924. if ((*((vu_short *) dest) & data) != data) {
  925. return (2);
  926. }
  927. /* Disable interrupts which might cause a timeout here */
  928. flag = disable_interrupts ();
  929. if (info->flash_id < FLASH_AMD_COMP) {
  930. /* AMD stuff */
  931. addr[0x0555] = 0x00AA;
  932. addr[0x02AA] = 0x0055;
  933. addr[0x0555] = 0x00A0;
  934. } else {
  935. /* intel stuff */
  936. *addr = 0x00D0;
  937. *addr = 0x0040;
  938. }
  939. *((vu_short *) dest) = data;
  940. /* re-enable interrupts if necessary */
  941. if (flag)
  942. enable_interrupts ();
  943. /* data polling for D7 */
  944. start = get_timer (0);
  945. if (info->flash_id < FLASH_AMD_COMP) {
  946. /* AMD stuff */
  947. while ((*((vu_short *) dest) & 0x0080) != (data & 0x0080)) {
  948. if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
  949. return (1);
  950. }
  951. }
  952. } else {
  953. /* intel stuff */
  954. while (!(addr[0] & 0x0080)) { /* wait for error or finish */
  955. if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT)
  956. return (1);
  957. }
  958. if (addr[0] & 0x003A) { /* check for error */
  959. barf = addr[0] & 0x003A;
  960. printf ("\nFlash write error at address %lx\n",
  961. (unsigned long) dest);
  962. if (barf & 0x0002)
  963. printf ("Block locked, not erased.\n");
  964. if (barf & 0x0010)
  965. printf ("Programming error.\n");
  966. if (barf & 0x0008)
  967. printf ("Vpp Low error.\n");
  968. return (2);
  969. }
  970. *addr = 0x00B0;
  971. *addr = 0x0070;
  972. while (!(addr[0] & 0x0080)) { /* wait for error or finish */
  973. if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT)
  974. return (1);
  975. }
  976. *addr = 0x00FF;
  977. }
  978. return (0);
  979. }
  980. #endif
  981. /*-----------------------------------------------------------------------*/