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.
 
 
 
 
 
 

276 lines
7.1 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2007 by Dominic Rath *
  3. * Dominic.Rath@gmx.de *
  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. #ifdef HAVE_CONFIG_H
  21. #include "config.h"
  22. #endif
  23. #include <stdlib.h>
  24. #include "log.h"
  25. #include "flash.h"
  26. #include "cfi.h"
  27. #include "non_cfi.h"
  28. /* non-CFI compatible flashes */
  29. non_cfi_t non_cfi_flashes[] = {
  30. {
  31. .mfr = CFI_MFR_SST,
  32. .id = 0xd4,
  33. .pri_id = 0x02,
  34. .dev_size = 0x10, /* 2^16 = 64KB */
  35. .interface_desc = 0x0, /* x8 only device */
  36. .max_buf_write_size = 0x0,
  37. .num_erase_regions = 1,
  38. .erase_region_info =
  39. {
  40. 0x0010000f, /* 16x 4KB */
  41. 0x00000000
  42. }
  43. },
  44. {
  45. .mfr = CFI_MFR_SST,
  46. .id = 0xd5,
  47. .pri_id = 0x02,
  48. .dev_size = 0x11, /* 2^17 = 128KB */
  49. .interface_desc = 0x0, /* x8 only device */
  50. .max_buf_write_size = 0x0,
  51. .num_erase_regions = 1,
  52. .erase_region_info =
  53. {
  54. 0x0010001f,
  55. 0x00000000
  56. }
  57. },
  58. {
  59. .mfr = CFI_MFR_SST,
  60. .id = 0xd6,
  61. .pri_id = 0x02,
  62. .dev_size = 0x12, /* 2^18 = 256KB */
  63. .interface_desc = 0x0, /* x8 only device */
  64. .max_buf_write_size = 0x0,
  65. .num_erase_regions = 1,
  66. .erase_region_info =
  67. {
  68. 0x0010003f,
  69. 0x00000000
  70. }
  71. },
  72. {
  73. .mfr = CFI_MFR_SST,
  74. .id = 0xd7,
  75. .pri_id = 0x02,
  76. .dev_size = 0x13, /* 2^19 = 512KB */
  77. .interface_desc = 0x0, /* x8 only device */
  78. .max_buf_write_size = 0x0,
  79. .num_erase_regions = 1,
  80. .erase_region_info =
  81. {
  82. 0x0010007f,
  83. 0x00000000
  84. }
  85. },
  86. {
  87. .mfr = CFI_MFR_SST,
  88. .id = 0x2780,
  89. .pri_id = 0x02,
  90. .dev_size = 0x13, /* 2^19 = 512KB */
  91. .interface_desc = 0x2, /* x8 or x16 device */
  92. .max_buf_write_size = 0x0,
  93. .num_erase_regions = 1,
  94. .erase_region_info =
  95. {
  96. 0x0010007f,
  97. 0x00000000
  98. }
  99. },
  100. {
  101. .mfr = CFI_MFR_ST,
  102. .id = 0xd6, /* ST29F400BB */
  103. .pri_id = 0x02,
  104. .dev_size = 0x13, /* 2^19 = 512KB */
  105. .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
  106. .max_buf_write_size = 0x0,
  107. .num_erase_regions = 4,
  108. .erase_region_info =
  109. {
  110. 0x00400000, /* 1x 16KB */
  111. 0x00200001, /* 2x 8KB */
  112. 0x00800000, /* 1x 32KB */
  113. 0x01000006, /* 7x 64KB */
  114. 0x00000000
  115. }
  116. },
  117. {
  118. .mfr = CFI_MFR_ST,
  119. .id = 0xd5, /* ST29F400BT */
  120. .pri_id = 0x02,
  121. .dev_size = 0x13, /* 2^19 = 512KB */
  122. .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
  123. .max_buf_write_size = 0x0,
  124. .num_erase_regions = 4,
  125. .erase_region_info =
  126. {
  127. 0x01000006, /* 7x 64KB */
  128. 0x00800000, /* 1x 32KB */
  129. 0x00200001, /* 2x 8KB */
  130. 0x00400000, /* 1x 16KB */
  131. 0x00000000
  132. }
  133. },
  134. {
  135. .mfr = CFI_MFR_AMD,
  136. .id = 0x22ab, /* AM29F400BB */
  137. .pri_id = 0x02,
  138. .dev_size = 0x13, /* 2^19 = 512KB */
  139. .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
  140. .max_buf_write_size = 0x0,
  141. .num_erase_regions = 4,
  142. .erase_region_info =
  143. {
  144. 0x00400000, /* 1x 16KB */
  145. 0x00200001, /* 2x 8KB */
  146. 0x00800000, /* 1x 32KB */
  147. 0x01000006, /* 7x 64KB */
  148. 0x00000000
  149. }
  150. },
  151. {
  152. .mfr = CFI_MFR_AMD,
  153. .id = 0x2223, /* AM29F400BT */
  154. .pri_id = 0x02,
  155. .dev_size = 0x13, /* 2^19 = 512KB */
  156. .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
  157. .max_buf_write_size = 0x0,
  158. .num_erase_regions = 4,
  159. .erase_region_info =
  160. {
  161. 0x01000006, /* 7x 64KB */
  162. 0x00800000, /* 1x 32KB */
  163. 0x00200001, /* 2x 8KB */
  164. 0x00400000, /* 1x 16KB */
  165. 0x00000000
  166. }
  167. },
  168. {
  169. .mfr = CFI_MFR_FUJITSU,
  170. .id = 0x226b, /* AM29SL800DB */
  171. .pri_id = 0x02,
  172. .dev_size = 0x14, /* 2^20 = 1MB */
  173. .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
  174. .max_buf_write_size = 0x0,
  175. .num_erase_regions = 4,
  176. .erase_region_info =
  177. {
  178. 0x00400000, /* 1x 16KB */
  179. 0x00200001, /* 2x 8KB */
  180. 0x00800000, /* 1x 32KB */
  181. 0x0100000e, /* 15x 64KB */
  182. 0x00000000
  183. }
  184. },
  185. {
  186. .mfr = 0,
  187. .id = 0,
  188. }
  189. };
  190. void cfi_fixup_non_cfi(flash_bank_t *bank, void *param)
  191. {
  192. cfi_flash_bank_t *cfi_info = bank->driver_priv;
  193. non_cfi_t *non_cfi = non_cfi_flashes;
  194. while (non_cfi->mfr)
  195. {
  196. if ((cfi_info->manufacturer == non_cfi->mfr)
  197. && (cfi_info->device_id == non_cfi->id))
  198. {
  199. break;
  200. }
  201. non_cfi++;
  202. }
  203. cfi_info->not_cfi = 1;
  204. /* fill in defaults for non-critical data */
  205. cfi_info->vcc_min = 0x0;
  206. cfi_info->vcc_max = 0x0;
  207. cfi_info->vpp_min = 0x0;
  208. cfi_info->vpp_max = 0x0;
  209. cfi_info->word_write_timeout_typ = 0x0;
  210. cfi_info->buf_write_timeout_typ = 0x0;
  211. cfi_info->block_erase_timeout_typ = 0x0;
  212. cfi_info->chip_erase_timeout_typ = 0x0;
  213. cfi_info->word_write_timeout_max = 0x0;
  214. cfi_info->buf_write_timeout_max = 0x0;
  215. cfi_info->block_erase_timeout_max = 0x0;
  216. cfi_info->chip_erase_timeout_max = 0x0;
  217. cfi_info->qry[0] = 'Q';
  218. cfi_info->qry[1] = 'R';
  219. cfi_info->qry[2] = 'Y';
  220. cfi_info->pri_id = non_cfi->pri_id;
  221. cfi_info->pri_addr = 0x0;
  222. cfi_info->alt_id = 0x0;
  223. cfi_info->alt_addr = 0x0;
  224. cfi_info->alt_ext = NULL;
  225. cfi_info->interface_desc = non_cfi->interface_desc;
  226. cfi_info->max_buf_write_size = non_cfi->max_buf_write_size;
  227. cfi_info->num_erase_regions = non_cfi->num_erase_regions;
  228. cfi_info->erase_region_info = non_cfi->erase_region_info;
  229. if (cfi_info->pri_id == 0x2)
  230. {
  231. cfi_spansion_pri_ext_t *pri_ext = malloc(sizeof(cfi_spansion_pri_ext_t));
  232. pri_ext->pri[0] = 'P';
  233. pri_ext->pri[1] = 'R';
  234. pri_ext->pri[2] = 'I';
  235. pri_ext->major_version = '1';
  236. pri_ext->minor_version = '0';
  237. pri_ext->SiliconRevision = 0x0;
  238. pri_ext->EraseSuspend = 0x0;
  239. pri_ext->EraseSuspend = 0x0;
  240. pri_ext->BlkProt = 0x0;
  241. pri_ext->TmpBlkUnprotect = 0x0;
  242. pri_ext->BlkProtUnprot = 0x0;
  243. pri_ext->SimultaneousOps = 0x0;
  244. pri_ext->BurstMode = 0x0;
  245. pri_ext->PageMode = 0x0;
  246. pri_ext->VppMin = 0x0;
  247. pri_ext->VppMax = 0x0;
  248. pri_ext->TopBottom = 0x0;
  249. pri_ext->_reversed_geometry = 0;
  250. cfi_info->pri_ext = pri_ext;
  251. } else if ((cfi_info->pri_id == 0x1) || (cfi_info->pri_id == 0x3))
  252. {
  253. LOG_ERROR("BUG: non-CFI flashes using the Intel commandset are not yet supported");
  254. exit(-1);
  255. }
  256. }