5c05fb3b7ec41056b5e7d6b9481d3feb58d59e80
[fw/openocd] / src / flash / nor / non_cfi.c
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2
3 /***************************************************************************
4  *   Copyright (C) 2007 by Dominic Rath                                    *
5  *   Dominic.Rath@gmx.de                                                   *
6  *   Copyright (C) 2009 Michael Schwingen                                  *
7  *   michael@schwingen.org                                                 *
8  ***************************************************************************/
9
10 #ifdef HAVE_CONFIG_H
11 #include "config.h"
12 #endif
13
14 #include "imp.h"
15 #include "cfi.h"
16 #include "non_cfi.h"
17
18 #define KB 1024
19 #define MB (1024*1024)
20 #define ERASE_REGION(num, size) (((size/256) << 16) | (num-1))
21
22 /* non-CFI compatible flashes */
23 static const struct non_cfi non_cfi_flashes[] = {
24         {
25                 .mfr = CFI_MFR_SST,
26                 .id = 0xd4,
27                 .pri_id = 0x02,
28                 .dev_size = 64*KB,
29                 .interface_desc = 0x0,          /* x8 only device */
30                 .max_buf_write_size = 0x0,
31                 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
32                 .num_erase_regions = 1,
33                 .erase_region_info = {
34                         ERASE_REGION(16, 4*KB)
35                 }
36         },
37         {
38                 .mfr = CFI_MFR_SST,
39                 .id = 0xd5,
40                 .pri_id = 0x02,
41                 .dev_size = 128*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                         ERASE_REGION(32, 4*KB)
48                 }
49         },
50         {
51                 .mfr = CFI_MFR_SST,
52                 .id = 0xd6,
53                 .pri_id = 0x02,
54                 .dev_size = 256*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(64, 4*KB)
61                 }
62         },
63         {
64                 .mfr = CFI_MFR_SST,
65                 .id = 0xd7,
66                 .pri_id = 0x02,
67                 .dev_size = 512*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(128, 4*KB)
74                 }
75         },
76         {
77                 .mfr = CFI_MFR_AMD,             /* Spansion AM29LV040B */
78                 .id = 0x4f,
79                 .pri_id = 0x02,
80                 .dev_size = 512*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(8, 64*KB)
87                 }
88         },
89         {
90                 .mfr = CFI_MFR_SST,
91                 .id = 0x2780,
92                 .pri_id = 0x02,
93                 .dev_size = 512*KB,
94                 .interface_desc = 0x2,          /* x8 or x16 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(128, 4*KB)
100                 }
101         },
102         {
103                 .mfr = CFI_MFR_ST,
104                 .id = 0xd6,                                     /* ST29F400BB */
105                 .pri_id = 0x02,
106                 .dev_size = 512*KB,
107                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
108                 .max_buf_write_size = 0x0,
109                 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
110                 .num_erase_regions = 4,
111                 .erase_region_info = {
112                         ERASE_REGION(1, 16*KB),
113                         ERASE_REGION(2,  8*KB),
114                         ERASE_REGION(1, 32*KB),
115                         ERASE_REGION(7, 64*KB)
116                 }
117         },
118         {
119                 .mfr = CFI_MFR_ST,
120                 .id = 0xd5,                                     /* ST29F400BT */
121                 .pri_id = 0x02,
122                 .dev_size = 512*KB,
123                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
124                 .max_buf_write_size = 0x0,
125                 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
126                 .num_erase_regions = 4,
127                 .erase_region_info = {
128                         ERASE_REGION(7, 64*KB),
129                         ERASE_REGION(1, 32*KB),
130                         ERASE_REGION(2,  8*KB),
131                         ERASE_REGION(1, 16*KB)
132                 }
133         },
134
135         /* SST 39VF* do not support DQ5 status polling - this currently is
136            only supported by the host algorithm, not by the target code using
137            the work area.
138            Only true for 8-bit and 32-bit wide memories. 16-bit wide memories
139            without DQ5 status polling are supported by the target code.
140         */
141         {
142                 .mfr = CFI_MFR_SST,
143                 .id = 0x2782,                           /* SST39xF160 */
144                 .pri_id = 0x02,
145                 .dev_size = 2*MB,
146                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
147                 .max_buf_write_size = 0x0,
148                 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7,
149                 .num_erase_regions = 1,
150                 .erase_region_info = {
151                         ERASE_REGION(512, 4*KB)
152                 }
153         },
154         {
155                 .mfr = CFI_MFR_SST,
156                 .id = 0x2783,                           /* SST39VF320 */
157                 .pri_id = 0x02,
158                 .dev_size = 4*MB,
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(1024, 4*KB)
165                 }
166         },
167         {
168                 .mfr = CFI_MFR_SST,
169                 .id = 0x234b,                           /* SST39VF1601 */
170                 .pri_id = 0x02,
171                 .dev_size = 2*MB,
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(512, 4*KB)
178                 }
179         },
180         {
181                 .mfr = CFI_MFR_SST,
182                 .id = 0x274b,                           /* SST39WF1601 */
183                 .pri_id = 0x02,
184                 .dev_size = 2*MB,
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)
191                 }
192         },
193         {
194                 .mfr = CFI_MFR_SST,
195                 .id = 0x234a,                           /* SST39VF1602 */
196                 .pri_id = 0x02,
197                 .dev_size = 2*MB,
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)
204                 }
205         },
206         {
207                 .mfr = CFI_MFR_SST,
208                 .id = 0x235b,                           /* SST39VF3201 */
209                 .pri_id = 0x02,
210                 .dev_size = 4*MB,
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(1024, 4*KB)
217                 }
218         },
219         {
220                 .mfr = CFI_MFR_SST,
221                 .id = 0x235a,                           /* SST39VF3202 */
222                 .pri_id = 0x02,
223                 .dev_size = 4*MB,
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)
230                 }
231         },
232         {
233                 .mfr = CFI_MFR_SST,
234                 .id = 0x236d,           /* SST39VF6401B */
235                 .pri_id = 0x02,
236                 .dev_size = 8*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                         ERASE_REGION(2048, 4*KB)
243                 }
244         },
245         {
246                 .mfr = CFI_MFR_AMD,
247                 .id = 0x22ab,                           /* AM29F400BB */
248                 .pri_id = 0x02,
249                 .dev_size = 512*KB,
250                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
251                 .max_buf_write_size = 0x0,
252                 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
253                 .num_erase_regions = 4,
254                 .erase_region_info = {
255                         ERASE_REGION(1, 16*KB),
256                         ERASE_REGION(2,  8*KB),
257                         ERASE_REGION(1, 32*KB),
258                         ERASE_REGION(7, 64*KB)
259                 }
260         },
261         {
262                 .mfr = CFI_MFR_AMD,
263                 .id = 0x2223,                           /* AM29F400BT */
264                 .pri_id = 0x02,
265                 .dev_size = 512*KB,
266                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
267                 .max_buf_write_size = 0x0,
268                 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
269                 .num_erase_regions = 4,
270                 .erase_region_info = {
271                         ERASE_REGION(7, 64*KB),
272                         ERASE_REGION(1, 32*KB),
273                         ERASE_REGION(2,  8*KB),
274                         ERASE_REGION(1, 16*KB)
275                 }
276         },
277         {
278                 .mfr = CFI_MFR_FUJITSU,
279                 .id = 0x226b,                           /* AM29SL800DB */
280                 .pri_id = 0x02,
281                 .dev_size = 1*MB,
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                         ERASE_REGION(1, 16*KB),
288                         ERASE_REGION(2,  8*KB),
289                         ERASE_REGION(1, 32*KB),
290                         ERASE_REGION(15, 64*KB)
291                 }
292         },
293         {
294                 .mfr = CFI_MFR_FUJITSU,
295                 .id = 0x22ea,                           /* MBM29SL800TE */
296                 .pri_id = 0x02,
297                 .dev_size = 1*MB,
298                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
299                 .max_buf_write_size = 0x0,
300                 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
301                 .num_erase_regions = 4,
302                 .erase_region_info = {
303                         ERASE_REGION(15, 64*KB),
304                         ERASE_REGION(1,  32*KB),
305                         ERASE_REGION(2,  8*KB),
306                         ERASE_REGION(1,  16*KB)
307                 }
308         },
309         {
310                 .mfr = CFI_MFR_FUJITSU,
311                 .id = 0xba,                             /* 29LV400BC */
312                 .pri_id = 0x02,
313                 .dev_size = 512*KB,
314                 .interface_desc = 0x1,          /* x8 or x16 device w/ nBYTE */
315                 .max_buf_write_size = 0x00,
316                 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
317                 .num_erase_regions = 4,
318                 .erase_region_info = {
319                         ERASE_REGION(1, 16*KB),
320                         ERASE_REGION(2,  8*KB),
321                         ERASE_REGION(1, 32*KB),
322                         ERASE_REGION(7, 64*KB)
323                 }
324         },
325         {
326                 .mfr = CFI_MFR_AMIC,
327                 .id = 0xb31a,                           /* A29L800A */
328                 .pri_id = 0x02,
329                 .dev_size = 1*MB,
330                 .interface_desc = 0x2,
331                 .max_buf_write_size = 0x0,
332                 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
333                 .num_erase_regions = 4,
334                 .erase_region_info = {
335                         ERASE_REGION(1, 16*KB),
336                         ERASE_REGION(2,  8*KB),
337                         ERASE_REGION(1, 32*KB),
338                         ERASE_REGION(15, 64*KB)
339                 }
340         },
341         {
342                 .mfr = CFI_MFR_MX,
343                 .id = 0x225b,                           /* MX29LV800B */
344                 .pri_id = 0x02,
345                 .dev_size = 1*MB,
346                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
347                 .max_buf_write_size = 0x0,
348                 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
349                 .num_erase_regions = 4,
350                 .erase_region_info = {
351                         ERASE_REGION(1, 16*KB),
352                         ERASE_REGION(2, 8*KB),
353                         ERASE_REGION(1, 32*KB),
354                         ERASE_REGION(15, 64*KB)
355                 }
356         },
357
358         {
359                 .mfr = CFI_MFR_MX,
360                 .id = 0x2249,                           /* MX29LV160AB: 2MB */
361                 .pri_id = 0x02,
362                 .dev_size = 2*MB,
363                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
364                 .max_buf_write_size = 0x0,
365                 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
366                 .num_erase_regions = 4,
367                 .erase_region_info = {
368                         ERASE_REGION(1, 16*KB),
369                         ERASE_REGION(2, 8*KB),
370                         ERASE_REGION(1, 32*KB),
371                         ERASE_REGION(31, 64*KB)
372                 }
373         },
374         {
375                 .mfr = CFI_MFR_MX,
376                 .id = 0x22C4,                           /* MX29LV160AT: 2MB */
377                 .pri_id = 0x02,
378                 .dev_size = 2*MB,
379                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
380                 .max_buf_write_size = 0x0,
381                 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
382                 .num_erase_regions = 4,
383                 .erase_region_info = {
384                         ERASE_REGION(31, 64*KB),
385                         ERASE_REGION(1, 32*KB),
386                         ERASE_REGION(2, 8*KB),
387                         ERASE_REGION(1, 16*KB)
388                 }
389         },
390         {
391                 .mfr = CFI_MFR_EON,
392                 .id = 0x225b,                           /* EN29LV800BB */
393                 .pri_id = 0x02,
394                 .dev_size = 1*MB,
395                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
396                 .max_buf_write_size = 0x0,
397                 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
398                 .num_erase_regions = 4,
399                 .erase_region_info = {
400                         ERASE_REGION(1, 16*KB),
401                         ERASE_REGION(2,  8*KB),
402                         ERASE_REGION(1, 32*KB),
403                         ERASE_REGION(15, 64*KB)
404                 }
405         },
406         {
407                 .mfr = CFI_MFR_ATMEL,
408                 .id = 0x00c0,                           /* Atmel 49BV1614 */
409                 .pri_id = 0x02,
410                 .dev_size = 2*MB,
411                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
412                 .max_buf_write_size = 0x0,
413                 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
414                 .num_erase_regions = 3,
415                 .erase_region_info = {
416                         ERASE_REGION(8,  8*KB),
417                         ERASE_REGION(2, 32*KB),
418                         ERASE_REGION(30, 64*KB)
419                 }
420         },
421         {
422                 .mfr = CFI_MFR_ATMEL,
423                 .id = 0xC2,                                     /* Atmel 49BV1614T */
424                 .pri_id = 0x02,
425                 .dev_size = 2*MB,
426                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
427                 .max_buf_write_size = 0x0,
428                 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
429                 .num_erase_regions = 3,
430                 .erase_region_info = {
431                         ERASE_REGION(30, 64*KB),
432                         ERASE_REGION(2, 32*KB),
433                         ERASE_REGION(8,  8*KB)
434                 }
435         },
436         {
437                 .mfr = CFI_MFR_AMD,
438                 .id = 0x225b,                           /* S29AL008D */
439                 .pri_id = 0x02,
440                 .dev_size = 1*MB,
441                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
442                 .max_buf_write_size = 0x0,
443                 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
444                 .num_erase_regions = 4,
445                 .erase_region_info = {
446                         ERASE_REGION(1, 16*KB),
447                         ERASE_REGION(2, 8*KB),
448                         ERASE_REGION(1, 32*KB),
449                         ERASE_REGION(15, 64*KB)
450                 }
451         },
452         {
453                 .mfr = 0,
454                 .id = 0,
455         }
456 };
457
458 void cfi_fixup_non_cfi(struct flash_bank *bank)
459 {
460         unsigned int mask;
461         struct cfi_flash_bank *cfi_info = bank->driver_priv;
462         const struct non_cfi *non_cfi = non_cfi_flashes;
463
464         if (cfi_info->x16_as_x8)
465                 mask = 0xFF;
466         else
467                 mask = 0xFFFF;
468
469         for (non_cfi = non_cfi_flashes; non_cfi->mfr; non_cfi++) {
470                 if ((cfi_info->manufacturer == non_cfi->mfr)
471                     && (cfi_info->device_id == (non_cfi->id & mask)))
472                         break;
473         }
474
475         /* only fixup jedec flashes found in table */
476         if (!non_cfi->mfr)
477                 return;
478
479         cfi_info->not_cfi = true;
480
481         /* fill in defaults for non-critical data */
482         cfi_info->vcc_min = 0x0;
483         cfi_info->vcc_max = 0x0;
484         cfi_info->vpp_min = 0x0;
485         cfi_info->vpp_max = 0x0;
486         /* these are used for timeouts - use vales that should be long enough
487            for normal operation. */
488         cfi_info->word_write_timeout_typ = 0x0a;
489         cfi_info->buf_write_timeout_typ = 0x0d;
490         cfi_info->block_erase_timeout_typ = 0x0d;
491         cfi_info->chip_erase_timeout_typ = 0x10;
492         cfi_info->word_write_timeout_max = 0x0;
493         cfi_info->buf_write_timeout_max = 0x0;
494         cfi_info->block_erase_timeout_max = 0x0;
495         cfi_info->chip_erase_timeout_max = 0x0;
496
497         cfi_info->qry[0] = 'Q';
498         cfi_info->qry[1] = 'R';
499         cfi_info->qry[2] = 'Y';
500
501         cfi_info->pri_id = non_cfi->pri_id;
502         cfi_info->pri_addr = 0x0;
503         cfi_info->alt_id = 0x0;
504         cfi_info->alt_addr = 0x0;
505         cfi_info->alt_ext = NULL;
506
507         cfi_info->interface_desc = non_cfi->interface_desc;
508         cfi_info->max_buf_write_size = non_cfi->max_buf_write_size;
509         cfi_info->status_poll_mask = non_cfi->status_poll_mask;
510         cfi_info->num_erase_regions = non_cfi->num_erase_regions;
511         size_t erase_region_info_size = sizeof(*cfi_info->erase_region_info) *
512                 cfi_info->num_erase_regions;
513         cfi_info->erase_region_info = malloc(erase_region_info_size);
514         memcpy(cfi_info->erase_region_info,
515                 non_cfi->erase_region_info, erase_region_info_size);
516         cfi_info->dev_size = non_cfi->dev_size;
517
518         if (cfi_info->pri_id == 0x2) {
519                 struct cfi_spansion_pri_ext *pri_ext = malloc(sizeof(struct cfi_spansion_pri_ext));
520
521                 pri_ext->pri[0] = 'P';
522                 pri_ext->pri[1] = 'R';
523                 pri_ext->pri[2] = 'I';
524
525                 pri_ext->major_version = '1';
526                 pri_ext->minor_version = '0';
527
528                 pri_ext->silicon_revision = 0x0;
529                 pri_ext->erase_suspend = 0x0;
530                 pri_ext->blk_prot = 0x0;
531                 pri_ext->tmp_blk_unprotected = 0x0;
532                 pri_ext->blk_prot_unprot = 0x0;
533                 pri_ext->simultaneous_ops = 0x0;
534                 pri_ext->burst_mode = 0x0;
535                 pri_ext->page_mode = 0x0;
536                 pri_ext->vpp_min = 0x0;
537                 pri_ext->vpp_max = 0x0;
538                 pri_ext->top_bottom = 0x0;
539
540                 pri_ext->_unlock1 = 0x5555;
541                 pri_ext->_unlock2 = 0x2AAA;
542                 pri_ext->_reversed_geometry = 0;
543
544                 cfi_info->pri_ext = pri_ext;
545         } else if ((cfi_info->pri_id == 0x1) || (cfi_info->pri_id == 0x3)) {
546                 LOG_ERROR("BUG: non-CFI flashes using the Intel commandset are not yet supported");
547                 exit(-1);
548         }
549 }