diff options
Diffstat (limited to 'drivers/mtd/chips/cfi_util.c')
-rw-r--r-- | drivers/mtd/chips/cfi_util.c | 62 |
1 files changed, 58 insertions, 4 deletions
diff --git a/drivers/mtd/chips/cfi_util.c b/drivers/mtd/chips/cfi_util.c index 0ee457018016..8d7553670526 100644 --- a/drivers/mtd/chips/cfi_util.c +++ b/drivers/mtd/chips/cfi_util.c | |||
@@ -24,6 +24,62 @@ | |||
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 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 | |||
54 | int __xipram qry_mode_on(uint32_t base, struct map_info *map, | ||
55 | struct cfi_private *cfi) | ||
56 | { | ||
57 | cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); | ||
58 | cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); | ||
59 | if (qry_present(map, base, cfi)) | ||
60 | return 1; | ||
61 | /* QRY not found probably we deal with some odd CFI chips */ | ||
62 | /* Some revisions of some old Intel chips? */ | ||
63 | cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); | ||
64 | cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); | ||
65 | cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); | ||
66 | if (qry_present(map, base, cfi)) | ||
67 | return 1; | ||
68 | /* ST M29DW chips */ | ||
69 | cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); | ||
70 | cfi_send_gen_cmd(0x98, 0x555, base, map, cfi, cfi->device_type, NULL); | ||
71 | if (qry_present(map, base, cfi)) | ||
72 | return 1; | ||
73 | /* QRY not found */ | ||
74 | return 0; | ||
75 | } | ||
76 | void __xipram qry_mode_off(uint32_t base, struct map_info *map, | ||
77 | struct cfi_private *cfi) | ||
78 | { | ||
79 | cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); | ||
80 | cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); | ||
81 | } | ||
82 | |||
27 | struct cfi_extquery * | 83 | struct cfi_extquery * |
28 | __xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* name) | 84 | __xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* name) |
29 | { | 85 | { |
@@ -48,8 +104,7 @@ __xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* n | |||
48 | #endif | 104 | #endif |
49 | 105 | ||
50 | /* Switch it into Query Mode */ | 106 | /* Switch it into Query Mode */ |
51 | cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); | 107 | qry_mode_on(base, map, cfi); |
52 | |||
53 | /* Read in the Extended Query Table */ | 108 | /* Read in the Extended Query Table */ |
54 | for (i=0; i<size; i++) { | 109 | for (i=0; i<size; i++) { |
55 | ((unsigned char *)extp)[i] = | 110 | ((unsigned char *)extp)[i] = |
@@ -57,8 +112,7 @@ __xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* n | |||
57 | } | 112 | } |
58 | 113 | ||
59 | /* Make sure it returns to read mode */ | 114 | /* Make sure it returns to read mode */ |
60 | cfi_send_gen_cmd(0xf0, 0, base, map, cfi, cfi->device_type, NULL); | 115 | qry_mode_off(base, map, cfi); |
61 | cfi_send_gen_cmd(0xff, 0, base, map, cfi, cfi->device_type, NULL); | ||
62 | 116 | ||
63 | #ifdef CONFIG_MTD_XIP | 117 | #ifdef CONFIG_MTD_XIP |
64 | (void) map_read(map, base); | 118 | (void) map_read(map, base); |