flash.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599
  1. /*
  2. * (C) Copyright 2002
  3. * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
  4. *
  5. * (C) Copyright 2002
  6. * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
  7. * Marius Groeger <mgroeger@sysgo.de>
  8. *
  9. * (C) Copyright 2002
  10. * Robert Schwebel, Pengutronix, <r.schwebel@pengutronix.de>
  11. *
  12. * See file CREDITS for list of people who contributed to this
  13. * project.
  14. *
  15. * This program is free software; you can redistribute it and/or
  16. * modify it under the terms of the GNU General Public License as
  17. * published by the Free Software Foundation; either version 2 of
  18. * the License, or (at your option) any later version.
  19. *
  20. * This program is distributed in the hope that it will be useful,
  21. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23. * GNU General Public License for more details.
  24. *
  25. * You should have received a copy of the GNU General Public License
  26. * along with this program; if not, write to the Free Software
  27. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  28. * MA 02111-1307 USA
  29. */
  30. #include <common.h>
  31. #include <asm/arch/pxa-regs.h>
  32. #if defined CFG_JFFS_CUSTOM_PART
  33. #include <jffs2/jffs2.h>
  34. #endif
  35. /* Debugging macros ------------------------------------------------------ */
  36. #undef FLASH_DEBUG
  37. //#define FLASH_DEBUG 1
  38. /* Some debug macros */
  39. #if (FLASH_DEBUG > 2 )
  40. #define PRINTK3(args...) printf(args)
  41. #else
  42. #define PRINTK3(args...)
  43. #endif
  44. #if FLASH_DEBUG > 1
  45. #define PRINTK2(args...) printf(args)
  46. #else
  47. #define PRINTK2(args...)
  48. #endif
  49. #ifdef FLASH_DEBUG
  50. #define PRINTK(args...) printf(args)
  51. #else
  52. #define PRINTK(args...)
  53. #endif
  54. /* ------------------------------------------------------------------------ */
  55. /* Development system: we have only 16 MB Flash */
  56. #ifdef CONFIG_MTD_INNOKOM_16MB
  57. #define FLASH_BANK_SIZE 0x01000000 /* 16 MB (during development) */
  58. #define MAIN_SECT_SIZE 0x00020000 /* 128k per sector */
  59. #endif
  60. /* Production system: we have 64 MB Flash */
  61. #ifdef CONFIG_MTD_INNOKOM_64MB
  62. #define FLASH_BANK_SIZE 0x04000000 /* 64 MB */
  63. #define MAIN_SECT_SIZE 0x00020000 /* 128k per sector */
  64. #endif
  65. flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
  66. #if defined CFG_JFFS_CUSTOM_PART
  67. /**
  68. * jffs2_part_info - get information about a JFFS2 partition
  69. *
  70. * @part_num: number of the partition you want to get info about
  71. * @return: struct part_info* in case of success, 0 if failure
  72. */
  73. static struct part_info part;
  74. #ifdef CONFIG_MTD_INNOKOM_16MB
  75. #ifdef CONFIG_MTD_INNOKOM_64MB
  76. #error Please define only one CONFIG_MTD_INNOKOM_XXMB option.
  77. #endif
  78. struct part_info* jffs2_part_info(int part_num) {
  79. PRINTK2("jffs2_part_info: part_num=%i\n",part_num);
  80. /* u-boot partition */
  81. if(part_num==0){
  82. if(part.usr_priv==(void*)1) return &part;
  83. memset(&part, 0, sizeof(part));
  84. part.offset=(char*)0x00000000;
  85. part.size=256*1024;
  86. /* Mark the struct as ready */
  87. part.usr_priv=(void*)1;
  88. PRINTK("part.offset = 0x%08x\n",(unsigned int)part.offset);
  89. PRINTK("part.size = 0x%08x\n",(unsigned int)part.size);
  90. return &part;
  91. }
  92. /* primary OS+firmware partition */
  93. if(part_num==1){
  94. if(part.usr_priv==(void*)1) return &part;
  95. memset(&part, 0, sizeof(part));
  96. part.offset=(char*)0x00040000;
  97. part.size=768*1024;
  98. /* Mark the struct as ready */
  99. part.usr_priv=(void*)1;
  100. PRINTK("part.offset = 0x%08x\n",(unsigned int)part.offset);
  101. PRINTK("part.size = 0x%08x\n",(unsigned int)part.size);
  102. return &part;
  103. }
  104. /* secondary OS+firmware partition */
  105. if(part_num==2){
  106. if(part.usr_priv==(void*)1) return &part;
  107. memset(&part, 0, sizeof(part));
  108. part.offset=(char*)0x00100000;
  109. part.size=8*1024*1024;
  110. /* Mark the struct as ready */
  111. part.usr_priv=(void*)1;
  112. PRINTK("part.offset = 0x%08x\n",(unsigned int)part.offset);
  113. PRINTK("part.size = 0x%08x\n",(unsigned int)part.size);
  114. return &part;
  115. }
  116. /* data partition */
  117. if(part_num==3){
  118. if(part.usr_priv==(void*)1) return &part;
  119. memset(&part, 0, sizeof(part));
  120. part.offset=(char*)0x00900000;
  121. part.size=7*1024*1024;
  122. /* Mark the struct as ready */
  123. part.usr_priv=(void*)1;
  124. PRINTK("part.offset = 0x%08x\n",(unsigned int)part.offset);
  125. PRINTK("part.size = 0x%08x\n",(unsigned int)part.size);
  126. return &part;
  127. }
  128. PRINTK("jffs2_part_info: end of partition table\n");
  129. return 0;
  130. }
  131. #endif /* CONFIG_MTD_INNOKOM_16MB */
  132. #ifdef CONFIG_MTD_INNOKOM_64MB
  133. #ifdef CONFIG_MTD_INNOKOM_16MB
  134. #error Please define only one CONFIG_MTD_INNOKOM_XXMB option.
  135. #endif
  136. struct part_info* jffs2_part_info(int part_num) {
  137. PRINTK2("jffs2_part_info: part_num=%i\n",part_num);
  138. /* u-boot partition */
  139. if(part_num==0){
  140. if(part.usr_priv==(void*)1) return &part;
  141. memset(&part, 0, sizeof(part));
  142. part.offset=(char*)0x00000000;
  143. part.size=256*1024;
  144. /* Mark the struct as ready */
  145. part.usr_priv=(void*)1;
  146. PRINTK("part.offset = 0x%08x\n",(unsigned int)part.offset);
  147. PRINTK("part.size = 0x%08x\n",(unsigned int)part.size);
  148. return &part;
  149. }
  150. /* primary OS+firmware partition */
  151. if(part_num==1){
  152. if(part.usr_priv==(void*)1) return &part;
  153. memset(&part, 0, sizeof(part));
  154. part.offset=(char*)0x00040000;
  155. part.size=16*1024*1024-128*1024;
  156. /* Mark the struct as ready */
  157. part.usr_priv=(void*)1;
  158. PRINTK("part.offset = 0x%08x\n",(unsigned int)part.offset);
  159. PRINTK("part.size = 0x%08x\n",(unsigned int)part.size);
  160. return &part;
  161. }
  162. /* secondary OS+firmware partition */
  163. if(part_num==2){
  164. if(part.usr_priv==(void*)1) return &part;
  165. memset(&part, 0, sizeof(part));
  166. part.offset=(char*)0x01020000;
  167. part.size=16*1024*1024-128*1024;
  168. /* Mark the struct as ready */
  169. part.usr_priv=(void*)1;
  170. PRINTK("part.offset = 0x%08x\n",(unsigned int)part.offset);
  171. PRINTK("part.size = 0x%08x\n",(unsigned int)part.size);
  172. return &part;
  173. }
  174. /* data partition */
  175. if(part_num==3){
  176. if(part.usr_priv==(void*)1) return &part;
  177. memset(&part, 0, sizeof(part));
  178. part.offset=(char*)0x02000000;
  179. part.size=32*1024*1024;
  180. /* Mark the struct as ready */
  181. part.usr_priv=(void*)1;
  182. PRINTK("part.offset = 0x%08x\n",(unsigned int)part.offset);
  183. PRINTK("part.size = 0x%08x\n",(unsigned int)part.size);
  184. return &part;
  185. }
  186. PRINTK("jffs2_part_info: end of partition table\n");
  187. return 0;
  188. }
  189. #endif /* CONFIG_MTD_INNOKOM_64MB */
  190. #endif /* defined CFG_JFFS_CUSTOM_PART */
  191. /**
  192. * flash_init: - initialize data structures for flash chips
  193. *
  194. * @return: size of the flash
  195. */
  196. ulong flash_init(void)
  197. {
  198. int i, j;
  199. ulong size = 0;
  200. for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
  201. ulong flashbase = 0;
  202. flash_info[i].flash_id =
  203. (INTEL_MANUFACT & FLASH_VENDMASK) |
  204. (INTEL_ID_28F128J3 & FLASH_TYPEMASK);
  205. flash_info[i].size = FLASH_BANK_SIZE;
  206. flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
  207. memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
  208. switch (i) {
  209. case 0:
  210. flashbase = PHYS_FLASH_1;
  211. break;
  212. default:
  213. panic("configured to many flash banks!\n");
  214. break;
  215. }
  216. for (j = 0; j < flash_info[i].sector_count; j++) {
  217. flash_info[i].start[j] = flashbase + j*MAIN_SECT_SIZE;
  218. }
  219. size += flash_info[i].size;
  220. }
  221. /* Protect u-boot sectors */
  222. flash_protect(FLAG_PROTECT_SET,
  223. CFG_FLASH_BASE,
  224. CFG_FLASH_BASE + (256*1024) - 1,
  225. &flash_info[0]);
  226. #ifdef CFG_ENV_IS_IN_FLASH
  227. flash_protect(FLAG_PROTECT_SET,
  228. CFG_ENV_ADDR,
  229. CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
  230. &flash_info[0]);
  231. #endif
  232. return size;
  233. }
  234. /**
  235. * flash_print_info: - print information about the flash situation
  236. *
  237. * @param info:
  238. */
  239. void flash_print_info (flash_info_t *info)
  240. {
  241. int i, j;
  242. for (j=0; j<CFG_MAX_FLASH_BANKS; j++) {
  243. switch (info->flash_id & FLASH_VENDMASK) {
  244. case (INTEL_MANUFACT & FLASH_VENDMASK):
  245. printf("Intel: ");
  246. break;
  247. default:
  248. printf("Unknown Vendor ");
  249. break;
  250. }
  251. switch (info->flash_id & FLASH_TYPEMASK) {
  252. case (INTEL_ID_28F128J3 & FLASH_TYPEMASK):
  253. printf("28F128J3 (128Mbit)\n");
  254. break;
  255. default:
  256. printf("Unknown Chip Type\n");
  257. return;
  258. }
  259. printf(" Size: %ld MB in %d Sectors\n",
  260. info->size >> 20, info->sector_count);
  261. printf(" Sector Start Addresses:");
  262. for (i = 0; i < info->sector_count; i++) {
  263. if ((i % 5) == 0) printf ("\n ");
  264. printf (" %08lX%s", info->start[i],
  265. info->protect[i] ? " (RO)" : " ");
  266. }
  267. printf ("\n");
  268. info++;
  269. }
  270. }
  271. /**
  272. * flash_erase: - erase flash sectors
  273. *
  274. */
  275. int flash_erase(flash_info_t *info, int s_first, int s_last)
  276. {
  277. int flag, prot, sect;
  278. int rc = ERR_OK;
  279. if (info->flash_id == FLASH_UNKNOWN)
  280. return ERR_UNKNOWN_FLASH_TYPE;
  281. if ((s_first < 0) || (s_first > s_last)) {
  282. return ERR_INVAL;
  283. }
  284. if ((info->flash_id & FLASH_VENDMASK) != (INTEL_MANUFACT & FLASH_VENDMASK))
  285. return ERR_UNKNOWN_FLASH_VENDOR;
  286. prot = 0;
  287. for (sect=s_first; sect<=s_last; ++sect) {
  288. if (info->protect[sect]) prot++;
  289. }
  290. if (prot) return ERR_PROTECTED;
  291. /*
  292. * Disable interrupts which might cause a timeout
  293. * here. Remember that our exception vectors are
  294. * at address 0 in the flash, and we don't want a
  295. * (ticker) exception to happen while the flash
  296. * chip is in programming mode.
  297. */
  298. flag = disable_interrupts();
  299. /* Start erase on unprotected sectors */
  300. for (sect = s_first; sect<=s_last && !ctrlc(); sect++) {
  301. printf("Erasing sector %2d ... ", sect);
  302. PRINTK("\n");
  303. /* arm simple, non interrupt dependent timer */
  304. reset_timer_masked();
  305. if (info->protect[sect] == 0) { /* not protected */
  306. u16 * volatile addr = (u16 * volatile)(info->start[sect]);
  307. PRINTK("unlocking sector\n");
  308. *addr = 0x0060;
  309. *addr = 0x00d0;
  310. *addr = 0x00ff;
  311. PRINTK("erasing sector\n");
  312. *addr = 0x0020;
  313. PRINTK("confirming erase\n");
  314. *addr = 0x00D0;
  315. while ((*addr & 0x0080) != 0x0080) {
  316. PRINTK(".");
  317. if (get_timer_masked() > CFG_FLASH_ERASE_TOUT) {
  318. *addr = 0x00B0; /* suspend erase*/
  319. *addr = 0x00FF; /* read mode */
  320. rc = ERR_TIMOUT;
  321. goto outahere;
  322. }
  323. }
  324. PRINTK("clearing status register\n");
  325. *addr = 0x0050;
  326. PRINTK("resetting to read mode");
  327. *addr = 0x00FF;
  328. }
  329. printf("ok.\n");
  330. }
  331. if (ctrlc()) printf("User Interrupt!\n");
  332. outahere:
  333. /* allow flash to settle - wait 10 ms */
  334. udelay_masked(10000);
  335. if (flag) enable_interrupts();
  336. return rc;
  337. }
  338. /**
  339. * write_word: - copy memory to flash
  340. *
  341. * @param info:
  342. * @param dest:
  343. * @param data:
  344. * @return:
  345. */
  346. static int write_word (flash_info_t *info, ulong dest, ushort data)
  347. {
  348. volatile u16 *addr = (u16 *)dest, val;
  349. int rc = ERR_OK;
  350. int flag;
  351. /* Check if Flash is (sufficiently) erased */
  352. if ((*addr & data) != data) return ERR_NOT_ERASED;
  353. /*
  354. * Disable interrupts which might cause a timeout
  355. * here. Remember that our exception vectors are
  356. * at address 0 in the flash, and we don't want a
  357. * (ticker) exception to happen while the flash
  358. * chip is in programming mode.
  359. */
  360. flag = disable_interrupts();
  361. /* clear status register command */
  362. *addr = 0x50;
  363. /* program set-up command */
  364. *addr = 0x40;
  365. /* latch address/data */
  366. *addr = data;
  367. /* arm simple, non interrupt dependent timer */
  368. reset_timer_masked();
  369. /* wait while polling the status register */
  370. while(((val = *addr) & 0x80) != 0x80) {
  371. if (get_timer_masked() > CFG_FLASH_WRITE_TOUT) {
  372. rc = ERR_TIMOUT;
  373. *addr = 0xB0; /* suspend program command */
  374. goto outahere;
  375. }
  376. }
  377. if(val & 0x1A) { /* check for error */
  378. printf("\nFlash write error %02x at address %08lx\n",
  379. (int)val, (unsigned long)dest);
  380. if(val & (1<<3)) {
  381. printf("Voltage range error.\n");
  382. rc = ERR_PROG_ERROR;
  383. goto outahere;
  384. }
  385. if(val & (1<<1)) {
  386. printf("Device protect error.\n");
  387. rc = ERR_PROTECTED;
  388. goto outahere;
  389. }
  390. if(val & (1<<4)) {
  391. printf("Programming error.\n");
  392. rc = ERR_PROG_ERROR;
  393. goto outahere;
  394. }
  395. rc = ERR_PROG_ERROR;
  396. goto outahere;
  397. }
  398. outahere:
  399. *addr = 0xFF; /* read array command */
  400. if (flag) enable_interrupts();
  401. return rc;
  402. }
  403. /**
  404. * write_buf: - Copy memory to flash.
  405. *
  406. * @param info:
  407. * @param src: source of copy transaction
  408. * @param addr: where to copy to
  409. * @param cnt: number of bytes to copy
  410. *
  411. * @return error code
  412. */
  413. int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
  414. {
  415. ulong cp, wp;
  416. ushort data;
  417. int l;
  418. int i, rc;
  419. wp = (addr & ~1); /* get lower word aligned address */
  420. /*
  421. * handle unaligned start bytes
  422. */
  423. if ((l = addr - wp) != 0) {
  424. data = 0;
  425. for (i=0, cp=wp; i<l; ++i, ++cp) {
  426. data = (data >> 8) | (*(uchar *)cp << 8);
  427. }
  428. for (; i<2 && cnt>0; ++i) {
  429. data = (data >> 8) | (*src++ << 8);
  430. --cnt;
  431. ++cp;
  432. }
  433. for (; cnt==0 && i<2; ++i, ++cp) {
  434. data = (data >> 8) | (*(uchar *)cp << 8);
  435. }
  436. if ((rc = write_word(info, wp, data)) != 0) {
  437. return (rc);
  438. }
  439. wp += 2;
  440. }
  441. /*
  442. * handle word aligned part
  443. */
  444. while (cnt >= 2) {
  445. /* data = *((vushort*)src); */
  446. data = *((ushort*)src);
  447. if ((rc = write_word(info, wp, data)) != 0) {
  448. return (rc);
  449. }
  450. src += 2;
  451. wp += 2;
  452. cnt -= 2;
  453. }
  454. if (cnt == 0) return ERR_OK;
  455. /*
  456. * handle unaligned tail bytes
  457. */
  458. data = 0;
  459. for (i=0, cp=wp; i<2 && cnt>0; ++i, ++cp) {
  460. data = (data >> 8) | (*src++ << 8);
  461. --cnt;
  462. }
  463. for (; i<2; ++i, ++cp) {
  464. data = (data >> 8) | (*(uchar *)cp << 8);
  465. }
  466. return write_word(info, wp, data);
  467. }