flash_old.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. /*
  2. * (C) Copyright 2002
  3. * Daniel Engström, Omicron Ceti AB, daniel@omicron.se
  4. *
  5. * (C) Copyright 2002
  6. * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
  7. * Alex Zuepke <azu@sysgo.de>
  8. *
  9. * See file CREDITS for list of people who contributed to this
  10. * project.
  11. *
  12. * This program is free software; you can redistribute it and/or
  13. * modify it under the terms of the GNU General Public License as
  14. * published by the Free Software Foundation; either version 2 of
  15. * the License, or (at your option) any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU General Public License
  23. * along with this program; if not, write to the Free Software
  24. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  25. * MA 02111-1307 USA
  26. */
  27. #include <common.h>
  28. #include <asm/io.h>
  29. ulong myflush(void);
  30. #define SC520_MAX_FLASH_BANKS 3
  31. #define SC520_FLASH_BANK0_BASE 0x38000000 /* BOOTCS */
  32. #define SC520_FLASH_BANK1_BASE 0x30000000 /* ROMCS0 */
  33. #define SC520_FLASH_BANK2_BASE 0x28000000 /* ROMCS1 */
  34. #define SC520_FLASH_BANKSIZE 0x8000000
  35. #define AMD29LV016_SIZE 0x200000
  36. #define AMD29LV016_SECTORS 32
  37. flash_info_t flash_info[SC520_MAX_FLASH_BANKS];
  38. #define CMD_READ_ARRAY 0x00F000F0
  39. #define CMD_UNLOCK1 0x00AA00AA
  40. #define CMD_UNLOCK2 0x00550055
  41. #define CMD_ERASE_SETUP 0x00800080
  42. #define CMD_ERASE_CONFIRM 0x00300030
  43. #define CMD_PROGRAM 0x00A000A0
  44. #define CMD_UNLOCK_BYPASS 0x00200020
  45. #define BIT_ERASE_DONE 0x00800080
  46. #define BIT_RDY_MASK 0x00800080
  47. #define BIT_PROGRAM_ERROR 0x00200020
  48. #define BIT_TIMEOUT 0x80000000 /* our flag */
  49. #define READY 1
  50. #define ERR 2
  51. #define TMO 4
  52. /*-----------------------------------------------------------------------
  53. */
  54. ulong flash_init(void)
  55. {
  56. int i, j;
  57. ulong size = 0;
  58. for (i = 0; i < SC520_MAX_FLASH_BANKS; i++) {
  59. ulong flashbase = 0;
  60. int sectsize = 0;
  61. if (i==0 || i==2) {
  62. /* FixMe: this assumes that bank 0 and 2
  63. * are mapped to the two 8Mb banks */
  64. flash_info[i].flash_id =
  65. (AMD_MANUFACT & FLASH_VENDMASK) |
  66. (AMD_ID_LV016B & FLASH_TYPEMASK);
  67. flash_info[i].size = AMD29LV016_SIZE*4;
  68. flash_info[i].sector_count = AMD29LV016_SECTORS;
  69. sectsize = (AMD29LV016_SIZE*4)/AMD29LV016_SECTORS;
  70. } else {
  71. /* FixMe: this assumes that bank1 is unmapped
  72. * (or mapped to the same flash bank as BOOTCS) */
  73. flash_info[i].flash_id = 0;
  74. flash_info[i].size = 0;
  75. flash_info[i].sector_count = 0;
  76. sectsize=0;
  77. }
  78. memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
  79. switch (i) {
  80. case 0:
  81. flashbase = SC520_FLASH_BANK0_BASE;
  82. break;
  83. case 1:
  84. flashbase = SC520_FLASH_BANK1_BASE;
  85. break;
  86. case 2:
  87. flashbase = SC520_FLASH_BANK0_BASE;
  88. break;
  89. default:
  90. panic("configured to many flash banks!\n");
  91. }
  92. for (j = 0; j < flash_info[i].sector_count; j++) {
  93. flash_info[i].start[j] = sectsize;
  94. flash_info[i].start[j] = flashbase + j * sectsize;
  95. }
  96. size += flash_info[i].size;
  97. }
  98. /*
  99. * Protect monitor and environment sectors
  100. */
  101. flash_protect(FLAG_PROTECT_SET,
  102. i386boot_start-SC520_FLASH_BANK0_BASE,
  103. i386boot_end-SC520_FLASH_BANK0_BASE,
  104. &flash_info[0]);
  105. #ifdef CFG_ENV_ADDR
  106. flash_protect(FLAG_PROTECT_SET,
  107. CFG_ENV_ADDR,
  108. CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
  109. &flash_info[0]);
  110. #endif
  111. return size;
  112. }
  113. /*-----------------------------------------------------------------------
  114. */
  115. void flash_print_info(flash_info_t *info)
  116. {
  117. int i;
  118. switch (info->flash_id & FLASH_VENDMASK) {
  119. case (AMD_MANUFACT & FLASH_VENDMASK):
  120. printf("AMD: ");
  121. break;
  122. default:
  123. printf("Unknown Vendor ");
  124. break;
  125. }
  126. switch (info->flash_id & FLASH_TYPEMASK) {
  127. case (AMD_ID_LV016B & FLASH_TYPEMASK):
  128. printf("4x Amd29LV016B (16Mbit)\n");
  129. break;
  130. default:
  131. printf("Unknown Chip Type\n");
  132. goto done;
  133. break;
  134. }
  135. printf(" Size: %ld MB in %d Sectors\n",
  136. info->size >> 20, info->sector_count);
  137. printf(" Sector Start Addresses:");
  138. for (i = 0; i < info->sector_count; i++) {
  139. if ((i % 5) == 0) {
  140. printf ("\n ");
  141. }
  142. printf (" %08lX%s", info->start[i],
  143. info->protect[i] ? " (RO)" : " ");
  144. }
  145. printf ("\n");
  146. done:
  147. }
  148. /*-----------------------------------------------------------------------
  149. */
  150. int flash_erase(flash_info_t *info, int s_first, int s_last)
  151. {
  152. ulong result;
  153. int iflag, prot, sect;
  154. int rc = ERR_OK;
  155. int chip1, chip2;
  156. /* first look for protection bits */
  157. if (info->flash_id == FLASH_UNKNOWN) {
  158. return ERR_UNKNOWN_FLASH_TYPE;
  159. }
  160. if ((s_first < 0) || (s_first > s_last)) {
  161. return ERR_INVAL;
  162. }
  163. if ((info->flash_id & FLASH_VENDMASK) !=
  164. (AMD_MANUFACT & FLASH_VENDMASK)) {
  165. return ERR_UNKNOWN_FLASH_VENDOR;
  166. }
  167. prot = 0;
  168. for (sect=s_first; sect<=s_last; ++sect) {
  169. if (info->protect[sect]) {
  170. prot++;
  171. }
  172. }
  173. if (prot) {
  174. return ERR_PROTECTED;
  175. }
  176. /*
  177. * Disable interrupts which might cause a timeout
  178. * here. Remember that our exception vectors are
  179. * at address 0 in the flash, and we don't want a
  180. * (ticker) exception to happen while the flash
  181. * chip is in programming mode.
  182. */
  183. iflag = disable_interrupts();
  184. /* Start erase on unprotected sectors */
  185. for (sect = s_first; sect<=s_last && !ctrlc(); sect++) {
  186. printf("Erasing sector %2d ... ", sect);
  187. /* arm simple, non interrupt dependent timer */
  188. reset_timer();
  189. if (info->protect[sect] == 0) {
  190. /* not protected */
  191. ulong addr = info->start[sect];
  192. writel(CMD_UNLOCK1, addr + 1);
  193. writel(CMD_UNLOCK2, addr + 2);
  194. writel(CMD_ERASE_SETUP, addr + 1);
  195. writel(CMD_UNLOCK1, addr + 1);
  196. writel(CMD_UNLOCK2, addr + 2);
  197. writel(CMD_ERASE_CONFIRM, addr);
  198. /* wait until flash is ready */
  199. chip1 = chip2 = 0;
  200. do {
  201. result = readl(addr);
  202. /* check timeout */
  203. if (get_timer(0) > CFG_FLASH_ERASE_TOUT) {
  204. writel(CMD_READ_ARRAY, addr + 1);
  205. chip1 = TMO;
  206. break;
  207. }
  208. if (!chip1 && (result & 0xFFFF) & BIT_ERASE_DONE) {
  209. chip1 = READY;
  210. }
  211. if (!chip1 && (result & 0xFFFF) & BIT_PROGRAM_ERROR) {
  212. chip1 = ERR;
  213. }
  214. if (!chip2 && (result >> 16) & BIT_ERASE_DONE) {
  215. chip2 = READY;
  216. }
  217. if (!chip2 && (result >> 16) & BIT_PROGRAM_ERROR) {
  218. chip2 = ERR;
  219. }
  220. } while (!chip1 || !chip2);
  221. writel(CMD_READ_ARRAY, addr + 1);
  222. if (chip1 == ERR || chip2 == ERR) {
  223. rc = ERR_PROG_ERROR;
  224. goto outahere;
  225. }
  226. if (chip1 == TMO) {
  227. rc = ERR_TIMOUT;
  228. goto outahere;
  229. }
  230. printf("ok.\n");
  231. } else { /* it was protected */
  232. printf("protected!\n");
  233. }
  234. }
  235. if (ctrlc()) {
  236. printf("User Interrupt!\n");
  237. }
  238. outahere:
  239. /* allow flash to settle - wait 10 ms */
  240. udelay(10000);
  241. if (iflag) {
  242. enable_interrupts();
  243. }
  244. return rc;
  245. }
  246. /*-----------------------------------------------------------------------
  247. * Copy memory to flash
  248. */
  249. volatile static int write_word(flash_info_t *info, ulong dest, ulong data)
  250. {
  251. ulong addr = dest;
  252. ulong result;
  253. int rc = ERR_OK;
  254. int iflag;
  255. int chip1, chip2;
  256. /*
  257. * Check if Flash is (sufficiently) erased
  258. */
  259. result = readl(addr);
  260. if ((result & data) != data) {
  261. return ERR_NOT_ERASED;
  262. }
  263. /*
  264. * Disable interrupts which might cause a timeout
  265. * here. Remember that our exception vectors are
  266. * at address 0 in the flash, and we don't want a
  267. * (ticker) exception to happen while the flash
  268. * chip is in programming mode.
  269. */
  270. iflag = disable_interrupts();
  271. writel(CMD_UNLOCK1, addr + 1);
  272. writel(CMD_UNLOCK2, addr + 2);
  273. writel(CMD_UNLOCK_BYPASS, addr + 1);
  274. writel(addr, CMD_PROGRAM);
  275. writel(addr, data);
  276. /* arm simple, non interrupt dependent timer */
  277. reset_timer();
  278. /* wait until flash is ready */
  279. chip1 = chip2 = 0;
  280. do {
  281. result = readl(addr);
  282. /* check timeout */
  283. if (get_timer(0) > CFG_FLASH_ERASE_TOUT) {
  284. chip1 = ERR | TMO;
  285. break;
  286. }
  287. if (!chip1 && ((result & 0x80) == (data & 0x80))) {
  288. chip1 = READY;
  289. }
  290. if (!chip1 && ((result & 0xFFFF) & BIT_PROGRAM_ERROR)) {
  291. result = readl(addr);
  292. if ((result & 0x80) == (data & 0x80)) {
  293. chip1 = READY;
  294. } else {
  295. chip1 = ERR;
  296. }
  297. }
  298. if (!chip2 && ((result & (0x80 << 16)) == (data & (0x80 << 16)))) {
  299. chip2 = READY;
  300. }
  301. if (!chip2 && ((result >> 16) & BIT_PROGRAM_ERROR)) {
  302. result = readl(addr);
  303. if ((result & (0x80 << 16)) == (data & (0x80 << 16))) {
  304. chip2 = READY;
  305. } else {
  306. chip2 = ERR;
  307. }
  308. }
  309. } while (!chip1 || !chip2);
  310. writel(CMD_READ_ARRAY, addr);
  311. if (chip1 == ERR || chip2 == ERR || readl(addr) != data) {
  312. rc = ERR_PROG_ERROR;
  313. }
  314. if (iflag) {
  315. enable_interrupts();
  316. }
  317. return rc;
  318. }
  319. /*-----------------------------------------------------------------------
  320. * Copy memory to flash.
  321. */
  322. int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
  323. {
  324. ulong cp, wp, data;
  325. int l;
  326. int i, rc;
  327. wp = (addr & ~3); /* get lower word aligned address */
  328. /*
  329. * handle unaligned start bytes
  330. */
  331. if ((l = addr - wp) != 0) {
  332. data = 0;
  333. for (i=0, cp=wp; i<l; ++i, ++cp) {
  334. data = (data >> 8) | (*(uchar *)cp << 24);
  335. }
  336. for (; i<4 && cnt>0; ++i) {
  337. data = (data >> 8) | (*src++ << 24);
  338. --cnt;
  339. ++cp;
  340. }
  341. for (; cnt==0 && i<4; ++i, ++cp) {
  342. data = (data >> 8) | (*(uchar *)cp << 24);
  343. }
  344. if ((rc = write_word(info, wp, data)) != 0) {
  345. return rc;
  346. }
  347. wp += 4;
  348. }
  349. /*
  350. * handle word aligned part
  351. */
  352. while (cnt >= 4) {
  353. data = *((vu_long*)src);
  354. if ((rc = write_word(info, wp, data)) != 0) {
  355. return rc;
  356. }
  357. src += 4;
  358. wp += 4;
  359. cnt -= 4;
  360. }
  361. if (cnt == 0) {
  362. return ERR_OK;
  363. }
  364. /*
  365. * handle unaligned tail bytes
  366. */
  367. data = 0;
  368. for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
  369. data = (data >> 8) | (*src++ << 24);
  370. --cnt;
  371. }
  372. for (; i<4; ++i, ++cp) {
  373. data = (data >> 8) | (*(uchar *)cp << 24);
  374. }
  375. return write_word(info, wp, data);
  376. }