intel_flash.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  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 marvell db64360 eval board by
  24. * Ingo Assmus <ingo.assmus@keymile.com>
  25. */
  26. #include <common.h>
  27. #include <mpc8xx.h>
  28. #include "../include/mv_gen_reg.h"
  29. #include "../include/memory.h"
  30. #include "intel_flash.h"
  31. /*-----------------------------------------------------------------------
  32. * Protection Flags:
  33. */
  34. #define FLAG_PROTECT_SET 0x01
  35. #define FLAG_PROTECT_CLEAR 0x02
  36. static void 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 bank_erase_init (flash_info_t * info, int sect)
  51. {
  52. bank_addr_t addrw, saddrw, eaddrw;
  53. int flag;
  54. #ifdef FLASH_DEBUG
  55. printf ("0x%08x BANK_CMD_PROG\n", BANK_CMD_PROG);
  56. printf ("0x%08x BANK_CMD_ERASE1\n", BANK_CMD_ERASE1);
  57. printf ("0x%08x BANK_CMD_ERASE2\n", BANK_CMD_ERASE2);
  58. printf ("0x%08x BANK_CMD_CLR_STAT\n", BANK_CMD_CLR_STAT);
  59. printf ("0x%08x BANK_CMD_RST\n", BANK_CMD_RST);
  60. printf ("0x%08x BANK_STAT_RDY\n", BANK_STAT_RDY);
  61. printf ("0x%08x BANK_STAT_ERR\n", BANK_STAT_ERR);
  62. #endif
  63. saddrw = (bank_addr_t) info->start[sect];
  64. eaddrw = BANK_ADDR_NEXT_WORD (saddrw);
  65. #ifdef FLASH_DEBUG
  66. printf ("erasing sector %d, start addr = 0x%08lx "
  67. "(bank next word addr = 0x%08lx)\n", sect,
  68. (unsigned long) saddrw, (unsigned long) eaddrw);
  69. #endif
  70. /* Disable intrs which might cause a timeout here */
  71. flag = disable_interrupts ();
  72. for (addrw = saddrw; addrw < eaddrw; addrw++) {
  73. #ifdef FLASH_DEBUG
  74. printf (" writing erase cmd to addr 0x%08lx\n",
  75. (unsigned long) addrw);
  76. #endif
  77. *addrw = BANK_CMD_ERASE1;
  78. *addrw = BANK_CMD_ERASE2;
  79. }
  80. /* re-enable interrupts if necessary */
  81. if (flag)
  82. enable_interrupts ();
  83. }
  84. static int bank_erase_poll (flash_info_t * info, int sect)
  85. {
  86. bank_addr_t addrw, saddrw, eaddrw;
  87. int sectdone, haderr;
  88. saddrw = (bank_addr_t) info->start[sect];
  89. eaddrw = BANK_ADDR_NEXT_WORD (saddrw);
  90. sectdone = 1;
  91. haderr = 0;
  92. for (addrw = saddrw; addrw < eaddrw; addrw++) {
  93. bank_word_t stat = *addrw;
  94. #ifdef FLASH_DEBUG
  95. printf (" checking status at addr "
  96. "0x%08x [0x%08x]\n", (unsigned long) addrw, stat);
  97. #endif
  98. if ((stat & BANK_STAT_RDY) != BANK_STAT_RDY)
  99. sectdone = 0;
  100. else if ((stat & BANK_STAT_ERR) != 0) {
  101. printf (" failed on sector %d "
  102. "(stat = 0x%08x) at "
  103. "address 0x%p\n", sect, stat, addrw);
  104. *addrw = BANK_CMD_CLR_STAT;
  105. haderr = 1;
  106. }
  107. }
  108. if (haderr)
  109. return (-1);
  110. else
  111. return (sectdone);
  112. }
  113. int write_word_intel (bank_addr_t addr, bank_word_t value)
  114. {
  115. bank_word_t stat;
  116. ulong start;
  117. int flag, retval;
  118. /* Disable interrupts which might cause a timeout here */
  119. flag = disable_interrupts ();
  120. *addr = BANK_CMD_PROG;
  121. *addr = value;
  122. /* re-enable interrupts if necessary */
  123. if (flag)
  124. enable_interrupts ();
  125. retval = 0;
  126. /* data polling for D7 */
  127. start = get_timer (0);
  128. do {
  129. if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
  130. retval = 1;
  131. goto done;
  132. }
  133. stat = *addr;
  134. } while ((stat & BANK_STAT_RDY) != BANK_STAT_RDY);
  135. if ((stat & BANK_STAT_ERR) != 0) {
  136. printf ("flash program failed (stat = 0x%08lx) "
  137. "at address 0x%08lx\n", (ulong) stat, (ulong) addr);
  138. *addr = BANK_CMD_CLR_STAT;
  139. retval = 3;
  140. }
  141. done:
  142. /* reset to read mode */
  143. *addr = BANK_CMD_RST;
  144. return (retval);
  145. }
  146. /*-----------------------------------------------------------------------
  147. */
  148. int flash_erase_intel (flash_info_t * info, int s_first, int s_last)
  149. {
  150. int prot, sect, haderr;
  151. ulong start, now, last;
  152. #ifdef FLASH_DEBUG
  153. printf ("\nflash_erase: erase %d sectors (%d to %d incl.) from\n"
  154. " Bank # %d: ", s_last - s_first + 1, s_first, s_last,
  155. (info - flash_info) + 1);
  156. flash_print_info (info);
  157. #endif
  158. if ((s_first < 0) || (s_first > s_last)) {
  159. if (info->flash_id == FLASH_UNKNOWN) {
  160. printf ("- missing\n");
  161. } else {
  162. printf ("- no sectors to erase\n");
  163. }
  164. return 1;
  165. }
  166. prot = 0;
  167. for (sect = s_first; sect <= s_last; ++sect) {
  168. if (info->protect[sect]) {
  169. prot++;
  170. }
  171. }
  172. if (prot) {
  173. printf ("- Warning: %d protected sector%s will not be erased!\n", prot, (prot > 1 ? "s" : ""));
  174. }
  175. start = get_timer (0);
  176. last = 0;
  177. haderr = 0;
  178. for (sect = s_first; sect <= s_last; sect++) {
  179. if (info->protect[sect] == 0) { /* not protected */
  180. ulong estart;
  181. int sectdone;
  182. bank_erase_init (info, sect);
  183. /* wait at least 80us - let's wait 1 ms */
  184. udelay (1000);
  185. estart = get_timer (start);
  186. do {
  187. now = get_timer (start);
  188. if (now - estart > CONFIG_SYS_FLASH_ERASE_TOUT) {
  189. printf ("Timeout (sect %d)\n", sect);
  190. haderr = 1;
  191. break;
  192. }
  193. #ifndef FLASH_DEBUG
  194. /* show that we're waiting */
  195. if ((now - last) > 1000) { /* every second */
  196. putc ('.');
  197. last = now;
  198. }
  199. #endif
  200. sectdone = bank_erase_poll (info, sect);
  201. if (sectdone < 0) {
  202. haderr = 1;
  203. break;
  204. }
  205. } while (!sectdone);
  206. if (haderr)
  207. break;
  208. }
  209. }
  210. if (haderr > 0)
  211. printf (" failed\n");
  212. else
  213. printf (" done\n");
  214. /* reset to read mode */
  215. for (sect = s_first; sect <= s_last; sect++) {
  216. if (info->protect[sect] == 0) { /* not protected */
  217. bank_reset (info, sect);
  218. }
  219. }
  220. return haderr;
  221. }