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, see <http://www.gnu.org/licenses/>. *
19 ***************************************************************************/
30 #define MB (1024*1024)
31 #define ERASE_REGION(num, size) (((size/256) << 16) | (num-1))
33 /* non-CFI compatible flashes */
34 static const struct non_cfi non_cfi_flashes
[] = {
40 .interface_desc
= 0x0, /* x8 only device */
41 .max_buf_write_size
= 0x0,
42 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
43 .num_erase_regions
= 1,
44 .erase_region_info
= {
45 ERASE_REGION(16, 4*KB
)
53 .interface_desc
= 0x0, /* x8 only device */
54 .max_buf_write_size
= 0x0,
55 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
56 .num_erase_regions
= 1,
57 .erase_region_info
= {
58 ERASE_REGION(32, 4*KB
)
66 .interface_desc
= 0x0, /* x8 only device */
67 .max_buf_write_size
= 0x0,
68 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
69 .num_erase_regions
= 1,
70 .erase_region_info
= {
71 ERASE_REGION(64, 4*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 ERASE_REGION(128, 4*KB
)
88 .mfr
= CFI_MFR_AMD
, /* Spansion AM29LV040B */
92 .interface_desc
= 0x0, /* x8 only device */
93 .max_buf_write_size
= 0x0,
94 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
95 .num_erase_regions
= 1,
96 .erase_region_info
= {
97 ERASE_REGION(8, 64*KB
)
105 .interface_desc
= 0x2, /* x8 or x16 device */
106 .max_buf_write_size
= 0x0,
107 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
108 .num_erase_regions
= 1,
109 .erase_region_info
= {
110 ERASE_REGION(128, 4*KB
)
115 .id
= 0xd6, /* ST29F400BB */
118 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
119 .max_buf_write_size
= 0x0,
120 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
121 .num_erase_regions
= 4,
122 .erase_region_info
= {
123 ERASE_REGION(1, 16*KB
),
124 ERASE_REGION(2, 8*KB
),
125 ERASE_REGION(1, 32*KB
),
126 ERASE_REGION(7, 64*KB
)
131 .id
= 0xd5, /* ST29F400BT */
134 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
135 .max_buf_write_size
= 0x0,
136 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
137 .num_erase_regions
= 4,
138 .erase_region_info
= {
139 ERASE_REGION(7, 64*KB
),
140 ERASE_REGION(1, 32*KB
),
141 ERASE_REGION(2, 8*KB
),
142 ERASE_REGION(1, 16*KB
)
146 /* SST 39VF* do not support DQ5 status polling - this currently is
147 only supported by the host algorithm, not by the target code using
149 Only true for 8-bit and 32-bit wide memories. 16-bit wide memories
150 without DQ5 status polling are supported by the target code.
154 .id
= 0x2782, /* SST39xF160 */
157 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
158 .max_buf_write_size
= 0x0,
159 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ6_DQ7
,
160 .num_erase_regions
= 1,
161 .erase_region_info
= {
162 ERASE_REGION(512, 4*KB
)
167 .id
= 0x2783, /* SST39VF320 */
170 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
171 .max_buf_write_size
= 0x0,
172 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ6_DQ7
,
173 .num_erase_regions
= 1,
174 .erase_region_info
= {
175 ERASE_REGION(1024, 4*KB
)
180 .id
= 0x234b, /* SST39VF1601 */
183 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
184 .max_buf_write_size
= 0x0,
185 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ6_DQ7
,
186 .num_erase_regions
= 1,
187 .erase_region_info
= {
188 ERASE_REGION(512, 4*KB
)
193 .id
= 0x274b, /* SST39WF1601 */
196 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
197 .max_buf_write_size
= 0x0,
198 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ6_DQ7
,
199 .num_erase_regions
= 1,
200 .erase_region_info
= {
201 ERASE_REGION(512, 4*KB
)
206 .id
= 0x234a, /* SST39VF1602 */
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,
213 .erase_region_info
= {
214 ERASE_REGION(512, 4*KB
)
219 .id
= 0x235b, /* SST39VF3201 */
222 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
223 .max_buf_write_size
= 0x0,
224 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ6_DQ7
,
225 .num_erase_regions
= 1,
226 .erase_region_info
= {
227 ERASE_REGION(1024, 4*KB
)
232 .id
= 0x235a, /* SST39VF3202 */
235 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
236 .max_buf_write_size
= 0x0,
237 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ6_DQ7
,
238 .num_erase_regions
= 1,
239 .erase_region_info
= {
240 ERASE_REGION(1024, 4*KB
)
245 .id
= 0x236d, /* SST39VF6401B */
248 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
249 .max_buf_write_size
= 0x0,
250 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ6_DQ7
,
251 .num_erase_regions
= 1,
252 .erase_region_info
= {
253 ERASE_REGION(2048, 4*KB
)
258 .id
= 0x22ab, /* AM29F400BB */
261 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
262 .max_buf_write_size
= 0x0,
263 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
264 .num_erase_regions
= 4,
265 .erase_region_info
= {
266 ERASE_REGION(1, 16*KB
),
267 ERASE_REGION(2, 8*KB
),
268 ERASE_REGION(1, 32*KB
),
269 ERASE_REGION(7, 64*KB
)
274 .id
= 0x2223, /* AM29F400BT */
277 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
278 .max_buf_write_size
= 0x0,
279 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
280 .num_erase_regions
= 4,
281 .erase_region_info
= {
282 ERASE_REGION(7, 64*KB
),
283 ERASE_REGION(1, 32*KB
),
284 ERASE_REGION(2, 8*KB
),
285 ERASE_REGION(1, 16*KB
)
289 .mfr
= CFI_MFR_FUJITSU
,
290 .id
= 0x226b, /* AM29SL800DB */
293 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
294 .max_buf_write_size
= 0x0,
295 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
296 .num_erase_regions
= 4,
297 .erase_region_info
= {
298 ERASE_REGION(1, 16*KB
),
299 ERASE_REGION(2, 8*KB
),
300 ERASE_REGION(1, 32*KB
),
301 ERASE_REGION(15, 64*KB
)
305 .mfr
= CFI_MFR_FUJITSU
,
306 .id
= 0x22ea, /* MBM29SL800TE */
309 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
310 .max_buf_write_size
= 0x0,
311 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
312 .num_erase_regions
= 4,
313 .erase_region_info
= {
314 ERASE_REGION(15, 64*KB
),
315 ERASE_REGION(1, 32*KB
),
316 ERASE_REGION(2, 8*KB
),
317 ERASE_REGION(1, 16*KB
)
321 .mfr
= CFI_MFR_FUJITSU
,
322 .id
= 0xba, /* 29LV400BC */
325 .interface_desc
= 0x1, /* x8 or x16 device w/ nBYTE */
326 .max_buf_write_size
= 0x00,
327 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
328 .num_erase_regions
= 4,
329 .erase_region_info
= {
330 ERASE_REGION(1, 16*KB
),
331 ERASE_REGION(2, 8*KB
),
332 ERASE_REGION(1, 32*KB
),
333 ERASE_REGION(7, 64*KB
)
338 .id
= 0xb31a, /* A29L800A */
341 .interface_desc
= 0x2,
342 .max_buf_write_size
= 0x0,
343 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
344 .num_erase_regions
= 4,
345 .erase_region_info
= {
346 ERASE_REGION(1, 16*KB
),
347 ERASE_REGION(2, 8*KB
),
348 ERASE_REGION(1, 32*KB
),
349 ERASE_REGION(15, 64*KB
)
354 .id
= 0x225b, /* MX29LV800B */
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
= 4,
361 .erase_region_info
= {
362 ERASE_REGION(1, 16*KB
),
363 ERASE_REGION(2, 8*KB
),
364 ERASE_REGION(1, 32*KB
),
365 ERASE_REGION(15, 64*KB
)
371 .id
= 0x2249, /* MX29LV160AB: 2MB */
374 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
375 .max_buf_write_size
= 0x0,
376 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
377 .num_erase_regions
= 4,
378 .erase_region_info
= {
379 ERASE_REGION(1, 16*KB
),
380 ERASE_REGION(2, 8*KB
),
381 ERASE_REGION(1, 32*KB
),
382 ERASE_REGION(31, 64*KB
)
387 .id
= 0x22C4, /* MX29LV160AT: 2MB */
390 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
391 .max_buf_write_size
= 0x0,
392 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
393 .num_erase_regions
= 4,
394 .erase_region_info
= {
395 ERASE_REGION(31, 64*KB
),
396 ERASE_REGION(1, 32*KB
),
397 ERASE_REGION(2, 8*KB
),
398 ERASE_REGION(1, 16*KB
)
403 .id
= 0x225b, /* EN29LV800BB */
406 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
407 .max_buf_write_size
= 0x0,
408 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
409 .num_erase_regions
= 4,
410 .erase_region_info
= {
411 ERASE_REGION(1, 16*KB
),
412 ERASE_REGION(2, 8*KB
),
413 ERASE_REGION(1, 32*KB
),
414 ERASE_REGION(15, 64*KB
)
418 .mfr
= CFI_MFR_ATMEL
,
419 .id
= 0x00c0, /* Atmel 49BV1614 */
422 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
423 .max_buf_write_size
= 0x0,
424 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
425 .num_erase_regions
= 3,
426 .erase_region_info
= {
427 ERASE_REGION(8, 8*KB
),
428 ERASE_REGION(2, 32*KB
),
429 ERASE_REGION(30, 64*KB
)
433 .mfr
= CFI_MFR_ATMEL
,
434 .id
= 0xC2, /* Atmel 49BV1614T */
437 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
438 .max_buf_write_size
= 0x0,
439 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
440 .num_erase_regions
= 3,
441 .erase_region_info
= {
442 ERASE_REGION(30, 64*KB
),
443 ERASE_REGION(2, 32*KB
),
444 ERASE_REGION(8, 8*KB
)
449 .id
= 0x225b, /* S29AL008D */
452 .interface_desc
= 0x2, /* x8 or x16 device with nBYTE */
453 .max_buf_write_size
= 0x0,
454 .status_poll_mask
= CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7
,
455 .num_erase_regions
= 4,
456 .erase_region_info
= {
457 ERASE_REGION(1, 16*KB
),
458 ERASE_REGION(2, 8*KB
),
459 ERASE_REGION(1, 32*KB
),
460 ERASE_REGION(15, 64*KB
)
469 void cfi_fixup_non_cfi(struct flash_bank
*bank
)
472 struct cfi_flash_bank
*cfi_info
= bank
->driver_priv
;
473 const struct non_cfi
*non_cfi
= non_cfi_flashes
;
475 if (cfi_info
->x16_as_x8
)
480 for (non_cfi
= non_cfi_flashes
; non_cfi
->mfr
; non_cfi
++) {
481 if ((cfi_info
->manufacturer
== non_cfi
->mfr
)
482 && (cfi_info
->device_id
== (non_cfi
->id
& mask
)))
486 /* only fixup jedec flashs found in table */
490 cfi_info
->not_cfi
= 1;
492 /* fill in defaults for non-critical data */
493 cfi_info
->vcc_min
= 0x0;
494 cfi_info
->vcc_max
= 0x0;
495 cfi_info
->vpp_min
= 0x0;
496 cfi_info
->vpp_max
= 0x0;
497 /* these are used for timeouts - use vales that should be long enough
498 for normal operation. */
499 cfi_info
->word_write_timeout_typ
= 0x0a;
500 cfi_info
->buf_write_timeout_typ
= 0x0d;
501 cfi_info
->block_erase_timeout_typ
= 0x0d;
502 cfi_info
->chip_erase_timeout_typ
= 0x10;
503 cfi_info
->word_write_timeout_max
= 0x0;
504 cfi_info
->buf_write_timeout_max
= 0x0;
505 cfi_info
->block_erase_timeout_max
= 0x0;
506 cfi_info
->chip_erase_timeout_max
= 0x0;
508 cfi_info
->qry
[0] = 'Q';
509 cfi_info
->qry
[1] = 'R';
510 cfi_info
->qry
[2] = 'Y';
512 cfi_info
->pri_id
= non_cfi
->pri_id
;
513 cfi_info
->pri_addr
= 0x0;
514 cfi_info
->alt_id
= 0x0;
515 cfi_info
->alt_addr
= 0x0;
516 cfi_info
->alt_ext
= NULL
;
518 cfi_info
->interface_desc
= non_cfi
->interface_desc
;
519 cfi_info
->max_buf_write_size
= non_cfi
->max_buf_write_size
;
520 cfi_info
->status_poll_mask
= non_cfi
->status_poll_mask
;
521 cfi_info
->num_erase_regions
= non_cfi
->num_erase_regions
;
522 size_t erase_region_info_size
= sizeof(*cfi_info
->erase_region_info
) *
523 cfi_info
->num_erase_regions
;
524 cfi_info
->erase_region_info
= malloc(erase_region_info_size
);
525 memcpy(cfi_info
->erase_region_info
,
526 non_cfi
->erase_region_info
, erase_region_info_size
);
527 cfi_info
->dev_size
= non_cfi
->dev_size
;
529 if (cfi_info
->pri_id
== 0x2) {
530 struct cfi_spansion_pri_ext
*pri_ext
= malloc(sizeof(struct cfi_spansion_pri_ext
));
532 pri_ext
->pri
[0] = 'P';
533 pri_ext
->pri
[1] = 'R';
534 pri_ext
->pri
[2] = 'I';
536 pri_ext
->major_version
= '1';
537 pri_ext
->minor_version
= '0';
539 pri_ext
->SiliconRevision
= 0x0;
540 pri_ext
->EraseSuspend
= 0x0;
541 pri_ext
->BlkProt
= 0x0;
542 pri_ext
->TmpBlkUnprotect
= 0x0;
543 pri_ext
->BlkProtUnprot
= 0x0;
544 pri_ext
->SimultaneousOps
= 0x0;
545 pri_ext
->BurstMode
= 0x0;
546 pri_ext
->PageMode
= 0x0;
547 pri_ext
->VppMin
= 0x0;
548 pri_ext
->VppMax
= 0x0;
549 pri_ext
->TopBottom
= 0x0;
551 pri_ext
->_unlock1
= 0x5555;
552 pri_ext
->_unlock2
= 0x2AAA;
553 pri_ext
->_reversed_geometry
= 0;
555 cfi_info
->pri_ext
= pri_ext
;
556 } else if ((cfi_info
->pri_id
== 0x1) || (cfi_info
->pri_id
== 0x3)) {
557 LOG_ERROR("BUG: non-CFI flashes using the Intel commandset are not yet supported");