1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2018 Macronix
4 *
5 * Author: Boris Brezillon <boris.brezillon@bootlin.com>
6 */
7
8#include <linux/bitfield.h>
9#include <linux/device.h>
10#include <linux/kernel.h>
11#include <linux/mtd/spinand.h>
12
13#define SPINAND_MFR_MACRONIX 0xC2
14#define MACRONIX_ECCSR_BF_LAST_PAGE(eccsr) FIELD_GET(GENMASK(3, 0), eccsr)
15#define MACRONIX_ECCSR_BF_ACCUMULATED_PAGES(eccsr) FIELD_GET(GENMASK(7, 4), eccsr)
16#define MACRONIX_CFG_CONT_READ BIT(2)
17#define MACRONIX_FEATURE_ADDR_READ_RETRY 0x70
18#define MACRONIX_NUM_READ_RETRY_MODES 5
19
20#define STATUS_ECC_HAS_BITFLIPS_THRESHOLD (3 << 4)
21
22/* Bitflip theshold configuration register */
23#define REG_CFG_BFT 0x10
24#define CFG_BFT(x) FIELD_PREP(GENMASK(7, 4), (x))
25
26struct macronix_priv {
27 bool cont_read;
28};
29
30static SPINAND_OP_VARIANTS(read_cache_variants,
31 SPINAND_PAGE_READ_FROM_CACHE_1S_1S_4S_OP(0, 1, NULL, 0),
32 SPINAND_PAGE_READ_FROM_CACHE_1S_1S_2S_OP(0, 1, NULL, 0),
33 SPINAND_PAGE_READ_FROM_CACHE_FAST_1S_1S_1S_OP(0, 1, NULL, 0),
34 SPINAND_PAGE_READ_FROM_CACHE_1S_1S_1S_OP(0, 1, NULL, 0));
35
36static SPINAND_OP_VARIANTS(write_cache_variants,
37 SPINAND_PROG_LOAD_1S_1S_4S_OP(true, 0, NULL, 0),
38 SPINAND_PROG_LOAD_1S_1S_1S_OP(false, 0, NULL, 0));
39
40static SPINAND_OP_VARIANTS(update_cache_variants,
41 SPINAND_PROG_LOAD_1S_1S_4S_OP(false, 0, NULL, 0),
42 SPINAND_PROG_LOAD_1S_1S_1S_OP(false, 0, NULL, 0));
43
44static int mx35lfxge4ab_ooblayout_ecc(struct mtd_info *mtd, int section,
45 struct mtd_oob_region *region)
46{
47 return -ERANGE;
48}
49
50static int mx35lfxge4ab_ooblayout_free(struct mtd_info *mtd, int section,
51 struct mtd_oob_region *region)
52{
53 if (section)
54 return -ERANGE;
55
56 region->offset = 2;
57 region->length = mtd->oobsize - 2;
58
59 return 0;
60}
61
62static const struct mtd_ooblayout_ops mx35lfxge4ab_ooblayout = {
63 .ecc = mx35lfxge4ab_ooblayout_ecc,
64 .free = mx35lfxge4ab_ooblayout_free,
65};
66
67static int macronix_get_eccsr(struct spinand_device *spinand, u8 *eccsr)
68{
69 struct macronix_priv *priv = spinand->priv;
70 struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(0x7c, 1),
71 SPI_MEM_OP_NO_ADDR,
72 SPI_MEM_OP_DUMMY(1, 1),
73 SPI_MEM_OP_DATA_IN(1, eccsr, 1));
74
75 int ret = spi_mem_exec_op(mem: spinand->spimem, op: &op);
76 if (ret)
77 return ret;
78
79 /*
80 * ECCSR exposes the number of bitflips for the last read page in bits [3:0].
81 * Continuous read compatible chips also expose the maximum number of
82 * bitflips for the whole (continuous) read operation in bits [7:4].
83 */
84 if (!priv->cont_read)
85 *eccsr = MACRONIX_ECCSR_BF_LAST_PAGE(*eccsr);
86 else
87 *eccsr = MACRONIX_ECCSR_BF_ACCUMULATED_PAGES(*eccsr);
88
89 return 0;
90}
91
92static int macronix_ecc_get_status(struct spinand_device *spinand,
93 u8 status)
94{
95 struct nand_device *nand = spinand_to_nand(spinand);
96 u8 eccsr;
97
98 switch (status & STATUS_ECC_MASK) {
99 case STATUS_ECC_NO_BITFLIPS:
100 return 0;
101
102 case STATUS_ECC_UNCOR_ERROR:
103 return -EBADMSG;
104
105 case STATUS_ECC_HAS_BITFLIPS:
106 /*
107 * Let's try to retrieve the real maximum number of bitflips
108 * in order to avoid forcing the wear-leveling layer to move
109 * data around if it's not necessary.
110 */
111 if (macronix_get_eccsr(spinand, eccsr: spinand->scratchbuf))
112 return nanddev_get_ecc_conf(nand)->strength;
113
114 eccsr = *spinand->scratchbuf;
115 if (WARN_ON(eccsr > nanddev_get_ecc_conf(nand)->strength || !eccsr))
116 return nanddev_get_ecc_conf(nand)->strength;
117
118 return eccsr;
119 default:
120 break;
121 }
122
123 return -EINVAL;
124}
125
126static int macronix_set_cont_read(struct spinand_device *spinand, bool enable)
127{
128 struct macronix_priv *priv = spinand->priv;
129 int ret;
130
131 ret = spinand_upd_cfg(spinand, MACRONIX_CFG_CONT_READ,
132 val: enable ? MACRONIX_CFG_CONT_READ : 0);
133 if (ret)
134 return ret;
135
136 priv->cont_read = enable;
137
138 return 0;
139}
140
141/**
142 * macronix_set_read_retry - Set the retry mode
143 * @spinand: SPI NAND device
144 * @retry_mode: Specify which retry mode to set
145 *
146 * Return: 0 on success, a negative error code otherwise.
147 */
148static int macronix_set_read_retry(struct spinand_device *spinand,
149 unsigned int retry_mode)
150{
151 struct spi_mem_op op = SPINAND_SET_FEATURE_1S_1S_1S_OP(MACRONIX_FEATURE_ADDR_READ_RETRY,
152 spinand->scratchbuf);
153
154 *spinand->scratchbuf = retry_mode;
155 return spi_mem_exec_op(mem: spinand->spimem, op: &op);
156}
157
158static const struct spinand_info macronix_spinand_table[] = {
159 SPINAND_INFO("MX35LF1GE4AB",
160 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x12),
161 NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
162 NAND_ECCREQ(4, 512),
163 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
164 &write_cache_variants,
165 &update_cache_variants),
166 SPINAND_HAS_QE_BIT,
167 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
168 macronix_ecc_get_status)),
169 SPINAND_INFO("MX35LF2GE4AB",
170 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x22),
171 NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 2, 1, 1),
172 NAND_ECCREQ(4, 512),
173 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
174 &write_cache_variants,
175 &update_cache_variants),
176 SPINAND_HAS_QE_BIT |
177 SPINAND_HAS_PROG_PLANE_SELECT_BIT |
178 SPINAND_HAS_READ_PLANE_SELECT_BIT,
179 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
180 SPINAND_INFO("MX35LF2GE4AD",
181 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x26, 0x03),
182 NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
183 NAND_ECCREQ(8, 512),
184 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
185 &write_cache_variants,
186 &update_cache_variants),
187 SPINAND_HAS_QE_BIT,
188 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
189 macronix_ecc_get_status),
190 SPINAND_CONT_READ(macronix_set_cont_read),
191 SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
192 macronix_set_read_retry)),
193 SPINAND_INFO("MX35LF4GE4AD",
194 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x37, 0x03),
195 NAND_MEMORG(1, 4096, 128, 64, 2048, 40, 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(&mx35lfxge4ab_ooblayout,
202 macronix_ecc_get_status),
203 SPINAND_CONT_READ(macronix_set_cont_read),
204 SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
205 macronix_set_read_retry)),
206 SPINAND_INFO("MX35LF1G24AD",
207 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x14, 0x03),
208 NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
209 NAND_ECCREQ(8, 512),
210 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
211 &write_cache_variants,
212 &update_cache_variants),
213 SPINAND_HAS_QE_BIT,
214 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL),
215 SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
216 macronix_set_read_retry)),
217 SPINAND_INFO("MX35LF2G24AD",
218 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x24, 0x03),
219 NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1),
220 NAND_ECCREQ(8, 512),
221 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
222 &write_cache_variants,
223 &update_cache_variants),
224 SPINAND_HAS_QE_BIT |
225 SPINAND_HAS_PROG_PLANE_SELECT_BIT,
226 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL),
227 SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
228 macronix_set_read_retry)),
229 SPINAND_INFO("MX35LF2G24AD-Z4I8",
230 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x64, 0x03),
231 NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
232 NAND_ECCREQ(8, 512),
233 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
234 &write_cache_variants,
235 &update_cache_variants),
236 SPINAND_HAS_QE_BIT,
237 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL),
238 SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
239 macronix_set_read_retry)),
240 SPINAND_INFO("MX35LF4G24AD",
241 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x35, 0x03),
242 NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 2, 1, 1),
243 NAND_ECCREQ(8, 512),
244 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
245 &write_cache_variants,
246 &update_cache_variants),
247 SPINAND_HAS_QE_BIT |
248 SPINAND_HAS_PROG_PLANE_SELECT_BIT,
249 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL),
250 SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
251 macronix_set_read_retry)),
252 SPINAND_INFO("MX35LF4G24AD-Z4I8",
253 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x75, 0x03),
254 NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
255 NAND_ECCREQ(8, 512),
256 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
257 &write_cache_variants,
258 &update_cache_variants),
259 SPINAND_HAS_QE_BIT,
260 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL),
261 SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
262 macronix_set_read_retry)),
263 SPINAND_INFO("MX31LF1GE4BC",
264 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x1e),
265 NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
266 NAND_ECCREQ(8, 512),
267 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
268 &write_cache_variants,
269 &update_cache_variants),
270 SPINAND_HAS_QE_BIT,
271 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
272 macronix_ecc_get_status)),
273 SPINAND_INFO("MX31UF1GE4BC",
274 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x9e),
275 NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
276 NAND_ECCREQ(8, 512),
277 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
278 &write_cache_variants,
279 &update_cache_variants),
280 SPINAND_HAS_QE_BIT,
281 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
282 macronix_ecc_get_status)),
283
284 SPINAND_INFO("MX35LF2G14AC",
285 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x20),
286 NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 2, 1, 1),
287 NAND_ECCREQ(4, 512),
288 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
289 &write_cache_variants,
290 &update_cache_variants),
291 SPINAND_HAS_QE_BIT |
292 SPINAND_HAS_PROG_PLANE_SELECT_BIT |
293 SPINAND_HAS_READ_PLANE_SELECT_BIT,
294 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
295 macronix_ecc_get_status)),
296 SPINAND_INFO("MX35UF4G24AD",
297 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xb5, 0x03),
298 NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 2, 1, 1),
299 NAND_ECCREQ(8, 512),
300 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
301 &write_cache_variants,
302 &update_cache_variants),
303 SPINAND_HAS_QE_BIT |
304 SPINAND_HAS_PROG_PLANE_SELECT_BIT,
305 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
306 macronix_ecc_get_status),
307 SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
308 macronix_set_read_retry)),
309 SPINAND_INFO("MX35UF4G24AD-Z4I8",
310 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xf5, 0x03),
311 NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
312 NAND_ECCREQ(8, 512),
313 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
314 &write_cache_variants,
315 &update_cache_variants),
316 SPINAND_HAS_QE_BIT,
317 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
318 macronix_ecc_get_status),
319 SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
320 macronix_set_read_retry)),
321 SPINAND_INFO("MX35UF4GE4AD",
322 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xb7, 0x03),
323 NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
324 NAND_ECCREQ(8, 512),
325 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
326 &write_cache_variants,
327 &update_cache_variants),
328 SPINAND_HAS_QE_BIT,
329 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
330 macronix_ecc_get_status),
331 SPINAND_CONT_READ(macronix_set_cont_read),
332 SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
333 macronix_set_read_retry)),
334 SPINAND_INFO("MX35UF2G14AC",
335 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa0),
336 NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 2, 1, 1),
337 NAND_ECCREQ(4, 512),
338 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
339 &write_cache_variants,
340 &update_cache_variants),
341 SPINAND_HAS_QE_BIT |
342 SPINAND_HAS_PROG_PLANE_SELECT_BIT |
343 SPINAND_HAS_READ_PLANE_SELECT_BIT,
344 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
345 macronix_ecc_get_status)),
346 SPINAND_INFO("MX35UF2G24AD",
347 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa4, 0x03),
348 NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1),
349 NAND_ECCREQ(8, 512),
350 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
351 &write_cache_variants,
352 &update_cache_variants),
353 SPINAND_HAS_QE_BIT |
354 SPINAND_HAS_PROG_PLANE_SELECT_BIT,
355 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
356 macronix_ecc_get_status),
357 SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
358 macronix_set_read_retry)),
359 SPINAND_INFO("MX35UF2G24AD-Z4I8",
360 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xe4, 0x03),
361 NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
362 NAND_ECCREQ(8, 512),
363 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
364 &write_cache_variants,
365 &update_cache_variants),
366 SPINAND_HAS_QE_BIT,
367 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
368 macronix_ecc_get_status),
369 SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
370 macronix_set_read_retry)),
371 SPINAND_INFO("MX35UF2GE4AD",
372 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa6, 0x03),
373 NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
374 NAND_ECCREQ(8, 512),
375 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
376 &write_cache_variants,
377 &update_cache_variants),
378 SPINAND_HAS_QE_BIT,
379 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
380 macronix_ecc_get_status),
381 SPINAND_CONT_READ(macronix_set_cont_read),
382 SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
383 macronix_set_read_retry)),
384 SPINAND_INFO("MX35UF2GE4AC",
385 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa2, 0x01),
386 NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
387 NAND_ECCREQ(4, 512),
388 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
389 &write_cache_variants,
390 &update_cache_variants),
391 SPINAND_HAS_QE_BIT,
392 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
393 macronix_ecc_get_status),
394 SPINAND_CONT_READ(macronix_set_cont_read)),
395 SPINAND_INFO("MX35UF1G14AC",
396 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x90),
397 NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
398 NAND_ECCREQ(4, 512),
399 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
400 &write_cache_variants,
401 &update_cache_variants),
402 SPINAND_HAS_QE_BIT,
403 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
404 macronix_ecc_get_status)),
405 SPINAND_INFO("MX35UF1G24AD",
406 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x94, 0x03),
407 NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
408 NAND_ECCREQ(8, 512),
409 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
410 &write_cache_variants,
411 &update_cache_variants),
412 SPINAND_HAS_QE_BIT,
413 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
414 macronix_ecc_get_status),
415 SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
416 macronix_set_read_retry)),
417 SPINAND_INFO("MX35UF1GE4AD",
418 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x96, 0x03),
419 NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
420 NAND_ECCREQ(8, 512),
421 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
422 &write_cache_variants,
423 &update_cache_variants),
424 SPINAND_HAS_QE_BIT,
425 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
426 macronix_ecc_get_status),
427 SPINAND_CONT_READ(macronix_set_cont_read),
428 SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
429 macronix_set_read_retry)),
430 SPINAND_INFO("MX35UF1GE4AC",
431 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x92, 0x01),
432 NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
433 NAND_ECCREQ(4, 512),
434 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
435 &write_cache_variants,
436 &update_cache_variants),
437 SPINAND_HAS_QE_BIT,
438 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
439 macronix_ecc_get_status),
440 SPINAND_CONT_READ(macronix_set_cont_read)),
441 SPINAND_INFO("MX31LF2GE4BC",
442 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x2e),
443 NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
444 NAND_ECCREQ(8, 512),
445 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
446 &write_cache_variants,
447 &update_cache_variants),
448 SPINAND_HAS_QE_BIT,
449 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
450 macronix_ecc_get_status)),
451 SPINAND_INFO("MX3UF2GE4BC",
452 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xae),
453 NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
454 NAND_ECCREQ(8, 512),
455 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
456 &write_cache_variants,
457 &update_cache_variants),
458 SPINAND_HAS_QE_BIT,
459 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
460 macronix_ecc_get_status)),
461};
462
463static int macronix_spinand_init(struct spinand_device *spinand)
464{
465 struct macronix_priv *priv;
466
467 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
468 if (!priv)
469 return -ENOMEM;
470
471 spinand->priv = priv;
472
473 return 0;
474}
475
476static void macronix_spinand_cleanup(struct spinand_device *spinand)
477{
478 kfree(objp: spinand->priv);
479}
480
481static const struct spinand_manufacturer_ops macronix_spinand_manuf_ops = {
482 .init = macronix_spinand_init,
483 .cleanup = macronix_spinand_cleanup,
484};
485
486const struct spinand_manufacturer macronix_spinand_manufacturer = {
487 .id = SPINAND_MFR_MACRONIX,
488 .name = "Macronix",
489 .chips = macronix_spinand_table,
490 .nchips = ARRAY_SIZE(macronix_spinand_table),
491 .ops = &macronix_spinand_manuf_ops,
492};
493

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of linux/drivers/mtd/nand/spi/macronix.c