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 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
21 ***************************************************************************/
32 #define MB (1024*1024)
33 #define ERASE_REGION(num, size) (((size/256) << 16) | (num-1))
35 /* non-CFI compatible flashes */
36 static struct non_cfi non_cfi_flashes
[] = {
42 .interface_desc
= 0x0, /* x8 only device */
43 .max_buf_write_size
= 0x0,
44 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
45 .num_erase_regions
= 1,
46 .erase_region_info
= {
47 ERASE_REGION(16, 4*KB
)
55 .interface_desc
= 0x0, /* x8 only device */
56 .max_buf_write_size
= 0x0,
57 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
58 .num_erase_regions
= 1,
59 .erase_region_info
= {
60 ERASE_REGION(32, 4*KB
)
68 .interface_desc
= 0x0, /* x8 only device */
69 .max_buf_write_size
= 0x0,
70 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
71 .num_erase_regions
= 1,
72 .erase_region_info
= {
73 ERASE_REGION(64, 4*KB
)
81 .interface_desc
= 0x0, /* x8 only device */
82 .max_buf_write_size
= 0x0,
83 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
84 .num_erase_regions
= 1,
85 .erase_region_info
= {
86 ERASE_REGION(128, 4*KB
)
90 .mfr
= CFI_MFR_AMD
, /* Spansion AM29LV040B */
94 .interface_desc
= 0x0, /* x8 only device */
95 .max_buf_write_size
= 0x0,
96 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
97 .num_erase_regions
= 1,
98 .erase_region_info
= {
99 ERASE_REGION(8, 64*KB
)
107 .interface_desc
= 0x2, /* x8 or x16 device */
108 .max_buf_write_size
= 0x0,
109 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
110 .num_erase_regions
= 1,
111 .erase_region_info
= {
112 ERASE_REGION(128, 4*KB
)
117 .id
= 0xd6, /* ST29F400BB */
120 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
121 .max_buf_write_size
= 0x0,
122 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
123 .num_erase_regions
= 4,
124 .erase_region_info
= {
125 ERASE_REGION(1, 16*KB
),
126 ERASE_REGION(2, 8*KB
),
127 ERASE_REGION(1, 32*KB
),
128 ERASE_REGION(7, 64*KB
)
133 .id
= 0xd5, /* ST29F400BT */
136 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
137 .max_buf_write_size
= 0x0,
138 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
139 .num_erase_regions
= 4,
140 .erase_region_info
= {
141 ERASE_REGION(7, 64*KB
),
142 ERASE_REGION(1, 32*KB
),
143 ERASE_REGION(2, 8*KB
),
144 ERASE_REGION(1, 16*KB
)
148 /* SST 39VF* do not support DQ5 status polling - this currently is
149 only supported by the host algorithm, not by the target code using
151 Only true for 8-bit and 32-bit wide memories. 16-bit wide memories
152 without DQ5 status polling are supported by the target code.
156 .id
= 0x2782, /* SST39xF160 */
159 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
160 .max_buf_write_size
= 0x0,
161 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ6_DQ7
,
162 .num_erase_regions
= 1,
163 .erase_region_info
= {
164 ERASE_REGION(512, 4*KB
)
169 .id
= 0x2783, /* SST39VF320 */
172 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
173 .max_buf_write_size
= 0x0,
174 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ6_DQ7
,
175 .num_erase_regions
= 1,
176 .erase_region_info
= {
177 ERASE_REGION(1024, 4*KB
)
182 .id
= 0x234b, /* SST39VF1601 */
185 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
186 .max_buf_write_size
= 0x0,
187 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ6_DQ7
,
188 .num_erase_regions
= 1,
189 .erase_region_info
= {
190 ERASE_REGION(512, 4*KB
)
195 .id
= 0x274b, /* SST39WF1601 */
198 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
199 .max_buf_write_size
= 0x0,
200 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ6_DQ7
,
201 .num_erase_regions
= 1,
202 .erase_region_info
= {
203 ERASE_REGION(512, 4*KB
)
208 .id
= 0x234a, /* SST39VF1602 */
211 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
212 .max_buf_write_size
= 0x0,
213 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ6_DQ7
,
214 .num_erase_regions
= 1,
215 .erase_region_info
= {
216 ERASE_REGION(512, 4*KB
)
221 .id
= 0x235b, /* SST39VF3201 */
224 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
225 .max_buf_write_size
= 0x0,
226 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ6_DQ7
,
227 .num_erase_regions
= 1,
228 .erase_region_info
= {
229 ERASE_REGION(1024, 4*KB
)
234 .id
= 0x235a, /* SST39VF3202 */
237 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
238 .max_buf_write_size
= 0x0,
239 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ6_DQ7
,
240 .num_erase_regions
= 1,
241 .erase_region_info
= {
242 ERASE_REGION(1024, 4*KB
)
247 .id
= 0x236d, /* SST39VF6401B */
250 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
251 .max_buf_write_size
= 0x0,
252 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ6_DQ7
,
253 .num_erase_regions
= 1,
254 .erase_region_info
= {
255 ERASE_REGION(2048, 4*KB
)
260 .id
= 0x22ab, /* AM29F400BB */
263 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
264 .max_buf_write_size
= 0x0,
265 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
266 .num_erase_regions
= 4,
267 .erase_region_info
= {
268 ERASE_REGION(1, 16*KB
),
269 ERASE_REGION(2, 8*KB
),
270 ERASE_REGION(1, 32*KB
),
271 ERASE_REGION(7, 64*KB
)
276 .id
= 0x2223, /* AM29F400BT */
279 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
280 .max_buf_write_size
= 0x0,
281 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
282 .num_erase_regions
= 4,
283 .erase_region_info
= {
284 ERASE_REGION(7, 64*KB
),
285 ERASE_REGION(1, 32*KB
),
286 ERASE_REGION(2, 8*KB
),
287 ERASE_REGION(1, 16*KB
)
291 .mfr
= CFI_MFR_FUJITSU
,
292 .id
= 0x226b, /* AM29SL800DB */
295 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
296 .max_buf_write_size
= 0x0,
297 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
298 .num_erase_regions
= 4,
299 .erase_region_info
= {
300 ERASE_REGION(1, 16*KB
),
301 ERASE_REGION(2, 8*KB
),
302 ERASE_REGION(1, 32*KB
),
303 ERASE_REGION(15, 64*KB
)
307 .mfr
= CFI_MFR_FUJITSU
,
308 .id
= 0x22ea, /* MBM29SL800TE */
311 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
312 .max_buf_write_size
= 0x0,
313 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
314 .num_erase_regions
= 4,
315 .erase_region_info
= {
316 ERASE_REGION(15, 64*KB
),
317 ERASE_REGION(1, 32*KB
),
318 ERASE_REGION(2, 8*KB
),
319 ERASE_REGION(1, 16*KB
)
323 .mfr
= CFI_MFR_FUJITSU
,
324 .id
= 0xba, /* 29LV400BC */
327 .interface_desc
= 0x1, /* x8 or x16 device w/ nBYTE */
328 .max_buf_write_size
= 0x00,
329 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
330 .num_erase_regions
= 4,
331 .erase_region_info
= {
332 ERASE_REGION(1, 16*KB
),
333 ERASE_REGION(2, 8*KB
),
334 ERASE_REGION(1, 32*KB
),
335 ERASE_REGION(7, 64*KB
)
340 .id
= 0xb31a, /* A29L800A */
343 .interface_desc
= 0x2,
344 .max_buf_write_size
= 0x0,
345 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
346 .num_erase_regions
= 4,
347 .erase_region_info
= {
348 ERASE_REGION(1, 16*KB
),
349 ERASE_REGION(2, 8*KB
),
350 ERASE_REGION(1, 32*KB
),
351 ERASE_REGION(15, 64*KB
)
356 .id
= 0x225b, /* MX29LV800B */
359 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
360 .max_buf_write_size
= 0x0,
361 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
362 .num_erase_regions
= 4,
363 .erase_region_info
= {
364 ERASE_REGION(1, 16*KB
),
365 ERASE_REGION(2, 8*KB
),
366 ERASE_REGION(1, 32*KB
),
367 ERASE_REGION(15, 64*KB
)
373 .id
= 0x2249, /* MX29LV160AB: 2MB */
376 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
377 .max_buf_write_size
= 0x0,
378 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
379 .num_erase_regions
= 4,
380 .erase_region_info
= {
381 ERASE_REGION(1, 16*KB
),
382 ERASE_REGION(2, 8*KB
),
383 ERASE_REGION(1, 32*KB
),
384 ERASE_REGION(31, 64*KB
)
389 .id
= 0x22C4, /* MX29LV160AT: 2MB */
392 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
393 .max_buf_write_size
= 0x0,
394 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
395 .num_erase_regions
= 4,
396 .erase_region_info
= {
397 ERASE_REGION(31, 64*KB
),
398 ERASE_REGION(1, 32*KB
),
399 ERASE_REGION(2, 8*KB
),
400 ERASE_REGION(1, 16*KB
)
405 .id
= 0x225b, /* EN29LV800BB */
408 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
409 .max_buf_write_size
= 0x0,
410 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
411 .num_erase_regions
= 4,
412 .erase_region_info
= {
413 ERASE_REGION(1, 16*KB
),
414 ERASE_REGION(2, 8*KB
),
415 ERASE_REGION(1, 32*KB
),
416 ERASE_REGION(15, 64*KB
)
420 .mfr
= CFI_MFR_ATMEL
,
421 .id
= 0x00c0, /* Atmel 49BV1614 */
424 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
425 .max_buf_write_size
= 0x0,
426 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
427 .num_erase_regions
= 3,
428 .erase_region_info
= {
429 ERASE_REGION(8, 8*KB
),
430 ERASE_REGION(2, 32*KB
),
431 ERASE_REGION(30, 64*KB
)
435 .mfr
= CFI_MFR_ATMEL
,
436 .id
= 0xC2, /* Atmel 49BV1614T */
439 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
440 .max_buf_write_size
= 0x0,
441 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
442 .num_erase_regions
= 3,
443 .erase_region_info
= {
444 ERASE_REGION(30, 64*KB
),
445 ERASE_REGION(2, 32*KB
),
446 ERASE_REGION(8, 8*KB
)
451 .id
= 0x225b, /* S29AL008D */
454 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
455 .max_buf_write_size
= 0x0,
456 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
457 .num_erase_regions
= 4,
458 .erase_region_info
= {
459 ERASE_REGION(1, 16*KB
),
460 ERASE_REGION(2, 8*KB
),
461 ERASE_REGION(1, 32*KB
),
462 ERASE_REGION(15, 64*KB
)
471 void cfi_fixup_non_cfi(struct flash_bank
*bank
)
474 struct cfi_flash_bank
*cfi_info
= bank
->driver_priv
;
475 struct non_cfi
*non_cfi
= non_cfi_flashes
;
477 if (cfi_info
->x16_as_x8
)
482 for (non_cfi
= non_cfi_flashes
; non_cfi
->mfr
; non_cfi
++) {
483 if ((cfi_info
->manufacturer
== non_cfi
->mfr
)
484 && (cfi_info
->device_id
== (non_cfi
->id
& mask
)))
488 /* only fixup jedec flashs found in table */
492 cfi_info
->not_cfi
= 1;
494 /* fill in defaults for non-critical data */
495 cfi_info
->vcc_min
= 0x0;
496 cfi_info
->vcc_max
= 0x0;
497 cfi_info
->vpp_min
= 0x0;
498 cfi_info
->vpp_max
= 0x0;
499 /* these are used for timeouts - use vales that should be long enough
500 for normal operation. */
501 cfi_info
->word_write_timeout_typ
= 0x0a;
502 cfi_info
->buf_write_timeout_typ
= 0x0d;
503 cfi_info
->block_erase_timeout_typ
= 0x0d;
504 cfi_info
->chip_erase_timeout_typ
= 0x10;
505 cfi_info
->word_write_timeout_max
= 0x0;
506 cfi_info
->buf_write_timeout_max
= 0x0;
507 cfi_info
->block_erase_timeout_max
= 0x0;
508 cfi_info
->chip_erase_timeout_max
= 0x0;
510 cfi_info
->qry
[0] = 'Q';
511 cfi_info
->qry
[1] = 'R';
512 cfi_info
->qry
[2] = 'Y';
514 cfi_info
->pri_id
= non_cfi
->pri_id
;
515 cfi_info
->pri_addr
= 0x0;
516 cfi_info
->alt_id
= 0x0;
517 cfi_info
->alt_addr
= 0x0;
518 cfi_info
->alt_ext
= NULL
;
520 cfi_info
->interface_desc
= non_cfi
->interface_desc
;
521 cfi_info
->max_buf_write_size
= non_cfi
->max_buf_write_size
;
522 cfi_info
->status_poll_mask
= non_cfi
->status_poll_mask
;
523 cfi_info
->num_erase_regions
= non_cfi
->num_erase_regions
;
524 size_t erase_region_info_size
= sizeof(*cfi_info
->erase_region_info
) *
525 cfi_info
->num_erase_regions
;
526 cfi_info
->erase_region_info
= malloc(erase_region_info_size
);
527 memcpy(cfi_info
->erase_region_info
,
528 non_cfi
->erase_region_info
, erase_region_info_size
);
529 cfi_info
->dev_size
= non_cfi
->dev_size
;
531 if (cfi_info
->pri_id
== 0x2) {
532 struct cfi_spansion_pri_ext
*pri_ext
= malloc(sizeof(struct cfi_spansion_pri_ext
));
534 pri_ext
->pri
[0] = 'P';
535 pri_ext
->pri
[1] = 'R';
536 pri_ext
->pri
[2] = 'I';
538 pri_ext
->major_version
= '1';
539 pri_ext
->minor_version
= '0';
541 pri_ext
->SiliconRevision
= 0x0;
542 pri_ext
->EraseSuspend
= 0x0;
543 pri_ext
->EraseSuspend
= 0x0;
544 pri_ext
->BlkProt
= 0x0;
545 pri_ext
->TmpBlkUnprotect
= 0x0;
546 pri_ext
->BlkProtUnprot
= 0x0;
547 pri_ext
->SimultaneousOps
= 0x0;
548 pri_ext
->BurstMode
= 0x0;
549 pri_ext
->PageMode
= 0x0;
550 pri_ext
->VppMin
= 0x0;
551 pri_ext
->VppMax
= 0x0;
552 pri_ext
->TopBottom
= 0x0;
554 pri_ext
->_unlock1
= 0x5555;
555 pri_ext
->_unlock2
= 0x2AAA;
556 pri_ext
->_reversed_geometry
= 0;
558 cfi_info
->pri_ext
= pri_ext
;
559 } else if ((cfi_info
->pri_id
== 0x1) || (cfi_info
->pri_id
== 0x3)) {
560 LOG_ERROR("BUG: non-CFI flashes using the Intel commandset are not yet supported");