add support for spansion flash on mindspeed c300 eval board
[openocd.git] / src / flash / nor / non_cfi.c
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
26 #include "imp.h"
27 #include "cfi.h"
28 #include "non_cfi.h"
29
30
31 #define KB 1024
32 #define MB (1024*1024)
33 #define ERASE_REGION(num, size) (((size/256) << 16) | (num-1))
34
35 /* non-CFI compatible flashes */
36 static struct non_cfi non_cfi_flashes[] = {
37 {
38 .mfr = CFI_MFR_SST,
39 .id = 0xd4,
40 .pri_id = 0x02,
41 .dev_size = 64*KB,
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 {
48 ERASE_REGION(16, 4*KB)
49 }
50 },
51 {
52 .mfr = CFI_MFR_SST,
53 .id = 0xd5,
54 .pri_id = 0x02,
55 .dev_size = 128*KB,
56 .interface_desc = 0x0, /* x8 only device */
57 .max_buf_write_size = 0x0,
58 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
59 .num_erase_regions = 1,
60 .erase_region_info =
61 {
62 ERASE_REGION(32, 4*KB)
63 }
64 },
65 {
66 .mfr = CFI_MFR_SST,
67 .id = 0xd6,
68 .pri_id = 0x02,
69 .dev_size = 256*KB,
70 .interface_desc = 0x0, /* x8 only device */
71 .max_buf_write_size = 0x0,
72 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
73 .num_erase_regions = 1,
74 .erase_region_info =
75 {
76 ERASE_REGION(64, 4*KB)
77 }
78 },
79 {
80 .mfr = CFI_MFR_SST,
81 .id = 0xd7,
82 .pri_id = 0x02,
83 .dev_size = 512*KB,
84 .interface_desc = 0x0, /* x8 only device */
85 .max_buf_write_size = 0x0,
86 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
87 .num_erase_regions = 1,
88 .erase_region_info =
89 {
90 ERASE_REGION(128, 4*KB)
91 }
92 },
93 {
94 .mfr = CFI_MFR_AMD, /* Spansion AM29LV040B */
95 .id = 0x4f,
96 .pri_id = 0x02,
97 .dev_size = 512*KB,
98 .interface_desc = 0x0, /* x8 only device */
99 .max_buf_write_size = 0x0,
100 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
101 .num_erase_regions = 1,
102 .erase_region_info =
103 {
104 ERASE_REGION(8, 64*KB)
105 }
106 },
107 {
108 .mfr = CFI_MFR_SST,
109 .id = 0x2780,
110 .pri_id = 0x02,
111 .dev_size = 512*KB,
112 .interface_desc = 0x2, /* x8 or x16 device */
113 .max_buf_write_size = 0x0,
114 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
115 .num_erase_regions = 1,
116 .erase_region_info =
117 {
118 ERASE_REGION(128, 4*KB)
119 }
120 },
121 {
122 .mfr = CFI_MFR_ST,
123 .id = 0xd6, /* ST29F400BB */
124 .pri_id = 0x02,
125 .dev_size = 512*KB,
126 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
127 .max_buf_write_size = 0x0,
128 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
129 .num_erase_regions = 4,
130 .erase_region_info =
131 {
132 ERASE_REGION(1, 16*KB),
133 ERASE_REGION(2, 8*KB),
134 ERASE_REGION(1, 32*KB),
135 ERASE_REGION(7, 64*KB)
136 }
137 },
138 {
139 .mfr = CFI_MFR_ST,
140 .id = 0xd5, /* ST29F400BT */
141 .pri_id = 0x02,
142 .dev_size = 512*KB,
143 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
144 .max_buf_write_size = 0x0,
145 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
146 .num_erase_regions = 4,
147 .erase_region_info =
148 {
149 ERASE_REGION(7, 64*KB),
150 ERASE_REGION(1, 32*KB),
151 ERASE_REGION(2, 8*KB),
152 ERASE_REGION(1, 16*KB)
153 }
154 },
155
156 /* SST 39VF* do not support DQ5 status polling - this currently is
157 only supported by the host algorithm, not by the target code using
158 the work area.
159 Only true for 8-bit and 32-bit wide memories. 16-bit wide memories
160 without DQ5 status polling are supported by the target code.
161 */
162 {
163 .mfr = CFI_MFR_SST,
164 .id = 0x2782, /* SST39xF160 */
165 .pri_id = 0x02,
166 .dev_size = 2*MB,
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,
171 .erase_region_info =
172 {
173 ERASE_REGION(512, 4*KB)
174 }
175 },
176 {
177 .mfr = CFI_MFR_SST,
178 .id = 0x2783, /* SST39VF320 */
179 .pri_id = 0x02,
180 .dev_size = 4*MB,
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,
185 .erase_region_info =
186 {
187 ERASE_REGION(1024, 4*KB)
188 }
189 },
190 {
191 .mfr = CFI_MFR_SST,
192 .id = 0x234b, /* SST39VF1601 */
193 .pri_id = 0x02,
194 .dev_size = 2*MB,
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,
199 .erase_region_info =
200 {
201 ERASE_REGION(512, 4*KB)
202 }
203 },
204 {
205 .mfr = CFI_MFR_SST,
206 .id = 0x234a, /* SST39VF1602 */
207 .pri_id = 0x02,
208 .dev_size = 2*MB,
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 {
215 ERASE_REGION(512, 4*KB)
216 }
217 },
218 {
219 .mfr = CFI_MFR_SST,
220 .id = 0x235b, /* SST39VF3201 */
221 .pri_id = 0x02,
222 .dev_size = 4*MB,
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,
227 .erase_region_info =
228 {
229 ERASE_REGION(1024, 4*KB)
230 }
231 },
232 {
233 .mfr = CFI_MFR_SST,
234 .id = 0x235a, /* SST39VF3202 */
235 .pri_id = 0x02,
236 .dev_size = 4*MB,
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 {
243 ERASE_REGION(1024, 4*KB)
244 }
245 },
246 {
247 .mfr = CFI_MFR_SST,
248 .id = 0x236d, /* SST39VF6401B */
249 .pri_id = 0x02,
250 .dev_size = 8*MB,
251 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
252 .max_buf_write_size = 0x0,
253 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7,
254 .num_erase_regions = 1,
255 .erase_region_info =
256 {
257 ERASE_REGION(2048, 4*KB)
258 }
259 },
260 {
261 .mfr = CFI_MFR_AMD,
262 .id = 0x22ab, /* AM29F400BB */
263 .pri_id = 0x02,
264 .dev_size = 512*KB,
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(7, 64*KB)
275 }
276 },
277 {
278 .mfr = CFI_MFR_AMD,
279 .id = 0x2223, /* AM29F400BT */
280 .pri_id = 0x02,
281 .dev_size = 512*KB,
282 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
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(7, 64*KB),
289 ERASE_REGION(1, 32*KB),
290 ERASE_REGION(2, 8*KB),
291 ERASE_REGION(1, 16*KB)
292 }
293 },
294 {
295 .mfr = CFI_MFR_FUJITSU,
296 .id = 0x226b, /* AM29SL800DB */
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_FUJITSU,
313 .id = 0x22ea, /* MBM29SL800TE */
314 .pri_id = 0x02,
315 .dev_size = 1*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(15, 64*KB),
323 ERASE_REGION(1, 32*KB),
324 ERASE_REGION(2, 8*KB),
325 ERASE_REGION(1, 16*KB)
326 }
327 },
328 {
329 .mfr = CFI_MFR_FUJITSU,
330 .id = 0xba, /* 29LV400BC */
331 .pri_id = 0x02,
332 .dev_size = 512*KB,
333 .interface_desc = 0x1, /* x8 or x16 device w/ nBYTE */
334 .max_buf_write_size = 0x00,
335 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
336 .num_erase_regions = 4,
337 .erase_region_info =
338 {
339 ERASE_REGION(1, 16*KB),
340 ERASE_REGION(2, 8*KB),
341 ERASE_REGION(1, 32*KB),
342 ERASE_REGION(7, 64*KB)
343 }
344 },
345 {
346 .mfr = CFI_MFR_AMIC,
347 .id = 0xb31a, /* A29L800A */
348 .pri_id = 0x02,
349 .dev_size = 1*MB,
350 .interface_desc = 0x2,
351 .max_buf_write_size = 0x0,
352 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
353 .num_erase_regions = 4,
354 .erase_region_info =
355 {
356 ERASE_REGION(1, 16*KB),
357 ERASE_REGION(2, 8*KB),
358 ERASE_REGION(1, 32*KB),
359 ERASE_REGION(15, 64*KB)
360 }
361 },
362 {
363 .mfr = CFI_MFR_MX,
364 .id = 0x225b, /* MX29LV800B */
365 .pri_id = 0x02,
366 .dev_size = 1*MB,
367 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
368 .max_buf_write_size = 0x0,
369 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
370 .num_erase_regions = 4,
371 .erase_region_info =
372 {
373 ERASE_REGION(1, 16*KB),
374 ERASE_REGION(2, 8*KB),
375 ERASE_REGION(1, 32*KB),
376 ERASE_REGION(15, 64*KB)
377 }
378 },
379
380 {
381 .mfr = CFI_MFR_MX,
382 .id = 0x2249, /* MX29LV160AB: 2MB */
383 .pri_id = 0x02,
384 .dev_size = 2*MB,
385 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
386 .max_buf_write_size = 0x0,
387 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
388 .num_erase_regions = 4,
389 .erase_region_info =
390 {
391 ERASE_REGION(1, 16*KB),
392 ERASE_REGION(2, 8*KB),
393 ERASE_REGION(1, 32*KB),
394 ERASE_REGION(31, 64*KB)
395 }
396 },
397 {
398 .mfr = CFI_MFR_MX,
399 .id = 0x22C4, /* MX29LV160AT: 2MB */
400 .pri_id = 0x02,
401 .dev_size = 2*MB,
402 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
403 .max_buf_write_size = 0x0,
404 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
405 .num_erase_regions = 4,
406 .erase_region_info =
407 {
408 ERASE_REGION(31, 64*KB),
409 ERASE_REGION(1, 32*KB),
410 ERASE_REGION(2, 8*KB),
411 ERASE_REGION(1, 16*KB)
412 }
413 },
414 {
415 .mfr = CFI_MFR_ATMEL,
416 .id = 0x00c0, /* Atmel 49BV1614 */
417 .pri_id = 0x02,
418 .dev_size = 2*MB,
419 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
420 .max_buf_write_size = 0x0,
421 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
422 .num_erase_regions = 3,
423 .erase_region_info =
424 {
425 ERASE_REGION(8, 8*KB),
426 ERASE_REGION(2, 32*KB),
427 ERASE_REGION(30, 64*KB)
428 }
429 },
430 {
431 .mfr = CFI_MFR_ATMEL,
432 .id = 0xC2, /* Atmel 49BV1614T */
433 .pri_id = 0x02,
434 .dev_size = 2*MB,
435 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
436 .max_buf_write_size = 0x0,
437 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
438 .num_erase_regions = 3,
439 .erase_region_info =
440 {
441 ERASE_REGION(30, 64*KB),
442 ERASE_REGION(2, 32*KB),
443 ERASE_REGION(8, 8*KB)
444 }
445 },
446 {
447 .mfr = CFI_MFR_AMD,
448 .id = 0x225b, /* S29AL008D */
449 .pri_id = 0x02,
450 .dev_size = 1*MB,
451 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
452 .max_buf_write_size = 0x0,
453 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
454 .num_erase_regions = 4,
455 .erase_region_info =
456 {
457 ERASE_REGION(1, 16*KB),
458 ERASE_REGION(2, 8*KB),
459 ERASE_REGION(1, 32*KB),
460 ERASE_REGION(15, 64*KB)
461 }
462 },
463 {
464 .mfr = 0,
465 .id = 0,
466 }
467 };
468
469 void cfi_fixup_non_cfi(struct flash_bank *bank)
470 {
471 unsigned int mask;
472 struct cfi_flash_bank *cfi_info = bank->driver_priv;
473 struct non_cfi *non_cfi = non_cfi_flashes;
474
475 if(cfi_info->x16_as_x8)
476 mask = 0xFF;
477 else
478 mask = 0xFFFF;
479
480 for (non_cfi = non_cfi_flashes; non_cfi->mfr; non_cfi++)
481 {
482 if ((cfi_info->manufacturer == non_cfi->mfr)
483 && (cfi_info->device_id == (non_cfi->id & mask)))
484 {
485 break;
486 }
487 }
488
489 /* only fixup jedec flashs found in table */
490 if (!non_cfi->mfr)
491 return;
492
493 cfi_info->not_cfi = 1;
494
495 /* fill in defaults for non-critical data */
496 cfi_info->vcc_min = 0x0;
497 cfi_info->vcc_max = 0x0;
498 cfi_info->vpp_min = 0x0;
499 cfi_info->vpp_max = 0x0;
500 /* these are used for timeouts - use vales that should be long enough
501 for normal operation. */
502 cfi_info->word_write_timeout_typ = 0x0a;
503 cfi_info->buf_write_timeout_typ = 0x0d;
504 cfi_info->block_erase_timeout_typ = 0x0d;
505 cfi_info->chip_erase_timeout_typ = 0x10;
506 cfi_info->word_write_timeout_max = 0x0;
507 cfi_info->buf_write_timeout_max = 0x0;
508 cfi_info->block_erase_timeout_max = 0x0;
509 cfi_info->chip_erase_timeout_max = 0x0;
510
511 cfi_info->qry[0] = 'Q';
512 cfi_info->qry[1] = 'R';
513 cfi_info->qry[2] = 'Y';
514
515 cfi_info->pri_id = non_cfi->pri_id;
516 cfi_info->pri_addr = 0x0;
517 cfi_info->alt_id = 0x0;
518 cfi_info->alt_addr = 0x0;
519 cfi_info->alt_ext = NULL;
520
521 cfi_info->interface_desc = non_cfi->interface_desc;
522 cfi_info->max_buf_write_size = non_cfi->max_buf_write_size;
523 cfi_info->status_poll_mask = non_cfi->status_poll_mask;
524 cfi_info->num_erase_regions = non_cfi->num_erase_regions;
525 size_t erase_region_info_size = sizeof(*cfi_info->erase_region_info) *
526 cfi_info->num_erase_regions;
527 cfi_info->erase_region_info = malloc(erase_region_info_size);
528 memcpy(cfi_info->erase_region_info,
529 non_cfi->erase_region_info, erase_region_info_size);
530 cfi_info->dev_size = non_cfi->dev_size;
531
532 if (cfi_info->pri_id == 0x2)
533 {
534 struct cfi_spansion_pri_ext *pri_ext = malloc(sizeof(struct cfi_spansion_pri_ext));
535
536 pri_ext->pri[0] = 'P';
537 pri_ext->pri[1] = 'R';
538 pri_ext->pri[2] = 'I';
539
540 pri_ext->major_version = '1';
541 pri_ext->minor_version = '0';
542
543 pri_ext->SiliconRevision = 0x0;
544 pri_ext->EraseSuspend = 0x0;
545 pri_ext->EraseSuspend = 0x0;
546 pri_ext->BlkProt = 0x0;
547 pri_ext->TmpBlkUnprotect = 0x0;
548 pri_ext->BlkProtUnprot = 0x0;
549 pri_ext->SimultaneousOps = 0x0;
550 pri_ext->BurstMode = 0x0;
551 pri_ext->PageMode = 0x0;
552 pri_ext->VppMin = 0x0;
553 pri_ext->VppMax = 0x0;
554 pri_ext->TopBottom = 0x0;
555
556 pri_ext->_unlock1 = 0x5555;
557 pri_ext->_unlock2 = 0x2AAA;
558 pri_ext->_reversed_geometry = 0;
559
560 cfi_info->pri_ext = pri_ext;
561 } else if ((cfi_info->pri_id == 0x1) || (cfi_info->pri_id == 0x3))
562 {
563 LOG_ERROR("BUG: non-CFI flashes using the Intel commandset are not yet supported");
564 exit(-1);
565 }
566 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)