b9ef1127331c435c364b908ef311d77787abdcf7
[fw/openocd] / src / flash / 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 <stdlib.h>
27
28 #include "log.h"
29
30 #include "flash.h"
31 #include "cfi.h"
32 #include "non_cfi.h"
33
34 #define KB 1024
35 #define MB (1024*1024)
36 #define ERASE_REGION(num, size) (((size/256)<<16)|(num-1))
37
38 /* non-CFI compatible flashes */
39 non_cfi_t non_cfi_flashes[] = {
40         {
41                 .mfr = CFI_MFR_SST,
42                 .id = 0xd4,
43                 .pri_id = 0x02,
44                 .dev_size = 64*KB,
45                 .interface_desc = 0x0,          /* x8 only device */
46                 .max_buf_write_size = 0x0,
47                 .num_erase_regions = 1,
48                 .erase_region_info =
49                 {
50                         ERASE_REGION(16, 4*KB)
51                 }
52         },
53         {
54                 .mfr = CFI_MFR_SST,
55                 .id = 0xd5,
56                 .pri_id = 0x02,
57                 .dev_size = 128*KB,
58                 .interface_desc = 0x0,          /* x8 only device */
59                 .max_buf_write_size = 0x0,
60                 .num_erase_regions = 1,
61                 .erase_region_info =
62                 {
63                         ERASE_REGION(32, 4*KB)
64                 }
65         },
66         {
67                 .mfr = CFI_MFR_SST,
68                 .id = 0xd6,
69                 .pri_id = 0x02,
70                 .dev_size = 256*KB,
71                 .interface_desc = 0x0,          /* x8 only device */
72                 .max_buf_write_size = 0x0,
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                 .num_erase_regions = 1,
87                 .erase_region_info =
88                 {
89                         ERASE_REGION(128, 4*KB)
90                 }
91         },
92         {
93                 .mfr = CFI_MFR_SST,
94                 .id = 0x2780,
95                 .pri_id = 0x02,
96                 .dev_size = 512*KB,
97                 .interface_desc = 0x2,          /* x8 or x16 device */
98                 .max_buf_write_size = 0x0,
99                 .num_erase_regions = 1,
100                 .erase_region_info =
101                 {
102                         ERASE_REGION(128, 4*KB)
103                 }
104         },
105         {
106                 .mfr = CFI_MFR_ST,
107                 .id = 0xd6,                                     /* ST29F400BB */
108                 .pri_id = 0x02,
109                 .dev_size = 512*KB,
110                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
111                 .max_buf_write_size = 0x0,
112                 .num_erase_regions = 4,
113                 .erase_region_info =
114                 {
115                         ERASE_REGION( 1, 16*KB),
116                         ERASE_REGION( 2,  8*KB),
117                         ERASE_REGION( 1, 32*KB),
118                         ERASE_REGION( 7, 64*KB)
119                 }
120         },
121         {
122                 .mfr = CFI_MFR_ST,
123                 .id = 0xd5,                                     /* ST29F400BT */
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                 .num_erase_regions = 4,
129                 .erase_region_info =
130                 {
131                         ERASE_REGION( 7, 64*KB),
132                         ERASE_REGION( 1, 32*KB),
133                         ERASE_REGION( 2,  8*KB),
134                         ERASE_REGION( 1, 16*KB)
135                 }
136         },
137         {
138                 .mfr = CFI_MFR_AMD,
139                 .id = 0x22ab,                           /* AM29F400BB */
140                 .pri_id = 0x02,
141                 .dev_size = 512*KB,
142                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
143                 .max_buf_write_size = 0x0,
144                 .num_erase_regions = 4,
145                 .erase_region_info =
146                 {
147                         ERASE_REGION( 1, 16*KB),
148                         ERASE_REGION( 2,  8*KB),
149                         ERASE_REGION( 1, 32*KB),
150                         ERASE_REGION( 7, 64*KB)
151                 }
152         },
153         {
154                 .mfr = CFI_MFR_AMD,
155                 .id = 0x2223,                           /* AM29F400BT */
156                 .pri_id = 0x02,
157                 .dev_size = 512*KB,
158                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
159                 .max_buf_write_size = 0x0,
160                 .num_erase_regions = 4,
161                 .erase_region_info =
162                 {
163                         ERASE_REGION( 7, 64*KB),
164                         ERASE_REGION( 1, 32*KB),
165                         ERASE_REGION( 2,  8*KB),
166                         ERASE_REGION( 1, 16*KB)
167                 }
168         },
169         {
170                 .mfr = CFI_MFR_FUJITSU,
171                 .id = 0x226b,                           /* AM29SL800DB */
172                 .pri_id = 0x02,
173                 .dev_size = 1*MB,
174                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
175                 .max_buf_write_size = 0x0,
176                 .num_erase_regions = 4,
177                 .erase_region_info =
178                 {
179                         ERASE_REGION( 1, 16*KB),
180                         ERASE_REGION( 2,  8*KB),
181                         ERASE_REGION( 1, 32*KB),
182                         ERASE_REGION(15, 64*KB)
183                 }
184         },
185         {
186                 .mfr = CFI_MFR_AMIC,
187                 .id = 0xb31a,                           /* A29L800A */
188                 .pri_id = 0x02,
189                 .dev_size = 1*MB,
190                 .interface_desc = 0x2,
191                 .max_buf_write_size = 0x0,
192                 .num_erase_regions = 4,
193                 .erase_region_info =
194                 {
195                         ERASE_REGION( 1, 16*KB),
196                         ERASE_REGION( 2,  8*KB),
197                         ERASE_REGION( 1, 32*KB),
198                         ERASE_REGION(15, 64*KB)
199                 }
200         },
201         {
202                 .mfr = CFI_MFR_MX,
203                 .id = 0x225b,                           /* MX29LV800B */
204                 .pri_id = 0x02,
205                 .dev_size = 1*MB,
206                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
207                 .max_buf_write_size = 0x0,
208                 .num_erase_regions = 4,
209                 .erase_region_info =
210                 {
211                         ERASE_REGION( 1, 16*KB),
212                         ERASE_REGION( 2, 8*KB),
213                         ERASE_REGION( 1, 32*KB),
214                         ERASE_REGION(15, 64*KB)
215                 }
216         },
217
218         {
219                 .mfr = CFI_MFR_MX,
220                 .id = 0x2249,                           /* MX29LV160AB: 2MB */
221                 .pri_id = 0x02,
222                 .dev_size = 2*MB,
223                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
224                 .max_buf_write_size = 0x0,
225                 .num_erase_regions = 4,
226                 .erase_region_info =
227                 {
228                         ERASE_REGION( 1, 16*KB),
229                         ERASE_REGION( 2, 8*KB),
230                         ERASE_REGION( 1, 32*KB),
231                         ERASE_REGION(31, 64*KB)
232                 }
233         },
234         {
235                 .mfr = CFI_MFR_MX,
236                 .id = 0x22C4,                           /* MX29LV160AT: 2MB */
237                 .pri_id = 0x02,
238                 .dev_size = 2*MB,
239                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
240                 .max_buf_write_size = 0x0,
241                 .num_erase_regions = 4,
242                 .erase_region_info =
243                 {
244                         ERASE_REGION(31, 64*KB),
245                         ERASE_REGION( 1, 32*KB),
246                         ERASE_REGION( 2, 8*KB),
247                         ERASE_REGION( 1, 16*KB)
248                 }
249         },
250         {
251                 .mfr = CFI_MFR_SST,
252                 .id = 0x2782,                           /* SST39xF160 */
253                 .pri_id = 0x02,
254                 .dev_size = 2*MB,
255                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
256                 .max_buf_write_size = 0x0,
257                 .num_erase_regions = 1,
258                 .erase_region_info =
259                 {
260                         ERASE_REGION(512, 4*KB)
261                 }
262         },
263         {
264                 .mfr = CFI_MFR_ATMEL,
265                 .id = 0x00c0,                           /* Atmel 49BV1614 */
266                 .pri_id = 0x02,
267                 .dev_size = 2*MB,
268                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
269                 .max_buf_write_size = 0x0,
270                 .num_erase_regions = 3,
271                 .erase_region_info =
272                 {
273                         ERASE_REGION( 8,  8*KB),
274                         ERASE_REGION( 2, 32*KB),
275                         ERASE_REGION(30, 64*KB)
276                 }
277         },
278         {
279                 .mfr = CFI_MFR_ATMEL,
280                 .id = 0xC2,                                     /* Atmel 49BV1614T */
281                 .pri_id = 0x02,
282                 .dev_size = 2*MB,
283                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
284                 .max_buf_write_size = 0x0,
285                 .num_erase_regions = 3,
286                 .erase_region_info =
287                 {
288                         ERASE_REGION(30, 64*KB),
289                         ERASE_REGION( 2, 32*KB),
290                         ERASE_REGION( 8,  8*KB)
291                 }
292         },
293         {
294                 .mfr = CFI_MFR_AMD,
295                 .id = 0x225b,                           /* S29AL008D */
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                 .num_erase_regions = 4,
301                 .erase_region_info =
302                 {
303                         ERASE_REGION( 1, 16*KB),
304                         ERASE_REGION( 2, 8*KB),
305                         ERASE_REGION( 1, 32*KB),
306                         ERASE_REGION(15, 64*KB)
307                 }
308         },
309         {
310                 .mfr = 0,
311                 .id = 0,
312         }
313 };
314
315 void cfi_fixup_non_cfi(flash_bank_t *bank)
316 {
317         cfi_flash_bank_t *cfi_info = bank->driver_priv;
318         non_cfi_t *non_cfi = non_cfi_flashes;
319
320         for (non_cfi = non_cfi_flashes; non_cfi->mfr; non_cfi++)
321         {
322                 if ((cfi_info->manufacturer == non_cfi->mfr)
323                         && (cfi_info->device_id == non_cfi->id))
324                 {
325                         break;
326                 }
327         }
328
329         /* only fixup jedec flashs found in table */
330         if (!non_cfi->mfr)
331                 return;
332
333         cfi_info->not_cfi = 1;
334
335         /* fill in defaults for non-critical data */
336         cfi_info->vcc_min = 0x0;
337         cfi_info->vcc_max = 0x0;
338         cfi_info->vpp_min = 0x0;
339         cfi_info->vpp_max = 0x0;
340         cfi_info->word_write_timeout_typ = 0x0;
341         cfi_info->buf_write_timeout_typ = 0x0;
342         cfi_info->block_erase_timeout_typ = 0x0;
343         cfi_info->chip_erase_timeout_typ = 0x0;
344         cfi_info->word_write_timeout_max = 0x0;
345         cfi_info->buf_write_timeout_max = 0x0;
346         cfi_info->block_erase_timeout_max = 0x0;
347         cfi_info->chip_erase_timeout_max = 0x0;
348
349         cfi_info->qry[0] = 'Q';
350         cfi_info->qry[1] = 'R';
351         cfi_info->qry[2] = 'Y';
352
353         cfi_info->pri_id = non_cfi->pri_id;
354         cfi_info->pri_addr = 0x0;
355         cfi_info->alt_id = 0x0;
356         cfi_info->alt_addr = 0x0;
357         cfi_info->alt_ext = NULL;
358
359         cfi_info->interface_desc = non_cfi->interface_desc;
360         cfi_info->max_buf_write_size = non_cfi->max_buf_write_size;
361         cfi_info->num_erase_regions = non_cfi->num_erase_regions;
362         cfi_info->erase_region_info = non_cfi->erase_region_info;
363         cfi_info->dev_size = non_cfi->dev_size;
364
365         if (cfi_info->pri_id == 0x2)
366         {
367                 cfi_spansion_pri_ext_t *pri_ext = malloc(sizeof(cfi_spansion_pri_ext_t));
368
369                 pri_ext->pri[0] = 'P';
370                 pri_ext->pri[1] = 'R';
371                 pri_ext->pri[2] = 'I';
372
373                 pri_ext->major_version = '1';
374                 pri_ext->minor_version = '0';
375
376                 pri_ext->SiliconRevision = 0x0;
377                 pri_ext->EraseSuspend = 0x0;
378                 pri_ext->EraseSuspend = 0x0;
379                 pri_ext->BlkProt = 0x0;
380                 pri_ext->TmpBlkUnprotect = 0x0;
381                 pri_ext->BlkProtUnprot = 0x0;
382                 pri_ext->SimultaneousOps = 0x0;
383                 pri_ext->BurstMode = 0x0;
384                 pri_ext->PageMode = 0x0;
385                 pri_ext->VppMin = 0x0;
386                 pri_ext->VppMax = 0x0;
387                 pri_ext->TopBottom = 0x0;
388
389                 pri_ext->_unlock1 = 0x5555;
390                 pri_ext->_unlock2 = 0x2AAA;
391                 pri_ext->_reversed_geometry = 0;
392
393                 cfi_info->pri_ext = pri_ext;
394         } else if ((cfi_info->pri_id == 0x1) || (cfi_info->pri_id == 0x3))
395         {
396                 LOG_ERROR("BUG: non-CFI flashes using the Intel commandset are not yet supported");
397                 exit(-1);
398         }
399 }