You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

197 lines
5.4 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2007 by Pavel Chromy *
  3. * chromy@asix.cz *
  4. * *
  5. * This program is free software; you can redistribute it and/or modify *
  6. * it under the terms of the GNU General Public License as published by *
  7. * the Free Software Foundation; either version 2 of the License, or *
  8. * (at your option) any later version. *
  9. * *
  10. * This program is distributed in the hope that it will be useful, *
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  13. * GNU General Public License for more details. *
  14. * *
  15. * You should have received a copy of the GNU General Public License *
  16. * along with this program; if not, write to the *
  17. * Free Software Foundation, Inc., *
  18. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  19. ***************************************************************************/
  20. #include "samflash.h"
  21. unsigned int flash_page_count = 1024;
  22. unsigned int flash_page_size = 256;
  23. /* pages per lock bit */
  24. unsigned int flash_lock_pages = 1024/16;
  25. /* detect chip and set loader parameters */
  26. int flash_init(void)
  27. {
  28. unsigned int nvpsiz;
  29. nvpsiz = (inr(DBGU_CIDR) >> 8)&0xf;
  30. switch (nvpsiz) {
  31. case 3:
  32. /* AT91SAM7x32 */
  33. flash_page_count = 256;
  34. flash_page_size = 128;
  35. flash_lock_pages = 256/8;
  36. break;
  37. case 5:
  38. /* AT91SAM7x64 */
  39. flash_page_count = 512;
  40. flash_page_size = 128;
  41. flash_lock_pages = 512/16;
  42. break;
  43. case 7:
  44. /* AT91SAM7x128*/
  45. flash_page_count = 512;
  46. flash_page_size = 256;
  47. flash_lock_pages = 512/8;
  48. break;
  49. case 9:
  50. /* AT91SAM7x256 */
  51. flash_page_count = 1024;
  52. flash_page_size = 256;
  53. flash_lock_pages = 1024/16;
  54. break;
  55. case 10:
  56. /* AT91SAM7x512 */
  57. flash_page_count = 2048;
  58. flash_page_size = 256;
  59. flash_lock_pages = 2048/32;
  60. break;
  61. default:
  62. return FLASH_STAT_INITE;
  63. }
  64. return FLASH_STAT_OK;
  65. }
  66. /* program single flash page */
  67. int flash_page_program(uint32 *data, int page_num)
  68. {
  69. int i;
  70. int efc_ofs;
  71. uint32 *flash_ptr;
  72. uint32 *data_ptr;
  73. /* select proper controller */
  74. if (page_num >= 1024) efc_ofs = 0x10;
  75. else efc_ofs = 0;
  76. /* wait until FLASH is ready, just for sure */
  77. while ((inr(MC_FSR + efc_ofs)&MC_FRDY) == 0);
  78. /* calculate page address, only lower 8 bits are used to address the latch,
  79. but the upper part of address is needed for writing to proper EFC */
  80. flash_ptr = (uint32 *)(FLASH_AREA_ADDR + (page_num*flash_page_size));
  81. data_ptr = data;
  82. /* copy data to latch */
  83. for (i = flash_page_size/4; i; i--) {
  84. /* we do not use memcpy to be sure that only 32 bit access is used */
  85. *(flash_ptr++)=*(data_ptr++);
  86. }
  87. /* page number and page write command to FCR */
  88. outr(MC_FCR + efc_ofs, ((page_num&0x3ff) << 8) | MC_KEY | MC_FCMD_WP);
  89. /* wait until it's done */
  90. while ((inr(MC_FSR + efc_ofs)&MC_FRDY) == 0);
  91. /* check for errors */
  92. if ((inr(MC_FSR + efc_ofs)&MC_PROGE)) return FLASH_STAT_PROGE;
  93. if ((inr(MC_FSR + efc_ofs)&MC_LOCKE)) return FLASH_STAT_LOCKE;
  94. #if 0
  95. /* verify written data */
  96. flash_ptr = (uint32 *)(FLASH_AREA_ADDR + (page_num*flash_page_size));
  97. data_ptr = data;
  98. for (i = flash_page_size/4; i; i--) {
  99. if (*(flash_ptr++)!=*(data_ptr++)) return FLASH_STAT_VERIFE;
  100. }
  101. #endif
  102. return FLASH_STAT_OK;
  103. }
  104. int flash_erase_plane(int efc_ofs)
  105. {
  106. unsigned int lockbits;
  107. int page_num;
  108. page_num = 0;
  109. lockbits = inr(MC_FSR + efc_ofs) >> 16;
  110. while (lockbits) {
  111. if (lockbits&1) {
  112. /* wait until FLASH is ready, just for sure */
  113. while ((inr(MC_FSR + efc_ofs)&MC_FRDY) == 0);
  114. outr(MC_FCR + efc_ofs, ((page_num&0x3ff) << 8) | 0x5a000004);
  115. /* wait until it's done */
  116. while ((inr(MC_FSR + efc_ofs)&MC_FRDY) == 0);
  117. /* check for errors */
  118. if ((inr(MC_FSR + efc_ofs)&MC_PROGE)) return FLASH_STAT_PROGE;
  119. if ((inr(MC_FSR + efc_ofs)&MC_LOCKE)) return FLASH_STAT_LOCKE;
  120. }
  121. if ((page_num += flash_lock_pages) > flash_page_count) break;
  122. lockbits>>=1;
  123. }
  124. /* wait until FLASH is ready, just for sure */
  125. while ((inr(MC_FSR + efc_ofs)&MC_FRDY) == 0);
  126. /* erase all command to FCR */
  127. outr(MC_FCR + efc_ofs, 0x5a000008);
  128. /* wait until it's done */
  129. while ((inr(MC_FSR + efc_ofs)&MC_FRDY) == 0);
  130. /* check for errors */
  131. if ((inr(MC_FSR + efc_ofs)&MC_PROGE)) return FLASH_STAT_PROGE;
  132. if ((inr(MC_FSR + efc_ofs)&MC_LOCKE)) return FLASH_STAT_LOCKE;
  133. /* set no erase before programming */
  134. outr(MC_FMR + efc_ofs, inr(MC_FMR + efc_ofs) | 0x80);
  135. return FLASH_STAT_OK;
  136. }
  137. /* erase whole chip */
  138. int flash_erase_all(void)
  139. {
  140. int result;
  141. if ((result = flash_erase_plane(0)) != FLASH_STAT_OK) return result;
  142. /* the second flash controller, if any */
  143. if (flash_page_count > 1024) result = flash_erase_plane(0x10);
  144. return result;
  145. }
  146. int flash_verify(uint32 adr, unsigned int len, uint8 *src)
  147. {
  148. unsigned char *flash_ptr;
  149. flash_ptr = (uint8 *)FLASH_AREA_ADDR + adr;
  150. for (;len; len--) {
  151. if (*(flash_ptr++)!=*(src++)) return FLASH_STAT_VERIFE;
  152. }
  153. return FLASH_STAT_OK;
  154. }