flash.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /*
  2. * (C) Copyright 2000-2004
  3. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  4. *
  5. * (C) Copyright 2004, Li-Pro.Net <www.li-pro.net>
  6. * Stephan Linz <linz@li-pro.net>
  7. *
  8. * See file CREDITS for list of people who contributed to this
  9. * project.
  10. *
  11. * This program is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU General Public License as
  13. * published by the Free Software Foundation; either version 2 of
  14. * the License, or (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program; if not, write to the Free Software
  23. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  24. * MA 02111-1307 USA
  25. */
  26. #include <common.h>
  27. #include <watchdog.h>
  28. #include <nios.h>
  29. flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
  30. /*--------------------------------------------------------------------*/
  31. void flash_print_info (flash_info_t * info)
  32. {
  33. int i, k;
  34. unsigned long size;
  35. int erased;
  36. volatile unsigned char *flash;
  37. printf (" Size: %ld KB in %d Sectors\n",
  38. info->size >> 10, info->sector_count);
  39. printf (" Sector Start Addresses:");
  40. for (i = 0; i < info->sector_count; ++i) {
  41. /* Check if whole sector is erased */
  42. if (i != (info->sector_count - 1))
  43. size = info->start[i + 1] - info->start[i];
  44. else
  45. size = info->start[0] + info->size - info->start[i];
  46. erased = 1;
  47. flash = (volatile unsigned char *) info->start[i];
  48. for (k = 0; k < size; k++) {
  49. if (*flash++ != 0xff) {
  50. erased = 0;
  51. break;
  52. }
  53. }
  54. /* Print the info */
  55. if ((i % 5) == 0)
  56. printf ("\n ");
  57. printf (" %08lX%s%s", info->start[i], erased ? " E" : " ",
  58. info->protect[i] ? "RO " : " ");
  59. }
  60. printf ("\n");
  61. }
  62. /*-------------------------------------------------------------------*/
  63. int flash_erase (flash_info_t * info, int s_first, int s_last)
  64. {
  65. volatile CONFIG_SYS_FLASH_WORD_SIZE *addr = (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[0]);
  66. volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2;
  67. int prot, sect, wait;
  68. unsigned oldpri;
  69. ulong start;
  70. /* Some sanity checking */
  71. if ((s_first < 0) || (s_first > s_last)) {
  72. printf ("- no sectors to erase\n");
  73. return 1;
  74. }
  75. prot = 0;
  76. for (sect = s_first; sect <= s_last; ++sect) {
  77. if (info->protect[sect]) {
  78. prot++;
  79. }
  80. }
  81. if (prot) {
  82. printf ("- Warning: %d protected sectors will not be erased!\n",
  83. prot);
  84. } else {
  85. printf ("\n");
  86. }
  87. #ifdef DEBUG
  88. for (sect = s_first; sect <= s_last; sect++) {
  89. printf("- Erase: Sect: %i @ 0x%08x\n", sect, info->start[sect]);
  90. }
  91. #endif
  92. /* NOTE: disabling interrupts on Nios can be very bad since it
  93. * also disables the LO_LIMIT exception. It's better here to
  94. * set the interrupt priority to 3 & restore it when we're done.
  95. */
  96. oldpri = ipri (3);
  97. /* It's ok to erase multiple sectors provided we don't delay more
  98. * than 50 usec between cmds ... at which point the erase time-out
  99. * occurs. So don't go and put printf() calls in the loop ... it
  100. * won't be very helpful ;-)
  101. */
  102. for (sect = s_first; sect <= s_last; sect++) {
  103. if (info->protect[sect] == 0) { /* not protected */
  104. addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[sect]);
  105. *addr = 0xf0;
  106. *(addr+0xAAA/2) = 0xaa;
  107. *(addr+0x554/2) = 0x55;
  108. *(addr+0xAAA/2) = 0x80;
  109. *(addr+0xAAA/2) = 0xaa;
  110. *(addr+0x554/2) = 0x55;
  111. *addr2 = 0x30;
  112. /* Now just wait for 0xffff & provide some user
  113. * feedback while we wait. Here we have to grant
  114. * timer interrupts. Otherwise get_timer() can't
  115. * work right. */
  116. ipri(oldpri);
  117. start = get_timer (0);
  118. while (*addr2 != 0xffff) {
  119. for (wait = 8; wait; wait--) {
  120. udelay (125 * 1000);
  121. }
  122. putc ('.');
  123. if (get_timer (start) > CONFIG_SYS_FLASH_ERASE_TOUT) {
  124. printf ("timeout\n");
  125. return 1;
  126. }
  127. }
  128. oldpri = ipri (3); /* disallow non important irqs again */
  129. }
  130. }
  131. printf ("\n");
  132. *addr = 0xf0;
  133. /* Restore interrupt priority */
  134. ipri (oldpri);
  135. return 0;
  136. }
  137. /*-----------------------------------------------------------------------
  138. * Copy memory to flash, returns:
  139. * 0 - OK
  140. * 1 - write timeout
  141. * 2 - Flash not erased
  142. */
  143. int write_buff (flash_info_t * info, uchar * srcbuffer, ulong addr, ulong cnt)
  144. {
  145. volatile CONFIG_SYS_FLASH_WORD_SIZE *cmd = (vu_short *) info->start[0];
  146. volatile CONFIG_SYS_FLASH_WORD_SIZE *dst = (vu_short *) addr;
  147. CONFIG_SYS_FLASH_WORD_SIZE *src = (void *) srcbuffer;
  148. CONFIG_SYS_FLASH_WORD_SIZE b;
  149. unsigned oldpri;
  150. ulong start;
  151. cnt /= sizeof(CONFIG_SYS_FLASH_WORD_SIZE);
  152. while (cnt) {
  153. /* Check for sufficient erase */
  154. b = *src;
  155. if ((*dst & b) != b) {
  156. printf ("%02x : %02x\n", *dst, b);
  157. return (2);
  158. }
  159. /* Disable interrupts other than window underflow
  160. * (interrupt priority 2)
  161. */
  162. oldpri = ipri (3);
  163. *(cmd+0xAAA/2) = 0xaa;
  164. *(cmd+0x554/2) = 0x55;
  165. *(cmd+0xAAA/2) = 0xa0;
  166. ipri (oldpri);
  167. *dst = b;
  168. /* Verify write */
  169. start = get_timer (0);
  170. while (*dst != b) {
  171. if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
  172. *cmd = 0xf0;
  173. return 1;
  174. }
  175. }
  176. dst++;
  177. src++;
  178. cnt--;
  179. }
  180. *cmd = 0xf0;
  181. return (0);
  182. }