]> git.sur5r.net Git - openocd/blob - src/flash/nor/non_cfi.c
Fujitsu MBM29SL800TE flash support
[openocd] / 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_SST,
95                 .id = 0x2780,
96                 .pri_id = 0x02,
97                 .dev_size = 512*KB,
98                 .interface_desc = 0x2,          /* x8 or x16 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(128, 4*KB)
105                 }
106         },
107         {
108                 .mfr = CFI_MFR_ST,
109                 .id = 0xd6,                                     /* ST29F400BB */
110                 .pri_id = 0x02,
111                 .dev_size = 512*KB,
112                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
113                 .max_buf_write_size = 0x0,
114                 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
115                 .num_erase_regions = 4,
116                 .erase_region_info =
117                 {
118                         ERASE_REGION(1, 16*KB),
119                         ERASE_REGION(2,  8*KB),
120                         ERASE_REGION(1, 32*KB),
121                         ERASE_REGION(7, 64*KB)
122                 }
123         },
124         {
125                 .mfr = CFI_MFR_ST,
126                 .id = 0xd5,                                     /* ST29F400BT */
127                 .pri_id = 0x02,
128                 .dev_size = 512*KB,
129                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
130                 .max_buf_write_size = 0x0,
131                 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
132                 .num_erase_regions = 4,
133                 .erase_region_info =
134                 {
135                         ERASE_REGION(7, 64*KB),
136                         ERASE_REGION(1, 32*KB),
137                         ERASE_REGION(2,  8*KB),
138                         ERASE_REGION(1, 16*KB)
139                 }
140         },
141
142         /* SST 39VF* do not support DQ5 status polling - this currently is
143            only supported by the host algorithm, not by the target code using
144            the work area.
145            Only true for 8-bit and 32-bit wide memories. 16-bit wide memories
146            without DQ5 status polling are supported by the target code.
147         */
148         {
149                 .mfr = CFI_MFR_SST,
150                 .id = 0x2782,                           /* SST39xF160 */
151                 .pri_id = 0x02,
152                 .dev_size = 2*MB,
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,
157                 .erase_region_info =
158                 {
159                         ERASE_REGION(512, 4*KB)
160                 }
161         },
162         {
163                 .mfr = CFI_MFR_SST,
164                 .id = 0x2783,                           /* SST39VF320 */
165                 .pri_id = 0x02,
166                 .dev_size = 4*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(1024, 4*KB)
174                 }
175         },
176         {
177                 .mfr = CFI_MFR_SST,
178                 .id = 0x234b,                           /* SST39VF1601 */
179                 .pri_id = 0x02,
180                 .dev_size = 2*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(512, 4*KB)
188                 }
189         },
190         {
191                 .mfr = CFI_MFR_SST,
192                 .id = 0x234a,                           /* SST39VF1602 */
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 = 0x235b,                           /* SST39VF3201 */
207                 .pri_id = 0x02,
208                 .dev_size = 4*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(1024, 4*KB)
216                 }
217         },
218         {
219                 .mfr = CFI_MFR_SST,
220                 .id = 0x235a,                           /* SST39VF3202 */
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_AMD,
234                 .id = 0x22ab,                           /* AM29F400BB */
235                 .pri_id = 0x02,
236                 .dev_size = 512*KB,
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,
241                 .erase_region_info =
242                 {
243                         ERASE_REGION(1, 16*KB),
244                         ERASE_REGION(2,  8*KB),
245                         ERASE_REGION(1, 32*KB),
246                         ERASE_REGION(7, 64*KB)
247                 }
248         },
249         {
250                 .mfr = CFI_MFR_AMD,
251                 .id = 0x2223,                           /* AM29F400BT */
252                 .pri_id = 0x02,
253                 .dev_size = 512*KB,
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,
258                 .erase_region_info =
259                 {
260                         ERASE_REGION(7, 64*KB),
261                         ERASE_REGION(1, 32*KB),
262                         ERASE_REGION(2,  8*KB),
263                         ERASE_REGION(1, 16*KB)
264                 }
265         },
266         {
267                 .mfr = CFI_MFR_FUJITSU,
268                 .id = 0x226b,                           /* AM29SL800DB */
269                 .pri_id = 0x02,
270                 .dev_size = 1*MB,
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,
275                 .erase_region_info =
276                 {
277                         ERASE_REGION(1, 16*KB),
278                         ERASE_REGION(2,  8*KB),
279                         ERASE_REGION(1, 32*KB),
280                         ERASE_REGION(15, 64*KB)
281                 }
282         },
283    {
284                 .mfr = CFI_MFR_FUJITSU,
285                 .id = 0x22ea,                           /* MBM29SL800TE */
286                 .pri_id = 0x02,
287                 .dev_size = 1*MB,
288                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
289                 .max_buf_write_size = 0x0,
290                 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
291                 .num_erase_regions = 4,
292                 .erase_region_info =
293                 {
294                         ERASE_REGION(15, 64*KB),
295                         ERASE_REGION(1,  32*KB),
296                         ERASE_REGION(2,  8*KB),
297                         ERASE_REGION(1,  16*KB)
298                 }
299         },
300         {
301                 .mfr = CFI_MFR_FUJITSU,
302                 .id = 0xba,                             /* 29LV400BC */
303                 .pri_id = 0x02,
304                 .dev_size = 512*KB,
305                 .interface_desc = 0x1,          /* x8 or x16 device w/ nBYTE */
306                 .max_buf_write_size = 0x00,
307                 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
308                 .num_erase_regions = 4,
309                 .erase_region_info =
310                 {
311                         ERASE_REGION(1, 16*KB),
312                         ERASE_REGION(2,  8*KB),
313                         ERASE_REGION(1, 32*KB),
314                         ERASE_REGION(7, 64*KB)
315                 }
316         },
317         {
318                 .mfr = CFI_MFR_AMIC,
319                 .id = 0xb31a,                           /* A29L800A */
320                 .pri_id = 0x02,
321                 .dev_size = 1*MB,
322                 .interface_desc = 0x2,
323                 .max_buf_write_size = 0x0,
324                 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
325                 .num_erase_regions = 4,
326                 .erase_region_info =
327                 {
328                         ERASE_REGION(1, 16*KB),
329                         ERASE_REGION(2,  8*KB),
330                         ERASE_REGION(1, 32*KB),
331                         ERASE_REGION(15, 64*KB)
332                 }
333         },
334         {
335                 .mfr = CFI_MFR_MX,
336                 .id = 0x225b,                           /* MX29LV800B */
337                 .pri_id = 0x02,
338                 .dev_size = 1*MB,
339                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
340                 .max_buf_write_size = 0x0,
341                 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
342                 .num_erase_regions = 4,
343                 .erase_region_info =
344                 {
345                         ERASE_REGION(1, 16*KB),
346                         ERASE_REGION(2, 8*KB),
347                         ERASE_REGION(1, 32*KB),
348                         ERASE_REGION(15, 64*KB)
349                 }
350         },
351
352         {
353                 .mfr = CFI_MFR_MX,
354                 .id = 0x2249,                           /* MX29LV160AB: 2MB */
355                 .pri_id = 0x02,
356                 .dev_size = 2*MB,
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                 {
363                         ERASE_REGION(1, 16*KB),
364                         ERASE_REGION(2, 8*KB),
365                         ERASE_REGION(1, 32*KB),
366                         ERASE_REGION(31, 64*KB)
367                 }
368         },
369         {
370                 .mfr = CFI_MFR_MX,
371                 .id = 0x22C4,                           /* MX29LV160AT: 2MB */
372                 .pri_id = 0x02,
373                 .dev_size = 2*MB,
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                 {
380                         ERASE_REGION(31, 64*KB),
381                         ERASE_REGION(1, 32*KB),
382                         ERASE_REGION(2, 8*KB),
383                         ERASE_REGION(1, 16*KB)
384                 }
385         },
386         {
387                 .mfr = CFI_MFR_ATMEL,
388                 .id = 0x00c0,                           /* Atmel 49BV1614 */
389                 .pri_id = 0x02,
390                 .dev_size = 2*MB,
391                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
392                 .max_buf_write_size = 0x0,
393                 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
394                 .num_erase_regions = 3,
395                 .erase_region_info =
396                 {
397                         ERASE_REGION(8,  8*KB),
398                         ERASE_REGION(2, 32*KB),
399                         ERASE_REGION(30, 64*KB)
400                 }
401         },
402         {
403                 .mfr = CFI_MFR_ATMEL,
404                 .id = 0xC2,                                     /* Atmel 49BV1614T */
405                 .pri_id = 0x02,
406                 .dev_size = 2*MB,
407                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
408                 .max_buf_write_size = 0x0,
409                 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
410                 .num_erase_regions = 3,
411                 .erase_region_info =
412                 {
413                         ERASE_REGION(30, 64*KB),
414                         ERASE_REGION(2, 32*KB),
415                         ERASE_REGION(8,  8*KB)
416                 }
417         },
418         {
419                 .mfr = CFI_MFR_AMD,
420                 .id = 0x225b,                           /* S29AL008D */
421                 .pri_id = 0x02,
422                 .dev_size = 1*MB,
423                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
424                 .max_buf_write_size = 0x0,
425                 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
426                 .num_erase_regions = 4,
427                 .erase_region_info =
428                 {
429                         ERASE_REGION(1, 16*KB),
430                         ERASE_REGION(2, 8*KB),
431                         ERASE_REGION(1, 32*KB),
432                         ERASE_REGION(15, 64*KB)
433                 }
434         },
435         {
436                 .mfr = 0,
437                 .id = 0,
438         }
439 };
440
441 void cfi_fixup_non_cfi(struct flash_bank *bank)
442 {
443         struct cfi_flash_bank *cfi_info = bank->driver_priv;
444         struct non_cfi *non_cfi = non_cfi_flashes;
445
446         for (non_cfi = non_cfi_flashes; non_cfi->mfr; non_cfi++)
447         {
448                 if ((cfi_info->manufacturer == non_cfi->mfr)
449                         && (cfi_info->device_id == non_cfi->id))
450                 {
451                         break;
452                 }
453         }
454
455         /* only fixup jedec flashs found in table */
456         if (!non_cfi->mfr)
457                 return;
458
459         cfi_info->not_cfi = 1;
460
461         /* fill in defaults for non-critical data */
462         cfi_info->vcc_min = 0x0;
463         cfi_info->vcc_max = 0x0;
464         cfi_info->vpp_min = 0x0;
465         cfi_info->vpp_max = 0x0;
466         cfi_info->word_write_timeout_typ = 0x0;
467         cfi_info->buf_write_timeout_typ = 0x0;
468         cfi_info->block_erase_timeout_typ = 0x0;
469         cfi_info->chip_erase_timeout_typ = 0x0;
470         cfi_info->word_write_timeout_max = 0x0;
471         cfi_info->buf_write_timeout_max = 0x0;
472         cfi_info->block_erase_timeout_max = 0x0;
473         cfi_info->chip_erase_timeout_max = 0x0;
474
475         cfi_info->qry[0] = 'Q';
476         cfi_info->qry[1] = 'R';
477         cfi_info->qry[2] = 'Y';
478
479         cfi_info->pri_id = non_cfi->pri_id;
480         cfi_info->pri_addr = 0x0;
481         cfi_info->alt_id = 0x0;
482         cfi_info->alt_addr = 0x0;
483         cfi_info->alt_ext = NULL;
484
485         cfi_info->interface_desc = non_cfi->interface_desc;
486         cfi_info->max_buf_write_size = non_cfi->max_buf_write_size;
487         cfi_info->status_poll_mask = non_cfi->status_poll_mask;
488         cfi_info->num_erase_regions = non_cfi->num_erase_regions;
489         cfi_info->erase_region_info = non_cfi->erase_region_info;
490         cfi_info->dev_size = non_cfi->dev_size;
491
492         if (cfi_info->pri_id == 0x2)
493         {
494                 struct cfi_spansion_pri_ext *pri_ext = malloc(sizeof(struct cfi_spansion_pri_ext));
495
496                 pri_ext->pri[0] = 'P';
497                 pri_ext->pri[1] = 'R';
498                 pri_ext->pri[2] = 'I';
499
500                 pri_ext->major_version = '1';
501                 pri_ext->minor_version = '0';
502
503                 pri_ext->SiliconRevision = 0x0;
504                 pri_ext->EraseSuspend = 0x0;
505                 pri_ext->EraseSuspend = 0x0;
506                 pri_ext->BlkProt = 0x0;
507                 pri_ext->TmpBlkUnprotect = 0x0;
508                 pri_ext->BlkProtUnprot = 0x0;
509                 pri_ext->SimultaneousOps = 0x0;
510                 pri_ext->BurstMode = 0x0;
511                 pri_ext->PageMode = 0x0;
512                 pri_ext->VppMin = 0x0;
513                 pri_ext->VppMax = 0x0;
514                 pri_ext->TopBottom = 0x0;
515
516                 pri_ext->_unlock1 = 0x5555;
517                 pri_ext->_unlock2 = 0x2AAA;
518                 pri_ext->_reversed_geometry = 0;
519
520                 cfi_info->pri_ext = pri_ext;
521         } else if ((cfi_info->pri_id == 0x1) || (cfi_info->pri_id == 0x3))
522         {
523                 LOG_ERROR("BUG: non-CFI flashes using the Intel commandset are not yet supported");
524                 exit(-1);
525         }
526 }