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.
 
 
 
 
 
 

492 lines
13 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2007 by Dominic Rath *
  3. * Dominic.Rath@gmx.de *
  4. * Copyright (C) 2009 Michael Schwingen *
  5. * michael@schwingen.org *
  6. * *
  7. * This program is free software; you can redistribute it and/or modify *
  8. * it under the terms of the GNU General Public License as published by *
  9. * the Free Software Foundation; either version 2 of the License, or *
  10. * (at your option) any later version. *
  11. * *
  12. * This program is distributed in the hope that it will be useful, *
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  15. * GNU General Public License for more details. *
  16. * *
  17. * You should have received a copy of the GNU General Public License *
  18. * along with this program; if not, write to the *
  19. * Free Software Foundation, Inc., *
  20. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  21. ***************************************************************************/
  22. #ifdef HAVE_CONFIG_H
  23. #include "config.h"
  24. #endif
  25. #include "non_cfi.h"
  26. #include "cfi.h"
  27. #define KB 1024
  28. #define MB (1024*1024)
  29. #define ERASE_REGION(num, size) (((size/256) << 16) | (num-1))
  30. /* non-CFI compatible flashes */
  31. static non_cfi_t non_cfi_flashes[] = {
  32. {
  33. .mfr = CFI_MFR_SST,
  34. .id = 0xd4,
  35. .pri_id = 0x02,
  36. .dev_size = 64*KB,
  37. .interface_desc = 0x0, /* x8 only device */
  38. .max_buf_write_size = 0x0,
  39. .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
  40. .num_erase_regions = 1,
  41. .erase_region_info =
  42. {
  43. ERASE_REGION(16, 4*KB)
  44. }
  45. },
  46. {
  47. .mfr = CFI_MFR_SST,
  48. .id = 0xd5,
  49. .pri_id = 0x02,
  50. .dev_size = 128*KB,
  51. .interface_desc = 0x0, /* x8 only device */
  52. .max_buf_write_size = 0x0,
  53. .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
  54. .num_erase_regions = 1,
  55. .erase_region_info =
  56. {
  57. ERASE_REGION(32, 4*KB)
  58. }
  59. },
  60. {
  61. .mfr = CFI_MFR_SST,
  62. .id = 0xd6,
  63. .pri_id = 0x02,
  64. .dev_size = 256*KB,
  65. .interface_desc = 0x0, /* x8 only device */
  66. .max_buf_write_size = 0x0,
  67. .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
  68. .num_erase_regions = 1,
  69. .erase_region_info =
  70. {
  71. ERASE_REGION(64, 4*KB)
  72. }
  73. },
  74. {
  75. .mfr = CFI_MFR_SST,
  76. .id = 0xd7,
  77. .pri_id = 0x02,
  78. .dev_size = 512*KB,
  79. .interface_desc = 0x0, /* x8 only device */
  80. .max_buf_write_size = 0x0,
  81. .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
  82. .num_erase_regions = 1,
  83. .erase_region_info =
  84. {
  85. ERASE_REGION(128, 4*KB)
  86. }
  87. },
  88. {
  89. .mfr = CFI_MFR_SST,
  90. .id = 0x2780,
  91. .pri_id = 0x02,
  92. .dev_size = 512*KB,
  93. .interface_desc = 0x2, /* x8 or x16 device */
  94. .max_buf_write_size = 0x0,
  95. .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
  96. .num_erase_regions = 1,
  97. .erase_region_info =
  98. {
  99. ERASE_REGION(128, 4*KB)
  100. }
  101. },
  102. {
  103. .mfr = CFI_MFR_ST,
  104. .id = 0xd6, /* ST29F400BB */
  105. .pri_id = 0x02,
  106. .dev_size = 512*KB,
  107. .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
  108. .max_buf_write_size = 0x0,
  109. .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
  110. .num_erase_regions = 4,
  111. .erase_region_info =
  112. {
  113. ERASE_REGION(1, 16*KB),
  114. ERASE_REGION(2, 8*KB),
  115. ERASE_REGION(1, 32*KB),
  116. ERASE_REGION(7, 64*KB)
  117. }
  118. },
  119. {
  120. .mfr = CFI_MFR_ST,
  121. .id = 0xd5, /* ST29F400BT */
  122. .pri_id = 0x02,
  123. .dev_size = 512*KB,
  124. .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
  125. .max_buf_write_size = 0x0,
  126. .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
  127. .num_erase_regions = 4,
  128. .erase_region_info =
  129. {
  130. ERASE_REGION(7, 64*KB),
  131. ERASE_REGION(1, 32*KB),
  132. ERASE_REGION(2, 8*KB),
  133. ERASE_REGION(1, 16*KB)
  134. }
  135. },
  136. /* SST 39VF* do not support DQ5 status polling - this currently is
  137. only supported by the host algorithm, not by the target code using
  138. the work area.
  139. Only true for 8-bit and 32-bit wide memories. 16-bit wide memories
  140. without DQ5 status polling are supported by the target code.
  141. */
  142. {
  143. .mfr = CFI_MFR_SST,
  144. .id = 0x2782, /* SST39xF160 */
  145. .pri_id = 0x02,
  146. .dev_size = 2*MB,
  147. .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
  148. .max_buf_write_size = 0x0,
  149. .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7,
  150. .num_erase_regions = 1,
  151. .erase_region_info =
  152. {
  153. ERASE_REGION(512, 4*KB)
  154. }
  155. },
  156. {
  157. .mfr = CFI_MFR_SST,
  158. .id = 0x2783, /* SST39VF320 */
  159. .pri_id = 0x02,
  160. .dev_size = 4*MB,
  161. .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
  162. .max_buf_write_size = 0x0,
  163. .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7,
  164. .num_erase_regions = 1,
  165. .erase_region_info =
  166. {
  167. ERASE_REGION(1024, 4*KB)
  168. }
  169. },
  170. {
  171. .mfr = CFI_MFR_SST,
  172. .id = 0x234b, /* SST39VF1601 */
  173. .pri_id = 0x02,
  174. .dev_size = 2*MB,
  175. .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
  176. .max_buf_write_size = 0x0,
  177. .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7,
  178. .num_erase_regions = 1,
  179. .erase_region_info =
  180. {
  181. ERASE_REGION(512, 4*KB)
  182. }
  183. },
  184. {
  185. .mfr = CFI_MFR_SST,
  186. .id = 0x234a, /* SST39VF1602 */
  187. .pri_id = 0x02,
  188. .dev_size = 2*MB,
  189. .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
  190. .max_buf_write_size = 0x0,
  191. .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7,
  192. .num_erase_regions = 1,
  193. .erase_region_info =
  194. {
  195. ERASE_REGION(512, 4*KB)
  196. }
  197. },
  198. {
  199. .mfr = CFI_MFR_SST,
  200. .id = 0x235b, /* SST39VF3201 */
  201. .pri_id = 0x02,
  202. .dev_size = 4*MB,
  203. .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
  204. .max_buf_write_size = 0x0,
  205. .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7,
  206. .num_erase_regions = 1,
  207. .erase_region_info =
  208. {
  209. ERASE_REGION(1024, 4*KB)
  210. }
  211. },
  212. {
  213. .mfr = CFI_MFR_SST,
  214. .id = 0x235a, /* SST39VF3202 */
  215. .pri_id = 0x02,
  216. .dev_size = 4*MB,
  217. .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
  218. .max_buf_write_size = 0x0,
  219. .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7,
  220. .num_erase_regions = 1,
  221. .erase_region_info =
  222. {
  223. ERASE_REGION(1024, 4*KB)
  224. }
  225. },
  226. {
  227. .mfr = CFI_MFR_AMD,
  228. .id = 0x22ab, /* AM29F400BB */
  229. .pri_id = 0x02,
  230. .dev_size = 512*KB,
  231. .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
  232. .max_buf_write_size = 0x0,
  233. .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
  234. .num_erase_regions = 4,
  235. .erase_region_info =
  236. {
  237. ERASE_REGION(1, 16*KB),
  238. ERASE_REGION(2, 8*KB),
  239. ERASE_REGION(1, 32*KB),
  240. ERASE_REGION(7, 64*KB)
  241. }
  242. },
  243. {
  244. .mfr = CFI_MFR_AMD,
  245. .id = 0x2223, /* AM29F400BT */
  246. .pri_id = 0x02,
  247. .dev_size = 512*KB,
  248. .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
  249. .max_buf_write_size = 0x0,
  250. .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
  251. .num_erase_regions = 4,
  252. .erase_region_info =
  253. {
  254. ERASE_REGION(7, 64*KB),
  255. ERASE_REGION(1, 32*KB),
  256. ERASE_REGION(2, 8*KB),
  257. ERASE_REGION(1, 16*KB)
  258. }
  259. },
  260. {
  261. .mfr = CFI_MFR_FUJITSU,
  262. .id = 0x226b, /* AM29SL800DB */
  263. .pri_id = 0x02,
  264. .dev_size = 1*MB,
  265. .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
  266. .max_buf_write_size = 0x0,
  267. .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
  268. .num_erase_regions = 4,
  269. .erase_region_info =
  270. {
  271. ERASE_REGION(1, 16*KB),
  272. ERASE_REGION(2, 8*KB),
  273. ERASE_REGION(1, 32*KB),
  274. ERASE_REGION(15, 64*KB)
  275. }
  276. },
  277. {
  278. .mfr = CFI_MFR_AMIC,
  279. .id = 0xb31a, /* A29L800A */
  280. .pri_id = 0x02,
  281. .dev_size = 1*MB,
  282. .interface_desc = 0x2,
  283. .max_buf_write_size = 0x0,
  284. .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
  285. .num_erase_regions = 4,
  286. .erase_region_info =
  287. {
  288. ERASE_REGION(1, 16*KB),
  289. ERASE_REGION(2, 8*KB),
  290. ERASE_REGION(1, 32*KB),
  291. ERASE_REGION(15, 64*KB)
  292. }
  293. },
  294. {
  295. .mfr = CFI_MFR_MX,
  296. .id = 0x225b, /* MX29LV800B */
  297. .pri_id = 0x02,
  298. .dev_size = 1*MB,
  299. .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
  300. .max_buf_write_size = 0x0,
  301. .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
  302. .num_erase_regions = 4,
  303. .erase_region_info =
  304. {
  305. ERASE_REGION(1, 16*KB),
  306. ERASE_REGION(2, 8*KB),
  307. ERASE_REGION(1, 32*KB),
  308. ERASE_REGION(15, 64*KB)
  309. }
  310. },
  311. {
  312. .mfr = CFI_MFR_MX,
  313. .id = 0x2249, /* MX29LV160AB: 2MB */
  314. .pri_id = 0x02,
  315. .dev_size = 2*MB,
  316. .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
  317. .max_buf_write_size = 0x0,
  318. .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
  319. .num_erase_regions = 4,
  320. .erase_region_info =
  321. {
  322. ERASE_REGION(1, 16*KB),
  323. ERASE_REGION(2, 8*KB),
  324. ERASE_REGION(1, 32*KB),
  325. ERASE_REGION(31, 64*KB)
  326. }
  327. },
  328. {
  329. .mfr = CFI_MFR_MX,
  330. .id = 0x22C4, /* MX29LV160AT: 2MB */
  331. .pri_id = 0x02,
  332. .dev_size = 2*MB,
  333. .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
  334. .max_buf_write_size = 0x0,
  335. .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
  336. .num_erase_regions = 4,
  337. .erase_region_info =
  338. {
  339. ERASE_REGION(31, 64*KB),
  340. ERASE_REGION(1, 32*KB),
  341. ERASE_REGION(2, 8*KB),
  342. ERASE_REGION(1, 16*KB)
  343. }
  344. },
  345. {
  346. .mfr = CFI_MFR_ATMEL,
  347. .id = 0x00c0, /* Atmel 49BV1614 */
  348. .pri_id = 0x02,
  349. .dev_size = 2*MB,
  350. .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
  351. .max_buf_write_size = 0x0,
  352. .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
  353. .num_erase_regions = 3,
  354. .erase_region_info =
  355. {
  356. ERASE_REGION(8, 8*KB),
  357. ERASE_REGION(2, 32*KB),
  358. ERASE_REGION(30, 64*KB)
  359. }
  360. },
  361. {
  362. .mfr = CFI_MFR_ATMEL,
  363. .id = 0xC2, /* Atmel 49BV1614T */
  364. .pri_id = 0x02,
  365. .dev_size = 2*MB,
  366. .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
  367. .max_buf_write_size = 0x0,
  368. .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
  369. .num_erase_regions = 3,
  370. .erase_region_info =
  371. {
  372. ERASE_REGION(30, 64*KB),
  373. ERASE_REGION(2, 32*KB),
  374. ERASE_REGION(8, 8*KB)
  375. }
  376. },
  377. {
  378. .mfr = CFI_MFR_AMD,
  379. .id = 0x225b, /* S29AL008D */
  380. .pri_id = 0x02,
  381. .dev_size = 1*MB,
  382. .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
  383. .max_buf_write_size = 0x0,
  384. .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
  385. .num_erase_regions = 4,
  386. .erase_region_info =
  387. {
  388. ERASE_REGION(1, 16*KB),
  389. ERASE_REGION(2, 8*KB),
  390. ERASE_REGION(1, 32*KB),
  391. ERASE_REGION(15, 64*KB)
  392. }
  393. },
  394. {
  395. .mfr = 0,
  396. .id = 0,
  397. }
  398. };
  399. void cfi_fixup_non_cfi(flash_bank_t *bank)
  400. {
  401. struct cfi_flash_bank *cfi_info = bank->driver_priv;
  402. non_cfi_t *non_cfi = non_cfi_flashes;
  403. for (non_cfi = non_cfi_flashes; non_cfi->mfr; non_cfi++)
  404. {
  405. if ((cfi_info->manufacturer == non_cfi->mfr)
  406. && (cfi_info->device_id == non_cfi->id))
  407. {
  408. break;
  409. }
  410. }
  411. /* only fixup jedec flashs found in table */
  412. if (!non_cfi->mfr)
  413. return;
  414. cfi_info->not_cfi = 1;
  415. /* fill in defaults for non-critical data */
  416. cfi_info->vcc_min = 0x0;
  417. cfi_info->vcc_max = 0x0;
  418. cfi_info->vpp_min = 0x0;
  419. cfi_info->vpp_max = 0x0;
  420. cfi_info->word_write_timeout_typ = 0x0;
  421. cfi_info->buf_write_timeout_typ = 0x0;
  422. cfi_info->block_erase_timeout_typ = 0x0;
  423. cfi_info->chip_erase_timeout_typ = 0x0;
  424. cfi_info->word_write_timeout_max = 0x0;
  425. cfi_info->buf_write_timeout_max = 0x0;
  426. cfi_info->block_erase_timeout_max = 0x0;
  427. cfi_info->chip_erase_timeout_max = 0x0;
  428. cfi_info->qry[0] = 'Q';
  429. cfi_info->qry[1] = 'R';
  430. cfi_info->qry[2] = 'Y';
  431. cfi_info->pri_id = non_cfi->pri_id;
  432. cfi_info->pri_addr = 0x0;
  433. cfi_info->alt_id = 0x0;
  434. cfi_info->alt_addr = 0x0;
  435. cfi_info->alt_ext = NULL;
  436. cfi_info->interface_desc = non_cfi->interface_desc;
  437. cfi_info->max_buf_write_size = non_cfi->max_buf_write_size;
  438. cfi_info->status_poll_mask = non_cfi->status_poll_mask;
  439. cfi_info->num_erase_regions = non_cfi->num_erase_regions;
  440. cfi_info->erase_region_info = non_cfi->erase_region_info;
  441. cfi_info->dev_size = non_cfi->dev_size;
  442. if (cfi_info->pri_id == 0x2)
  443. {
  444. struct cfi_spansion_pri_ext *pri_ext = malloc(sizeof(struct cfi_spansion_pri_ext));
  445. pri_ext->pri[0] = 'P';
  446. pri_ext->pri[1] = 'R';
  447. pri_ext->pri[2] = 'I';
  448. pri_ext->major_version = '1';
  449. pri_ext->minor_version = '0';
  450. pri_ext->SiliconRevision = 0x0;
  451. pri_ext->EraseSuspend = 0x0;
  452. pri_ext->EraseSuspend = 0x0;
  453. pri_ext->BlkProt = 0x0;
  454. pri_ext->TmpBlkUnprotect = 0x0;
  455. pri_ext->BlkProtUnprot = 0x0;
  456. pri_ext->SimultaneousOps = 0x0;
  457. pri_ext->BurstMode = 0x0;
  458. pri_ext->PageMode = 0x0;
  459. pri_ext->VppMin = 0x0;
  460. pri_ext->VppMax = 0x0;
  461. pri_ext->TopBottom = 0x0;
  462. pri_ext->_unlock1 = 0x5555;
  463. pri_ext->_unlock2 = 0x2AAA;
  464. pri_ext->_reversed_geometry = 0;
  465. cfi_info->pri_ext = pri_ext;
  466. } else if ((cfi_info->pri_id == 0x1) || (cfi_info->pri_id == 0x3))
  467. {
  468. LOG_ERROR("BUG: non-CFI flashes using the Intel commandset are not yet supported");
  469. exit(-1);
  470. }
  471. }