flash.c 13 KB

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