flash.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. /*
  2. * flash.c: Support code for the flash chips on the Xilinx ML2 board
  3. *
  4. * Copyright 2002 Mind NV
  5. *
  6. * http://www.mind.be/
  7. *
  8. * Author : Peter De Schrijver (p2@mind.be)
  9. *
  10. * This software may be used and distributed according to the terms of
  11. * the GNU General Public License (GPL) version 2, incorporated herein by
  12. * reference. Drivers based on or derived from this code fall under the GPL
  13. * and must retain the authorship, copyright and this license notice. This
  14. * file is not a complete program and may only be used when the entire program
  15. * is licensed under the GPL.
  16. *
  17. */
  18. #include <common.h>
  19. #include <asm/u-boot.h>
  20. #include <configs/ML2.h>
  21. #define FLASH_BANK_SIZE (64*1024*1024)
  22. flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
  23. #define SECT_SIZE (512*1024)
  24. #define CMD_READ_ARRAY 0x00FF00FF00FF00FULL
  25. #define CMD_IDENTIFY 0x0090009000900090ULL
  26. #define CMD_ERASE_SETUP 0x0020002000200020ULL
  27. #define CMD_ERASE_CONFIRM 0x00D000D000D000D0ULL
  28. #define CMD_PROGRAM 0x0040004000400040ULL
  29. #define CMD_RESUME 0x00D000D000D000D0ULL
  30. #define CMD_SUSPEND 0x00B000B000B000B0ULL
  31. #define CMD_STATUS_READ 0x0070007000700070ULL
  32. #define CMD_STATUS_RESET 0x0050005000500050ULL
  33. #define BIT_BUSY 0x0080008000800080ULL
  34. #define BIT_ERASE_SUSPEND 0x004000400400040ULL
  35. #define BIT_ERASE_ERROR 0x0020002000200020ULL
  36. #define BIT_PROGRAM_ERROR 0x0010001000100010ULL
  37. #define BIT_VPP_RANGE_ERROR 0x0008000800080008ULL
  38. #define BIT_PROGRAM_SUSPEND 0x0004000400040004ULL
  39. #define BIT_PROTECT_ERROR 0x0002000200020002ULL
  40. #define BIT_UNDEFINED 0x0001000100010001ULL
  41. #define BIT_SEQUENCE_ERROR 0x0030003000300030ULL
  42. #define BIT_TIMEOUT 0x80000000
  43. inline void eieio(void) {
  44. __asm__ __volatile__ ("eieio" : : : "memory");
  45. }
  46. ulong flash_init(void) {
  47. int i, j;
  48. ulong size = 0;
  49. for(i=0;i<CFG_MAX_FLASH_BANKS;i++) {
  50. ulong flashbase = 0;
  51. flash_info[i].flash_id = (INTEL_MANUFACT & FLASH_VENDMASK) |
  52. (INTEL_ID_28F128J3A & FLASH_TYPEMASK);
  53. flash_info[i].size = FLASH_BANK_SIZE;
  54. flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
  55. memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
  56. if (i==0)
  57. flashbase = CFG_FLASH_BASE;
  58. else
  59. panic("configured too many flash banks!\n");
  60. for (j = 0; j < flash_info[i].sector_count; j++)
  61. flash_info[i].start[j]=flashbase + j * SECT_SIZE;
  62. size += flash_info[i].size;
  63. }
  64. return size;
  65. }
  66. void flash_print_info (flash_info_t *info) {
  67. int i;
  68. switch (info->flash_id & FLASH_VENDMASK) {
  69. case (INTEL_MANUFACT & FLASH_VENDMASK):
  70. printf("Intel: ");
  71. break;
  72. default:
  73. printf("Unknown Vendor ");
  74. break;
  75. }
  76. switch (info->flash_id & FLASH_TYPEMASK) {
  77. case (INTEL_ID_28F128J3A & FLASH_TYPEMASK):
  78. printf("4x 28F128J3A (128Mbit)\n");
  79. break;
  80. default:
  81. printf("Unknown Chip Type\n");
  82. break;
  83. }
  84. printf(" Size: %ld MB in %d Sectors\n", info->size >> 20, info->sector_count);
  85. printf(" Sector Start Addresses:");
  86. for (i = 0; i < info->sector_count; i++) {
  87. if ((i % 5) == 0)
  88. printf("\n ");
  89. printf (" %08lX%s", info->start[i],
  90. info->protect[i] ? " (RO)" : " ");
  91. }
  92. printf ("\n");
  93. }
  94. int flash_error (unsigned long long code) {
  95. if (code & BIT_TIMEOUT) {
  96. printf ("Timeout\n");
  97. return ERR_TIMOUT;
  98. }
  99. if (~code & BIT_BUSY) {
  100. printf ("Busy\n");
  101. return ERR_PROG_ERROR;
  102. }
  103. if (code & BIT_VPP_RANGE_ERROR) {
  104. printf ("Vpp range error\n");
  105. return ERR_PROG_ERROR;
  106. }
  107. if (code & BIT_PROTECT_ERROR) {
  108. printf ("Device protect error\n");
  109. return ERR_PROG_ERROR;
  110. }
  111. if (code & BIT_SEQUENCE_ERROR) {
  112. printf ("Command seqence error\n");
  113. return ERR_PROG_ERROR;
  114. }
  115. if (code & BIT_ERASE_ERROR) {
  116. printf ("Block erase error\n");
  117. return ERR_PROG_ERROR;
  118. }
  119. if (code & BIT_PROGRAM_ERROR) {
  120. printf ("Program error\n");
  121. return ERR_PROG_ERROR;
  122. }
  123. if (code & BIT_ERASE_SUSPEND) {
  124. printf ("Block erase suspended\n");
  125. return ERR_PROG_ERROR;
  126. }
  127. if (code & BIT_PROGRAM_SUSPEND) {
  128. printf ("Program suspended\n");
  129. return ERR_PROG_ERROR;
  130. }
  131. return ERR_OK;
  132. }
  133. int flash_erase (flash_info_t *info, int s_first, int s_last) {
  134. int rc = ERR_OK;
  135. int sect;
  136. unsigned long long result;
  137. if (info->flash_id == FLASH_UNKNOWN)
  138. return ERR_UNKNOWN_FLASH_TYPE;
  139. if ((s_first < 0) || (s_first > s_last))
  140. return ERR_INVAL;
  141. if ((info->flash_id & FLASH_VENDMASK) != (INTEL_MANUFACT & FLASH_VENDMASK))
  142. return ERR_UNKNOWN_FLASH_VENDOR;
  143. for (sect=s_first; sect<=s_last; ++sect)
  144. if (info->protect[sect])
  145. return ERR_PROTECTED;
  146. for (sect = s_first; sect<=s_last && !ctrlc(); sect++) {
  147. volatile unsigned long long *addr=
  148. (unsigned long long *)(info->start[sect]);
  149. printf("Erasing sector %2d ... ", sect);
  150. *addr=CMD_STATUS_RESET;
  151. eieio();
  152. *addr=CMD_ERASE_SETUP;
  153. eieio();
  154. *addr=CMD_ERASE_CONFIRM;
  155. eieio();
  156. do {
  157. result = *addr;
  158. } while(~result & BIT_BUSY);
  159. *addr=CMD_READ_ARRAY;
  160. if ((rc = flash_error(result)) == ERR_OK)
  161. printf("ok.\n");
  162. else
  163. break;
  164. }
  165. if (ctrlc())
  166. printf("User Interrupt!\n");
  167. return rc;
  168. }
  169. static int write_word (flash_info_t *info, ulong dest, unsigned long long data) {
  170. volatile unsigned long long *addr=(unsigned long long *)dest;
  171. unsigned long long result;
  172. int rc = ERR_OK;
  173. result = *addr;
  174. if ((result & data) != data)
  175. return ERR_NOT_ERASED;
  176. *addr=CMD_STATUS_RESET;
  177. eieio();
  178. *addr=CMD_PROGRAM;
  179. eieio();
  180. *addr=data;
  181. eieio();
  182. do {
  183. result = *addr;
  184. } while(~result & BIT_BUSY);
  185. *addr=CMD_READ_ARRAY;
  186. rc = flash_error(result);
  187. return rc;
  188. }
  189. int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) {
  190. ulong cp, wp;
  191. unsigned long long data;
  192. int l;
  193. int i,rc;
  194. wp=(addr & ~7);
  195. if((l=addr-wp) != 0) {
  196. data=0;
  197. for(i=0,cp=wp;i<l;++i,++cp)
  198. data = (data >> 8) | (*(uchar *)cp << 24);
  199. for (; i<8 && cnt>0; ++i) {
  200. data = (data >> 8) | (*src++ << 24);
  201. --cnt;
  202. ++cp;
  203. }
  204. for (; i<8; ++i, ++cp)
  205. data = (data >> 8) | (*(uchar *)cp << 24);
  206. if ((rc = write_word(info, wp, data)) != 0)
  207. return rc;
  208. wp+=8;
  209. }
  210. while(cnt>=8) {
  211. data = *((unsigned long long *)src);
  212. if ((rc = write_word(info, wp, data)) != 0)
  213. return rc;
  214. src+=8;
  215. wp+=8;
  216. cnt-=8;
  217. }
  218. if(cnt == 0)
  219. return ERR_OK;
  220. data = 0;
  221. for (i=0, cp=wp; i<8 && cnt>0; ++i, ++cp) {
  222. data = (data >> 8) | (*src++ << 24);
  223. --cnt;
  224. }
  225. for (; i<8; ++i, ++cp) {
  226. data = (data >> 8) | (*(uchar *)cp << 24);
  227. }
  228. return write_word(info, wp, data);
  229. }