flash.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. /*
  2. * U-boot - flash.c Flash driver for PSD4256GV
  3. *
  4. * Copyright (c) 2005 blackfin.uclinux.org
  5. * This file is based on BF533EzFlash.c originally written by Analog Devices, Inc.
  6. *
  7. * (C) Copyright 2000-2004
  8. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  9. *
  10. * See file CREDITS for list of people who contributed to this
  11. * project.
  12. *
  13. * This program is free software; you can redistribute it and/or
  14. * modify it under the terms of the GNU General Public License as
  15. * published by the Free Software Foundation; either version 2 of
  16. * the License, or (at your option) any later version.
  17. *
  18. * This program is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU General Public License
  24. * along with this program; if not, write to the Free Software
  25. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  26. * MA 02111-1307 USA
  27. */
  28. #include <malloc.h>
  29. #include <config.h>
  30. #include <asm/io.h>
  31. #include "flash-defines.h"
  32. void flash_reset(void)
  33. {
  34. reset_flash();
  35. }
  36. unsigned long flash_get_size(ulong baseaddr, flash_info_t * info, int bank_flag)
  37. {
  38. int id = 0, i = 0;
  39. static int FlagDev = 1;
  40. id = get_codes();
  41. if (FlagDev) {
  42. FlagDev = 0;
  43. }
  44. info->flash_id = id;
  45. switch (bank_flag) {
  46. case 0:
  47. for (i = PriFlashABegin; i < SecFlashABegin; i++)
  48. info->start[i] = (baseaddr + (i * AFP_SectorSize1));
  49. for (i = SecFlashABegin; i < NUM_SECTORS; i++)
  50. info->start[i] =
  51. (baseaddr + SecFlashAOff +
  52. ((i - SecFlashABegin) * AFP_SectorSize2));
  53. info->size = 0x400000;
  54. info->sector_count = NUM_SECTORS;
  55. break;
  56. case 1:
  57. info->start[0] = baseaddr + SecFlashASec1Off;
  58. info->start[1] = baseaddr + SecFlashASec2Off;
  59. info->start[2] = baseaddr + SecFlashASec3Off;
  60. info->start[3] = baseaddr + SecFlashASec4Off;
  61. info->size = 0x10000;
  62. info->sector_count = 4;
  63. break;
  64. case 2:
  65. info->start[0] = baseaddr + SecFlashBSec1Off;
  66. info->start[1] = baseaddr + SecFlashBSec2Off;
  67. info->start[2] = baseaddr + SecFlashBSec3Off;
  68. info->start[3] = baseaddr + SecFlashBSec4Off;
  69. info->size = 0x10000;
  70. info->sector_count = 4;
  71. break;
  72. }
  73. return (info->size);
  74. }
  75. unsigned long flash_init(void)
  76. {
  77. unsigned long size_b;
  78. int i;
  79. size_b = 0;
  80. for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
  81. flash_info[i].flash_id = FLASH_UNKNOWN;
  82. }
  83. size_b = flash_get_size(CFG_FLASH_BASE, &flash_info[0], 0);
  84. if (flash_info[0].flash_id == FLASH_UNKNOWN || size_b == 0) {
  85. printf("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
  86. size_b, size_b >> 20);
  87. }
  88. /* flash_protect (int flag, ulong from, ulong to, flash_info_t *info) */
  89. (void)flash_protect(FLAG_PROTECT_SET, CFG_FLASH_BASE,
  90. (flash_info[0].start[2] - 1), &flash_info[0]);
  91. #if (BFIN_BOOT_MODE == BF537_BYPASS_BOOT)
  92. (void)flash_protect(FLAG_PROTECT_SET, 0x203F0000, 0x203FFFFF,
  93. &flash_info[0]);
  94. #endif
  95. return (size_b);
  96. }
  97. void flash_print_info(flash_info_t * info)
  98. {
  99. int i;
  100. if (info->flash_id == FLASH_UNKNOWN) {
  101. printf("missing or unknown FLASH type\n");
  102. return;
  103. }
  104. switch (info->flash_id) {
  105. case (STM_ID_29W320EB & 0xFFFF):
  106. case (STM_ID_29W320DB & 0xFFFF):
  107. printf("ST Microelectronics ");
  108. break;
  109. default:
  110. printf("Unknown Vendor: (0x%08X) ", info->flash_id);
  111. break;
  112. }
  113. for (i = 0; i < info->sector_count; ++i) {
  114. if ((i % 5) == 0)
  115. printf("\n ");
  116. printf(" %08lX%s",
  117. info->start[i], info->protect[i] ? " (RO)" : " ");
  118. }
  119. printf("\n");
  120. return;
  121. }
  122. int flash_erase(flash_info_t * info, int s_first, int s_last)
  123. {
  124. int cnt = 0, i;
  125. int prot, sect;
  126. prot = 0;
  127. for (sect = s_first; sect <= s_last; ++sect) {
  128. if (info->protect[sect])
  129. prot++;
  130. }
  131. if (prot)
  132. printf("- Warning: %d protected sectors will not be erased!\n",
  133. prot);
  134. else
  135. printf("\n");
  136. cnt = s_last - s_first + 1;
  137. #if (BFIN_BOOT_MODE == BF537_BYPASS_BOOT)
  138. printf("Erasing Flash locations, Please Wait\n");
  139. for (i = s_first; i <= s_last; i++) {
  140. if (info->protect[i] == 0) { /* not protected */
  141. if (erase_block_flash(i) < 0) {
  142. printf("Error Sector erasing \n");
  143. return FLASH_FAIL;
  144. }
  145. }
  146. }
  147. #elif (BFIN_BOOT_MODE == BF537_SPI_MASTER_BOOT)
  148. if (cnt == FLASH_TOT_SECT) {
  149. printf("Erasing flash, Please Wait \n");
  150. if (erase_flash() < 0) {
  151. printf("Erasing flash failed \n");
  152. return FLASH_FAIL;
  153. }
  154. } else {
  155. printf("Erasing Flash locations, Please Wait\n");
  156. for (i = s_first; i <= s_last; i++) {
  157. if (info->protect[i] == 0) { /* not protected */
  158. if (erase_block_flash(i) < 0) {
  159. printf("Error Sector erasing \n");
  160. return FLASH_FAIL;
  161. }
  162. }
  163. }
  164. }
  165. #endif
  166. printf("\n");
  167. return FLASH_SUCCESS;
  168. }
  169. int write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt)
  170. {
  171. int d;
  172. if (addr % 2) {
  173. read_flash(addr - 1 - CFG_FLASH_BASE, &d);
  174. d = (int)((d & 0x00FF) | (*src++ << 8));
  175. write_data(addr - 1, 2, (uchar *) & d);
  176. write_data(addr + 1, cnt - 1, src);
  177. } else
  178. write_data(addr, cnt, src);
  179. return FLASH_SUCCESS;
  180. }
  181. int write_data(long lStart, long lCount, uchar * pnData)
  182. {
  183. long i = 0;
  184. unsigned long ulOffset = lStart - CFG_FLASH_BASE;
  185. int d;
  186. int nSector = 0;
  187. int flag = 0;
  188. if (lCount % 2) {
  189. flag = 1;
  190. lCount = lCount - 1;
  191. }
  192. for (i = 0; i < lCount - 1; i += 2, ulOffset += 2) {
  193. get_sector_number(ulOffset, &nSector);
  194. read_flash(ulOffset, &d);
  195. if (d != 0xffff) {
  196. printf
  197. ("Flash not erased at offset 0x%x Please erase to reprogram \n",
  198. ulOffset);
  199. return FLASH_FAIL;
  200. }
  201. unlock_flash(ulOffset);
  202. d = (int)(pnData[i] | pnData[i + 1] << 8);
  203. write_flash(ulOffset, d);
  204. if (poll_toggle_bit(ulOffset) < 0) {
  205. printf("Error programming the flash \n");
  206. return FLASH_FAIL;
  207. }
  208. if ((i > 0) && (!(i % AFP_SectorSize2)))
  209. printf(".");
  210. }
  211. if (flag) {
  212. get_sector_number(ulOffset, &nSector);
  213. read_flash(ulOffset, &d);
  214. if (d != 0xffff) {
  215. printf
  216. ("Flash not erased at offset 0x%x Please erase to reprogram \n",
  217. ulOffset);
  218. return FLASH_FAIL;
  219. }
  220. unlock_flash(ulOffset);
  221. d = (int)(pnData[i] | (d & 0xFF00));
  222. write_flash(ulOffset, d);
  223. if (poll_toggle_bit(ulOffset) < 0) {
  224. printf("Error programming the flash \n");
  225. return FLASH_FAIL;
  226. }
  227. }
  228. return FLASH_SUCCESS;
  229. }
  230. int write_flash(long nOffset, int nValue)
  231. {
  232. long addr;
  233. addr = (CFG_FLASH_BASE + nOffset);
  234. *(unsigned volatile short *)addr = nValue;
  235. sync();
  236. #if (BFIN_BOOT_MODE == BF537_SPI_MASTER_BOOT)
  237. if (icache_status())
  238. udelay(CONFIG_CCLK_HZ / 1000000);
  239. #endif
  240. return FLASH_SUCCESS;
  241. }
  242. int read_flash(long nOffset, int *pnValue)
  243. {
  244. unsigned short *pFlashAddr =
  245. (unsigned short *)(CFG_FLASH_BASE + nOffset);
  246. *pnValue = *pFlashAddr;
  247. return TRUE;
  248. }
  249. int poll_toggle_bit(long lOffset)
  250. {
  251. unsigned int u1, u2;
  252. volatile unsigned long *FB =
  253. (volatile unsigned long *)(CFG_FLASH_BASE + lOffset);
  254. while (1) {
  255. u1 = *(volatile unsigned short *)FB;
  256. u2 = *(volatile unsigned short *)FB;
  257. u1 ^= u2;
  258. if (!(u1 & 0x0040))
  259. break;
  260. if (!(u2 & 0x0020))
  261. continue;
  262. else {
  263. u1 = *(volatile unsigned short *)FB;
  264. u2 = *(volatile unsigned short *)FB;
  265. u1 ^= u2;
  266. if (!(u1 & 0x0040))
  267. break;
  268. else {
  269. reset_flash();
  270. return FLASH_FAIL;
  271. }
  272. }
  273. }
  274. return FLASH_SUCCESS;
  275. }
  276. void reset_flash(void)
  277. {
  278. write_flash(WRITESEQ1, RESET_VAL);
  279. /* Wait for 10 micro seconds */
  280. udelay(10);
  281. }
  282. int erase_flash(void)
  283. {
  284. write_flash(WRITESEQ1, WRITEDATA1);
  285. write_flash(WRITESEQ2, WRITEDATA2);
  286. write_flash(WRITESEQ3, WRITEDATA3);
  287. write_flash(WRITESEQ4, WRITEDATA4);
  288. write_flash(WRITESEQ5, WRITEDATA5);
  289. write_flash(WRITESEQ6, WRITEDATA6);
  290. if (poll_toggle_bit(0x0000) < 0)
  291. return FLASH_FAIL;
  292. return FLASH_SUCCESS;
  293. }
  294. int erase_block_flash(int nBlock)
  295. {
  296. long ulSectorOff = 0x0;
  297. if ((nBlock < 0) || (nBlock > AFP_NumSectors))
  298. return FALSE;
  299. // figure out the offset of the block in flash
  300. if ((nBlock >= 0) && (nBlock < SecFlashABegin))
  301. ulSectorOff = nBlock * AFP_SectorSize1;
  302. else if ((nBlock >= SecFlashABegin) && (nBlock < NUM_SECTORS))
  303. ulSectorOff =
  304. SecFlashAOff + (nBlock - SecFlashABegin) * AFP_SectorSize2;
  305. // no such sector
  306. else
  307. return FLASH_FAIL;
  308. write_flash((WRITESEQ1 | ulSectorOff), WRITEDATA1);
  309. write_flash((WRITESEQ2 | ulSectorOff), WRITEDATA2);
  310. write_flash((WRITESEQ3 | ulSectorOff), WRITEDATA3);
  311. write_flash((WRITESEQ4 | ulSectorOff), WRITEDATA4);
  312. write_flash((WRITESEQ5 | ulSectorOff), WRITEDATA5);
  313. write_flash(ulSectorOff, BlockEraseVal);
  314. if (poll_toggle_bit(ulSectorOff) < 0)
  315. return FLASH_FAIL;
  316. printf(".");
  317. return FLASH_SUCCESS;
  318. }
  319. void unlock_flash(long ulOffset)
  320. {
  321. unsigned long ulOffsetAddr = ulOffset;
  322. ulOffsetAddr &= 0xFFFF0000;
  323. write_flash((WRITESEQ1 | ulOffsetAddr), UNLOCKDATA1);
  324. write_flash((WRITESEQ2 | ulOffsetAddr), UNLOCKDATA2);
  325. write_flash((WRITESEQ3 | ulOffsetAddr), UNLOCKDATA3);
  326. }
  327. int get_codes()
  328. {
  329. int dev_id = 0;
  330. write_flash(WRITESEQ1, GETCODEDATA1);
  331. write_flash(WRITESEQ2, GETCODEDATA2);
  332. write_flash(WRITESEQ3, GETCODEDATA3);
  333. read_flash(0x0402, &dev_id);
  334. dev_id &= 0x0000FFFF;
  335. reset_flash();
  336. return dev_id;
  337. }
  338. void get_sector_number(long ulOffset, int *pnSector)
  339. {
  340. int nSector = 0;
  341. long lMainEnd = 0x400000;
  342. long lBootEnd = 0x10000;
  343. // sector numbers for the FLASH A boot sectors
  344. if (ulOffset < lBootEnd) {
  345. nSector = (int)ulOffset / AFP_SectorSize1;
  346. }
  347. // sector numbers for the FLASH B boot sectors
  348. else if ((ulOffset >= lBootEnd) && (ulOffset < lMainEnd)) {
  349. nSector = ((ulOffset / (AFP_SectorSize2)) + 7);
  350. }
  351. // if it is a valid sector, set it
  352. if ((nSector >= 0) && (nSector < AFP_NumSectors))
  353. *pnSector = nSector;
  354. }