diff options
Diffstat (limited to 'drivers/mtd/chips/cfi_util.c')
-rw-r--r-- | drivers/mtd/chips/cfi_util.c | 66 |
1 files changed, 62 insertions, 4 deletions
diff --git a/drivers/mtd/chips/cfi_util.c b/drivers/mtd/chips/cfi_util.c index 0ee457018016..34d40e25d312 100644 --- a/drivers/mtd/chips/cfi_util.c +++ b/drivers/mtd/chips/cfi_util.c | |||
@@ -24,6 +24,66 @@ | |||
24 | #include <linux/mtd/cfi.h> | 24 | #include <linux/mtd/cfi.h> |
25 | #include <linux/mtd/compatmac.h> | 25 | #include <linux/mtd/compatmac.h> |
26 | 26 | ||
27 | int __xipram cfi_qry_present(struct map_info *map, __u32 base, | ||
28 | struct cfi_private *cfi) | ||
29 | { | ||
30 | int osf = cfi->interleave * cfi->device_type; /* scale factor */ | ||
31 | map_word val[3]; | ||
32 | map_word qry[3]; | ||
33 | |||
34 | qry[0] = cfi_build_cmd('Q', map, cfi); | ||
35 | qry[1] = cfi_build_cmd('R', map, cfi); | ||
36 | qry[2] = cfi_build_cmd('Y', map, cfi); | ||
37 | |||
38 | val[0] = map_read(map, base + osf*0x10); | ||
39 | val[1] = map_read(map, base + osf*0x11); | ||
40 | val[2] = map_read(map, base + osf*0x12); | ||
41 | |||
42 | if (!map_word_equal(map, qry[0], val[0])) | ||
43 | return 0; | ||
44 | |||
45 | if (!map_word_equal(map, qry[1], val[1])) | ||
46 | return 0; | ||
47 | |||
48 | if (!map_word_equal(map, qry[2], val[2])) | ||
49 | return 0; | ||
50 | |||
51 | return 1; /* "QRY" found */ | ||
52 | } | ||
53 | EXPORT_SYMBOL_GPL(cfi_qry_present); | ||
54 | |||
55 | int __xipram cfi_qry_mode_on(uint32_t base, struct map_info *map, | ||
56 | struct cfi_private *cfi) | ||
57 | { | ||
58 | cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); | ||
59 | cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); | ||
60 | if (cfi_qry_present(map, base, cfi)) | ||
61 | return 1; | ||
62 | /* QRY not found probably we deal with some odd CFI chips */ | ||
63 | /* Some revisions of some old Intel chips? */ | ||
64 | cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); | ||
65 | cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); | ||
66 | cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); | ||
67 | if (cfi_qry_present(map, base, cfi)) | ||
68 | return 1; | ||
69 | /* ST M29DW chips */ | ||
70 | cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); | ||
71 | cfi_send_gen_cmd(0x98, 0x555, base, map, cfi, cfi->device_type, NULL); | ||
72 | if (cfi_qry_present(map, base, cfi)) | ||
73 | return 1; | ||
74 | /* QRY not found */ | ||
75 | return 0; | ||
76 | } | ||
77 | EXPORT_SYMBOL_GPL(cfi_qry_mode_on); | ||
78 | |||
79 | void __xipram cfi_qry_mode_off(uint32_t base, struct map_info *map, | ||
80 | struct cfi_private *cfi) | ||
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 | } | ||
85 | EXPORT_SYMBOL_GPL(cfi_qry_mode_off); | ||
86 | |||
27 | struct cfi_extquery * | 87 | struct cfi_extquery * |
28 | __xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* name) | 88 | __xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* name) |
29 | { | 89 | { |
@@ -48,8 +108,7 @@ __xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* n | |||
48 | #endif | 108 | #endif |
49 | 109 | ||
50 | /* Switch it into Query Mode */ | 110 | /* Switch it into Query Mode */ |
51 | cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); | 111 | cfi_qry_mode_on(base, map, cfi); |
52 | |||
53 | /* Read in the Extended Query Table */ | 112 | /* Read in the Extended Query Table */ |
54 | for (i=0; i<size; i++) { | 113 | for (i=0; i<size; i++) { |
55 | ((unsigned char *)extp)[i] = | 114 | ((unsigned char *)extp)[i] = |
@@ -57,8 +116,7 @@ __xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* n | |||
57 | } | 116 | } |
58 | 117 | ||
59 | /* Make sure it returns to read mode */ | 118 | /* Make sure it returns to read mode */ |
60 | cfi_send_gen_cmd(0xf0, 0, base, map, cfi, cfi->device_type, NULL); | 119 | cfi_qry_mode_off(base, map, cfi); |
61 | cfi_send_gen_cmd(0xff, 0, base, map, cfi, cfi->device_type, NULL); | ||
62 | 120 | ||
63 | #ifdef CONFIG_MTD_XIP | 121 | #ifdef CONFIG_MTD_XIP |
64 | (void) map_read(map, base); | 122 | (void) map_read(map, base); |