PageRenderTime 47ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/board/idmr/flash.c

https://gitlab.com/HarveyHunt/CI20_u-boot
C | 342 lines | 235 code | 72 blank | 35 comment | 56 complexity | 6701a5a310622f405f662f21e1734d19 MD5 | raw file
  1. /*
  2. * (C) Copyright 2000-2006
  3. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  4. *
  5. * SPDX-License-Identifier: GPL-2.0+
  6. */
  7. #include <common.h>
  8. #define PHYS_FLASH_1 CONFIG_SYS_FLASH_BASE
  9. #define FLASH_BANK_SIZE 0x800000
  10. #define EN29LV640 0x227e227e
  11. flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
  12. void flash_print_info (flash_info_t * info)
  13. {
  14. int i;
  15. switch (info->flash_id & FLASH_VENDMASK) {
  16. case (AMD_MANUFACT & FLASH_VENDMASK):
  17. printf ("AMD: ");
  18. break;
  19. default:
  20. printf ("Unknown Vendor ");
  21. break;
  22. }
  23. switch (info->flash_id & FLASH_TYPEMASK) {
  24. case (EN29LV640 & FLASH_TYPEMASK):
  25. printf ("EN29LV640 (16Mbit)\n");
  26. break;
  27. default:
  28. printf ("Unknown Chip Type\n");
  29. goto Done;
  30. break;
  31. }
  32. printf (" Size: %ld MB in %d Sectors\n",
  33. info->size >> 20, info->sector_count);
  34. printf (" Sector Start Addresses:");
  35. for (i = 0; i < info->sector_count; i++) {
  36. if ((i % 5) == 0) {
  37. printf ("\n ");
  38. }
  39. printf (" %08lX%s", info->start[i],
  40. info->protect[i] ? " (RO)" : " ");
  41. }
  42. printf ("\n");
  43. Done:
  44. return;
  45. }
  46. unsigned long flash_init (void)
  47. {
  48. int i, j;
  49. ulong size = 0;
  50. for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
  51. ulong flashbase = 0;
  52. flash_info[i].flash_id =
  53. (AMD_MANUFACT & FLASH_VENDMASK) |
  54. (EN29LV640 & FLASH_TYPEMASK);
  55. flash_info[i].size = FLASH_BANK_SIZE;
  56. flash_info[i].sector_count = CONFIG_SYS_MAX_FLASH_SECT;
  57. memset (flash_info[i].protect, 0, CONFIG_SYS_MAX_FLASH_SECT);
  58. if (i == 0)
  59. flashbase = PHYS_FLASH_1;
  60. else
  61. panic ("configured to many flash banks!\n");
  62. for (j = 0; j < flash_info[i].sector_count; j++) {
  63. flash_info[i].start[j] = flashbase + 0x10000 * j;
  64. }
  65. size += flash_info[i].size;
  66. }
  67. flash_protect (FLAG_PROTECT_SET,
  68. CONFIG_SYS_FLASH_BASE,
  69. CONFIG_SYS_FLASH_BASE + 0x2ffff, &flash_info[0]);
  70. return size;
  71. }
  72. #define CMD_READ_ARRAY 0x00F0
  73. #define CMD_UNLOCK1 0x00AA
  74. #define CMD_UNLOCK2 0x0055
  75. #define CMD_ERASE_SETUP 0x0080
  76. #define CMD_ERASE_CONFIRM 0x0030
  77. #define CMD_PROGRAM 0x00A0
  78. #define CMD_UNLOCK_BYPASS 0x0020
  79. #define MEM_FLASH_ADDR1 (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x00000555<<1)))
  80. #define MEM_FLASH_ADDR2 (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x000002AA<<1)))
  81. #define BIT_ERASE_DONE 0x0080
  82. #define BIT_RDY_MASK 0x0080
  83. #define BIT_PROGRAM_ERROR 0x0020
  84. #define BIT_TIMEOUT 0x80000000 /* our flag */
  85. #define READY 1
  86. #define ERR 2
  87. #define TMO 4
  88. int flash_erase (flash_info_t * info, int s_first, int s_last)
  89. {
  90. ulong result;
  91. int iflag, prot, sect;
  92. int rc = ERR_OK;
  93. int chip1;
  94. ulong start;
  95. /* first look for protection bits */
  96. if (info->flash_id == FLASH_UNKNOWN)
  97. return ERR_UNKNOWN_FLASH_TYPE;
  98. if ((s_first < 0) || (s_first > s_last)) {
  99. return ERR_INVAL;
  100. }
  101. if ((info->flash_id & FLASH_VENDMASK) !=
  102. (AMD_MANUFACT & FLASH_VENDMASK)) {
  103. return ERR_UNKNOWN_FLASH_VENDOR;
  104. }
  105. prot = 0;
  106. for (sect = s_first; sect <= s_last; ++sect) {
  107. if (info->protect[sect]) {
  108. prot++;
  109. }
  110. }
  111. if (prot)
  112. return ERR_PROTECTED;
  113. /*
  114. * Disable interrupts which might cause a timeout
  115. * here. Remember that our exception vectors are
  116. * at address 0 in the flash, and we don't want a
  117. * (ticker) exception to happen while the flash
  118. * chip is in programming mode.
  119. */
  120. iflag = disable_interrupts ();
  121. printf ("\n");
  122. /* Start erase on unprotected sectors */
  123. for (sect = s_first; sect <= s_last && !ctrlc (); sect++) {
  124. printf ("Erasing sector %2d ... ", sect);
  125. /* arm simple, non interrupt dependent timer */
  126. start = get_timer(0);
  127. if (info->protect[sect] == 0) { /* not protected */
  128. volatile u16 *addr =
  129. (volatile u16 *) (info->start[sect]);
  130. MEM_FLASH_ADDR1 = CMD_UNLOCK1;
  131. MEM_FLASH_ADDR2 = CMD_UNLOCK2;
  132. MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;
  133. MEM_FLASH_ADDR1 = CMD_UNLOCK1;
  134. MEM_FLASH_ADDR2 = CMD_UNLOCK2;
  135. *addr = CMD_ERASE_CONFIRM;
  136. /* wait until flash is ready */
  137. chip1 = 0;
  138. do {
  139. result = *addr;
  140. /* check timeout */
  141. if (get_timer(start) > CONFIG_SYS_FLASH_ERASE_TOUT * CONFIG_SYS_HZ / 1000) {
  142. MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
  143. chip1 = TMO;
  144. break;
  145. }
  146. if (!chip1
  147. && (result & 0xFFFF) & BIT_ERASE_DONE)
  148. chip1 = READY;
  149. } while (!chip1);
  150. MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
  151. if (chip1 == ERR) {
  152. rc = ERR_PROG_ERROR;
  153. goto outahere;
  154. }
  155. if (chip1 == TMO) {
  156. rc = ERR_TIMOUT;
  157. goto outahere;
  158. }
  159. printf ("ok.\n");
  160. } else { /* it was protected */
  161. printf ("protected!\n");
  162. }
  163. }
  164. if (ctrlc ())
  165. printf ("User Interrupt!\n");
  166. outahere:
  167. /* allow flash to settle - wait 10 ms */
  168. printf("Waiting 10 ms...");
  169. udelay (10000);
  170. /* for (i = 0; i < 10 * 1000 * 1000; ++i)
  171. asm(" nop");
  172. */
  173. printf("done\n");
  174. if (iflag)
  175. enable_interrupts ();
  176. return rc;
  177. }
  178. static int write_word (flash_info_t * info, ulong dest, ulong data)
  179. {
  180. volatile u16 *addr = (volatile u16 *) dest;
  181. ulong result;
  182. int rc = ERR_OK;
  183. int iflag;
  184. int chip1;
  185. ulong start;
  186. /*
  187. * Check if Flash is (sufficiently) erased
  188. */
  189. result = *addr;
  190. if ((result & data) != data)
  191. return ERR_NOT_ERASED;
  192. /*
  193. * Disable interrupts which might cause a timeout
  194. * here. Remember that our exception vectors are
  195. * at address 0 in the flash, and we don't want a
  196. * (ticker) exception to happen while the flash
  197. * chip is in programming mode.
  198. */
  199. iflag = disable_interrupts ();
  200. MEM_FLASH_ADDR1 = CMD_UNLOCK1;
  201. MEM_FLASH_ADDR2 = CMD_UNLOCK2;
  202. MEM_FLASH_ADDR1 = CMD_PROGRAM;
  203. *addr = data;
  204. /* arm simple, non interrupt dependent timer */
  205. start = get_timer(0);
  206. /* wait until flash is ready */
  207. chip1 = 0;
  208. do {
  209. result = *addr;
  210. /* check timeout */
  211. if (get_timer(start) > CONFIG_SYS_FLASH_ERASE_TOUT * CONFIG_SYS_HZ / 1000) {
  212. chip1 = ERR | TMO;
  213. break;
  214. }
  215. if (!chip1 && ((result & 0x80) == (data & 0x80)))
  216. chip1 = READY;
  217. } while (!chip1);
  218. *addr = CMD_READ_ARRAY;
  219. if (chip1 == ERR || *addr != data)
  220. rc = ERR_PROG_ERROR;
  221. if (iflag)
  222. enable_interrupts ();
  223. return rc;
  224. }
  225. int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
  226. {
  227. ulong wp, data;
  228. int rc;
  229. if (addr & 1) {
  230. printf ("unaligned destination not supported\n");
  231. return ERR_ALIGN;
  232. }
  233. #if 0
  234. if (cnt & 1) {
  235. printf ("odd transfer sizes not supported\n");
  236. return ERR_ALIGN;
  237. }
  238. #endif
  239. wp = addr;
  240. if (addr & 1) {
  241. data = (*((volatile u8 *) addr) << 8) | *((volatile u8 *)
  242. src);
  243. if ((rc = write_word (info, wp - 1, data)) != 0) {
  244. return (rc);
  245. }
  246. src += 1;
  247. wp += 1;
  248. cnt -= 1;
  249. }
  250. while (cnt >= 2) {
  251. data = *((volatile u16 *) src);
  252. if ((rc = write_word (info, wp, data)) != 0) {
  253. return (rc);
  254. }
  255. src += 2;
  256. wp += 2;
  257. cnt -= 2;
  258. }
  259. if (cnt == 1) {
  260. data = (*((volatile u8 *) src) << 8) |
  261. *((volatile u8 *) (wp + 1));
  262. if ((rc = write_word (info, wp, data)) != 0) {
  263. return (rc);
  264. }
  265. src += 1;
  266. wp += 1;
  267. cnt -= 1;
  268. }
  269. return ERR_OK;
  270. }