intel_flash.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. /*
  2. * (C) Copyright 2000
  3. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  4. *
  5. * See file CREDITS for list of people who contributed to this
  6. * project.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21. * MA 02111-1307 USA
  22. *
  23. * Hacked for the Hymod board by Murray.Jensen@cmst.csiro.au, 20-Oct-00
  24. */
  25. #include <common.h>
  26. #include <mpc8xx.h>
  27. #include <galileo/gt64260R.h>
  28. #include <galileo/memory.h>
  29. #include "intel_flash.h"
  30. /*-----------------------------------------------------------------------
  31. * Protection Flags:
  32. */
  33. #define FLAG_PROTECT_SET 0x01
  34. #define FLAG_PROTECT_CLEAR 0x02
  35. static void
  36. bank_reset(flash_info_t *info, int sect)
  37. {
  38. bank_addr_t addrw, eaddrw;
  39. addrw = (bank_addr_t)info->start[sect];
  40. eaddrw = BANK_ADDR_NEXT_WORD(addrw);
  41. while (addrw < eaddrw) {
  42. #ifdef FLASH_DEBUG
  43. printf(" writing reset cmd to addr 0x%08lx\n",
  44. (unsigned long)addrw);
  45. #endif
  46. *addrw = BANK_CMD_RST;
  47. addrw++;
  48. }
  49. }
  50. static void
  51. bank_erase_init(flash_info_t *info, int sect)
  52. {
  53. bank_addr_t addrw, saddrw, eaddrw;
  54. int flag;
  55. #ifdef FLASH_DEBUG
  56. printf("0x%08x BANK_CMD_PROG\n", BANK_CMD_PROG);
  57. printf("0x%08x BANK_CMD_ERASE1\n", BANK_CMD_ERASE1);
  58. printf("0x%08x BANK_CMD_ERASE2\n", BANK_CMD_ERASE2);
  59. printf("0x%08x BANK_CMD_CLR_STAT\n", BANK_CMD_CLR_STAT);
  60. printf("0x%08x BANK_CMD_RST\n", BANK_CMD_RST);
  61. printf("0x%08x BANK_STAT_RDY\n", BANK_STAT_RDY);
  62. printf("0x%08x BANK_STAT_ERR\n", BANK_STAT_ERR);
  63. #endif
  64. saddrw = (bank_addr_t)info->start[sect];
  65. eaddrw = BANK_ADDR_NEXT_WORD(saddrw);
  66. #ifdef FLASH_DEBUG
  67. printf("erasing sector %d, start addr = 0x%08lx "
  68. "(bank next word addr = 0x%08lx)\n", sect,
  69. (unsigned long)saddrw, (unsigned long)eaddrw);
  70. #endif
  71. /* Disable intrs which might cause a timeout here */
  72. flag = disable_interrupts();
  73. for (addrw = saddrw; addrw < eaddrw; addrw++) {
  74. #ifdef FLASH_DEBUG
  75. printf(" writing erase cmd to addr 0x%08lx\n",
  76. (unsigned long)addrw);
  77. #endif
  78. *addrw = BANK_CMD_ERASE1;
  79. *addrw = BANK_CMD_ERASE2;
  80. }
  81. /* re-enable interrupts if necessary */
  82. if (flag)
  83. enable_interrupts();
  84. }
  85. static int
  86. bank_erase_poll(flash_info_t *info, int sect)
  87. {
  88. bank_addr_t addrw, saddrw, eaddrw;
  89. int sectdone, haderr;
  90. saddrw = (bank_addr_t)info->start[sect];
  91. eaddrw = BANK_ADDR_NEXT_WORD(saddrw);
  92. sectdone = 1;
  93. haderr = 0;
  94. for (addrw = saddrw; addrw < eaddrw; addrw++) {
  95. bank_word_t stat = *addrw;
  96. #ifdef FLASH_DEBUG
  97. printf(" checking status at addr "
  98. "0x%08x [0x%08x]\n",
  99. (unsigned long)addrw, stat);
  100. #endif
  101. if ((stat & BANK_STAT_RDY) != BANK_STAT_RDY)
  102. sectdone = 0;
  103. else if ((stat & BANK_STAT_ERR) != 0) {
  104. printf(" failed on sector %d "
  105. "(stat = 0x%08x) at "
  106. "address 0x%p\n",
  107. sect, stat, addrw);
  108. *addrw = BANK_CMD_CLR_STAT;
  109. haderr = 1;
  110. }
  111. }
  112. if (haderr)
  113. return (-1);
  114. else
  115. return (sectdone);
  116. }
  117. int
  118. write_word_intel(bank_addr_t addr, bank_word_t value)
  119. {
  120. bank_word_t stat;
  121. ulong start;
  122. int flag, retval;
  123. /* Disable interrupts which might cause a timeout here */
  124. flag = disable_interrupts();
  125. *addr = BANK_CMD_PROG;
  126. *addr = value;
  127. /* re-enable interrupts if necessary */
  128. if (flag)
  129. enable_interrupts();
  130. retval = 0;
  131. /* data polling for D7 */
  132. start = get_timer (0);
  133. do {
  134. if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
  135. retval = 1;
  136. goto done;
  137. }
  138. stat = *addr;
  139. } while ((stat & BANK_STAT_RDY) != BANK_STAT_RDY);
  140. if ((stat & BANK_STAT_ERR) != 0) {
  141. printf("flash program failed (stat = 0x%08lx) "
  142. "at address 0x%08lx\n", (ulong)stat, (ulong)addr);
  143. *addr = BANK_CMD_CLR_STAT;
  144. retval = 3;
  145. }
  146. done:
  147. /* reset to read mode */
  148. *addr = BANK_CMD_RST;
  149. return (retval);
  150. }
  151. /*-----------------------------------------------------------------------
  152. */
  153. int
  154. flash_erase_intel(flash_info_t *info, int s_first, int s_last)
  155. {
  156. int prot, sect, haderr;
  157. ulong start, now, last;
  158. #ifdef FLASH_DEBUG
  159. printf("\nflash_erase: erase %d sectors (%d to %d incl.) from\n"
  160. " Bank # %d: ", s_last - s_first + 1, s_first, s_last,
  161. (info - flash_info) + 1);
  162. flash_print_info(info);
  163. #endif
  164. if ((s_first < 0) || (s_first > s_last)) {
  165. if (info->flash_id == FLASH_UNKNOWN) {
  166. printf ("- missing\n");
  167. } else {
  168. printf ("- no sectors to erase\n");
  169. }
  170. return 1;
  171. }
  172. prot = 0;
  173. for (sect=s_first; sect<=s_last; ++sect) {
  174. if (info->protect[sect]) {
  175. prot++;
  176. }
  177. }
  178. if (prot) {
  179. printf("- Warning: %d protected sector%s will not be erased!\n",
  180. prot, (prot > 1 ? "s" : ""));
  181. }
  182. start = get_timer (0);
  183. last = 0;
  184. haderr = 0;
  185. for (sect = s_first; sect <= s_last; sect++) {
  186. if (info->protect[sect] == 0) { /* not protected */
  187. ulong estart;
  188. int sectdone;
  189. bank_erase_init(info, sect);
  190. /* wait at least 80us - let's wait 1 ms */
  191. udelay (1000);
  192. estart = get_timer(start);
  193. do {
  194. now = get_timer(start);
  195. if (now - estart > CFG_FLASH_ERASE_TOUT) {
  196. printf ("Timeout (sect %d)\n", sect);
  197. haderr = 1;
  198. break;
  199. }
  200. #ifndef FLASH_DEBUG
  201. /* show that we're waiting */
  202. if ((now - last) > 1000) { /* every second */
  203. putc ('.');
  204. last = now;
  205. }
  206. #endif
  207. sectdone = bank_erase_poll(info, sect);
  208. if (sectdone < 0) {
  209. haderr = 1;
  210. break;
  211. }
  212. } while (!sectdone);
  213. if (haderr)
  214. break;
  215. }
  216. }
  217. if (haderr > 0)
  218. printf (" failed\n");
  219. else
  220. printf (" done\n");
  221. /* reset to read mode */
  222. for (sect = s_first; sect <= s_last; sect++) {
  223. if (info->protect[sect] == 0) { /* not protected */
  224. bank_reset(info, sect);
  225. }
  226. }
  227. return haderr;
  228. }