1 /***************************************************************************
2 * Copyright (C) 2007 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * Copyright (C) 2009 Michael Schwingen *
5 * michael@schwingen.org *
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. *
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. *
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 ***************************************************************************/
35 #define MB (1024*1024)
36 #define ERASE_REGION(num, size) (((size/256)<<16)|(num-1))
38 /* non-CFI compatible flashes */
39 non_cfi_t non_cfi_flashes[] = {
45 .interface_desc = 0x0, /* x8 only device */
46 .max_buf_write_size = 0x0,
47 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
48 .num_erase_regions = 1,
51 ERASE_REGION(16, 4*KB)
59 .interface_desc = 0x0, /* x8 only device */
60 .max_buf_write_size = 0x0,
61 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
62 .num_erase_regions = 1,
65 ERASE_REGION(32, 4*KB)
73 .interface_desc = 0x0, /* x8 only device */
74 .max_buf_write_size = 0x0,
75 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
76 .num_erase_regions = 1,
79 ERASE_REGION(64, 4*KB)
87 .interface_desc = 0x0, /* x8 only device */
88 .max_buf_write_size = 0x0,
89 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
90 .num_erase_regions = 1,
93 ERASE_REGION(128, 4*KB)
101 .interface_desc = 0x2, /* x8 or x16 device */
102 .max_buf_write_size = 0x0,
103 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
104 .num_erase_regions = 1,
107 ERASE_REGION(128, 4*KB)
112 .id = 0xd6, /* ST29F400BB */
115 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
116 .max_buf_write_size = 0x0,
117 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
118 .num_erase_regions = 4,
121 ERASE_REGION( 1, 16*KB),
122 ERASE_REGION( 2, 8*KB),
123 ERASE_REGION( 1, 32*KB),
124 ERASE_REGION( 7, 64*KB)
129 .id = 0xd5, /* ST29F400BT */
132 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
133 .max_buf_write_size = 0x0,
134 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
135 .num_erase_regions = 4,
138 ERASE_REGION( 7, 64*KB),
139 ERASE_REGION( 1, 32*KB),
140 ERASE_REGION( 2, 8*KB),
141 ERASE_REGION( 1, 16*KB)
145 /* SST 39VF* do not support DQ5 status polling - this currently is
146 only supported by the host algorithm, not by the target code using
150 .id = 0x2782, /* SST39xF160 */
153 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
154 .max_buf_write_size = 0x0,
155 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7,
156 .num_erase_regions = 1,
159 ERASE_REGION(512, 4*KB)
164 .id = 0x2783, /* SST39VF320 */
167 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
168 .max_buf_write_size = 0x0,
169 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7,
170 .num_erase_regions = 1,
173 ERASE_REGION(1024, 4*KB)
178 .id = 0x234b, /* SST39VF1601 */
181 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
182 .max_buf_write_size = 0x0,
183 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7,
184 .num_erase_regions = 1,
187 ERASE_REGION(512, 4*KB)
192 .id = 0x234a, /* SST39VF1602 */
195 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
196 .max_buf_write_size = 0x0,
197 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7,
198 .num_erase_regions = 1,
201 ERASE_REGION(512, 4*KB)
206 .id = 0x235b, /* SST39VF3201 */
209 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
210 .max_buf_write_size = 0x0,
211 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7,
212 .num_erase_regions = 1,
215 ERASE_REGION(1024, 4*KB)
220 .id = 0x235a, /* SST39VF3202 */
223 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
224 .max_buf_write_size = 0x0,
225 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7,
226 .num_erase_regions = 1,
229 ERASE_REGION(1024, 4*KB)
234 .id = 0x22ab, /* AM29F400BB */
237 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
238 .max_buf_write_size = 0x0,
239 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
240 .num_erase_regions = 4,
243 ERASE_REGION( 1, 16*KB),
244 ERASE_REGION( 2, 8*KB),
245 ERASE_REGION( 1, 32*KB),
246 ERASE_REGION( 7, 64*KB)
251 .id = 0x2223, /* AM29F400BT */
254 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
255 .max_buf_write_size = 0x0,
256 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
257 .num_erase_regions = 4,
260 ERASE_REGION( 7, 64*KB),
261 ERASE_REGION( 1, 32*KB),
262 ERASE_REGION( 2, 8*KB),
263 ERASE_REGION( 1, 16*KB)
267 .mfr = CFI_MFR_FUJITSU,
268 .id = 0x226b, /* AM29SL800DB */
271 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
272 .max_buf_write_size = 0x0,
273 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
274 .num_erase_regions = 4,
277 ERASE_REGION( 1, 16*KB),
278 ERASE_REGION( 2, 8*KB),
279 ERASE_REGION( 1, 32*KB),
280 ERASE_REGION(15, 64*KB)
285 .id = 0xb31a, /* A29L800A */
288 .interface_desc = 0x2,
289 .max_buf_write_size = 0x0,
290 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
291 .num_erase_regions = 4,
294 ERASE_REGION( 1, 16*KB),
295 ERASE_REGION( 2, 8*KB),
296 ERASE_REGION( 1, 32*KB),
297 ERASE_REGION(15, 64*KB)
302 .id = 0x225b, /* MX29LV800B */
305 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
306 .max_buf_write_size = 0x0,
307 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
308 .num_erase_regions = 4,
311 ERASE_REGION( 1, 16*KB),
312 ERASE_REGION( 2, 8*KB),
313 ERASE_REGION( 1, 32*KB),
314 ERASE_REGION(15, 64*KB)
320 .id = 0x2249, /* MX29LV160AB: 2MB */
323 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
324 .max_buf_write_size = 0x0,
325 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
326 .num_erase_regions = 4,
329 ERASE_REGION( 1, 16*KB),
330 ERASE_REGION( 2, 8*KB),
331 ERASE_REGION( 1, 32*KB),
332 ERASE_REGION(31, 64*KB)
337 .id = 0x22C4, /* MX29LV160AT: 2MB */
340 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
341 .max_buf_write_size = 0x0,
342 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
343 .num_erase_regions = 4,
346 ERASE_REGION(31, 64*KB),
347 ERASE_REGION( 1, 32*KB),
348 ERASE_REGION( 2, 8*KB),
349 ERASE_REGION( 1, 16*KB)
353 .mfr = CFI_MFR_ATMEL,
354 .id = 0x00c0, /* Atmel 49BV1614 */
357 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
358 .max_buf_write_size = 0x0,
359 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
360 .num_erase_regions = 3,
363 ERASE_REGION( 8, 8*KB),
364 ERASE_REGION( 2, 32*KB),
365 ERASE_REGION(30, 64*KB)
369 .mfr = CFI_MFR_ATMEL,
370 .id = 0xC2, /* Atmel 49BV1614T */
373 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
374 .max_buf_write_size = 0x0,
375 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
376 .num_erase_regions = 3,
379 ERASE_REGION(30, 64*KB),
380 ERASE_REGION( 2, 32*KB),
381 ERASE_REGION( 8, 8*KB)
386 .id = 0x225b, /* S29AL008D */
389 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
390 .max_buf_write_size = 0x0,
391 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
392 .num_erase_regions = 4,
395 ERASE_REGION( 1, 16*KB),
396 ERASE_REGION( 2, 8*KB),
397 ERASE_REGION( 1, 32*KB),
398 ERASE_REGION(15, 64*KB)
407 void cfi_fixup_non_cfi(flash_bank_t *bank)
409 cfi_flash_bank_t *cfi_info = bank->driver_priv;
410 non_cfi_t *non_cfi = non_cfi_flashes;
412 for (non_cfi = non_cfi_flashes; non_cfi->mfr; non_cfi++)
414 if ((cfi_info->manufacturer == non_cfi->mfr)
415 && (cfi_info->device_id == non_cfi->id))
421 /* only fixup jedec flashs found in table */
425 cfi_info->not_cfi = 1;
427 /* fill in defaults for non-critical data */
428 cfi_info->vcc_min = 0x0;
429 cfi_info->vcc_max = 0x0;
430 cfi_info->vpp_min = 0x0;
431 cfi_info->vpp_max = 0x0;
432 cfi_info->word_write_timeout_typ = 0x0;
433 cfi_info->buf_write_timeout_typ = 0x0;
434 cfi_info->block_erase_timeout_typ = 0x0;
435 cfi_info->chip_erase_timeout_typ = 0x0;
436 cfi_info->word_write_timeout_max = 0x0;
437 cfi_info->buf_write_timeout_max = 0x0;
438 cfi_info->block_erase_timeout_max = 0x0;
439 cfi_info->chip_erase_timeout_max = 0x0;
441 cfi_info->qry[0] = 'Q';
442 cfi_info->qry[1] = 'R';
443 cfi_info->qry[2] = 'Y';
445 cfi_info->pri_id = non_cfi->pri_id;
446 cfi_info->pri_addr = 0x0;
447 cfi_info->alt_id = 0x0;
448 cfi_info->alt_addr = 0x0;
449 cfi_info->alt_ext = NULL;
451 cfi_info->interface_desc = non_cfi->interface_desc;
452 cfi_info->max_buf_write_size = non_cfi->max_buf_write_size;
453 cfi_info->status_poll_mask = non_cfi->status_poll_mask;
454 cfi_info->num_erase_regions = non_cfi->num_erase_regions;
455 cfi_info->erase_region_info = non_cfi->erase_region_info;
456 cfi_info->dev_size = non_cfi->dev_size;
458 if (cfi_info->pri_id == 0x2)
460 cfi_spansion_pri_ext_t *pri_ext = malloc(sizeof(cfi_spansion_pri_ext_t));
462 pri_ext->pri[0] = 'P';
463 pri_ext->pri[1] = 'R';
464 pri_ext->pri[2] = 'I';
466 pri_ext->major_version = '1';
467 pri_ext->minor_version = '0';
469 pri_ext->SiliconRevision = 0x0;
470 pri_ext->EraseSuspend = 0x0;
471 pri_ext->EraseSuspend = 0x0;
472 pri_ext->BlkProt = 0x0;
473 pri_ext->TmpBlkUnprotect = 0x0;
474 pri_ext->BlkProtUnprot = 0x0;
475 pri_ext->SimultaneousOps = 0x0;
476 pri_ext->BurstMode = 0x0;
477 pri_ext->PageMode = 0x0;
478 pri_ext->VppMin = 0x0;
479 pri_ext->VppMax = 0x0;
480 pri_ext->TopBottom = 0x0;
482 pri_ext->_unlock1 = 0x5555;
483 pri_ext->_unlock2 = 0x2AAA;
484 pri_ext->_reversed_geometry = 0;
486 cfi_info->pri_ext = pri_ext;
487 } else if ((cfi_info->pri_id == 0x1) || (cfi_info->pri_id == 0x3))
489 LOG_ERROR("BUG: non-CFI flashes using the Intel commandset are not yet supported");