flash.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536
  1. /*
  2. * (C) Copyright 2002
  3. * MAZeT GmbH <www.mazet.de>
  4. * Stephan Linz <linz@mazet.de>, <linz@li-pro.net>
  5. *
  6. * The most stuff comes from PPCBoot and Linux.
  7. *
  8. * IMMS gGmbH <www.imms.de>
  9. * Thomas Elste <info@elste.org>
  10. *
  11. * Modifications for ModNET50 Board
  12. *
  13. * See file CREDITS for list of people who contributed to this
  14. * project.
  15. *
  16. * This program is free software; you can redistribute it and/or
  17. * modify it under the terms of the GNU General Public License as
  18. * published by the Free Software Foundation; either version 2 of
  19. * the License, or (at your option) any later version.
  20. *
  21. * This program is distributed in the hope that it will be useful,
  22. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  23. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  24. * GNU General Public License for more details.
  25. *
  26. * You should have received a copy of the GNU General Public License
  27. * along with this program; if not, write to the Free Software
  28. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  29. * MA 02111-1307 USA
  30. */
  31. #include <common.h>
  32. #include <asm/arch/netarm_registers.h>
  33. #define SCR (*(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + NETARM_GEN_SYSTEM_CONTROL))
  34. #define ALIGN_ABORT_OFF SCR = SCR & ~NETARM_GEN_SYS_CFG_ALIGN_ABORT
  35. #define ALIGN_ABORT_ON SCR = SCR | NETARM_GEN_SYS_CFG_ALIGN_ABORT
  36. #define PROG_ADDR (0x555*2)
  37. #define SETUP_ADDR (0x555*2)
  38. #define ID_ADDR (0x555*2)
  39. #define UNLOCK_ADDR1 (0x555*2)
  40. #define UNLOCK_ADDR2 (0x2AA*2)
  41. #define UNLOCK_CMD1 (0xAA)
  42. #define UNLOCK_CMD2 (0x55)
  43. #define ERASE_SUSPEND_CMD (0xB0)
  44. #define ERASE_RESUME_CMD (0x30)
  45. #define RESET_CMD (0xF0)
  46. #define ID_CMD (0x90)
  47. #define SECERASE_CMD (0x30)
  48. #define CHIPERASE_CMD (0x10)
  49. #define PROG_CMD (0xa0)
  50. #define SETUP_CMD (0x80)
  51. #define DQ2 (0x04)
  52. #define DQ3 (DQ2*2)
  53. #define DQ5 (DQ3*4)
  54. #define DQ6 (DQ5*2)
  55. #define WRITE_UNLOCK(addr) { \
  56. *(volatile __u16*)(addr + UNLOCK_ADDR1) = (__u16)UNLOCK_CMD1; \
  57. *(volatile __u16*)(addr + UNLOCK_ADDR2) = (__u16)UNLOCK_CMD2; \
  58. }
  59. #define CONFIG_AM29_RESERVED (0)
  60. #define K (1024)
  61. #define MB (4)
  62. #define CELL_SIZE (64*K)
  63. #define DEVICE_SIZE (MB*K*K)
  64. #define CELLS_PER_DEVICE (DEVICE_SIZE/CELL_SIZE)
  65. #define RESERVED_CELLS (CONFIG_AM29_RESERVED*K)/CELL_SIZE
  66. #define MAX_FLASH_DEVICES (1)
  67. #define AVAIL_SIZE (DEVICE_SIZE*MAX_FLASH_DEVICES - RESERVED_CELLS*CELL_SIZE)
  68. flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
  69. static __u16 toggling_bits;
  70. /*-----------------------------------------------------------------------
  71. */
  72. ulong flash_get_size (ulong baseaddr, flash_info_t * info)
  73. {
  74. short i;
  75. __u16 flashtest;
  76. /* Write auto select command sequence and test FLASH answer */
  77. WRITE_UNLOCK (baseaddr);
  78. *(volatile __u16 *) (baseaddr + ID_ADDR) = (__u16) ID_CMD;
  79. flashtest /* manufacturer ID */ = *(volatile __u16 *) (baseaddr);
  80. *(volatile __u16 *) (baseaddr + ID_ADDR) = (__u16) RESET_CMD;
  81. switch ((__u32) ((flashtest << 16) + flashtest)) {
  82. case AMD_MANUFACT:
  83. info->flash_id = FLASH_MAN_AMD & FLASH_VENDMASK;
  84. break;
  85. case FUJ_MANUFACT:
  86. info->flash_id = FLASH_MAN_FUJ & FLASH_VENDMASK;
  87. break;
  88. default:
  89. info->flash_id = FLASH_UNKNOWN;
  90. info->sector_count = 0;
  91. info->size = 0;
  92. return (0); /* no or unknown flash */
  93. }
  94. /* Write auto select command sequence and test FLASH answer */
  95. WRITE_UNLOCK (baseaddr);
  96. *(volatile __u16 *) (baseaddr + ID_ADDR) = (__u16) ID_CMD;
  97. flashtest /* device ID */ = *(volatile __u16 *) (baseaddr + 2);
  98. *(volatile __u16 *) (baseaddr + ID_ADDR) = (__u16) RESET_CMD;
  99. /* toggling_bits = (flashtest == TOSHIBA)?(DQ6):(DQ2|DQ6); */
  100. toggling_bits = (DQ2 | DQ6);
  101. switch ((__u32) ((flashtest << 16) + flashtest)) {
  102. case AMD_ID_LV160B:
  103. info->flash_id +=
  104. (FLASH_AM160LV | FLASH_AM160B) & FLASH_TYPEMASK;
  105. info->sector_count = CFG_MAX_FLASH_SECT;
  106. info->size = CFG_FLASH_SIZE;
  107. /* 1*16K Boot Block
  108. 2*8K Parameter Block
  109. 1*32K Small Main Block */
  110. info->start[0] = baseaddr;
  111. info->start[1] = baseaddr + 0x4000;
  112. info->start[2] = baseaddr + 0x6000;
  113. info->start[3] = baseaddr + 0x8000;
  114. for (i = 1; i < info->sector_count; i++)
  115. info->start[3 + i] = baseaddr + i * CFG_MAIN_SECT_SIZE;
  116. break;
  117. default:
  118. info->flash_id = FLASH_UNKNOWN;
  119. return (0); /* no or unknown flash */
  120. }
  121. for (i = 0; i < info->sector_count; i++) {
  122. /* Write auto select command sequence and test FLASH answer */
  123. WRITE_UNLOCK (info->start[i]);
  124. *(volatile __u16 *) (info->start[i] + ID_ADDR) = (__u16) ID_CMD;
  125. flashtest /* protected verify */ = *(volatile __u16 *) (info->start[i] + 4);
  126. *(volatile __u16 *) (info->start[i] + ID_ADDR) = (__u16) RESET_CMD;
  127. if (flashtest & 0x0001) {
  128. info->protect[i] = 1; /* D0 = 1 if protected */
  129. } else {
  130. info->protect[i] = 0;
  131. }
  132. }
  133. return (info->size);
  134. }
  135. /*-----------------------------------------------------------------------
  136. */
  137. ulong flash_init (void)
  138. {
  139. ulong size = 0;
  140. int i;
  141. /* Init: no FLASHes known */
  142. for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
  143. flash_info[i].flash_id = FLASH_UNKNOWN;
  144. }
  145. /* Static FLASH Bank configuration here (only one bank) */
  146. size = flash_get_size (CFG_FLASH_BASE, &flash_info[0]);
  147. if (flash_info[0].flash_id == FLASH_UNKNOWN || size == 0) {
  148. printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
  149. size, size >> 20);
  150. }
  151. /*
  152. * protect monitor and environment sectors
  153. */
  154. flash_protect (FLAG_PROTECT_SET,
  155. CFG_FLASH_BASE,
  156. CFG_FLASH_BASE + monitor_flash_len - 1,
  157. &flash_info[0]);
  158. flash_protect (FLAG_PROTECT_SET,
  159. CFG_ENV_ADDR,
  160. CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
  161. return size;
  162. }
  163. /*-----------------------------------------------------------------------
  164. */
  165. void flash_print_info (flash_info_t * info)
  166. {
  167. int i;
  168. if (info->flash_id == FLASH_UNKNOWN) {
  169. printf ("missing or unknown FLASH type\n");
  170. return;
  171. }
  172. switch (info->flash_id & FLASH_VENDMASK) {
  173. case FLASH_MAN_AMD:
  174. printf ("AMD ");
  175. break;
  176. case FLASH_MAN_FUJ:
  177. printf ("Fujitsu ");
  178. break;
  179. default:
  180. printf ("Unknown Vendor ");
  181. break;
  182. }
  183. switch (info->flash_id & FLASH_TYPEMASK) {
  184. case FLASH_AMDL323B:
  185. printf ("29DL323B (32 M, bottom sector)\n");
  186. break;
  187. case (FLASH_AM160LV | FLASH_AM160B):
  188. printf ("29LV160BE (1M x 16, bottom sector)\n");
  189. break;
  190. default:
  191. printf ("Unknown Chip Type\n");
  192. break;
  193. }
  194. printf (" Size: %ld MB in %d Sectors\n",
  195. info->size >> 20, info->sector_count);
  196. printf (" Sector Start Addresses:");
  197. for (i = 0; i < info->sector_count; i++) {
  198. if ((i % 4) == 0)
  199. printf ("\n ");
  200. printf (" S%02d @ 0x%08lX%s", i,
  201. info->start[i], info->protect[i] ? " !" : " ");
  202. }
  203. printf ("\n");
  204. return;
  205. }
  206. /*-----------------------------------------------------------------------
  207. */
  208. int flash_check_protection (flash_info_t * info, int s_first, int s_last)
  209. {
  210. int sect, prot = 0;
  211. for (sect = s_first; sect <= s_last; sect++)
  212. if (info->protect[sect])
  213. prot++;
  214. if (prot)
  215. printf ("- can't erase %d protected sectors\n", prot);
  216. return prot;
  217. }
  218. /*-----------------------------------------------------------------------
  219. */
  220. int flash_check_erase_amd (ulong start)
  221. {
  222. __u16 v1, v2;
  223. v1 = *(volatile __u16 *) (start);
  224. v2 = *(volatile __u16 *) (start);
  225. if (((v1 ^ v2) & toggling_bits) == toggling_bits) {
  226. if (((v1 | v2) & DQ5) == DQ5) {
  227. printf ("[DQ5] ");
  228. /* OOPS: exceeded timing limits */
  229. v1 = *(volatile __u16 *) (start);
  230. v2 = *(volatile __u16 *) (start);
  231. if (((v1 ^ v2) & toggling_bits) == toggling_bits) {
  232. printf ("[%s] ",
  233. ((toggling_bits & (DQ2 | DQ6)) ==
  234. (DQ2 | DQ6)) ? "DQ2,DQ6" : "DQ6");
  235. /* OOPS: there is an erasure in progress,
  236. * try to reset chip */
  237. *(volatile __u16 *) (start) =
  238. (__u16) RESET_CMD;
  239. return 1; /* still busy */
  240. }
  241. }
  242. return 1; /* still busy */
  243. }
  244. return 0; /* be free */
  245. }
  246. /*-----------------------------------------------------------------------
  247. */
  248. int flash_erase (flash_info_t * info, int s_first, int s_last)
  249. {
  250. int flag, sect, setup_offset = 0;
  251. int rc = ERR_OK;
  252. if (info->flash_id == FLASH_UNKNOWN) {
  253. printf ("- missing\n");
  254. return ERR_UNKNOWN_FLASH_TYPE;
  255. }
  256. if ((s_first < 0) || (s_first > s_last)) {
  257. printf ("- no sectors to erase\n");
  258. return ERR_INVAL;
  259. }
  260. if (flash_check_protection (info, s_first, s_last))
  261. return ERR_PROTECTED;
  262. switch (info->flash_id & FLASH_VENDMASK) {
  263. case FLASH_MAN_FUJ:
  264. case FLASH_MAN_AMD:
  265. switch (info->flash_id & FLASH_TYPEMASK) {
  266. case (FLASH_AM160LV | FLASH_AM160B):
  267. setup_offset = UNLOCK_ADDR1; /* just the adress for setup_cmd differs */
  268. case FLASH_AMDL323B:
  269. /*
  270. * Disable interrupts which might cause a timeout
  271. * here. Remember that our exception vectors are
  272. * at address 0 in the flash, and we don't want a
  273. * (ticker) exception to happen while the flash
  274. * chip is in programming mode.
  275. */
  276. flag = disable_interrupts ();
  277. /* Start erase on unprotected sectors */
  278. for (sect = s_first; sect <= s_last && !ctrlc ();
  279. sect++) {
  280. printf ("Erasing sector %2d ... ", sect);
  281. if (info->protect[sect] == 0) {
  282. /* not protected */
  283. /* Write sector erase command sequence */
  284. WRITE_UNLOCK (info->start[0]);
  285. *(volatile __u16 *) (info->start[0] +
  286. setup_offset) =
  287. (__u16) SETUP_CMD;
  288. WRITE_UNLOCK (info->start[0]);
  289. *(volatile __u16 *) (info->
  290. start[sect]) =
  291. (__u16) SECERASE_CMD;
  292. /* wait some time */
  293. reset_timer_masked ();
  294. while (get_timer_masked () < 1000) {
  295. }
  296. /* arm simple, non interrupt dependent timer */
  297. reset_timer_masked ();
  298. while (flash_check_erase_amd (info->start[sect])) {
  299. if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) {
  300. printf ("timeout!\n");
  301. /* OOPS: reach timeout,
  302. * try to reset chip
  303. */
  304. *(volatile __u16 *) (info-> start[sect]) = (__u16) RESET_CMD;
  305. rc = ERR_TIMOUT;
  306. goto outahere_323B;
  307. }
  308. }
  309. printf ("ok.\n");
  310. } else {
  311. printf ("protected!\n");
  312. }
  313. }
  314. if (ctrlc ())
  315. printf ("User Interrupt!\n");
  316. outahere_323B:
  317. /* allow flash to settle - wait 10 ms */
  318. udelay_masked (10000);
  319. if (flag)
  320. enable_interrupts ();
  321. return rc;
  322. default:
  323. printf ("- unknown chip type\n");
  324. return ERR_UNKNOWN_FLASH_TYPE;
  325. }
  326. break;
  327. default:
  328. printf ("- unknown vendor ");
  329. return ERR_UNKNOWN_FLASH_VENDOR;
  330. }
  331. }
  332. /*-----------------------------------------------------------------------
  333. */
  334. int flash_check_write_amd (ulong dest)
  335. {
  336. __u16 v1, v2;
  337. v1 = *(volatile __u16 *) (dest);
  338. v2 = *(volatile __u16 *) (dest);
  339. /* DQ6 toggles during write */
  340. if (((v1 ^ v2) & DQ6) == DQ6) {
  341. if (((v1 | v2) & DQ5) == DQ5) {
  342. printf ("[DQ5] @ %08lX\n", dest);
  343. /* OOPS: exceeded timing limits,
  344. * try to reset chip */
  345. *(volatile __u16 *) (dest) = (__u16) RESET_CMD;
  346. return 0; /* be free */
  347. }
  348. return 1; /* still busy */
  349. }
  350. return 0; /* be free */
  351. }
  352. /*-----------------------------------------------------------------------
  353. * Copy memory to flash
  354. */
  355. static int write_word (flash_info_t * info, ulong dest, ushort data)
  356. {
  357. int rc = ERR_OK;
  358. int flag;
  359. /* Check if Flash is (sufficiently) erased */
  360. if ((*(__u16 *) (dest) & data) != data)
  361. return ERR_NOT_ERASED;
  362. /*
  363. * Disable interrupts which might cause a timeout
  364. * here. Remember that our exception vectors are
  365. * at address 0 in the flash, and we don't want a
  366. * (ticker) exception to happen while the flash
  367. * chip is in programming mode.
  368. */
  369. flag = disable_interrupts ();
  370. /* Write program command sequence */
  371. WRITE_UNLOCK (info->start[0]);
  372. /* Flash dependend program seqence */
  373. switch (info->flash_id & FLASH_VENDMASK) {
  374. case FLASH_MAN_FUJ:
  375. case FLASH_MAN_AMD:
  376. switch (info->flash_id & FLASH_TYPEMASK) {
  377. case (FLASH_AM160LV | FLASH_AM160B):
  378. *(volatile __u16 *) (info->start[0] + UNLOCK_ADDR1) =
  379. (__u16) PROG_CMD;
  380. *(volatile __u16 *) (dest) = (__u16) data;
  381. break;
  382. case FLASH_AMDL323B:
  383. *(volatile __u16 *) (dest) = (__u16) PROG_CMD;
  384. *(volatile __u16 *) (dest) = (__u16) data;
  385. break;
  386. }
  387. }
  388. /* arm simple, non interrupt dependent timer */
  389. reset_timer_masked ();
  390. while (flash_check_write_amd (dest)) {
  391. if (get_timer_masked () > CFG_FLASH_WRITE_TOUT) {
  392. printf ("timeout! @ %08lX\n", dest);
  393. /* OOPS: reach timeout,
  394. * try to reset chip */
  395. *(volatile __u16 *) (dest) = (__u16) RESET_CMD;
  396. rc = ERR_TIMOUT;
  397. goto outahere_323B;
  398. }
  399. }
  400. /* Check if Flash was (accurately) written */
  401. if (*(__u16 *) (dest) != data)
  402. rc = ERR_PROG_ERROR;
  403. outahere_323B:
  404. if (flag)
  405. enable_interrupts ();
  406. return rc;
  407. }
  408. /*-----------------------------------------------------------------------
  409. * Copy memory to flash.
  410. */
  411. int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
  412. {
  413. ulong cp, wp;
  414. ushort data;
  415. int l;
  416. int i, rc;
  417. wp = (addr & ~1); /* get lower word aligned address */
  418. /*
  419. * handle unaligned start bytes
  420. */
  421. if ((l = addr - wp) != 0) {
  422. data = 0;
  423. for (i = 0, cp = wp; i < l; ++i, ++cp) {
  424. data = (data >> 8) | (*(uchar *) cp << 8);
  425. }
  426. for (; i < 2 && cnt > 0; ++i) {
  427. data = (data >> 8) | (*src++ << 8);
  428. --cnt;
  429. ++cp;
  430. }
  431. for (; cnt == 0 && i < 2; ++i, ++cp) {
  432. data = (data >> 8) | (*(uchar *) cp << 8);
  433. }
  434. if ((rc = write_word (info, wp, data)) != 0) {
  435. return (rc);
  436. }
  437. wp += 2;
  438. }
  439. /*
  440. * handle word aligned part
  441. */
  442. while (cnt >= 2) {
  443. data = *((ushort *) src);
  444. if ((rc = write_word (info, wp, data)) != 0)
  445. return (rc);
  446. src += 2;
  447. wp += 2;
  448. cnt -= 2;
  449. }
  450. if (cnt == 0)
  451. return ERR_OK;
  452. /*
  453. * handle unaligned tail bytes
  454. */
  455. data = 0;
  456. for (i = 0, cp = wp; i < 2 && cnt > 0; ++i, ++cp) {
  457. data = (data >> 8) | (*src++ << 8);
  458. --cnt;
  459. }
  460. for (; i < 2; ++i, ++cp) {
  461. data = (data >> 8) | (*(uchar *) cp << 8);
  462. }
  463. return write_word (info, wp, data);
  464. }