aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/chips/cfi_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/chips/cfi_util.c')
-rw-r--r--drivers/mtd/chips/cfi_util.c62
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
27int __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
54int __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}
76void __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
27struct cfi_extquery * 83struct 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);