1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* |
3 | * Copyright 2009-2015 Freescale Semiconductor, Inc. and others |
4 | * |
5 | * Description: MPC5125, VF610, MCF54418 and Kinetis K70 Nand driver. |
6 | * Jason ported to M54418TWR and MVFA5 (VF610). |
7 | * Authors: Stefan Agner <stefan.agner@toradex.com> |
8 | * Bill Pringlemeir <bpringlemeir@nbsps.com> |
9 | * Shaohui Xie <b21989@freescale.com> |
10 | * Jason Jin <Jason.jin@freescale.com> |
11 | * |
12 | * Based on original driver mpc5121_nfc.c. |
13 | * |
14 | * Limitations: |
15 | * - Untested on MPC5125 and M54418. |
16 | * - DMA and pipelining not used. |
17 | * - 2K pages or less. |
18 | * - HW ECC: Only 2K page with 64+ OOB. |
19 | * - HW ECC: Only 24 and 32-bit error correction implemented. |
20 | */ |
21 | |
22 | #include <linux/module.h> |
23 | #include <linux/bitops.h> |
24 | #include <linux/clk.h> |
25 | #include <linux/delay.h> |
26 | #include <linux/init.h> |
27 | #include <linux/interrupt.h> |
28 | #include <linux/io.h> |
29 | #include <linux/mtd/mtd.h> |
30 | #include <linux/mtd/rawnand.h> |
31 | #include <linux/mtd/partitions.h> |
32 | #include <linux/of.h> |
33 | #include <linux/platform_device.h> |
34 | #include <linux/property.h> |
35 | #include <linux/slab.h> |
36 | #include <linux/swab.h> |
37 | |
38 | #define DRV_NAME "vf610_nfc" |
39 | |
40 | /* Register Offsets */ |
41 | #define NFC_FLASH_CMD1 0x3F00 |
42 | #define NFC_FLASH_CMD2 0x3F04 |
43 | #define NFC_COL_ADDR 0x3F08 |
44 | #define NFC_ROW_ADDR 0x3F0c |
45 | #define NFC_ROW_ADDR_INC 0x3F14 |
46 | #define NFC_FLASH_STATUS1 0x3F18 |
47 | #define NFC_FLASH_STATUS2 0x3F1c |
48 | #define NFC_CACHE_SWAP 0x3F28 |
49 | #define NFC_SECTOR_SIZE 0x3F2c |
50 | #define NFC_FLASH_CONFIG 0x3F30 |
51 | #define NFC_IRQ_STATUS 0x3F38 |
52 | |
53 | /* Addresses for NFC MAIN RAM BUFFER areas */ |
54 | #define NFC_MAIN_AREA(n) ((n) * 0x1000) |
55 | |
56 | #define PAGE_2K 0x0800 |
57 | #define OOB_64 0x0040 |
58 | #define OOB_MAX 0x0100 |
59 | |
60 | /* NFC_CMD2[CODE] controller cycle bit masks */ |
61 | #define COMMAND_CMD_BYTE1 BIT(14) |
62 | #define COMMAND_CAR_BYTE1 BIT(13) |
63 | #define COMMAND_CAR_BYTE2 BIT(12) |
64 | #define COMMAND_RAR_BYTE1 BIT(11) |
65 | #define COMMAND_RAR_BYTE2 BIT(10) |
66 | #define COMMAND_RAR_BYTE3 BIT(9) |
67 | #define COMMAND_NADDR_BYTES(x) GENMASK(13, 13 - (x) + 1) |
68 | #define COMMAND_WRITE_DATA BIT(8) |
69 | #define COMMAND_CMD_BYTE2 BIT(7) |
70 | #define COMMAND_RB_HANDSHAKE BIT(6) |
71 | #define COMMAND_READ_DATA BIT(5) |
72 | #define COMMAND_CMD_BYTE3 BIT(4) |
73 | #define COMMAND_READ_STATUS BIT(3) |
74 | #define COMMAND_READ_ID BIT(2) |
75 | |
76 | /* NFC ECC mode define */ |
77 | #define ECC_BYPASS 0 |
78 | #define ECC_45_BYTE 6 |
79 | #define ECC_60_BYTE 7 |
80 | |
81 | /*** Register Mask and bit definitions */ |
82 | |
83 | /* NFC_FLASH_CMD1 Field */ |
84 | #define CMD_BYTE2_MASK 0xFF000000 |
85 | #define CMD_BYTE2_SHIFT 24 |
86 | |
87 | /* NFC_FLASH_CM2 Field */ |
88 | #define CMD_BYTE1_MASK 0xFF000000 |
89 | #define CMD_BYTE1_SHIFT 24 |
90 | #define CMD_CODE_MASK 0x00FFFF00 |
91 | #define CMD_CODE_SHIFT 8 |
92 | #define BUFNO_MASK 0x00000006 |
93 | #define BUFNO_SHIFT 1 |
94 | #define START_BIT BIT(0) |
95 | |
96 | /* NFC_COL_ADDR Field */ |
97 | #define COL_ADDR_MASK 0x0000FFFF |
98 | #define COL_ADDR_SHIFT 0 |
99 | #define COL_ADDR(pos, val) (((val) & 0xFF) << (8 * (pos))) |
100 | |
101 | /* NFC_ROW_ADDR Field */ |
102 | #define ROW_ADDR_MASK 0x00FFFFFF |
103 | #define ROW_ADDR_SHIFT 0 |
104 | #define ROW_ADDR(pos, val) (((val) & 0xFF) << (8 * (pos))) |
105 | |
106 | #define ROW_ADDR_CHIP_SEL_RB_MASK 0xF0000000 |
107 | #define ROW_ADDR_CHIP_SEL_RB_SHIFT 28 |
108 | #define ROW_ADDR_CHIP_SEL_MASK 0x0F000000 |
109 | #define ROW_ADDR_CHIP_SEL_SHIFT 24 |
110 | |
111 | /* NFC_FLASH_STATUS2 Field */ |
112 | #define STATUS_BYTE1_MASK 0x000000FF |
113 | |
114 | /* NFC_FLASH_CONFIG Field */ |
115 | #define CONFIG_ECC_SRAM_ADDR_MASK 0x7FC00000 |
116 | #define CONFIG_ECC_SRAM_ADDR_SHIFT 22 |
117 | #define CONFIG_ECC_SRAM_REQ_BIT BIT(21) |
118 | #define CONFIG_DMA_REQ_BIT BIT(20) |
119 | #define CONFIG_ECC_MODE_MASK 0x000E0000 |
120 | #define CONFIG_ECC_MODE_SHIFT 17 |
121 | #define CONFIG_FAST_FLASH_BIT BIT(16) |
122 | #define CONFIG_16BIT BIT(7) |
123 | #define CONFIG_BOOT_MODE_BIT BIT(6) |
124 | #define CONFIG_ADDR_AUTO_INCR_BIT BIT(5) |
125 | #define CONFIG_BUFNO_AUTO_INCR_BIT BIT(4) |
126 | #define CONFIG_PAGE_CNT_MASK 0xF |
127 | #define CONFIG_PAGE_CNT_SHIFT 0 |
128 | |
129 | /* NFC_IRQ_STATUS Field */ |
130 | #define IDLE_IRQ_BIT BIT(29) |
131 | #define IDLE_EN_BIT BIT(20) |
132 | #define CMD_DONE_CLEAR_BIT BIT(18) |
133 | #define IDLE_CLEAR_BIT BIT(17) |
134 | |
135 | /* |
136 | * ECC status - seems to consume 8 bytes (double word). The documented |
137 | * status byte is located in the lowest byte of the second word (which is |
138 | * the 4th or 7th byte depending on endianness). |
139 | * Calculate an offset to store the ECC status at the end of the buffer. |
140 | */ |
141 | #define ECC_SRAM_ADDR (PAGE_2K + OOB_MAX - 8) |
142 | |
143 | #define ECC_STATUS 0x4 |
144 | #define ECC_STATUS_MASK 0x80 |
145 | #define ECC_STATUS_ERR_COUNT 0x3F |
146 | |
147 | enum vf610_nfc_variant { |
148 | NFC_VFC610 = 1, |
149 | }; |
150 | |
151 | struct vf610_nfc { |
152 | struct nand_controller base; |
153 | struct nand_chip chip; |
154 | struct device *dev; |
155 | void __iomem *regs; |
156 | struct completion cmd_done; |
157 | /* Status and ID are in alternate locations. */ |
158 | enum vf610_nfc_variant variant; |
159 | struct clk *clk; |
160 | /* |
161 | * Indicate that user data is accessed (full page/oob). This is |
162 | * useful to indicate the driver whether to swap byte endianness. |
163 | * See comments in vf610_nfc_rd_from_sram/vf610_nfc_wr_to_sram. |
164 | */ |
165 | bool data_access; |
166 | u32 ecc_mode; |
167 | }; |
168 | |
169 | static inline struct vf610_nfc *chip_to_nfc(struct nand_chip *chip) |
170 | { |
171 | return container_of(chip, struct vf610_nfc, chip); |
172 | } |
173 | |
174 | static inline u32 vf610_nfc_read(struct vf610_nfc *nfc, uint reg) |
175 | { |
176 | return readl(addr: nfc->regs + reg); |
177 | } |
178 | |
179 | static inline void vf610_nfc_write(struct vf610_nfc *nfc, uint reg, u32 val) |
180 | { |
181 | writel(val, addr: nfc->regs + reg); |
182 | } |
183 | |
184 | static inline void vf610_nfc_set(struct vf610_nfc *nfc, uint reg, u32 bits) |
185 | { |
186 | vf610_nfc_write(nfc, reg, val: vf610_nfc_read(nfc, reg) | bits); |
187 | } |
188 | |
189 | static inline void vf610_nfc_clear(struct vf610_nfc *nfc, uint reg, u32 bits) |
190 | { |
191 | vf610_nfc_write(nfc, reg, val: vf610_nfc_read(nfc, reg) & ~bits); |
192 | } |
193 | |
194 | static inline void vf610_nfc_set_field(struct vf610_nfc *nfc, u32 reg, |
195 | u32 mask, u32 shift, u32 val) |
196 | { |
197 | vf610_nfc_write(nfc, reg, |
198 | val: (vf610_nfc_read(nfc, reg) & (~mask)) | val << shift); |
199 | } |
200 | |
201 | static inline bool vf610_nfc_kernel_is_little_endian(void) |
202 | { |
203 | #ifdef __LITTLE_ENDIAN |
204 | return true; |
205 | #else |
206 | return false; |
207 | #endif |
208 | } |
209 | |
210 | /* |
211 | * Read accessor for internal SRAM buffer |
212 | * @dst: destination address in regular memory |
213 | * @src: source address in SRAM buffer |
214 | * @len: bytes to copy |
215 | * @fix_endian: Fix endianness if required |
216 | * |
217 | * Use this accessor for the internal SRAM buffers. On the ARM |
218 | * Freescale Vybrid SoC it's known that the driver can treat |
219 | * the SRAM buffer as if it's memory. Other platform might need |
220 | * to treat the buffers differently. |
221 | * |
222 | * The controller stores bytes from the NAND chip internally in big |
223 | * endianness. On little endian platforms such as Vybrid this leads |
224 | * to reversed byte order. |
225 | * For performance reason (and earlier probably due to unawareness) |
226 | * the driver avoids correcting endianness where it has control over |
227 | * write and read side (e.g. page wise data access). |
228 | */ |
229 | static inline void vf610_nfc_rd_from_sram(void *dst, const void __iomem *src, |
230 | size_t len, bool fix_endian) |
231 | { |
232 | if (vf610_nfc_kernel_is_little_endian() && fix_endian) { |
233 | unsigned int i; |
234 | |
235 | for (i = 0; i < len; i += 4) { |
236 | u32 val = swab32(__raw_readl(src + i)); |
237 | |
238 | memcpy(dst + i, &val, min(sizeof(val), len - i)); |
239 | } |
240 | } else { |
241 | memcpy_fromio(dst, src, len); |
242 | } |
243 | } |
244 | |
245 | /* |
246 | * Write accessor for internal SRAM buffer |
247 | * @dst: destination address in SRAM buffer |
248 | * @src: source address in regular memory |
249 | * @len: bytes to copy |
250 | * @fix_endian: Fix endianness if required |
251 | * |
252 | * Use this accessor for the internal SRAM buffers. On the ARM |
253 | * Freescale Vybrid SoC it's known that the driver can treat |
254 | * the SRAM buffer as if it's memory. Other platform might need |
255 | * to treat the buffers differently. |
256 | * |
257 | * The controller stores bytes from the NAND chip internally in big |
258 | * endianness. On little endian platforms such as Vybrid this leads |
259 | * to reversed byte order. |
260 | * For performance reason (and earlier probably due to unawareness) |
261 | * the driver avoids correcting endianness where it has control over |
262 | * write and read side (e.g. page wise data access). |
263 | */ |
264 | static inline void vf610_nfc_wr_to_sram(void __iomem *dst, const void *src, |
265 | size_t len, bool fix_endian) |
266 | { |
267 | if (vf610_nfc_kernel_is_little_endian() && fix_endian) { |
268 | unsigned int i; |
269 | |
270 | for (i = 0; i < len; i += 4) { |
271 | u32 val; |
272 | |
273 | memcpy(&val, src + i, min(sizeof(val), len - i)); |
274 | __raw_writel(swab32(val), addr: dst + i); |
275 | } |
276 | } else { |
277 | memcpy_toio(dst, src, len); |
278 | } |
279 | } |
280 | |
281 | /* Clear flags for upcoming command */ |
282 | static inline void vf610_nfc_clear_status(struct vf610_nfc *nfc) |
283 | { |
284 | u32 tmp = vf610_nfc_read(nfc, NFC_IRQ_STATUS); |
285 | |
286 | tmp |= CMD_DONE_CLEAR_BIT | IDLE_CLEAR_BIT; |
287 | vf610_nfc_write(nfc, NFC_IRQ_STATUS, val: tmp); |
288 | } |
289 | |
290 | static void vf610_nfc_done(struct vf610_nfc *nfc) |
291 | { |
292 | unsigned long timeout = msecs_to_jiffies(m: 100); |
293 | |
294 | /* |
295 | * Barrier is needed after this write. This write need |
296 | * to be done before reading the next register the first |
297 | * time. |
298 | * vf610_nfc_set implicates such a barrier by using writel |
299 | * to write to the register. |
300 | */ |
301 | vf610_nfc_set(nfc, NFC_IRQ_STATUS, IDLE_EN_BIT); |
302 | vf610_nfc_set(nfc, NFC_FLASH_CMD2, START_BIT); |
303 | |
304 | if (!wait_for_completion_timeout(x: &nfc->cmd_done, timeout)) |
305 | dev_warn(nfc->dev, "Timeout while waiting for BUSY.\n" ); |
306 | |
307 | vf610_nfc_clear_status(nfc); |
308 | } |
309 | |
310 | static irqreturn_t vf610_nfc_irq(int irq, void *data) |
311 | { |
312 | struct vf610_nfc *nfc = data; |
313 | |
314 | vf610_nfc_clear(nfc, NFC_IRQ_STATUS, IDLE_EN_BIT); |
315 | complete(&nfc->cmd_done); |
316 | |
317 | return IRQ_HANDLED; |
318 | } |
319 | |
320 | static inline void vf610_nfc_ecc_mode(struct vf610_nfc *nfc, int ecc_mode) |
321 | { |
322 | vf610_nfc_set_field(nfc, NFC_FLASH_CONFIG, |
323 | CONFIG_ECC_MODE_MASK, |
324 | CONFIG_ECC_MODE_SHIFT, val: ecc_mode); |
325 | } |
326 | |
327 | static inline void vf610_nfc_run(struct vf610_nfc *nfc, u32 col, u32 row, |
328 | u32 cmd1, u32 cmd2, u32 trfr_sz) |
329 | { |
330 | vf610_nfc_set_field(nfc, NFC_COL_ADDR, COL_ADDR_MASK, |
331 | COL_ADDR_SHIFT, val: col); |
332 | |
333 | vf610_nfc_set_field(nfc, NFC_ROW_ADDR, ROW_ADDR_MASK, |
334 | ROW_ADDR_SHIFT, val: row); |
335 | |
336 | vf610_nfc_write(nfc, NFC_SECTOR_SIZE, val: trfr_sz); |
337 | vf610_nfc_write(nfc, NFC_FLASH_CMD1, val: cmd1); |
338 | vf610_nfc_write(nfc, NFC_FLASH_CMD2, val: cmd2); |
339 | |
340 | dev_dbg(nfc->dev, |
341 | "col 0x%04x, row 0x%08x, cmd1 0x%08x, cmd2 0x%08x, len %d\n" , |
342 | col, row, cmd1, cmd2, trfr_sz); |
343 | |
344 | vf610_nfc_done(nfc); |
345 | } |
346 | |
347 | static inline const struct nand_op_instr * |
348 | vf610_get_next_instr(const struct nand_subop *subop, int *op_id) |
349 | { |
350 | if (*op_id + 1 >= subop->ninstrs) |
351 | return NULL; |
352 | |
353 | (*op_id)++; |
354 | |
355 | return &subop->instrs[*op_id]; |
356 | } |
357 | |
358 | static int vf610_nfc_cmd(struct nand_chip *chip, |
359 | const struct nand_subop *subop) |
360 | { |
361 | const struct nand_op_instr *instr; |
362 | struct vf610_nfc *nfc = chip_to_nfc(chip); |
363 | int op_id = -1, trfr_sz = 0, offset = 0; |
364 | u32 col = 0, row = 0, cmd1 = 0, cmd2 = 0, code = 0; |
365 | bool force8bit = false; |
366 | |
367 | /* |
368 | * Some ops are optional, but the hardware requires the operations |
369 | * to be in this exact order. |
370 | * The op parser enforces the order and makes sure that there isn't |
371 | * a read and write element in a single operation. |
372 | */ |
373 | instr = vf610_get_next_instr(subop, op_id: &op_id); |
374 | if (!instr) |
375 | return -EINVAL; |
376 | |
377 | if (instr && instr->type == NAND_OP_CMD_INSTR) { |
378 | cmd2 |= instr->ctx.cmd.opcode << CMD_BYTE1_SHIFT; |
379 | code |= COMMAND_CMD_BYTE1; |
380 | |
381 | instr = vf610_get_next_instr(subop, op_id: &op_id); |
382 | } |
383 | |
384 | if (instr && instr->type == NAND_OP_ADDR_INSTR) { |
385 | int naddrs = nand_subop_get_num_addr_cyc(subop, op_id); |
386 | int i = nand_subop_get_addr_start_off(subop, op_id); |
387 | |
388 | for (; i < naddrs; i++) { |
389 | u8 val = instr->ctx.addr.addrs[i]; |
390 | |
391 | if (i < 2) |
392 | col |= COL_ADDR(i, val); |
393 | else |
394 | row |= ROW_ADDR(i - 2, val); |
395 | } |
396 | code |= COMMAND_NADDR_BYTES(naddrs); |
397 | |
398 | instr = vf610_get_next_instr(subop, op_id: &op_id); |
399 | } |
400 | |
401 | if (instr && instr->type == NAND_OP_DATA_OUT_INSTR) { |
402 | trfr_sz = nand_subop_get_data_len(subop, op_id); |
403 | offset = nand_subop_get_data_start_off(subop, op_id); |
404 | force8bit = instr->ctx.data.force_8bit; |
405 | |
406 | /* |
407 | * Don't fix endianness on page access for historical reasons. |
408 | * See comment in vf610_nfc_wr_to_sram |
409 | */ |
410 | vf610_nfc_wr_to_sram(dst: nfc->regs + NFC_MAIN_AREA(0) + offset, |
411 | src: instr->ctx.data.buf.out + offset, |
412 | len: trfr_sz, fix_endian: !nfc->data_access); |
413 | code |= COMMAND_WRITE_DATA; |
414 | |
415 | instr = vf610_get_next_instr(subop, op_id: &op_id); |
416 | } |
417 | |
418 | if (instr && instr->type == NAND_OP_CMD_INSTR) { |
419 | cmd1 |= instr->ctx.cmd.opcode << CMD_BYTE2_SHIFT; |
420 | code |= COMMAND_CMD_BYTE2; |
421 | |
422 | instr = vf610_get_next_instr(subop, op_id: &op_id); |
423 | } |
424 | |
425 | if (instr && instr->type == NAND_OP_WAITRDY_INSTR) { |
426 | code |= COMMAND_RB_HANDSHAKE; |
427 | |
428 | instr = vf610_get_next_instr(subop, op_id: &op_id); |
429 | } |
430 | |
431 | if (instr && instr->type == NAND_OP_DATA_IN_INSTR) { |
432 | trfr_sz = nand_subop_get_data_len(subop, op_id); |
433 | offset = nand_subop_get_data_start_off(subop, op_id); |
434 | force8bit = instr->ctx.data.force_8bit; |
435 | |
436 | code |= COMMAND_READ_DATA; |
437 | } |
438 | |
439 | if (force8bit && (chip->options & NAND_BUSWIDTH_16)) |
440 | vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_16BIT); |
441 | |
442 | cmd2 |= code << CMD_CODE_SHIFT; |
443 | |
444 | vf610_nfc_run(nfc, col, row, cmd1, cmd2, trfr_sz); |
445 | |
446 | if (instr && instr->type == NAND_OP_DATA_IN_INSTR) { |
447 | /* |
448 | * Don't fix endianness on page access for historical reasons. |
449 | * See comment in vf610_nfc_rd_from_sram |
450 | */ |
451 | vf610_nfc_rd_from_sram(dst: instr->ctx.data.buf.in + offset, |
452 | src: nfc->regs + NFC_MAIN_AREA(0) + offset, |
453 | len: trfr_sz, fix_endian: !nfc->data_access); |
454 | } |
455 | |
456 | if (force8bit && (chip->options & NAND_BUSWIDTH_16)) |
457 | vf610_nfc_set(nfc, NFC_FLASH_CONFIG, CONFIG_16BIT); |
458 | |
459 | return 0; |
460 | } |
461 | |
462 | static const struct nand_op_parser vf610_nfc_op_parser = NAND_OP_PARSER( |
463 | NAND_OP_PARSER_PATTERN(vf610_nfc_cmd, |
464 | NAND_OP_PARSER_PAT_CMD_ELEM(true), |
465 | NAND_OP_PARSER_PAT_ADDR_ELEM(true, 5), |
466 | NAND_OP_PARSER_PAT_DATA_OUT_ELEM(true, PAGE_2K + OOB_MAX), |
467 | NAND_OP_PARSER_PAT_CMD_ELEM(true), |
468 | NAND_OP_PARSER_PAT_WAITRDY_ELEM(true)), |
469 | NAND_OP_PARSER_PATTERN(vf610_nfc_cmd, |
470 | NAND_OP_PARSER_PAT_CMD_ELEM(true), |
471 | NAND_OP_PARSER_PAT_ADDR_ELEM(true, 5), |
472 | NAND_OP_PARSER_PAT_CMD_ELEM(true), |
473 | NAND_OP_PARSER_PAT_WAITRDY_ELEM(true), |
474 | NAND_OP_PARSER_PAT_DATA_IN_ELEM(true, PAGE_2K + OOB_MAX)), |
475 | ); |
476 | |
477 | /* |
478 | * This function supports Vybrid only (MPC5125 would have full RB and four CS) |
479 | */ |
480 | static void vf610_nfc_select_target(struct nand_chip *chip, unsigned int cs) |
481 | { |
482 | struct vf610_nfc *nfc = chip_to_nfc(chip); |
483 | u32 tmp; |
484 | |
485 | /* Vybrid only (MPC5125 would have full RB and four CS) */ |
486 | if (nfc->variant != NFC_VFC610) |
487 | return; |
488 | |
489 | tmp = vf610_nfc_read(nfc, NFC_ROW_ADDR); |
490 | tmp &= ~(ROW_ADDR_CHIP_SEL_RB_MASK | ROW_ADDR_CHIP_SEL_MASK); |
491 | tmp |= 1 << ROW_ADDR_CHIP_SEL_RB_SHIFT; |
492 | tmp |= BIT(cs) << ROW_ADDR_CHIP_SEL_SHIFT; |
493 | |
494 | vf610_nfc_write(nfc, NFC_ROW_ADDR, val: tmp); |
495 | } |
496 | |
497 | static int vf610_nfc_exec_op(struct nand_chip *chip, |
498 | const struct nand_operation *op, |
499 | bool check_only) |
500 | { |
501 | if (!check_only) |
502 | vf610_nfc_select_target(chip, cs: op->cs); |
503 | |
504 | return nand_op_parser_exec_op(chip, parser: &vf610_nfc_op_parser, op, |
505 | check_only); |
506 | } |
507 | |
508 | static inline int vf610_nfc_correct_data(struct nand_chip *chip, uint8_t *dat, |
509 | uint8_t *oob, int page) |
510 | { |
511 | struct vf610_nfc *nfc = chip_to_nfc(chip); |
512 | struct mtd_info *mtd = nand_to_mtd(chip); |
513 | u32 ecc_status_off = NFC_MAIN_AREA(0) + ECC_SRAM_ADDR + ECC_STATUS; |
514 | u8 ecc_status; |
515 | u8 ecc_count; |
516 | int flips_threshold = nfc->chip.ecc.strength / 2; |
517 | |
518 | ecc_status = vf610_nfc_read(nfc, reg: ecc_status_off) & 0xff; |
519 | ecc_count = ecc_status & ECC_STATUS_ERR_COUNT; |
520 | |
521 | if (!(ecc_status & ECC_STATUS_MASK)) |
522 | return ecc_count; |
523 | |
524 | nfc->data_access = true; |
525 | nand_read_oob_op(chip: &nfc->chip, page, offset_in_page: 0, buf: oob, len: mtd->oobsize); |
526 | nfc->data_access = false; |
527 | |
528 | /* |
529 | * On an erased page, bit count (including OOB) should be zero or |
530 | * at least less then half of the ECC strength. |
531 | */ |
532 | return nand_check_erased_ecc_chunk(data: dat, datalen: nfc->chip.ecc.size, ecc: oob, |
533 | ecclen: mtd->oobsize, NULL, extraooblen: 0, |
534 | threshold: flips_threshold); |
535 | } |
536 | |
537 | static void vf610_nfc_fill_row(struct nand_chip *chip, int page, u32 *code, |
538 | u32 *row) |
539 | { |
540 | *row = ROW_ADDR(0, page & 0xff) | ROW_ADDR(1, page >> 8); |
541 | *code |= COMMAND_RAR_BYTE1 | COMMAND_RAR_BYTE2; |
542 | |
543 | if (chip->options & NAND_ROW_ADDR_3) { |
544 | *row |= ROW_ADDR(2, page >> 16); |
545 | *code |= COMMAND_RAR_BYTE3; |
546 | } |
547 | } |
548 | |
549 | static int vf610_nfc_read_page(struct nand_chip *chip, uint8_t *buf, |
550 | int oob_required, int page) |
551 | { |
552 | struct vf610_nfc *nfc = chip_to_nfc(chip); |
553 | struct mtd_info *mtd = nand_to_mtd(chip); |
554 | int trfr_sz = mtd->writesize + mtd->oobsize; |
555 | u32 row = 0, cmd1 = 0, cmd2 = 0, code = 0; |
556 | int stat; |
557 | |
558 | vf610_nfc_select_target(chip, cs: chip->cur_cs); |
559 | |
560 | cmd2 |= NAND_CMD_READ0 << CMD_BYTE1_SHIFT; |
561 | code |= COMMAND_CMD_BYTE1 | COMMAND_CAR_BYTE1 | COMMAND_CAR_BYTE2; |
562 | |
563 | vf610_nfc_fill_row(chip, page, code: &code, row: &row); |
564 | |
565 | cmd1 |= NAND_CMD_READSTART << CMD_BYTE2_SHIFT; |
566 | code |= COMMAND_CMD_BYTE2 | COMMAND_RB_HANDSHAKE | COMMAND_READ_DATA; |
567 | |
568 | cmd2 |= code << CMD_CODE_SHIFT; |
569 | |
570 | vf610_nfc_ecc_mode(nfc, ecc_mode: nfc->ecc_mode); |
571 | vf610_nfc_run(nfc, col: 0, row, cmd1, cmd2, trfr_sz); |
572 | vf610_nfc_ecc_mode(nfc, ECC_BYPASS); |
573 | |
574 | /* |
575 | * Don't fix endianness on page access for historical reasons. |
576 | * See comment in vf610_nfc_rd_from_sram |
577 | */ |
578 | vf610_nfc_rd_from_sram(dst: buf, src: nfc->regs + NFC_MAIN_AREA(0), |
579 | len: mtd->writesize, fix_endian: false); |
580 | if (oob_required) |
581 | vf610_nfc_rd_from_sram(dst: chip->oob_poi, |
582 | src: nfc->regs + NFC_MAIN_AREA(0) + |
583 | mtd->writesize, |
584 | len: mtd->oobsize, fix_endian: false); |
585 | |
586 | stat = vf610_nfc_correct_data(chip, dat: buf, oob: chip->oob_poi, page); |
587 | |
588 | if (stat < 0) { |
589 | mtd->ecc_stats.failed++; |
590 | return 0; |
591 | } else { |
592 | mtd->ecc_stats.corrected += stat; |
593 | return stat; |
594 | } |
595 | } |
596 | |
597 | static int vf610_nfc_write_page(struct nand_chip *chip, const uint8_t *buf, |
598 | int oob_required, int page) |
599 | { |
600 | struct vf610_nfc *nfc = chip_to_nfc(chip); |
601 | struct mtd_info *mtd = nand_to_mtd(chip); |
602 | int trfr_sz = mtd->writesize + mtd->oobsize; |
603 | u32 row = 0, cmd1 = 0, cmd2 = 0, code = 0; |
604 | u8 status; |
605 | int ret; |
606 | |
607 | vf610_nfc_select_target(chip, cs: chip->cur_cs); |
608 | |
609 | cmd2 |= NAND_CMD_SEQIN << CMD_BYTE1_SHIFT; |
610 | code |= COMMAND_CMD_BYTE1 | COMMAND_CAR_BYTE1 | COMMAND_CAR_BYTE2; |
611 | |
612 | vf610_nfc_fill_row(chip, page, code: &code, row: &row); |
613 | |
614 | cmd1 |= NAND_CMD_PAGEPROG << CMD_BYTE2_SHIFT; |
615 | code |= COMMAND_CMD_BYTE2 | COMMAND_WRITE_DATA; |
616 | |
617 | /* |
618 | * Don't fix endianness on page access for historical reasons. |
619 | * See comment in vf610_nfc_wr_to_sram |
620 | */ |
621 | vf610_nfc_wr_to_sram(dst: nfc->regs + NFC_MAIN_AREA(0), src: buf, |
622 | len: mtd->writesize, fix_endian: false); |
623 | |
624 | code |= COMMAND_RB_HANDSHAKE; |
625 | cmd2 |= code << CMD_CODE_SHIFT; |
626 | |
627 | vf610_nfc_ecc_mode(nfc, ecc_mode: nfc->ecc_mode); |
628 | vf610_nfc_run(nfc, col: 0, row, cmd1, cmd2, trfr_sz); |
629 | vf610_nfc_ecc_mode(nfc, ECC_BYPASS); |
630 | |
631 | ret = nand_status_op(chip, status: &status); |
632 | if (ret) |
633 | return ret; |
634 | |
635 | if (status & NAND_STATUS_FAIL) |
636 | return -EIO; |
637 | |
638 | return 0; |
639 | } |
640 | |
641 | static int vf610_nfc_read_page_raw(struct nand_chip *chip, u8 *buf, |
642 | int oob_required, int page) |
643 | { |
644 | struct vf610_nfc *nfc = chip_to_nfc(chip); |
645 | int ret; |
646 | |
647 | nfc->data_access = true; |
648 | ret = nand_read_page_raw(chip, buf, oob_required, page); |
649 | nfc->data_access = false; |
650 | |
651 | return ret; |
652 | } |
653 | |
654 | static int vf610_nfc_write_page_raw(struct nand_chip *chip, const u8 *buf, |
655 | int oob_required, int page) |
656 | { |
657 | struct vf610_nfc *nfc = chip_to_nfc(chip); |
658 | struct mtd_info *mtd = nand_to_mtd(chip); |
659 | int ret; |
660 | |
661 | nfc->data_access = true; |
662 | ret = nand_prog_page_begin_op(chip, page, offset_in_page: 0, buf, len: mtd->writesize); |
663 | if (!ret && oob_required) |
664 | ret = nand_write_data_op(chip, buf: chip->oob_poi, len: mtd->oobsize, |
665 | force_8bit: false); |
666 | nfc->data_access = false; |
667 | |
668 | if (ret) |
669 | return ret; |
670 | |
671 | return nand_prog_page_end_op(chip); |
672 | } |
673 | |
674 | static int vf610_nfc_read_oob(struct nand_chip *chip, int page) |
675 | { |
676 | struct vf610_nfc *nfc = chip_to_nfc(chip); |
677 | int ret; |
678 | |
679 | nfc->data_access = true; |
680 | ret = nand_read_oob_std(chip, page); |
681 | nfc->data_access = false; |
682 | |
683 | return ret; |
684 | } |
685 | |
686 | static int vf610_nfc_write_oob(struct nand_chip *chip, int page) |
687 | { |
688 | struct mtd_info *mtd = nand_to_mtd(chip); |
689 | struct vf610_nfc *nfc = chip_to_nfc(chip); |
690 | int ret; |
691 | |
692 | nfc->data_access = true; |
693 | ret = nand_prog_page_begin_op(chip, page, offset_in_page: mtd->writesize, |
694 | buf: chip->oob_poi, len: mtd->oobsize); |
695 | nfc->data_access = false; |
696 | |
697 | if (ret) |
698 | return ret; |
699 | |
700 | return nand_prog_page_end_op(chip); |
701 | } |
702 | |
703 | static const struct of_device_id vf610_nfc_dt_ids[] = { |
704 | { .compatible = "fsl,vf610-nfc" , .data = (void *)NFC_VFC610 }, |
705 | { /* sentinel */ } |
706 | }; |
707 | MODULE_DEVICE_TABLE(of, vf610_nfc_dt_ids); |
708 | |
709 | static void vf610_nfc_preinit_controller(struct vf610_nfc *nfc) |
710 | { |
711 | vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_16BIT); |
712 | vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_ADDR_AUTO_INCR_BIT); |
713 | vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_BUFNO_AUTO_INCR_BIT); |
714 | vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_BOOT_MODE_BIT); |
715 | vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_DMA_REQ_BIT); |
716 | vf610_nfc_set(nfc, NFC_FLASH_CONFIG, CONFIG_FAST_FLASH_BIT); |
717 | vf610_nfc_ecc_mode(nfc, ECC_BYPASS); |
718 | |
719 | /* Disable virtual pages, only one elementary transfer unit */ |
720 | vf610_nfc_set_field(nfc, NFC_FLASH_CONFIG, CONFIG_PAGE_CNT_MASK, |
721 | CONFIG_PAGE_CNT_SHIFT, val: 1); |
722 | } |
723 | |
724 | static void vf610_nfc_init_controller(struct vf610_nfc *nfc) |
725 | { |
726 | if (nfc->chip.options & NAND_BUSWIDTH_16) |
727 | vf610_nfc_set(nfc, NFC_FLASH_CONFIG, CONFIG_16BIT); |
728 | else |
729 | vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_16BIT); |
730 | |
731 | if (nfc->chip.ecc.engine_type == NAND_ECC_ENGINE_TYPE_ON_HOST) { |
732 | /* Set ECC status offset in SRAM */ |
733 | vf610_nfc_set_field(nfc, NFC_FLASH_CONFIG, |
734 | CONFIG_ECC_SRAM_ADDR_MASK, |
735 | CONFIG_ECC_SRAM_ADDR_SHIFT, |
736 | ECC_SRAM_ADDR >> 3); |
737 | |
738 | /* Enable ECC status in SRAM */ |
739 | vf610_nfc_set(nfc, NFC_FLASH_CONFIG, CONFIG_ECC_SRAM_REQ_BIT); |
740 | } |
741 | } |
742 | |
743 | static int vf610_nfc_attach_chip(struct nand_chip *chip) |
744 | { |
745 | struct mtd_info *mtd = nand_to_mtd(chip); |
746 | struct vf610_nfc *nfc = chip_to_nfc(chip); |
747 | |
748 | vf610_nfc_init_controller(nfc); |
749 | |
750 | /* Bad block options. */ |
751 | if (chip->bbt_options & NAND_BBT_USE_FLASH) |
752 | chip->bbt_options |= NAND_BBT_NO_OOB; |
753 | |
754 | /* Single buffer only, max 256 OOB minus ECC status */ |
755 | if (mtd->writesize + mtd->oobsize > PAGE_2K + OOB_MAX - 8) { |
756 | dev_err(nfc->dev, "Unsupported flash page size\n" ); |
757 | return -ENXIO; |
758 | } |
759 | |
760 | if (chip->ecc.engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST) |
761 | return 0; |
762 | |
763 | if (mtd->writesize != PAGE_2K && mtd->oobsize < 64) { |
764 | dev_err(nfc->dev, "Unsupported flash with hwecc\n" ); |
765 | return -ENXIO; |
766 | } |
767 | |
768 | if (chip->ecc.size != mtd->writesize) { |
769 | dev_err(nfc->dev, "Step size needs to be page size\n" ); |
770 | return -ENXIO; |
771 | } |
772 | |
773 | /* Only 64 byte ECC layouts known */ |
774 | if (mtd->oobsize > 64) |
775 | mtd->oobsize = 64; |
776 | |
777 | /* Use default large page ECC layout defined in NAND core */ |
778 | mtd_set_ooblayout(mtd, ooblayout: nand_get_large_page_ooblayout()); |
779 | if (chip->ecc.strength == 32) { |
780 | nfc->ecc_mode = ECC_60_BYTE; |
781 | chip->ecc.bytes = 60; |
782 | } else if (chip->ecc.strength == 24) { |
783 | nfc->ecc_mode = ECC_45_BYTE; |
784 | chip->ecc.bytes = 45; |
785 | } else { |
786 | dev_err(nfc->dev, "Unsupported ECC strength\n" ); |
787 | return -ENXIO; |
788 | } |
789 | |
790 | chip->ecc.read_page = vf610_nfc_read_page; |
791 | chip->ecc.write_page = vf610_nfc_write_page; |
792 | chip->ecc.read_page_raw = vf610_nfc_read_page_raw; |
793 | chip->ecc.write_page_raw = vf610_nfc_write_page_raw; |
794 | chip->ecc.read_oob = vf610_nfc_read_oob; |
795 | chip->ecc.write_oob = vf610_nfc_write_oob; |
796 | |
797 | chip->ecc.size = PAGE_2K; |
798 | |
799 | return 0; |
800 | } |
801 | |
802 | static const struct nand_controller_ops vf610_nfc_controller_ops = { |
803 | .attach_chip = vf610_nfc_attach_chip, |
804 | .exec_op = vf610_nfc_exec_op, |
805 | |
806 | }; |
807 | |
808 | static int vf610_nfc_probe(struct platform_device *pdev) |
809 | { |
810 | struct vf610_nfc *nfc; |
811 | struct mtd_info *mtd; |
812 | struct nand_chip *chip; |
813 | struct device_node *child; |
814 | int err; |
815 | int irq; |
816 | |
817 | nfc = devm_kzalloc(dev: &pdev->dev, size: sizeof(*nfc), GFP_KERNEL); |
818 | if (!nfc) |
819 | return -ENOMEM; |
820 | |
821 | nfc->dev = &pdev->dev; |
822 | chip = &nfc->chip; |
823 | mtd = nand_to_mtd(chip); |
824 | |
825 | mtd->owner = THIS_MODULE; |
826 | mtd->dev.parent = nfc->dev; |
827 | mtd->name = DRV_NAME; |
828 | |
829 | irq = platform_get_irq(pdev, 0); |
830 | if (irq < 0) |
831 | return irq; |
832 | |
833 | nfc->regs = devm_platform_ioremap_resource(pdev, index: 0); |
834 | if (IS_ERR(ptr: nfc->regs)) |
835 | return PTR_ERR(ptr: nfc->regs); |
836 | |
837 | nfc->clk = devm_clk_get_enabled(dev: &pdev->dev, NULL); |
838 | if (IS_ERR(ptr: nfc->clk)) { |
839 | dev_err(nfc->dev, "Unable to get and enable clock!\n" ); |
840 | return PTR_ERR(ptr: nfc->clk); |
841 | } |
842 | |
843 | nfc->variant = (enum vf610_nfc_variant)device_get_match_data(dev: &pdev->dev); |
844 | if (!nfc->variant) |
845 | return -ENODEV; |
846 | |
847 | for_each_available_child_of_node(nfc->dev->of_node, child) { |
848 | if (of_device_is_compatible(device: child, "fsl,vf610-nfc-nandcs" )) { |
849 | |
850 | if (nand_get_flash_node(chip)) { |
851 | dev_err(nfc->dev, |
852 | "Only one NAND chip supported!\n" ); |
853 | of_node_put(node: child); |
854 | return -EINVAL; |
855 | } |
856 | |
857 | nand_set_flash_node(chip, np: child); |
858 | } |
859 | } |
860 | |
861 | if (!nand_get_flash_node(chip)) { |
862 | dev_err(nfc->dev, "NAND chip sub-node missing!\n" ); |
863 | return -ENODEV; |
864 | } |
865 | |
866 | chip->options |= NAND_NO_SUBPAGE_WRITE; |
867 | |
868 | init_completion(x: &nfc->cmd_done); |
869 | |
870 | err = devm_request_irq(dev: nfc->dev, irq, handler: vf610_nfc_irq, irqflags: 0, DRV_NAME, dev_id: nfc); |
871 | if (err) { |
872 | dev_err(nfc->dev, "Error requesting IRQ!\n" ); |
873 | return err; |
874 | } |
875 | |
876 | vf610_nfc_preinit_controller(nfc); |
877 | |
878 | nand_controller_init(nfc: &nfc->base); |
879 | nfc->base.ops = &vf610_nfc_controller_ops; |
880 | chip->controller = &nfc->base; |
881 | |
882 | /* Scan the NAND chip */ |
883 | err = nand_scan(chip, max_chips: 1); |
884 | if (err) |
885 | return err; |
886 | |
887 | platform_set_drvdata(pdev, data: nfc); |
888 | |
889 | /* Register device in MTD */ |
890 | err = mtd_device_register(mtd, NULL, 0); |
891 | if (err) |
892 | goto err_cleanup_nand; |
893 | return 0; |
894 | |
895 | err_cleanup_nand: |
896 | nand_cleanup(chip); |
897 | return err; |
898 | } |
899 | |
900 | static void vf610_nfc_remove(struct platform_device *pdev) |
901 | { |
902 | struct vf610_nfc *nfc = platform_get_drvdata(pdev); |
903 | struct nand_chip *chip = &nfc->chip; |
904 | int ret; |
905 | |
906 | ret = mtd_device_unregister(master: nand_to_mtd(chip)); |
907 | WARN_ON(ret); |
908 | nand_cleanup(chip); |
909 | } |
910 | |
911 | #ifdef CONFIG_PM_SLEEP |
912 | static int vf610_nfc_suspend(struct device *dev) |
913 | { |
914 | struct vf610_nfc *nfc = dev_get_drvdata(dev); |
915 | |
916 | clk_disable_unprepare(clk: nfc->clk); |
917 | return 0; |
918 | } |
919 | |
920 | static int vf610_nfc_resume(struct device *dev) |
921 | { |
922 | struct vf610_nfc *nfc = dev_get_drvdata(dev); |
923 | int err; |
924 | |
925 | err = clk_prepare_enable(clk: nfc->clk); |
926 | if (err) |
927 | return err; |
928 | |
929 | vf610_nfc_preinit_controller(nfc); |
930 | vf610_nfc_init_controller(nfc); |
931 | return 0; |
932 | } |
933 | #endif |
934 | |
935 | static SIMPLE_DEV_PM_OPS(vf610_nfc_pm_ops, vf610_nfc_suspend, vf610_nfc_resume); |
936 | |
937 | static struct platform_driver vf610_nfc_driver = { |
938 | .driver = { |
939 | .name = DRV_NAME, |
940 | .of_match_table = vf610_nfc_dt_ids, |
941 | .pm = &vf610_nfc_pm_ops, |
942 | }, |
943 | .probe = vf610_nfc_probe, |
944 | .remove_new = vf610_nfc_remove, |
945 | }; |
946 | |
947 | module_platform_driver(vf610_nfc_driver); |
948 | |
949 | MODULE_AUTHOR("Stefan Agner <stefan.agner@toradex.com>" ); |
950 | MODULE_DESCRIPTION("Freescale VF610/MPC5125 NFC MTD NAND driver" ); |
951 | MODULE_LICENSE("GPL" ); |
952 | |