upgrade to linux 2.6.10-1.12_FC2
[linux-2.6.git] / drivers / mtd / chips / cfi_probe.c
1 /* 
2    Common Flash Interface probe code.
3    (C) 2000 Red Hat. GPL'd.
4    $Id: cfi_probe.c,v 1.79 2004/10/20 23:04:01 dwmw2 Exp $
5 */
6
7 #include <linux/config.h>
8 #include <linux/module.h>
9 #include <linux/types.h>
10 #include <linux/kernel.h>
11 #include <linux/init.h>
12 #include <asm/io.h>
13 #include <asm/byteorder.h>
14 #include <linux/errno.h>
15 #include <linux/slab.h>
16 #include <linux/interrupt.h>
17
18 #include <linux/mtd/map.h>
19 #include <linux/mtd/cfi.h>
20 #include <linux/mtd/gen_probe.h>
21
22 //#define DEBUG_CFI 
23
24 #ifdef DEBUG_CFI
25 static void print_cfi_ident(struct cfi_ident *);
26 #endif
27
28 static int cfi_probe_chip(struct map_info *map, __u32 base,
29                           unsigned long *chip_map, struct cfi_private *cfi);
30 static int cfi_chip_setup(struct map_info *map, struct cfi_private *cfi);
31
32 struct mtd_info *cfi_probe(struct map_info *map);
33
34 /* check for QRY.
35    in: interleave,type,mode
36    ret: table index, <0 for error
37  */
38 static int qry_present(struct map_info *map, __u32 base,
39                                 struct cfi_private *cfi)
40 {
41         int osf = cfi->interleave * cfi->device_type;   // scale factor
42         map_word val[3];
43         map_word qry[3];
44
45         qry[0] = cfi_build_cmd('Q', map, cfi);
46         qry[1] = cfi_build_cmd('R', map, cfi);
47         qry[2] = cfi_build_cmd('Y', map, cfi);
48
49         val[0] = map_read(map, base + osf*0x10);
50         val[1] = map_read(map, base + osf*0x11);
51         val[2] = map_read(map, base + osf*0x12);
52
53         if (!map_word_equal(map, qry[0], val[0]))
54                 return 0;
55
56         if (!map_word_equal(map, qry[1], val[1]))
57                 return 0;
58
59         if (!map_word_equal(map, qry[2], val[2]))
60                 return 0;
61
62         return 1;       // nothing found
63 }
64
65 static int cfi_probe_chip(struct map_info *map, __u32 base,
66                           unsigned long *chip_map, struct cfi_private *cfi)
67 {
68         int i;
69         
70         if ((base + 0) >= map->size) {
71                 printk(KERN_NOTICE
72                         "Probe at base[0x00](0x%08lx) past the end of the map(0x%08lx)\n",
73                         (unsigned long)base, map->size -1);
74                 return 0;
75         }
76         if ((base + 0xff) >= map->size) {
77                 printk(KERN_NOTICE
78                         "Probe at base[0x55](0x%08lx) past the end of the map(0x%08lx)\n",
79                         (unsigned long)base + 0x55, map->size -1);
80                 return 0;
81         }
82         cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
83         cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
84         cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
85
86         if (!qry_present(map,base,cfi))
87                 return 0;
88
89         if (!cfi->numchips) {
90                 /* This is the first time we're called. Set up the CFI 
91                    stuff accordingly and return */
92                 return cfi_chip_setup(map, cfi);
93         }
94
95         /* Check each previous chip to see if it's an alias */
96         for (i=0; i < (base >> cfi->chipshift); i++) {
97                 unsigned long start;
98                 if(!test_bit(i, chip_map)) {
99                         /* Skip location; no valid chip at this address */
100                         continue; 
101                 }
102                 start = i << cfi->chipshift;
103                 /* This chip should be in read mode if it's one
104                    we've already touched. */
105                 if (qry_present(map, start, cfi)) {
106                         /* Eep. This chip also had the QRY marker. 
107                          * Is it an alias for the new one? */
108                         cfi_send_gen_cmd(0xF0, 0, start, map, cfi, cfi->device_type, NULL);
109                         cfi_send_gen_cmd(0xFF, 0, start, map, cfi, cfi->device_type, NULL);
110
111                         /* If the QRY marker goes away, it's an alias */
112                         if (!qry_present(map, start, cfi)) {
113                                 printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
114                                        map->name, base, start);
115                                 return 0;
116                         }
117                         /* Yes, it's actually got QRY for data. Most 
118                          * unfortunate. Stick the new chip in read mode
119                          * too and if it's the same, assume it's an alias. */
120                         /* FIXME: Use other modes to do a proper check */
121                         cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
122                         cfi_send_gen_cmd(0xFF, 0, start, map, cfi, cfi->device_type, NULL);
123                         
124                         if (qry_present(map, base, cfi)) {
125                                 printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
126                                        map->name, base, start);
127                                 return 0;
128                         }
129                 }
130         }
131         
132         /* OK, if we got to here, then none of the previous chips appear to
133            be aliases for the current one. */
134         set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */
135         cfi->numchips++;
136         
137         /* Put it back into Read Mode */
138         cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
139         cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
140
141         printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n",
142                map->name, cfi->interleave, cfi->device_type*8, base,
143                map->bankwidth*8);
144         
145         return 1;
146 }
147
148 static int cfi_chip_setup(struct map_info *map, 
149                    struct cfi_private *cfi)
150 {
151         int ofs_factor = cfi->interleave*cfi->device_type;
152         __u32 base = 0;
153         int num_erase_regions = cfi_read_query(map, base + (0x10 + 28)*ofs_factor);
154         int i;
155
156 #ifdef DEBUG_CFI
157         printk("Number of erase regions: %d\n", num_erase_regions);
158 #endif
159         if (!num_erase_regions)
160                 return 0;
161
162         cfi->cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL);
163         if (!cfi->cfiq) {
164                 printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name);
165                 return 0;
166         }
167         
168         memset(cfi->cfiq,0,sizeof(struct cfi_ident));   
169         
170         cfi->cfi_mode = CFI_MODE_CFI;
171         
172         /* Read the CFI info structure */
173         for (i=0; i<(sizeof(struct cfi_ident) + num_erase_regions * 4); i++) {
174                 ((unsigned char *)cfi->cfiq)[i] = cfi_read_query(map,base + (0x10 + i)*ofs_factor);
175         }
176         
177         /* Do any necessary byteswapping */
178         cfi->cfiq->P_ID = le16_to_cpu(cfi->cfiq->P_ID);
179         
180         cfi->cfiq->P_ADR = le16_to_cpu(cfi->cfiq->P_ADR);
181         cfi->cfiq->A_ID = le16_to_cpu(cfi->cfiq->A_ID);
182         cfi->cfiq->A_ADR = le16_to_cpu(cfi->cfiq->A_ADR);
183         cfi->cfiq->InterfaceDesc = le16_to_cpu(cfi->cfiq->InterfaceDesc);
184         cfi->cfiq->MaxBufWriteSize = le16_to_cpu(cfi->cfiq->MaxBufWriteSize);
185
186 #ifdef DEBUG_CFI
187         /* Dump the information therein */
188         print_cfi_ident(cfi->cfiq);
189 #endif
190
191         for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
192                 cfi->cfiq->EraseRegionInfo[i] = le32_to_cpu(cfi->cfiq->EraseRegionInfo[i]);
193                 
194 #ifdef DEBUG_CFI                
195                 printk("  Erase Region #%d: BlockSize 0x%4.4X bytes, %d blocks\n",
196                        i, (cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff, 
197                        (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1);
198 #endif
199         }
200
201         /* Note we put the device back into Read Mode BEFORE going into Auto
202          * Select Mode, as some devices support nesting of modes, others
203          * don't. This way should always work.
204          * On cmdset 0001 the writes of 0xaa and 0x55 are not needed, and
205          * so should be treated as nops or illegal (and so put the device
206          * back into Read Mode, which is a nop in this case).
207          */
208         cfi_send_gen_cmd(0xf0,     0, base, map, cfi, cfi->device_type, NULL);
209         cfi_send_gen_cmd(0xaa, 0x555, base, map, cfi, cfi->device_type, NULL);
210         cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL);
211         cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL);
212         cfi->mfr = cfi_read_query(map, base);
213         cfi->id = cfi_read_query(map, base + ofs_factor);    
214
215         /* Put it back into Read Mode */
216         cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
217         /* ... even if it's an Intel chip */
218         cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
219
220         printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n",
221                map->name, cfi->interleave, cfi->device_type*8, base,
222                map->bankwidth*8);
223
224         return 1;
225 }
226
227 #ifdef DEBUG_CFI
228 static char *vendorname(__u16 vendor) 
229 {
230         switch (vendor) {
231         case P_ID_NONE:
232                 return "None";
233                 
234         case P_ID_INTEL_EXT:
235                 return "Intel/Sharp Extended";
236                 
237         case P_ID_AMD_STD:
238                 return "AMD/Fujitsu Standard";
239                 
240         case P_ID_INTEL_STD:
241                 return "Intel/Sharp Standard";
242                 
243         case P_ID_AMD_EXT:
244                 return "AMD/Fujitsu Extended";
245
246         case P_ID_WINBOND:
247                 return "Winbond Standard";
248                 
249         case P_ID_ST_ADV:
250                 return "ST Advanced";
251
252         case P_ID_MITSUBISHI_STD:
253                 return "Mitsubishi Standard";
254                 
255         case P_ID_MITSUBISHI_EXT:
256                 return "Mitsubishi Extended";
257
258         case P_ID_SST_PAGE:
259                 return "SST Page Write";
260
261         case P_ID_INTEL_PERFORMANCE:
262                 return "Intel Performance Code";
263                 
264         case P_ID_INTEL_DATA:
265                 return "Intel Data";
266                 
267         case P_ID_RESERVED:
268                 return "Not Allowed / Reserved for Future Use";
269                 
270         default:
271                 return "Unknown";
272         }
273 }
274
275
276 static void print_cfi_ident(struct cfi_ident *cfip)
277 {
278 #if 0
279         if (cfip->qry[0] != 'Q' || cfip->qry[1] != 'R' || cfip->qry[2] != 'Y') {
280                 printk("Invalid CFI ident structure.\n");
281                 return;
282         }       
283 #endif          
284         printk("Primary Vendor Command Set: %4.4X (%s)\n", cfip->P_ID, vendorname(cfip->P_ID));
285         if (cfip->P_ADR)
286                 printk("Primary Algorithm Table at %4.4X\n", cfip->P_ADR);
287         else
288                 printk("No Primary Algorithm Table\n");
289         
290         printk("Alternative Vendor Command Set: %4.4X (%s)\n", cfip->A_ID, vendorname(cfip->A_ID));
291         if (cfip->A_ADR)
292                 printk("Alternate Algorithm Table at %4.4X\n", cfip->A_ADR);
293         else
294                 printk("No Alternate Algorithm Table\n");
295                 
296                 
297         printk("Vcc Minimum: %2d.%d V\n", cfip->VccMin >> 4, cfip->VccMin & 0xf);
298         printk("Vcc Maximum: %2d.%d V\n", cfip->VccMax >> 4, cfip->VccMax & 0xf);
299         if (cfip->VppMin) {
300                 printk("Vpp Minimum: %2d.%d V\n", cfip->VppMin >> 4, cfip->VppMin & 0xf);
301                 printk("Vpp Maximum: %2d.%d V\n", cfip->VppMax >> 4, cfip->VppMax & 0xf);
302         }
303         else
304                 printk("No Vpp line\n");
305         
306         printk("Typical byte/word write timeout: %d µs\n", 1<<cfip->WordWriteTimeoutTyp);
307         printk("Maximum byte/word write timeout: %d µs\n", (1<<cfip->WordWriteTimeoutMax) * (1<<cfip->WordWriteTimeoutTyp));
308         
309         if (cfip->BufWriteTimeoutTyp || cfip->BufWriteTimeoutMax) {
310                 printk("Typical full buffer write timeout: %d µs\n", 1<<cfip->BufWriteTimeoutTyp);
311                 printk("Maximum full buffer write timeout: %d µs\n", (1<<cfip->BufWriteTimeoutMax) * (1<<cfip->BufWriteTimeoutTyp));
312         }
313         else
314                 printk("Full buffer write not supported\n");
315         
316         printk("Typical block erase timeout: %d ms\n", 1<<cfip->BlockEraseTimeoutTyp);
317         printk("Maximum block erase timeout: %d ms\n", (1<<cfip->BlockEraseTimeoutMax) * (1<<cfip->BlockEraseTimeoutTyp));
318         if (cfip->ChipEraseTimeoutTyp || cfip->ChipEraseTimeoutMax) {
319                 printk("Typical chip erase timeout: %d ms\n", 1<<cfip->ChipEraseTimeoutTyp); 
320                 printk("Maximum chip erase timeout: %d ms\n", (1<<cfip->ChipEraseTimeoutMax) * (1<<cfip->ChipEraseTimeoutTyp));
321         }
322         else
323                 printk("Chip erase not supported\n");
324         
325         printk("Device size: 0x%X bytes (%d MiB)\n", 1 << cfip->DevSize, 1<< (cfip->DevSize - 20));
326         printk("Flash Device Interface description: 0x%4.4X\n", cfip->InterfaceDesc);
327         switch(cfip->InterfaceDesc) {
328         case 0:
329                 printk("  - x8-only asynchronous interface\n");
330                 break;
331                 
332         case 1:
333                 printk("  - x16-only asynchronous interface\n");
334                 break;
335                 
336         case 2:
337                 printk("  - supports x8 and x16 via BYTE# with asynchronous interface\n");
338                 break;
339                 
340         case 3:
341                 printk("  - x32-only asynchronous interface\n");
342                 break;
343                 
344         case 4:
345                 printk("  - supports x16 and x32 via Word# with asynchronous interface\n");
346                 break;
347                 
348         case 65535:
349                 printk("  - Not Allowed / Reserved\n");
350                 break;
351                 
352         default:
353                 printk("  - Unknown\n");
354                 break;
355         }
356         
357         printk("Max. bytes in buffer write: 0x%x\n", 1<< cfip->MaxBufWriteSize);
358         printk("Number of Erase Block Regions: %d\n", cfip->NumEraseRegions);
359         
360 }
361 #endif /* DEBUG_CFI */
362
363 static struct chip_probe cfi_chip_probe = {
364         .name           = "CFI",
365         .probe_chip     = cfi_probe_chip
366 };
367
368 struct mtd_info *cfi_probe(struct map_info *map)
369 {
370         /*
371          * Just use the generic probe stuff to call our CFI-specific
372          * chip_probe routine in all the possible permutations, etc.
373          */
374         return mtd_do_chip_probe(map, &cfi_chip_probe);
375 }
376
377 static struct mtd_chip_driver cfi_chipdrv = {
378         .probe          = cfi_probe,
379         .name           = "cfi_probe",
380         .module         = THIS_MODULE
381 };
382
383 int __init cfi_probe_init(void)
384 {
385         register_mtd_chip_driver(&cfi_chipdrv);
386         return 0;
387 }
388
389 static void __exit cfi_probe_exit(void)
390 {
391         unregister_mtd_chip_driver(&cfi_chipdrv);
392 }
393
394 module_init(cfi_probe_init);
395 module_exit(cfi_probe_exit);
396
397 MODULE_LICENSE("GPL");
398 MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org> et al.");
399 MODULE_DESCRIPTION("Probe code for CFI-compliant flash chips");