flash.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. /*
  2. * (C) Copyright 2002
  3. * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
  4. * Marius Groeger <mgroeger@sysgo.de>
  5. *
  6. * See file CREDITS for list of people who contributed to this
  7. * project.
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License as
  11. * published by the Free Software Foundation; either version 2 of
  12. * the License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  22. * MA 02111-1307 USA
  23. */
  24. #include <common.h>
  25. #define FLASH_BANK_SIZE 0x800000
  26. #define MAIN_SECT_SIZE 0x20000
  27. #define PARAM_SECT_SIZE 0x4000
  28. flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
  29. /*-----------------------------------------------------------------------
  30. */
  31. ulong flash_init (void)
  32. {
  33. int i, j;
  34. ulong size = 0;
  35. for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
  36. ulong flashbase = 0;
  37. flash_info[i].flash_id =
  38. (INTEL_MANUFACT & FLASH_VENDMASK) |
  39. (INTEL_ID_28F320B3T & FLASH_TYPEMASK);
  40. flash_info[i].size = FLASH_BANK_SIZE;
  41. flash_info[i].sector_count = CONFIG_SYS_MAX_FLASH_SECT;
  42. memset (flash_info[i].protect, 0, CONFIG_SYS_MAX_FLASH_SECT);
  43. if (i == 0)
  44. flashbase = PHYS_FLASH_1;
  45. else if (i == 1)
  46. flashbase = PHYS_FLASH_2;
  47. else
  48. panic ("configured too many flash banks!\n");
  49. for (j = 0; j < flash_info[i].sector_count; j++) {
  50. if (j <= 7) {
  51. flash_info[i].start[j] =
  52. flashbase + j * PARAM_SECT_SIZE;
  53. } else {
  54. flash_info[i].start[j] =
  55. flashbase + (j - 7) * MAIN_SECT_SIZE;
  56. }
  57. }
  58. size += flash_info[i].size;
  59. }
  60. /* Protect monitor and environment sectors
  61. */
  62. flash_protect (FLAG_PROTECT_SET,
  63. CONFIG_SYS_FLASH_BASE,
  64. CONFIG_SYS_FLASH_BASE + monitor_flash_len - 1,
  65. &flash_info[0]);
  66. flash_protect (FLAG_PROTECT_SET,
  67. CONFIG_ENV_ADDR,
  68. CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, &flash_info[0]);
  69. return size;
  70. }
  71. /*-----------------------------------------------------------------------
  72. */
  73. void flash_print_info (flash_info_t * info)
  74. {
  75. int i;
  76. switch (info->flash_id & FLASH_VENDMASK) {
  77. case (INTEL_MANUFACT & FLASH_VENDMASK):
  78. printf ("Intel: ");
  79. break;
  80. default:
  81. printf ("Unknown Vendor ");
  82. break;
  83. }
  84. switch (info->flash_id & FLASH_TYPEMASK) {
  85. case (INTEL_ID_28F320B3T & FLASH_TYPEMASK):
  86. printf ("28F320F3B (16Mbit)\n");
  87. break;
  88. default:
  89. printf ("Unknown Chip Type\n");
  90. goto Done;
  91. break;
  92. }
  93. printf (" Size: %ld MB in %d Sectors\n",
  94. info->size >> 20, info->sector_count);
  95. printf (" Sector Start Addresses:");
  96. for (i = 0; i < info->sector_count; i++) {
  97. if ((i % 5) == 0) {
  98. printf ("\n ");
  99. }
  100. printf (" %08lX%s", info->start[i],
  101. info->protect[i] ? " (RO)" : " ");
  102. }
  103. printf ("\n");
  104. Done:;
  105. }
  106. /*-----------------------------------------------------------------------
  107. */
  108. int flash_erase (flash_info_t * info, int s_first, int s_last)
  109. {
  110. int flag, prot, sect;
  111. int rc = ERR_OK;
  112. ulong start;
  113. if (info->flash_id == FLASH_UNKNOWN)
  114. return ERR_UNKNOWN_FLASH_TYPE;
  115. if ((s_first < 0) || (s_first > s_last)) {
  116. return ERR_INVAL;
  117. }
  118. if ((info->flash_id & FLASH_VENDMASK) !=
  119. (INTEL_MANUFACT & FLASH_VENDMASK)) {
  120. return ERR_UNKNOWN_FLASH_VENDOR;
  121. }
  122. prot = 0;
  123. for (sect = s_first; sect <= s_last; ++sect) {
  124. if (info->protect[sect]) {
  125. prot++;
  126. }
  127. }
  128. if (prot)
  129. return ERR_PROTECTED;
  130. /*
  131. * Disable interrupts which might cause a timeout
  132. * here. Remember that our exception vectors are
  133. * at address 0 in the flash, and we don't want a
  134. * (ticker) exception to happen while the flash
  135. * chip is in programming mode.
  136. */
  137. flag = disable_interrupts ();
  138. /* Start erase on unprotected sectors */
  139. for (sect = s_first; sect <= s_last && !ctrlc (); sect++) {
  140. printf ("Erasing sector %2d ... ", sect);
  141. /* arm simple, non interrupt dependent timer */
  142. start = get_timer(0);
  143. if (info->protect[sect] == 0) { /* not protected */
  144. vu_long *addr = (vu_long *) (info->start[sect]);
  145. *addr = 0x00200020; /* erase setup */
  146. *addr = 0x00D000D0; /* erase confirm */
  147. while ((*addr & 0x00800080) != 0x00800080) {
  148. if (get_timer(start) >
  149. CONFIG_SYS_FLASH_ERASE_TOUT) {
  150. *addr = 0x00B000B0; /* suspend erase */
  151. *addr = 0x00FF00FF; /* reset to read mode */
  152. rc = ERR_TIMOUT;
  153. goto outahere;
  154. }
  155. }
  156. *addr = 0x00FF00FF; /* reset to read mode */
  157. }
  158. printf ("ok.\n");
  159. }
  160. if (ctrlc ())
  161. printf ("User Interrupt!\n");
  162. outahere:
  163. /* allow flash to settle - wait 10 ms */
  164. udelay_masked (10000);
  165. if (flag)
  166. enable_interrupts ();
  167. return rc;
  168. }
  169. /*-----------------------------------------------------------------------
  170. * Copy memory to flash
  171. */
  172. static int write_word (flash_info_t * info, ulong dest, ulong data)
  173. {
  174. vu_long *addr = (vu_long *) dest;
  175. ulong barf;
  176. int rc = ERR_OK;
  177. int flag;
  178. ulong start;
  179. /* Check if Flash is (sufficiently) erased
  180. */
  181. if ((*addr & data) != data)
  182. return ERR_NOT_ERASED;
  183. /*
  184. * Disable interrupts which might cause a timeout
  185. * here. Remember that our exception vectors are
  186. * at address 0 in the flash, and we don't want a
  187. * (ticker) exception to happen while the flash
  188. * chip is in programming mode.
  189. */
  190. flag = disable_interrupts ();
  191. /* clear status register command */
  192. *addr = 0x00500050;
  193. /* program set-up command */
  194. *addr = 0x00400040;
  195. /* latch address/data */
  196. *addr = data;
  197. /* arm simple, non interrupt dependent timer */
  198. start = get_timer(0);
  199. /* read status register command */
  200. *addr = 0x00700070;
  201. /* wait while polling the status register */
  202. while ((*addr & 0x00800080) != 0x00800080) {
  203. if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
  204. rc = ERR_TIMOUT;
  205. /* suspend program command */
  206. *addr = 0x00B000B0;
  207. goto outahere;
  208. }
  209. if (*addr & 0x003A003A) { /* check for error */
  210. barf = *addr;
  211. if (barf & 0x003A0000) {
  212. barf >>= 16;
  213. } else {
  214. barf &= 0x0000003A;
  215. }
  216. printf ("\nFlash write error %02lx at address %08lx\n", barf, (unsigned long) dest);
  217. if (barf & 0x0002) {
  218. printf ("Block locked, not erased.\n");
  219. rc = ERR_NOT_ERASED;
  220. goto outahere;
  221. }
  222. if (barf & 0x0010) {
  223. printf ("Programming error.\n");
  224. rc = ERR_PROG_ERROR;
  225. goto outahere;
  226. }
  227. if (barf & 0x0008) {
  228. printf ("Vpp Low error.\n");
  229. rc = ERR_PROG_ERROR;
  230. goto outahere;
  231. }
  232. rc = ERR_PROG_ERROR;
  233. goto outahere;
  234. }
  235. }
  236. outahere:
  237. /* read array command */
  238. *addr = 0x00FF00FF;
  239. if (flag)
  240. enable_interrupts ();
  241. return rc;
  242. }
  243. /*-----------------------------------------------------------------------
  244. * Copy memory to flash.
  245. */
  246. int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
  247. {
  248. ulong cp, wp, data;
  249. int l;
  250. int i, rc;
  251. wp = (addr & ~3); /* get lower word aligned address */
  252. /*
  253. * handle unaligned start bytes
  254. */
  255. if ((l = addr - wp) != 0) {
  256. data = 0;
  257. for (i = 0, cp = wp; i < l; ++i, ++cp) {
  258. data = (data >> 8) | (*(uchar *) cp << 24);
  259. }
  260. for (; i < 4 && cnt > 0; ++i) {
  261. data = (data >> 8) | (*src++ << 24);
  262. --cnt;
  263. ++cp;
  264. }
  265. for (; cnt == 0 && i < 4; ++i, ++cp) {
  266. data = (data >> 8) | (*(uchar *) cp << 24);
  267. }
  268. if ((rc = write_word (info, wp, data)) != 0) {
  269. return (rc);
  270. }
  271. wp += 4;
  272. }
  273. /*
  274. * handle word aligned part
  275. */
  276. while (cnt >= 4) {
  277. data = *((vu_long *) src);
  278. if ((rc = write_word (info, wp, data)) != 0) {
  279. return (rc);
  280. }
  281. src += 4;
  282. wp += 4;
  283. cnt -= 4;
  284. }
  285. if (cnt == 0) {
  286. return ERR_OK;
  287. }
  288. /*
  289. * handle unaligned tail bytes
  290. */
  291. data = 0;
  292. for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
  293. data = (data >> 8) | (*src++ << 24);
  294. --cnt;
  295. }
  296. for (; i < 4; ++i, ++cp) {
  297. data = (data >> 8) | (*(uchar *) cp << 24);
  298. }
  299. return write_word (info, wp, data);
  300. }