1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | Common Flash Interface probe code. |
4 | (C) 2000 Red Hat. |
5 | */ |
6 | |
7 | #include <linux/module.h> |
8 | #include <linux/types.h> |
9 | #include <linux/kernel.h> |
10 | #include <linux/init.h> |
11 | #include <asm/io.h> |
12 | #include <asm/byteorder.h> |
13 | #include <linux/errno.h> |
14 | #include <linux/slab.h> |
15 | #include <linux/interrupt.h> |
16 | |
17 | #include <linux/mtd/xip.h> |
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 | #ifdef CONFIG_MTD_XIP |
35 | |
36 | /* only needed for short periods, so this is rather simple */ |
37 | #define xip_disable() local_irq_disable() |
38 | |
39 | #define xip_allowed(base, map) \ |
40 | do { \ |
41 | (void) map_read(map, base); \ |
42 | xip_iprefetch(); \ |
43 | local_irq_enable(); \ |
44 | } while (0) |
45 | |
46 | #define xip_enable(base, map, cfi) \ |
47 | do { \ |
48 | cfi_qry_mode_off(base, map, cfi); \ |
49 | xip_allowed(base, map); \ |
50 | } while (0) |
51 | |
52 | #define xip_disable_qry(base, map, cfi) \ |
53 | do { \ |
54 | xip_disable(); \ |
55 | cfi_qry_mode_on(base, map, cfi); \ |
56 | } while (0) |
57 | |
58 | #else |
59 | |
60 | #define xip_disable() do { } while (0) |
61 | #define xip_allowed(base, map) do { } while (0) |
62 | #define xip_enable(base, map, cfi) do { } while (0) |
63 | #define xip_disable_qry(base, map, cfi) do { } while (0) |
64 | |
65 | #endif |
66 | |
67 | /* |
68 | * This fixup occurs immediately after reading the CFI structure and can affect |
69 | * the number of chips detected, unlike cfi_fixup, which occurs after an |
70 | * mtd_info structure has been created for the chip. |
71 | */ |
72 | struct cfi_early_fixup { |
73 | uint16_t mfr; |
74 | uint16_t id; |
75 | void (*fixup)(struct cfi_private *cfi); |
76 | }; |
77 | |
78 | static void cfi_early_fixup(struct cfi_private *cfi, |
79 | const struct cfi_early_fixup *fixups) |
80 | { |
81 | const struct cfi_early_fixup *f; |
82 | |
83 | for (f = fixups; f->fixup; f++) { |
84 | if (((f->mfr == CFI_MFR_ANY) || (f->mfr == cfi->mfr)) && |
85 | ((f->id == CFI_ID_ANY) || (f->id == cfi->id))) { |
86 | f->fixup(cfi); |
87 | } |
88 | } |
89 | } |
90 | |
91 | /* check for QRY. |
92 | in: interleave,type,mode |
93 | ret: table index, <0 for error |
94 | */ |
95 | |
96 | static int __xipram cfi_probe_chip(struct map_info *map, __u32 base, |
97 | unsigned long *chip_map, struct cfi_private *cfi) |
98 | { |
99 | int i; |
100 | |
101 | if ((base + 0) >= map->size) { |
102 | printk(KERN_NOTICE |
103 | "Probe at base[0x00](0x%08lx) past the end of the map(0x%08lx)\n" , |
104 | (unsigned long)base, map->size -1); |
105 | return 0; |
106 | } |
107 | if ((base + 0xff) >= map->size) { |
108 | printk(KERN_NOTICE |
109 | "Probe at base[0x55](0x%08lx) past the end of the map(0x%08lx)\n" , |
110 | (unsigned long)base + 0x55, map->size -1); |
111 | return 0; |
112 | } |
113 | |
114 | xip_disable(); |
115 | if (!cfi_qry_mode_on(base, map, cfi)) { |
116 | xip_enable(base, map, cfi); |
117 | return 0; |
118 | } |
119 | |
120 | if (!cfi->numchips) { |
121 | /* This is the first time we're called. Set up the CFI |
122 | stuff accordingly and return */ |
123 | return cfi_chip_setup(map, cfi); |
124 | } |
125 | |
126 | /* Check each previous chip to see if it's an alias */ |
127 | for (i=0; i < (base >> cfi->chipshift); i++) { |
128 | unsigned long start; |
129 | if(!test_bit(i, chip_map)) { |
130 | /* Skip location; no valid chip at this address */ |
131 | continue; |
132 | } |
133 | start = i << cfi->chipshift; |
134 | /* This chip should be in read mode if it's one |
135 | we've already touched. */ |
136 | if (cfi_qry_present(map, base: start, cfi)) { |
137 | /* Eep. This chip also had the QRY marker. |
138 | * Is it an alias for the new one? */ |
139 | cfi_qry_mode_off(base: start, map, cfi); |
140 | |
141 | /* If the QRY marker goes away, it's an alias */ |
142 | if (!cfi_qry_present(map, base: start, cfi)) { |
143 | xip_allowed(base, map); |
144 | printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n" , |
145 | map->name, base, start); |
146 | return 0; |
147 | } |
148 | /* Yes, it's actually got QRY for data. Most |
149 | * unfortunate. Stick the new chip in read mode |
150 | * too and if it's the same, assume it's an alias. */ |
151 | /* FIXME: Use other modes to do a proper check */ |
152 | cfi_qry_mode_off(base, map, cfi); |
153 | |
154 | if (cfi_qry_present(map, base, cfi)) { |
155 | xip_allowed(base, map); |
156 | printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n" , |
157 | map->name, base, start); |
158 | return 0; |
159 | } |
160 | } |
161 | } |
162 | |
163 | /* OK, if we got to here, then none of the previous chips appear to |
164 | be aliases for the current one. */ |
165 | set_bit(nr: (base >> cfi->chipshift), addr: chip_map); /* Update chip map */ |
166 | cfi->numchips++; |
167 | |
168 | /* Put it back into Read Mode */ |
169 | cfi_qry_mode_off(base, map, cfi); |
170 | xip_allowed(base, map); |
171 | |
172 | printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n" , |
173 | map->name, cfi->interleave, cfi->device_type*8, base, |
174 | map->bankwidth*8); |
175 | |
176 | return 1; |
177 | } |
178 | |
179 | static void fixup_s70gl02gs_chips(struct cfi_private *cfi) |
180 | { |
181 | /* |
182 | * S70GL02GS flash reports a single 256 MiB chip, but is really made up |
183 | * of two 128 MiB chips with 1024 sectors each. |
184 | */ |
185 | cfi->cfiq->DevSize = 27; |
186 | cfi->cfiq->EraseRegionInfo[0] = 0x20003ff; |
187 | pr_warn("Bad S70GL02GS CFI data; adjust to detect 2 chips\n" ); |
188 | } |
189 | |
190 | static const struct cfi_early_fixup cfi_early_fixup_table[] = { |
191 | { CFI_MFR_AMD, 0x4801, fixup_s70gl02gs_chips }, |
192 | { }, |
193 | }; |
194 | |
195 | static int __xipram cfi_chip_setup(struct map_info *map, |
196 | struct cfi_private *cfi) |
197 | { |
198 | int ofs_factor = cfi->interleave*cfi->device_type; |
199 | __u32 base = 0; |
200 | int num_erase_regions = cfi_read_query(map, addr: base + (0x10 + 28)*ofs_factor); |
201 | int i; |
202 | int addr_unlock1 = 0x555, addr_unlock2 = 0x2AA; |
203 | |
204 | xip_enable(base, map, cfi); |
205 | #ifdef DEBUG_CFI |
206 | printk("Number of erase regions: %d\n" , num_erase_regions); |
207 | #endif |
208 | if (!num_erase_regions) |
209 | return 0; |
210 | |
211 | cfi->cfiq = kmalloc(size: sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL); |
212 | if (!cfi->cfiq) |
213 | return 0; |
214 | |
215 | memset(cfi->cfiq,0,sizeof(struct cfi_ident)); |
216 | |
217 | cfi->cfi_mode = CFI_MODE_CFI; |
218 | |
219 | cfi->sector_erase_cmd = CMD(0x30); |
220 | |
221 | /* Read the CFI info structure */ |
222 | xip_disable_qry(base, map, cfi); |
223 | for (i=0; i<(sizeof(struct cfi_ident) + num_erase_regions * 4); i++) |
224 | ((unsigned char *)cfi->cfiq)[i] = cfi_read_query(map,addr: base + (0x10 + i)*ofs_factor); |
225 | |
226 | /* Do any necessary byteswapping */ |
227 | cfi->cfiq->P_ID = le16_to_cpu(cfi->cfiq->P_ID); |
228 | |
229 | cfi->cfiq->P_ADR = le16_to_cpu(cfi->cfiq->P_ADR); |
230 | cfi->cfiq->A_ID = le16_to_cpu(cfi->cfiq->A_ID); |
231 | cfi->cfiq->A_ADR = le16_to_cpu(cfi->cfiq->A_ADR); |
232 | cfi->cfiq->InterfaceDesc = le16_to_cpu(cfi->cfiq->InterfaceDesc); |
233 | cfi->cfiq->MaxBufWriteSize = le16_to_cpu(cfi->cfiq->MaxBufWriteSize); |
234 | |
235 | #ifdef DEBUG_CFI |
236 | /* Dump the information therein */ |
237 | print_cfi_ident(cfi->cfiq); |
238 | #endif |
239 | |
240 | for (i=0; i<cfi->cfiq->NumEraseRegions; i++) { |
241 | cfi->cfiq->EraseRegionInfo[i] = le32_to_cpu(cfi->cfiq->EraseRegionInfo[i]); |
242 | |
243 | #ifdef DEBUG_CFI |
244 | printk(" Erase Region #%d: BlockSize 0x%4.4X bytes, %d blocks\n" , |
245 | i, (cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff, |
246 | (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1); |
247 | #endif |
248 | } |
249 | |
250 | if (cfi->cfiq->P_ID == P_ID_SST_OLD) { |
251 | addr_unlock1 = 0x5555; |
252 | addr_unlock2 = 0x2AAA; |
253 | } |
254 | |
255 | /* |
256 | * Note we put the device back into Read Mode BEFORE going into Auto |
257 | * Select Mode, as some devices support nesting of modes, others |
258 | * don't. This way should always work. |
259 | * On cmdset 0001 the writes of 0xaa and 0x55 are not needed, and |
260 | * so should be treated as nops or illegal (and so put the device |
261 | * back into Read Mode, which is a nop in this case). |
262 | */ |
263 | cfi_send_gen_cmd(cmd: 0xf0, cmd_addr: 0, base, map, cfi, type: cfi->device_type, NULL); |
264 | cfi_send_gen_cmd(cmd: 0xaa, cmd_addr: addr_unlock1, base, map, cfi, type: cfi->device_type, NULL); |
265 | cfi_send_gen_cmd(cmd: 0x55, cmd_addr: addr_unlock2, base, map, cfi, type: cfi->device_type, NULL); |
266 | cfi_send_gen_cmd(cmd: 0x90, cmd_addr: addr_unlock1, base, map, cfi, type: cfi->device_type, NULL); |
267 | cfi->mfr = cfi_read_query16(map, addr: base); |
268 | cfi->id = cfi_read_query16(map, addr: base + ofs_factor); |
269 | |
270 | /* Get AMD/Spansion extended JEDEC ID */ |
271 | if (cfi->mfr == CFI_MFR_AMD && (cfi->id & 0xff) == 0x7e) |
272 | cfi->id = cfi_read_query(map, addr: base + 0xe * ofs_factor) << 8 | |
273 | cfi_read_query(map, addr: base + 0xf * ofs_factor); |
274 | |
275 | /* Put it back into Read Mode */ |
276 | cfi_qry_mode_off(base, map, cfi); |
277 | xip_allowed(base, map); |
278 | |
279 | cfi_early_fixup(cfi, fixups: cfi_early_fixup_table); |
280 | |
281 | printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank. Manufacturer ID %#08x Chip ID %#08x\n" , |
282 | map->name, cfi->interleave, cfi->device_type*8, base, |
283 | map->bankwidth*8, cfi->mfr, cfi->id); |
284 | |
285 | return 1; |
286 | } |
287 | |
288 | #ifdef DEBUG_CFI |
289 | static char *vendorname(__u16 vendor) |
290 | { |
291 | switch (vendor) { |
292 | case P_ID_NONE: |
293 | return "None" ; |
294 | |
295 | case P_ID_INTEL_EXT: |
296 | return "Intel/Sharp Extended" ; |
297 | |
298 | case P_ID_AMD_STD: |
299 | return "AMD/Fujitsu Standard" ; |
300 | |
301 | case P_ID_INTEL_STD: |
302 | return "Intel/Sharp Standard" ; |
303 | |
304 | case P_ID_AMD_EXT: |
305 | return "AMD/Fujitsu Extended" ; |
306 | |
307 | case P_ID_WINBOND: |
308 | return "Winbond Standard" ; |
309 | |
310 | case P_ID_ST_ADV: |
311 | return "ST Advanced" ; |
312 | |
313 | case P_ID_MITSUBISHI_STD: |
314 | return "Mitsubishi Standard" ; |
315 | |
316 | case P_ID_MITSUBISHI_EXT: |
317 | return "Mitsubishi Extended" ; |
318 | |
319 | case P_ID_SST_PAGE: |
320 | return "SST Page Write" ; |
321 | |
322 | case P_ID_SST_OLD: |
323 | return "SST 39VF160x/39VF320x" ; |
324 | |
325 | case P_ID_INTEL_PERFORMANCE: |
326 | return "Intel Performance Code" ; |
327 | |
328 | case P_ID_INTEL_DATA: |
329 | return "Intel Data" ; |
330 | |
331 | case P_ID_RESERVED: |
332 | return "Not Allowed / Reserved for Future Use" ; |
333 | |
334 | default: |
335 | return "Unknown" ; |
336 | } |
337 | } |
338 | |
339 | |
340 | static void print_cfi_ident(struct cfi_ident *cfip) |
341 | { |
342 | #if 0 |
343 | if (cfip->qry[0] != 'Q' || cfip->qry[1] != 'R' || cfip->qry[2] != 'Y') { |
344 | printk("Invalid CFI ident structure.\n" ); |
345 | return; |
346 | } |
347 | #endif |
348 | printk("Primary Vendor Command Set: %4.4X (%s)\n" , cfip->P_ID, vendorname(cfip->P_ID)); |
349 | if (cfip->P_ADR) |
350 | printk("Primary Algorithm Table at %4.4X\n" , cfip->P_ADR); |
351 | else |
352 | printk("No Primary Algorithm Table\n" ); |
353 | |
354 | printk("Alternative Vendor Command Set: %4.4X (%s)\n" , cfip->A_ID, vendorname(cfip->A_ID)); |
355 | if (cfip->A_ADR) |
356 | printk("Alternate Algorithm Table at %4.4X\n" , cfip->A_ADR); |
357 | else |
358 | printk("No Alternate Algorithm Table\n" ); |
359 | |
360 | |
361 | printk("Vcc Minimum: %2d.%d V\n" , cfip->VccMin >> 4, cfip->VccMin & 0xf); |
362 | printk("Vcc Maximum: %2d.%d V\n" , cfip->VccMax >> 4, cfip->VccMax & 0xf); |
363 | if (cfip->VppMin) { |
364 | printk("Vpp Minimum: %2d.%d V\n" , cfip->VppMin >> 4, cfip->VppMin & 0xf); |
365 | printk("Vpp Maximum: %2d.%d V\n" , cfip->VppMax >> 4, cfip->VppMax & 0xf); |
366 | } |
367 | else |
368 | printk("No Vpp line\n" ); |
369 | |
370 | printk("Typical byte/word write timeout: %d µs\n" , 1<<cfip->WordWriteTimeoutTyp); |
371 | printk("Maximum byte/word write timeout: %d µs\n" , (1<<cfip->WordWriteTimeoutMax) * (1<<cfip->WordWriteTimeoutTyp)); |
372 | |
373 | if (cfip->BufWriteTimeoutTyp || cfip->BufWriteTimeoutMax) { |
374 | printk("Typical full buffer write timeout: %d µs\n" , 1<<cfip->BufWriteTimeoutTyp); |
375 | printk("Maximum full buffer write timeout: %d µs\n" , (1<<cfip->BufWriteTimeoutMax) * (1<<cfip->BufWriteTimeoutTyp)); |
376 | } |
377 | else |
378 | printk("Full buffer write not supported\n" ); |
379 | |
380 | printk("Typical block erase timeout: %d ms\n" , 1<<cfip->BlockEraseTimeoutTyp); |
381 | printk("Maximum block erase timeout: %d ms\n" , (1<<cfip->BlockEraseTimeoutMax) * (1<<cfip->BlockEraseTimeoutTyp)); |
382 | if (cfip->ChipEraseTimeoutTyp || cfip->ChipEraseTimeoutMax) { |
383 | printk("Typical chip erase timeout: %d ms\n" , 1<<cfip->ChipEraseTimeoutTyp); |
384 | printk("Maximum chip erase timeout: %d ms\n" , (1<<cfip->ChipEraseTimeoutMax) * (1<<cfip->ChipEraseTimeoutTyp)); |
385 | } |
386 | else |
387 | printk("Chip erase not supported\n" ); |
388 | |
389 | printk("Device size: 0x%X bytes (%d MiB)\n" , 1 << cfip->DevSize, 1<< (cfip->DevSize - 20)); |
390 | printk("Flash Device Interface description: 0x%4.4X\n" , cfip->InterfaceDesc); |
391 | switch(cfip->InterfaceDesc) { |
392 | case CFI_INTERFACE_X8_ASYNC: |
393 | printk(" - x8-only asynchronous interface\n" ); |
394 | break; |
395 | |
396 | case CFI_INTERFACE_X16_ASYNC: |
397 | printk(" - x16-only asynchronous interface\n" ); |
398 | break; |
399 | |
400 | case CFI_INTERFACE_X8_BY_X16_ASYNC: |
401 | printk(" - supports x8 and x16 via BYTE# with asynchronous interface\n" ); |
402 | break; |
403 | |
404 | case CFI_INTERFACE_X32_ASYNC: |
405 | printk(" - x32-only asynchronous interface\n" ); |
406 | break; |
407 | |
408 | case CFI_INTERFACE_X16_BY_X32_ASYNC: |
409 | printk(" - supports x16 and x32 via Word# with asynchronous interface\n" ); |
410 | break; |
411 | |
412 | case CFI_INTERFACE_NOT_ALLOWED: |
413 | printk(" - Not Allowed / Reserved\n" ); |
414 | break; |
415 | |
416 | default: |
417 | printk(" - Unknown\n" ); |
418 | break; |
419 | } |
420 | |
421 | printk("Max. bytes in buffer write: 0x%x\n" , 1<< cfip->MaxBufWriteSize); |
422 | printk("Number of Erase Block Regions: %d\n" , cfip->NumEraseRegions); |
423 | |
424 | } |
425 | #endif /* DEBUG_CFI */ |
426 | |
427 | static struct chip_probe cfi_chip_probe = { |
428 | .name = "CFI" , |
429 | .probe_chip = cfi_probe_chip |
430 | }; |
431 | |
432 | struct mtd_info *cfi_probe(struct map_info *map) |
433 | { |
434 | /* |
435 | * Just use the generic probe stuff to call our CFI-specific |
436 | * chip_probe routine in all the possible permutations, etc. |
437 | */ |
438 | return mtd_do_chip_probe(map, cp: &cfi_chip_probe); |
439 | } |
440 | |
441 | static struct mtd_chip_driver cfi_chipdrv = { |
442 | .probe = cfi_probe, |
443 | .name = "cfi_probe" , |
444 | .module = THIS_MODULE |
445 | }; |
446 | |
447 | static int __init cfi_probe_init(void) |
448 | { |
449 | register_mtd_chip_driver(&cfi_chipdrv); |
450 | return 0; |
451 | } |
452 | |
453 | static void __exit cfi_probe_exit(void) |
454 | { |
455 | unregister_mtd_chip_driver(&cfi_chipdrv); |
456 | } |
457 | |
458 | module_init(cfi_probe_init); |
459 | module_exit(cfi_probe_exit); |
460 | |
461 | MODULE_LICENSE("GPL" ); |
462 | MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org> et al." ); |
463 | MODULE_DESCRIPTION("Probe code for CFI-compliant flash chips" ); |
464 | |