hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/mtd/nand/spi/unim.c
....@@ -10,7 +10,8 @@
1010 #include <linux/kernel.h>
1111 #include <linux/mtd/spinand.h>
1212
13
-#define SPINAND_MFR_UNIM 0xA1
13
+#define SPINAND_MFR_UNIM_ZL 0xA1
14
+#define SPINAND_MFR_UNIM 0xB0
1415
1516 static SPINAND_OP_VARIANTS(read_cache_variants,
1617 SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
....@@ -57,6 +58,59 @@
5758 .free = tx25g01_ooblayout_free,
5859 };
5960
61
+
62
+static int um19a0xisw_ooblayout_ecc(struct mtd_info *mtd, int section,
63
+ struct mtd_oob_region *region)
64
+{
65
+ return -ERANGE;
66
+}
67
+
68
+static int um19a0xisw_ooblayout_free(struct mtd_info *mtd, int section,
69
+ struct mtd_oob_region *region)
70
+{
71
+ if (section)
72
+ return -ERANGE;
73
+
74
+ region->offset = 2;
75
+ region->length = 62;
76
+
77
+ return 0;
78
+}
79
+
80
+static const struct mtd_ooblayout_ops um19a0xisw_ooblayout = {
81
+ .ecc = um19a0xisw_ooblayout_ecc,
82
+ .free = um19a0xisw_ooblayout_free,
83
+};
84
+
85
+static int um19a1xisw_ooblayout_ecc(struct mtd_info *mtd, int section,
86
+ struct mtd_oob_region *region)
87
+{
88
+ if (section)
89
+ return -ERANGE;
90
+
91
+ region->offset = 64;
92
+ region->length = 64;
93
+
94
+ return 0;
95
+}
96
+
97
+static int um19a1xisw_ooblayout_free(struct mtd_info *mtd, int section,
98
+ struct mtd_oob_region *region)
99
+{
100
+ if (section)
101
+ return -ERANGE;
102
+
103
+ region->offset = 2;
104
+ region->length = 62;
105
+
106
+ return 0;
107
+}
108
+
109
+static const struct mtd_ooblayout_ops um19a1xisw_ooblayout = {
110
+ .ecc = um19a1xisw_ooblayout_ecc,
111
+ .free = um19a1xisw_ooblayout_free,
112
+};
113
+
60114 /*
61115 * ecc bits: 0xC0[4,6]
62116 * [0b000], No bit errors were detected;
....@@ -80,7 +134,32 @@
80134 return -EBADMSG;
81135 }
82136
83
-static const struct spinand_info unim_spinand_table[] = {
137
+/*
138
+ * ecc bits: 0xC0[4,6]
139
+ * [0b000], No bit errors were detected;
140
+ * [0b001] and [0b011], 1~6 Bit errors were detected and corrected. Not
141
+ * reach Flipping Bits;
142
+ * [0b101], Bit error count equals the bit flip
143
+ * detection threshold
144
+ * [0b010], Multiple bit errors were detected and
145
+ * not corrected.
146
+ * others, Reserved.
147
+ */
148
+static int um19axxisw_ecc_ecc_get_status(struct spinand_device *spinand,
149
+ u8 status)
150
+{
151
+ struct nand_device *nand = spinand_to_nand(spinand);
152
+ u8 eccsr = (status & GENMASK(6, 4)) >> 4;
153
+
154
+ if (eccsr <= 1 || eccsr == 3)
155
+ return eccsr;
156
+ else if (eccsr == 5)
157
+ return nanddev_get_ecc_requirements(nand)->strength;
158
+ else
159
+ return -EBADMSG;
160
+}
161
+
162
+static const struct spinand_info unim_zl_spinand_table[] = {
84163 SPINAND_INFO("TX25G01",
85164 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xF1),
86165 NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
....@@ -92,9 +171,56 @@
92171 SPINAND_ECCINFO(&tx25g01_ooblayout, tx25g01_ecc_get_status)),
93172 };
94173
174
+static const struct spinand_info unim_spinand_table[] = {
175
+ SPINAND_INFO("UM19A1HISW",
176
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x24),
177
+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
178
+ NAND_ECCREQ(8, 512),
179
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
180
+ &write_cache_variants,
181
+ &update_cache_variants),
182
+ SPINAND_HAS_QE_BIT,
183
+ SPINAND_ECCINFO(&um19a1xisw_ooblayout, um19axxisw_ecc_ecc_get_status)),
184
+ SPINAND_INFO("UM19A0HCSW",
185
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x14),
186
+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
187
+ NAND_ECCREQ(8, 512),
188
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
189
+ &write_cache_variants,
190
+ &update_cache_variants),
191
+ SPINAND_HAS_QE_BIT,
192
+ SPINAND_ECCINFO(&um19a0xisw_ooblayout, um19axxisw_ecc_ecc_get_status)),
193
+ SPINAND_INFO("UM19A0LCSW",
194
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x15),
195
+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
196
+ NAND_ECCREQ(8, 512),
197
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
198
+ &write_cache_variants,
199
+ &update_cache_variants),
200
+ SPINAND_HAS_QE_BIT,
201
+ SPINAND_ECCINFO(&um19a0xisw_ooblayout, um19axxisw_ecc_ecc_get_status)),
202
+ SPINAND_INFO("UM19A1LISW",
203
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x25),
204
+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
205
+ NAND_ECCREQ(8, 512),
206
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
207
+ &write_cache_variants,
208
+ &update_cache_variants),
209
+ SPINAND_HAS_QE_BIT,
210
+ SPINAND_ECCINFO(&um19a1xisw_ooblayout, um19axxisw_ecc_ecc_get_status)),
211
+};
212
+
95213 static const struct spinand_manufacturer_ops unim_spinand_manuf_ops = {
96214 };
97215
216
+const struct spinand_manufacturer unim_zl_spinand_manufacturer = {
217
+ .id = SPINAND_MFR_UNIM_ZL,
218
+ .name = "UNIM_ZL",
219
+ .chips = unim_zl_spinand_table,
220
+ .nchips = ARRAY_SIZE(unim_zl_spinand_table),
221
+ .ops = &unim_spinand_manuf_ops,
222
+};
223
+
98224 const struct spinand_manufacturer unim_spinand_manufacturer = {
99225 .id = SPINAND_MFR_UNIM,
100226 .name = "UNIM",