- add new non-cfi SST flash device. Thanks Øyvind Harboe
[fw/openocd] / src / flash / non_cfi.c
1 /***************************************************************************
2  *   Copyright (C) 2007 by Dominic Rath                                    *
3  *   Dominic.Rath@gmx.de                                                   *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include <stdlib.h>
25
26 #include "log.h"
27
28 #include "flash.h"
29 #include "cfi.h"
30 #include "non_cfi.h"
31
32 /* non-CFI compatible flashes */
33 non_cfi_t non_cfi_flashes[] = {
34         {
35                 .mfr = CFI_MFR_SST,
36                 .id = 0xd4,
37                 .pri_id = 0x02,
38                 .dev_size = 0x10,                       /* 2^16 = 64KB */
39                 .interface_desc = 0x0,          /* x8 only device */
40                 .max_buf_write_size = 0x0,
41                 .num_erase_regions = 1,
42                 .erase_region_info =
43                 {
44                         0x0010000f,                             /* 16x  4KB */
45                         0x00000000
46                 }
47         },
48         {
49                 .mfr = CFI_MFR_SST,
50                 .id = 0xd5,
51                 .pri_id = 0x02,
52                 .dev_size = 0x11,                       /* 2^17 = 128KB */
53                 .interface_desc = 0x0,          /* x8 only device */
54                 .max_buf_write_size = 0x0,
55                 .num_erase_regions = 1,
56                 .erase_region_info =
57                 {
58                         0x0010001f,
59                         0x00000000
60                 }
61         },
62         {
63                 .mfr = CFI_MFR_SST,
64                 .id = 0xd6,
65                 .pri_id = 0x02,
66                 .dev_size = 0x12,                       /* 2^18 = 256KB */
67                 .interface_desc = 0x0,          /* x8 only device */
68                 .max_buf_write_size = 0x0,
69                 .num_erase_regions = 1,
70                 .erase_region_info =
71                 {
72                         0x0010003f,
73                         0x00000000
74                 }
75         },
76         {
77                 .mfr = CFI_MFR_SST,
78                 .id = 0xd7,
79                 .pri_id = 0x02,
80                 .dev_size = 0x13,                       /* 2^19 = 512KB */
81                 .interface_desc = 0x0,          /* x8 only device */
82                 .max_buf_write_size = 0x0,
83                 .num_erase_regions = 1,
84                 .erase_region_info =
85                 {
86                         0x0010007f,
87                         0x00000000
88                 }
89         },
90         {
91                 .mfr = CFI_MFR_SST,
92                 .id = 0x2780,
93                 .pri_id = 0x02,
94                 .dev_size = 0x13,                       /* 2^19 = 512KB */
95                 .interface_desc = 0x2,          /* x8 or x16 device */
96                 .max_buf_write_size = 0x0,
97                 .num_erase_regions = 1,
98                 .erase_region_info =
99                 {
100                         0x0010007f,
101                         0x00000000
102                 }
103         },
104         {
105                 .mfr = CFI_MFR_ST,
106                 .id = 0xd6,                                     /* ST29F400BB */
107                 .pri_id = 0x02,
108                 .dev_size = 0x13,                       /* 2^19 = 512KB */
109                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
110                 .max_buf_write_size = 0x0,
111                 .num_erase_regions = 4,
112                 .erase_region_info =
113                 {
114                         0x00400000,             /* 1x 16KB */
115                         0x00200001,             /* 2x  8KB */
116                         0x00800000,             /* 1x 32KB */
117                         0x01000006,             /* 7x 64KB */
118                         0x00000000
119                 }
120         },
121         {
122                 .mfr = CFI_MFR_ST,
123                 .id = 0xd5,                                     /* ST29F400BT */
124                 .pri_id = 0x02,
125                 .dev_size = 0x13,                       /* 2^19 = 512KB */
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                         0x01000006,             /* 7x 64KB */
132                         0x00800000,             /* 1x 32KB */
133                         0x00200001,             /* 2x  8KB */
134                         0x00400000,             /* 1x 16KB */
135                         0x00000000
136                 }
137         },
138         {
139                 .mfr = CFI_MFR_AMD,
140                 .id = 0x22ab,                           /* AM29F400BB */
141                 .pri_id = 0x02,
142                 .dev_size = 0x13,                       /* 2^19 = 512KB */
143                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
144                 .max_buf_write_size = 0x0,
145                 .num_erase_regions = 4,
146                 .erase_region_info =
147                 {
148                         0x00400000,             /* 1x 16KB */
149                         0x00200001,             /* 2x  8KB */
150                         0x00800000,             /* 1x 32KB */
151                         0x01000006,             /* 7x 64KB */
152                         0x00000000
153                 }
154         },
155         {
156                 .mfr = CFI_MFR_AMD,
157                 .id = 0x2223,                           /* AM29F400BT */
158                 .pri_id = 0x02,
159                 .dev_size = 0x13,                       /* 2^19 = 512KB */
160                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
161                 .max_buf_write_size = 0x0,
162                 .num_erase_regions = 4,
163                 .erase_region_info =
164                 {
165                         0x01000006,             /* 7x 64KB */
166                         0x00800000,             /* 1x 32KB */
167                         0x00200001,             /* 2x  8KB */
168                         0x00400000,             /* 1x 16KB */
169                         0x00000000
170                 }
171         },
172         {
173                 .mfr = 0,
174                 .id = 0,
175         }
176 };
177
178 void cfi_fixup_non_cfi(flash_bank_t *bank, void *param)
179 {
180         cfi_flash_bank_t *cfi_info = bank->driver_priv;
181         non_cfi_t *non_cfi = non_cfi_flashes;
182         
183         while (non_cfi->mfr)
184         {
185                 if ((cfi_info->manufacturer == non_cfi->mfr)
186                         && (cfi_info->device_id == non_cfi->id))
187                 {
188                         break;
189                 }
190                 non_cfi++;
191         }
192         
193         cfi_info->not_cfi = 1;
194         
195         /* fill in defaults for non-critical data */
196         cfi_info->vcc_min = 0x0;
197         cfi_info->vcc_max = 0x0;
198         cfi_info->vpp_min = 0x0;
199         cfi_info->vpp_max = 0x0;
200         cfi_info->word_write_timeout_typ = 0x0;
201         cfi_info->buf_write_timeout_typ = 0x0;
202         cfi_info->block_erase_timeout_typ = 0x0;
203         cfi_info->chip_erase_timeout_typ = 0x0;
204         cfi_info->word_write_timeout_max = 0x0;
205         cfi_info->buf_write_timeout_max = 0x0;
206         cfi_info->block_erase_timeout_max = 0x0;
207         cfi_info->chip_erase_timeout_max = 0x0;
208         
209         cfi_info->qry[0] = 'Q';
210         cfi_info->qry[1] = 'R';
211         cfi_info->qry[2] = 'Y';
212         
213         cfi_info->pri_id = non_cfi->pri_id;
214         cfi_info->pri_addr = 0x0;
215         cfi_info->alt_id = 0x0;
216         cfi_info->alt_addr = 0x0;
217         cfi_info->alt_ext = NULL;
218         
219         cfi_info->interface_desc = non_cfi->interface_desc;
220         cfi_info->max_buf_write_size = non_cfi->max_buf_write_size;
221         cfi_info->num_erase_regions = non_cfi->num_erase_regions;
222         cfi_info->erase_region_info = non_cfi->erase_region_info;
223         
224         if (cfi_info->pri_id == 0x2)
225         {
226                 cfi_spansion_pri_ext_t *pri_ext = malloc(sizeof(cfi_spansion_pri_ext_t));
227
228                 pri_ext->pri[0] = 'P';
229                 pri_ext->pri[1] = 'R';
230                 pri_ext->pri[2] = 'I';
231                 
232                 pri_ext->major_version = '1';
233                 pri_ext->minor_version = '0';
234                 
235                 pri_ext->SiliconRevision = 0x0;
236                 pri_ext->EraseSuspend = 0x0;
237                 pri_ext->EraseSuspend = 0x0;
238                 pri_ext->BlkProt = 0x0;
239                 pri_ext->TmpBlkUnprotect = 0x0;
240                 pri_ext->BlkProtUnprot = 0x0;
241                 pri_ext->SimultaneousOps = 0x0;
242                 pri_ext->BurstMode = 0x0;
243                 pri_ext->PageMode = 0x0;
244                 pri_ext->VppMin = 0x0;
245                 pri_ext->VppMax = 0x0;
246                 pri_ext->TopBottom = 0x0;
247         
248                 pri_ext->_reversed_geometry = 0;
249                 
250                 cfi_info->pri_ext = pri_ext;
251         } else if ((cfi_info->pri_id == 0x1) || (cfi_info->pri_id == 0x3))
252         {
253                 ERROR("BUG: non-CFI flashes using the Intel commandset are not yet supported");
254                 exit(-1);
255         }
256 }
257
258