Merge tag 'for-linus-20160324' of git://git.infradead.org/linux-mtd
[deliverable/linux.git] / drivers / mtd / nand / sunxi_nand.c
1 /*
2 * Copyright (C) 2013 Boris BREZILLON <b.brezillon.dev@gmail.com>
3 *
4 * Derived from:
5 * https://github.com/yuq/sunxi-nfc-mtd
6 * Copyright (C) 2013 Qiang Yu <yuq825@gmail.com>
7 *
8 * https://github.com/hno/Allwinner-Info
9 * Copyright (C) 2013 Henrik Nordström <Henrik Nordström>
10 *
11 * Copyright (C) 2013 Dmitriy B. <rzk333@gmail.com>
12 * Copyright (C) 2013 Sergey Lapin <slapin@ossfans.org>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 */
24
25 #include <linux/dma-mapping.h>
26 #include <linux/slab.h>
27 #include <linux/module.h>
28 #include <linux/moduleparam.h>
29 #include <linux/platform_device.h>
30 #include <linux/of.h>
31 #include <linux/of_device.h>
32 #include <linux/of_gpio.h>
33 #include <linux/of_mtd.h>
34 #include <linux/mtd/mtd.h>
35 #include <linux/mtd/nand.h>
36 #include <linux/mtd/partitions.h>
37 #include <linux/clk.h>
38 #include <linux/delay.h>
39 #include <linux/dmaengine.h>
40 #include <linux/gpio.h>
41 #include <linux/interrupt.h>
42 #include <linux/io.h>
43
44 #define NFC_REG_CTL 0x0000
45 #define NFC_REG_ST 0x0004
46 #define NFC_REG_INT 0x0008
47 #define NFC_REG_TIMING_CTL 0x000C
48 #define NFC_REG_TIMING_CFG 0x0010
49 #define NFC_REG_ADDR_LOW 0x0014
50 #define NFC_REG_ADDR_HIGH 0x0018
51 #define NFC_REG_SECTOR_NUM 0x001C
52 #define NFC_REG_CNT 0x0020
53 #define NFC_REG_CMD 0x0024
54 #define NFC_REG_RCMD_SET 0x0028
55 #define NFC_REG_WCMD_SET 0x002C
56 #define NFC_REG_IO_DATA 0x0030
57 #define NFC_REG_ECC_CTL 0x0034
58 #define NFC_REG_ECC_ST 0x0038
59 #define NFC_REG_DEBUG 0x003C
60 #define NFC_REG_ECC_ERR_CNT(x) ((0x0040 + (x)) & ~0x3)
61 #define NFC_REG_USER_DATA(x) (0x0050 + ((x) * 4))
62 #define NFC_REG_SPARE_AREA 0x00A0
63 #define NFC_REG_PAT_ID 0x00A4
64 #define NFC_RAM0_BASE 0x0400
65 #define NFC_RAM1_BASE 0x0800
66
67 /* define bit use in NFC_CTL */
68 #define NFC_EN BIT(0)
69 #define NFC_RESET BIT(1)
70 #define NFC_BUS_WIDTH_MSK BIT(2)
71 #define NFC_BUS_WIDTH_8 (0 << 2)
72 #define NFC_BUS_WIDTH_16 (1 << 2)
73 #define NFC_RB_SEL_MSK BIT(3)
74 #define NFC_RB_SEL(x) ((x) << 3)
75 #define NFC_CE_SEL_MSK GENMASK(26, 24)
76 #define NFC_CE_SEL(x) ((x) << 24)
77 #define NFC_CE_CTL BIT(6)
78 #define NFC_PAGE_SHIFT_MSK GENMASK(11, 8)
79 #define NFC_PAGE_SHIFT(x) (((x) < 10 ? 0 : (x) - 10) << 8)
80 #define NFC_SAM BIT(12)
81 #define NFC_RAM_METHOD BIT(14)
82 #define NFC_DEBUG_CTL BIT(31)
83
84 /* define bit use in NFC_ST */
85 #define NFC_RB_B2R BIT(0)
86 #define NFC_CMD_INT_FLAG BIT(1)
87 #define NFC_DMA_INT_FLAG BIT(2)
88 #define NFC_CMD_FIFO_STATUS BIT(3)
89 #define NFC_STA BIT(4)
90 #define NFC_NATCH_INT_FLAG BIT(5)
91 #define NFC_RB_STATE(x) BIT(x + 8)
92
93 /* define bit use in NFC_INT */
94 #define NFC_B2R_INT_ENABLE BIT(0)
95 #define NFC_CMD_INT_ENABLE BIT(1)
96 #define NFC_DMA_INT_ENABLE BIT(2)
97 #define NFC_INT_MASK (NFC_B2R_INT_ENABLE | \
98 NFC_CMD_INT_ENABLE | \
99 NFC_DMA_INT_ENABLE)
100
101 /* define bit use in NFC_TIMING_CTL */
102 #define NFC_TIMING_CTL_EDO BIT(8)
103
104 /* define NFC_TIMING_CFG register layout */
105 #define NFC_TIMING_CFG(tWB, tADL, tWHR, tRHW, tCAD) \
106 (((tWB) & 0x3) | (((tADL) & 0x3) << 2) | \
107 (((tWHR) & 0x3) << 4) | (((tRHW) & 0x3) << 6) | \
108 (((tCAD) & 0x7) << 8))
109
110 /* define bit use in NFC_CMD */
111 #define NFC_CMD_LOW_BYTE_MSK GENMASK(7, 0)
112 #define NFC_CMD_HIGH_BYTE_MSK GENMASK(15, 8)
113 #define NFC_CMD(x) (x)
114 #define NFC_ADR_NUM_MSK GENMASK(18, 16)
115 #define NFC_ADR_NUM(x) (((x) - 1) << 16)
116 #define NFC_SEND_ADR BIT(19)
117 #define NFC_ACCESS_DIR BIT(20)
118 #define NFC_DATA_TRANS BIT(21)
119 #define NFC_SEND_CMD1 BIT(22)
120 #define NFC_WAIT_FLAG BIT(23)
121 #define NFC_SEND_CMD2 BIT(24)
122 #define NFC_SEQ BIT(25)
123 #define NFC_DATA_SWAP_METHOD BIT(26)
124 #define NFC_ROW_AUTO_INC BIT(27)
125 #define NFC_SEND_CMD3 BIT(28)
126 #define NFC_SEND_CMD4 BIT(29)
127 #define NFC_CMD_TYPE_MSK GENMASK(31, 30)
128 #define NFC_NORMAL_OP (0 << 30)
129 #define NFC_ECC_OP (1 << 30)
130 #define NFC_PAGE_OP (2 << 30)
131
132 /* define bit use in NFC_RCMD_SET */
133 #define NFC_READ_CMD_MSK GENMASK(7, 0)
134 #define NFC_RND_READ_CMD0_MSK GENMASK(15, 8)
135 #define NFC_RND_READ_CMD1_MSK GENMASK(23, 16)
136
137 /* define bit use in NFC_WCMD_SET */
138 #define NFC_PROGRAM_CMD_MSK GENMASK(7, 0)
139 #define NFC_RND_WRITE_CMD_MSK GENMASK(15, 8)
140 #define NFC_READ_CMD0_MSK GENMASK(23, 16)
141 #define NFC_READ_CMD1_MSK GENMASK(31, 24)
142
143 /* define bit use in NFC_ECC_CTL */
144 #define NFC_ECC_EN BIT(0)
145 #define NFC_ECC_PIPELINE BIT(3)
146 #define NFC_ECC_EXCEPTION BIT(4)
147 #define NFC_ECC_BLOCK_SIZE_MSK BIT(5)
148 #define NFC_RANDOM_EN BIT(9)
149 #define NFC_RANDOM_DIRECTION BIT(10)
150 #define NFC_ECC_MODE_MSK GENMASK(15, 12)
151 #define NFC_ECC_MODE(x) ((x) << 12)
152 #define NFC_RANDOM_SEED_MSK GENMASK(30, 16)
153 #define NFC_RANDOM_SEED(x) ((x) << 16)
154
155 /* define bit use in NFC_ECC_ST */
156 #define NFC_ECC_ERR(x) BIT(x)
157 #define NFC_ECC_PAT_FOUND(x) BIT(x + 16)
158 #define NFC_ECC_ERR_CNT(b, x) (((x) >> ((b) * 8)) & 0xff)
159
160 #define NFC_DEFAULT_TIMEOUT_MS 1000
161
162 #define NFC_SRAM_SIZE 1024
163
164 #define NFC_MAX_CS 7
165
166 /*
167 * Ready/Busy detection type: describes the Ready/Busy detection modes
168 *
169 * @RB_NONE: no external detection available, rely on STATUS command
170 * and software timeouts
171 * @RB_NATIVE: use sunxi NAND controller Ready/Busy support. The Ready/Busy
172 * pin of the NAND flash chip must be connected to one of the
173 * native NAND R/B pins (those which can be muxed to the NAND
174 * Controller)
175 * @RB_GPIO: use a simple GPIO to handle Ready/Busy status. The Ready/Busy
176 * pin of the NAND flash chip must be connected to a GPIO capable
177 * pin.
178 */
179 enum sunxi_nand_rb_type {
180 RB_NONE,
181 RB_NATIVE,
182 RB_GPIO,
183 };
184
185 /*
186 * Ready/Busy structure: stores information related to Ready/Busy detection
187 *
188 * @type: the Ready/Busy detection mode
189 * @info: information related to the R/B detection mode. Either a gpio
190 * id or a native R/B id (those supported by the NAND controller).
191 */
192 struct sunxi_nand_rb {
193 enum sunxi_nand_rb_type type;
194 union {
195 int gpio;
196 int nativeid;
197 } info;
198 };
199
200 /*
201 * Chip Select structure: stores information related to NAND Chip Select
202 *
203 * @cs: the NAND CS id used to communicate with a NAND Chip
204 * @rb: the Ready/Busy description
205 */
206 struct sunxi_nand_chip_sel {
207 u8 cs;
208 struct sunxi_nand_rb rb;
209 };
210
211 /*
212 * sunxi HW ECC infos: stores information related to HW ECC support
213 *
214 * @mode: the sunxi ECC mode field deduced from ECC requirements
215 * @layout: the OOB layout depending on the ECC requirements and the
216 * selected ECC mode
217 */
218 struct sunxi_nand_hw_ecc {
219 int mode;
220 struct nand_ecclayout layout;
221 };
222
223 /*
224 * NAND chip structure: stores NAND chip device related information
225 *
226 * @node: used to store NAND chips into a list
227 * @nand: base NAND chip structure
228 * @mtd: base MTD structure
229 * @clk_rate: clk_rate required for this NAND chip
230 * @timing_cfg TIMING_CFG register value for this NAND chip
231 * @selected: current active CS
232 * @nsels: number of CS lines required by the NAND chip
233 * @sels: array of CS lines descriptions
234 */
235 struct sunxi_nand_chip {
236 struct list_head node;
237 struct nand_chip nand;
238 unsigned long clk_rate;
239 u32 timing_cfg;
240 u32 timing_ctl;
241 int selected;
242 int nsels;
243 struct sunxi_nand_chip_sel sels[0];
244 };
245
246 static inline struct sunxi_nand_chip *to_sunxi_nand(struct nand_chip *nand)
247 {
248 return container_of(nand, struct sunxi_nand_chip, nand);
249 }
250
251 /*
252 * NAND Controller structure: stores sunxi NAND controller information
253 *
254 * @controller: base controller structure
255 * @dev: parent device (used to print error messages)
256 * @regs: NAND controller registers
257 * @ahb_clk: NAND Controller AHB clock
258 * @mod_clk: NAND Controller mod clock
259 * @assigned_cs: bitmask describing already assigned CS lines
260 * @clk_rate: NAND controller current clock rate
261 * @chips: a list containing all the NAND chips attached to
262 * this NAND controller
263 * @complete: a completion object used to wait for NAND
264 * controller events
265 */
266 struct sunxi_nfc {
267 struct nand_hw_control controller;
268 struct device *dev;
269 void __iomem *regs;
270 struct clk *ahb_clk;
271 struct clk *mod_clk;
272 unsigned long assigned_cs;
273 unsigned long clk_rate;
274 struct list_head chips;
275 struct completion complete;
276 };
277
278 static inline struct sunxi_nfc *to_sunxi_nfc(struct nand_hw_control *ctrl)
279 {
280 return container_of(ctrl, struct sunxi_nfc, controller);
281 }
282
283 static irqreturn_t sunxi_nfc_interrupt(int irq, void *dev_id)
284 {
285 struct sunxi_nfc *nfc = dev_id;
286 u32 st = readl(nfc->regs + NFC_REG_ST);
287 u32 ien = readl(nfc->regs + NFC_REG_INT);
288
289 if (!(ien & st))
290 return IRQ_NONE;
291
292 if ((ien & st) == ien)
293 complete(&nfc->complete);
294
295 writel(st & NFC_INT_MASK, nfc->regs + NFC_REG_ST);
296 writel(~st & ien & NFC_INT_MASK, nfc->regs + NFC_REG_INT);
297
298 return IRQ_HANDLED;
299 }
300
301 static int sunxi_nfc_wait_int(struct sunxi_nfc *nfc, u32 flags,
302 unsigned int timeout_ms)
303 {
304 init_completion(&nfc->complete);
305
306 writel(flags, nfc->regs + NFC_REG_INT);
307
308 if (!timeout_ms)
309 timeout_ms = NFC_DEFAULT_TIMEOUT_MS;
310
311 if (!wait_for_completion_timeout(&nfc->complete,
312 msecs_to_jiffies(timeout_ms))) {
313 dev_err(nfc->dev, "wait interrupt timedout\n");
314 return -ETIMEDOUT;
315 }
316
317 return 0;
318 }
319
320 static int sunxi_nfc_wait_cmd_fifo_empty(struct sunxi_nfc *nfc)
321 {
322 unsigned long timeout = jiffies +
323 msecs_to_jiffies(NFC_DEFAULT_TIMEOUT_MS);
324
325 do {
326 if (!(readl(nfc->regs + NFC_REG_ST) & NFC_CMD_FIFO_STATUS))
327 return 0;
328 } while (time_before(jiffies, timeout));
329
330 dev_err(nfc->dev, "wait for empty cmd FIFO timedout\n");
331 return -ETIMEDOUT;
332 }
333
334 static int sunxi_nfc_rst(struct sunxi_nfc *nfc)
335 {
336 unsigned long timeout = jiffies +
337 msecs_to_jiffies(NFC_DEFAULT_TIMEOUT_MS);
338
339 writel(0, nfc->regs + NFC_REG_ECC_CTL);
340 writel(NFC_RESET, nfc->regs + NFC_REG_CTL);
341
342 do {
343 if (!(readl(nfc->regs + NFC_REG_CTL) & NFC_RESET))
344 return 0;
345 } while (time_before(jiffies, timeout));
346
347 dev_err(nfc->dev, "wait for NAND controller reset timedout\n");
348 return -ETIMEDOUT;
349 }
350
351 static int sunxi_nfc_dev_ready(struct mtd_info *mtd)
352 {
353 struct nand_chip *nand = mtd_to_nand(mtd);
354 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
355 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
356 struct sunxi_nand_rb *rb;
357 unsigned long timeo = (sunxi_nand->nand.state == FL_ERASING ? 400 : 20);
358 int ret;
359
360 if (sunxi_nand->selected < 0)
361 return 0;
362
363 rb = &sunxi_nand->sels[sunxi_nand->selected].rb;
364
365 switch (rb->type) {
366 case RB_NATIVE:
367 ret = !!(readl(nfc->regs + NFC_REG_ST) &
368 NFC_RB_STATE(rb->info.nativeid));
369 if (ret)
370 break;
371
372 sunxi_nfc_wait_int(nfc, NFC_RB_B2R, timeo);
373 ret = !!(readl(nfc->regs + NFC_REG_ST) &
374 NFC_RB_STATE(rb->info.nativeid));
375 break;
376 case RB_GPIO:
377 ret = gpio_get_value(rb->info.gpio);
378 break;
379 case RB_NONE:
380 default:
381 ret = 0;
382 dev_err(nfc->dev, "cannot check R/B NAND status!\n");
383 break;
384 }
385
386 return ret;
387 }
388
389 static void sunxi_nfc_select_chip(struct mtd_info *mtd, int chip)
390 {
391 struct nand_chip *nand = mtd_to_nand(mtd);
392 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
393 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
394 struct sunxi_nand_chip_sel *sel;
395 u32 ctl;
396
397 if (chip > 0 && chip >= sunxi_nand->nsels)
398 return;
399
400 if (chip == sunxi_nand->selected)
401 return;
402
403 ctl = readl(nfc->regs + NFC_REG_CTL) &
404 ~(NFC_PAGE_SHIFT_MSK | NFC_CE_SEL_MSK | NFC_RB_SEL_MSK | NFC_EN);
405
406 if (chip >= 0) {
407 sel = &sunxi_nand->sels[chip];
408
409 ctl |= NFC_CE_SEL(sel->cs) | NFC_EN |
410 NFC_PAGE_SHIFT(nand->page_shift - 10);
411 if (sel->rb.type == RB_NONE) {
412 nand->dev_ready = NULL;
413 } else {
414 nand->dev_ready = sunxi_nfc_dev_ready;
415 if (sel->rb.type == RB_NATIVE)
416 ctl |= NFC_RB_SEL(sel->rb.info.nativeid);
417 }
418
419 writel(mtd->writesize, nfc->regs + NFC_REG_SPARE_AREA);
420
421 if (nfc->clk_rate != sunxi_nand->clk_rate) {
422 clk_set_rate(nfc->mod_clk, sunxi_nand->clk_rate);
423 nfc->clk_rate = sunxi_nand->clk_rate;
424 }
425 }
426
427 writel(sunxi_nand->timing_ctl, nfc->regs + NFC_REG_TIMING_CTL);
428 writel(sunxi_nand->timing_cfg, nfc->regs + NFC_REG_TIMING_CFG);
429 writel(ctl, nfc->regs + NFC_REG_CTL);
430
431 sunxi_nand->selected = chip;
432 }
433
434 static void sunxi_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
435 {
436 struct nand_chip *nand = mtd_to_nand(mtd);
437 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
438 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
439 int ret;
440 int cnt;
441 int offs = 0;
442 u32 tmp;
443
444 while (len > offs) {
445 cnt = min(len - offs, NFC_SRAM_SIZE);
446
447 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
448 if (ret)
449 break;
450
451 writel(cnt, nfc->regs + NFC_REG_CNT);
452 tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD;
453 writel(tmp, nfc->regs + NFC_REG_CMD);
454
455 ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
456 if (ret)
457 break;
458
459 if (buf)
460 memcpy_fromio(buf + offs, nfc->regs + NFC_RAM0_BASE,
461 cnt);
462 offs += cnt;
463 }
464 }
465
466 static void sunxi_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf,
467 int len)
468 {
469 struct nand_chip *nand = mtd_to_nand(mtd);
470 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
471 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
472 int ret;
473 int cnt;
474 int offs = 0;
475 u32 tmp;
476
477 while (len > offs) {
478 cnt = min(len - offs, NFC_SRAM_SIZE);
479
480 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
481 if (ret)
482 break;
483
484 writel(cnt, nfc->regs + NFC_REG_CNT);
485 memcpy_toio(nfc->regs + NFC_RAM0_BASE, buf + offs, cnt);
486 tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD |
487 NFC_ACCESS_DIR;
488 writel(tmp, nfc->regs + NFC_REG_CMD);
489
490 ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
491 if (ret)
492 break;
493
494 offs += cnt;
495 }
496 }
497
498 static uint8_t sunxi_nfc_read_byte(struct mtd_info *mtd)
499 {
500 uint8_t ret;
501
502 sunxi_nfc_read_buf(mtd, &ret, 1);
503
504 return ret;
505 }
506
507 static void sunxi_nfc_cmd_ctrl(struct mtd_info *mtd, int dat,
508 unsigned int ctrl)
509 {
510 struct nand_chip *nand = mtd_to_nand(mtd);
511 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
512 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
513 int ret;
514 u32 tmp;
515
516 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
517 if (ret)
518 return;
519
520 if (ctrl & NAND_CTRL_CHANGE) {
521 tmp = readl(nfc->regs + NFC_REG_CTL);
522 if (ctrl & NAND_NCE)
523 tmp |= NFC_CE_CTL;
524 else
525 tmp &= ~NFC_CE_CTL;
526 writel(tmp, nfc->regs + NFC_REG_CTL);
527 }
528
529 if (dat == NAND_CMD_NONE)
530 return;
531
532 if (ctrl & NAND_CLE) {
533 writel(NFC_SEND_CMD1 | dat, nfc->regs + NFC_REG_CMD);
534 } else {
535 writel(dat, nfc->regs + NFC_REG_ADDR_LOW);
536 writel(NFC_SEND_ADR, nfc->regs + NFC_REG_CMD);
537 }
538
539 sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
540 }
541
542 /* These seed values have been extracted from Allwinner's BSP */
543 static const u16 sunxi_nfc_randomizer_page_seeds[] = {
544 0x2b75, 0x0bd0, 0x5ca3, 0x62d1, 0x1c93, 0x07e9, 0x2162, 0x3a72,
545 0x0d67, 0x67f9, 0x1be7, 0x077d, 0x032f, 0x0dac, 0x2716, 0x2436,
546 0x7922, 0x1510, 0x3860, 0x5287, 0x480f, 0x4252, 0x1789, 0x5a2d,
547 0x2a49, 0x5e10, 0x437f, 0x4b4e, 0x2f45, 0x216e, 0x5cb7, 0x7130,
548 0x2a3f, 0x60e4, 0x4dc9, 0x0ef0, 0x0f52, 0x1bb9, 0x6211, 0x7a56,
549 0x226d, 0x4ea7, 0x6f36, 0x3692, 0x38bf, 0x0c62, 0x05eb, 0x4c55,
550 0x60f4, 0x728c, 0x3b6f, 0x2037, 0x7f69, 0x0936, 0x651a, 0x4ceb,
551 0x6218, 0x79f3, 0x383f, 0x18d9, 0x4f05, 0x5c82, 0x2912, 0x6f17,
552 0x6856, 0x5938, 0x1007, 0x61ab, 0x3e7f, 0x57c2, 0x542f, 0x4f62,
553 0x7454, 0x2eac, 0x7739, 0x42d4, 0x2f90, 0x435a, 0x2e52, 0x2064,
554 0x637c, 0x66ad, 0x2c90, 0x0bad, 0x759c, 0x0029, 0x0986, 0x7126,
555 0x1ca7, 0x1605, 0x386a, 0x27f5, 0x1380, 0x6d75, 0x24c3, 0x0f8e,
556 0x2b7a, 0x1418, 0x1fd1, 0x7dc1, 0x2d8e, 0x43af, 0x2267, 0x7da3,
557 0x4e3d, 0x1338, 0x50db, 0x454d, 0x764d, 0x40a3, 0x42e6, 0x262b,
558 0x2d2e, 0x1aea, 0x2e17, 0x173d, 0x3a6e, 0x71bf, 0x25f9, 0x0a5d,
559 0x7c57, 0x0fbe, 0x46ce, 0x4939, 0x6b17, 0x37bb, 0x3e91, 0x76db,
560 };
561
562 /*
563 * sunxi_nfc_randomizer_ecc512_seeds and sunxi_nfc_randomizer_ecc1024_seeds
564 * have been generated using
565 * sunxi_nfc_randomizer_step(seed, (step_size * 8) + 15), which is what
566 * the randomizer engine does internally before de/scrambling OOB data.
567 *
568 * Those tables are statically defined to avoid calculating randomizer state
569 * at runtime.
570 */
571 static const u16 sunxi_nfc_randomizer_ecc512_seeds[] = {
572 0x3346, 0x367f, 0x1f18, 0x769a, 0x4f64, 0x068c, 0x2ef1, 0x6b64,
573 0x28a9, 0x15d7, 0x30f8, 0x3659, 0x53db, 0x7c5f, 0x71d4, 0x4409,
574 0x26eb, 0x03cc, 0x655d, 0x47d4, 0x4daa, 0x0877, 0x712d, 0x3617,
575 0x3264, 0x49aa, 0x7f9e, 0x588e, 0x4fbc, 0x7176, 0x7f91, 0x6c6d,
576 0x4b95, 0x5fb7, 0x3844, 0x4037, 0x0184, 0x081b, 0x0ee8, 0x5b91,
577 0x293d, 0x1f71, 0x0e6f, 0x402b, 0x5122, 0x1e52, 0x22be, 0x3d2d,
578 0x75bc, 0x7c60, 0x6291, 0x1a2f, 0x61d4, 0x74aa, 0x4140, 0x29ab,
579 0x472d, 0x2852, 0x017e, 0x15e8, 0x5ec2, 0x17cf, 0x7d0f, 0x06b8,
580 0x117a, 0x6b94, 0x789b, 0x3126, 0x6ac5, 0x5be7, 0x150f, 0x51f8,
581 0x7889, 0x0aa5, 0x663d, 0x77e8, 0x0b87, 0x3dcb, 0x360d, 0x218b,
582 0x512f, 0x7dc9, 0x6a4d, 0x630a, 0x3547, 0x1dd2, 0x5aea, 0x69a5,
583 0x7bfa, 0x5e4f, 0x1519, 0x6430, 0x3a0e, 0x5eb3, 0x5425, 0x0c7a,
584 0x5540, 0x3670, 0x63c1, 0x31e9, 0x5a39, 0x2de7, 0x5979, 0x2891,
585 0x1562, 0x014b, 0x5b05, 0x2756, 0x5a34, 0x13aa, 0x6cb5, 0x2c36,
586 0x5e72, 0x1306, 0x0861, 0x15ef, 0x1ee8, 0x5a37, 0x7ac4, 0x45dd,
587 0x44c4, 0x7266, 0x2f41, 0x3ccc, 0x045e, 0x7d40, 0x7c66, 0x0fa0,
588 };
589
590 static const u16 sunxi_nfc_randomizer_ecc1024_seeds[] = {
591 0x2cf5, 0x35f1, 0x63a4, 0x5274, 0x2bd2, 0x778b, 0x7285, 0x32b6,
592 0x6a5c, 0x70d6, 0x757d, 0x6769, 0x5375, 0x1e81, 0x0cf3, 0x3982,
593 0x6787, 0x042a, 0x6c49, 0x1925, 0x56a8, 0x40a9, 0x063e, 0x7bd9,
594 0x4dbf, 0x55ec, 0x672e, 0x7334, 0x5185, 0x4d00, 0x232a, 0x7e07,
595 0x445d, 0x6b92, 0x528f, 0x4255, 0x53ba, 0x7d82, 0x2a2e, 0x3a4e,
596 0x75eb, 0x450c, 0x6844, 0x1b5d, 0x581a, 0x4cc6, 0x0379, 0x37b2,
597 0x419f, 0x0e92, 0x6b27, 0x5624, 0x01e3, 0x07c1, 0x44a5, 0x130c,
598 0x13e8, 0x5910, 0x0876, 0x60c5, 0x54e3, 0x5b7f, 0x2269, 0x509f,
599 0x7665, 0x36fd, 0x3e9a, 0x0579, 0x6295, 0x14ef, 0x0a81, 0x1bcc,
600 0x4b16, 0x64db, 0x0514, 0x4f07, 0x0591, 0x3576, 0x6853, 0x0d9e,
601 0x259f, 0x38b7, 0x64fb, 0x3094, 0x4693, 0x6ddd, 0x29bb, 0x0bc8,
602 0x3f47, 0x490e, 0x0c0e, 0x7933, 0x3c9e, 0x5840, 0x398d, 0x3e68,
603 0x4af1, 0x71f5, 0x57cf, 0x1121, 0x64eb, 0x3579, 0x15ac, 0x584d,
604 0x5f2a, 0x47e2, 0x6528, 0x6eac, 0x196e, 0x6b96, 0x0450, 0x0179,
605 0x609c, 0x06e1, 0x4626, 0x42c7, 0x273e, 0x486f, 0x0705, 0x1601,
606 0x145b, 0x407e, 0x062b, 0x57a5, 0x53f9, 0x5659, 0x4410, 0x3ccd,
607 };
608
609 static u16 sunxi_nfc_randomizer_step(u16 state, int count)
610 {
611 state &= 0x7fff;
612
613 /*
614 * This loop is just a simple implementation of a Fibonacci LFSR using
615 * the x16 + x15 + 1 polynomial.
616 */
617 while (count--)
618 state = ((state >> 1) |
619 (((state ^ (state >> 1)) & 1) << 14)) & 0x7fff;
620
621 return state;
622 }
623
624 static u16 sunxi_nfc_randomizer_state(struct mtd_info *mtd, int page, bool ecc)
625 {
626 const u16 *seeds = sunxi_nfc_randomizer_page_seeds;
627 int mod = mtd_div_by_ws(mtd->erasesize, mtd);
628
629 if (mod > ARRAY_SIZE(sunxi_nfc_randomizer_page_seeds))
630 mod = ARRAY_SIZE(sunxi_nfc_randomizer_page_seeds);
631
632 if (ecc) {
633 if (mtd->ecc_step_size == 512)
634 seeds = sunxi_nfc_randomizer_ecc512_seeds;
635 else
636 seeds = sunxi_nfc_randomizer_ecc1024_seeds;
637 }
638
639 return seeds[page % mod];
640 }
641
642 static void sunxi_nfc_randomizer_config(struct mtd_info *mtd,
643 int page, bool ecc)
644 {
645 struct nand_chip *nand = mtd_to_nand(mtd);
646 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
647 u32 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL);
648 u16 state;
649
650 if (!(nand->options & NAND_NEED_SCRAMBLING))
651 return;
652
653 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL);
654 state = sunxi_nfc_randomizer_state(mtd, page, ecc);
655 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_RANDOM_SEED_MSK;
656 writel(ecc_ctl | NFC_RANDOM_SEED(state), nfc->regs + NFC_REG_ECC_CTL);
657 }
658
659 static void sunxi_nfc_randomizer_enable(struct mtd_info *mtd)
660 {
661 struct nand_chip *nand = mtd_to_nand(mtd);
662 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
663
664 if (!(nand->options & NAND_NEED_SCRAMBLING))
665 return;
666
667 writel(readl(nfc->regs + NFC_REG_ECC_CTL) | NFC_RANDOM_EN,
668 nfc->regs + NFC_REG_ECC_CTL);
669 }
670
671 static void sunxi_nfc_randomizer_disable(struct mtd_info *mtd)
672 {
673 struct nand_chip *nand = mtd_to_nand(mtd);
674 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
675
676 if (!(nand->options & NAND_NEED_SCRAMBLING))
677 return;
678
679 writel(readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_RANDOM_EN,
680 nfc->regs + NFC_REG_ECC_CTL);
681 }
682
683 static void sunxi_nfc_randomize_bbm(struct mtd_info *mtd, int page, u8 *bbm)
684 {
685 u16 state = sunxi_nfc_randomizer_state(mtd, page, true);
686
687 bbm[0] ^= state;
688 bbm[1] ^= sunxi_nfc_randomizer_step(state, 8);
689 }
690
691 static void sunxi_nfc_randomizer_write_buf(struct mtd_info *mtd,
692 const uint8_t *buf, int len,
693 bool ecc, int page)
694 {
695 sunxi_nfc_randomizer_config(mtd, page, ecc);
696 sunxi_nfc_randomizer_enable(mtd);
697 sunxi_nfc_write_buf(mtd, buf, len);
698 sunxi_nfc_randomizer_disable(mtd);
699 }
700
701 static void sunxi_nfc_randomizer_read_buf(struct mtd_info *mtd, uint8_t *buf,
702 int len, bool ecc, int page)
703 {
704 sunxi_nfc_randomizer_config(mtd, page, ecc);
705 sunxi_nfc_randomizer_enable(mtd);
706 sunxi_nfc_read_buf(mtd, buf, len);
707 sunxi_nfc_randomizer_disable(mtd);
708 }
709
710 static void sunxi_nfc_hw_ecc_enable(struct mtd_info *mtd)
711 {
712 struct nand_chip *nand = mtd_to_nand(mtd);
713 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
714 struct sunxi_nand_hw_ecc *data = nand->ecc.priv;
715 u32 ecc_ctl;
716
717 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL);
718 ecc_ctl &= ~(NFC_ECC_MODE_MSK | NFC_ECC_PIPELINE |
719 NFC_ECC_BLOCK_SIZE_MSK);
720 ecc_ctl |= NFC_ECC_EN | NFC_ECC_MODE(data->mode) | NFC_ECC_EXCEPTION;
721
722 writel(ecc_ctl, nfc->regs + NFC_REG_ECC_CTL);
723 }
724
725 static void sunxi_nfc_hw_ecc_disable(struct mtd_info *mtd)
726 {
727 struct nand_chip *nand = mtd_to_nand(mtd);
728 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
729
730 writel(readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_ECC_EN,
731 nfc->regs + NFC_REG_ECC_CTL);
732 }
733
734 static inline void sunxi_nfc_user_data_to_buf(u32 user_data, u8 *buf)
735 {
736 buf[0] = user_data;
737 buf[1] = user_data >> 8;
738 buf[2] = user_data >> 16;
739 buf[3] = user_data >> 24;
740 }
741
742 static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd,
743 u8 *data, int data_off,
744 u8 *oob, int oob_off,
745 int *cur_off,
746 unsigned int *max_bitflips,
747 bool bbm, int page)
748 {
749 struct nand_chip *nand = mtd_to_nand(mtd);
750 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
751 struct nand_ecc_ctrl *ecc = &nand->ecc;
752 int raw_mode = 0;
753 u32 status;
754 int ret;
755
756 if (*cur_off != data_off)
757 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, data_off, -1);
758
759 sunxi_nfc_randomizer_read_buf(mtd, NULL, ecc->size, false, page);
760
761 if (data_off + ecc->size != oob_off)
762 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
763
764 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
765 if (ret)
766 return ret;
767
768 sunxi_nfc_randomizer_enable(mtd);
769 writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_ECC_OP,
770 nfc->regs + NFC_REG_CMD);
771
772 ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
773 sunxi_nfc_randomizer_disable(mtd);
774 if (ret)
775 return ret;
776
777 *cur_off = oob_off + ecc->bytes + 4;
778
779 status = readl(nfc->regs + NFC_REG_ECC_ST);
780 if (status & NFC_ECC_PAT_FOUND(0)) {
781 u8 pattern = 0xff;
782
783 if (unlikely(!(readl(nfc->regs + NFC_REG_PAT_ID) & 0x1)))
784 pattern = 0x0;
785
786 memset(data, pattern, ecc->size);
787 memset(oob, pattern, ecc->bytes + 4);
788
789 return 1;
790 }
791
792 ret = NFC_ECC_ERR_CNT(0, readl(nfc->regs + NFC_REG_ECC_ERR_CNT(0)));
793
794 memcpy_fromio(data, nfc->regs + NFC_RAM0_BASE, ecc->size);
795
796 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
797 sunxi_nfc_randomizer_read_buf(mtd, oob, ecc->bytes + 4, true, page);
798
799 if (status & NFC_ECC_ERR(0)) {
800 /*
801 * Re-read the data with the randomizer disabled to identify
802 * bitflips in erased pages.
803 */
804 if (nand->options & NAND_NEED_SCRAMBLING) {
805 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, data_off, -1);
806 nand->read_buf(mtd, data, ecc->size);
807 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
808 nand->read_buf(mtd, oob, ecc->bytes + 4);
809 }
810
811 ret = nand_check_erased_ecc_chunk(data, ecc->size,
812 oob, ecc->bytes + 4,
813 NULL, 0, ecc->strength);
814 if (ret >= 0)
815 raw_mode = 1;
816 } else {
817 /*
818 * The engine protects 4 bytes of OOB data per chunk.
819 * Retrieve the corrected OOB bytes.
820 */
821 sunxi_nfc_user_data_to_buf(readl(nfc->regs + NFC_REG_USER_DATA(0)),
822 oob);
823
824 /* De-randomize the Bad Block Marker. */
825 if (bbm && nand->options & NAND_NEED_SCRAMBLING)
826 sunxi_nfc_randomize_bbm(mtd, page, oob);
827 }
828
829 if (ret < 0) {
830 mtd->ecc_stats.failed++;
831 } else {
832 mtd->ecc_stats.corrected += ret;
833 *max_bitflips = max_t(unsigned int, *max_bitflips, ret);
834 }
835
836 return raw_mode;
837 }
838
839 static void sunxi_nfc_hw_ecc_read_extra_oob(struct mtd_info *mtd,
840 u8 *oob, int *cur_off,
841 bool randomize, int page)
842 {
843 struct nand_chip *nand = mtd_to_nand(mtd);
844 struct nand_ecc_ctrl *ecc = &nand->ecc;
845 int offset = ((ecc->bytes + 4) * ecc->steps);
846 int len = mtd->oobsize - offset;
847
848 if (len <= 0)
849 return;
850
851 if (*cur_off != offset)
852 nand->cmdfunc(mtd, NAND_CMD_RNDOUT,
853 offset + mtd->writesize, -1);
854
855 if (!randomize)
856 sunxi_nfc_read_buf(mtd, oob + offset, len);
857 else
858 sunxi_nfc_randomizer_read_buf(mtd, oob + offset, len,
859 false, page);
860
861 *cur_off = mtd->oobsize + mtd->writesize;
862 }
863
864 static inline u32 sunxi_nfc_buf_to_user_data(const u8 *buf)
865 {
866 return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
867 }
868
869 static int sunxi_nfc_hw_ecc_write_chunk(struct mtd_info *mtd,
870 const u8 *data, int data_off,
871 const u8 *oob, int oob_off,
872 int *cur_off, bool bbm,
873 int page)
874 {
875 struct nand_chip *nand = mtd_to_nand(mtd);
876 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
877 struct nand_ecc_ctrl *ecc = &nand->ecc;
878 int ret;
879
880 if (data_off != *cur_off)
881 nand->cmdfunc(mtd, NAND_CMD_RNDIN, data_off, -1);
882
883 sunxi_nfc_randomizer_write_buf(mtd, data, ecc->size, false, page);
884
885 /* Fill OOB data in */
886 if ((nand->options & NAND_NEED_SCRAMBLING) && bbm) {
887 u8 user_data[4];
888
889 memcpy(user_data, oob, 4);
890 sunxi_nfc_randomize_bbm(mtd, page, user_data);
891 writel(sunxi_nfc_buf_to_user_data(user_data),
892 nfc->regs + NFC_REG_USER_DATA(0));
893 } else {
894 writel(sunxi_nfc_buf_to_user_data(oob),
895 nfc->regs + NFC_REG_USER_DATA(0));
896 }
897
898 if (data_off + ecc->size != oob_off)
899 nand->cmdfunc(mtd, NAND_CMD_RNDIN, oob_off, -1);
900
901 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
902 if (ret)
903 return ret;
904
905 sunxi_nfc_randomizer_enable(mtd);
906 writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD |
907 NFC_ACCESS_DIR | NFC_ECC_OP,
908 nfc->regs + NFC_REG_CMD);
909
910 ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
911 sunxi_nfc_randomizer_disable(mtd);
912 if (ret)
913 return ret;
914
915 *cur_off = oob_off + ecc->bytes + 4;
916
917 return 0;
918 }
919
920 static void sunxi_nfc_hw_ecc_write_extra_oob(struct mtd_info *mtd,
921 u8 *oob, int *cur_off,
922 int page)
923 {
924 struct nand_chip *nand = mtd_to_nand(mtd);
925 struct nand_ecc_ctrl *ecc = &nand->ecc;
926 int offset = ((ecc->bytes + 4) * ecc->steps);
927 int len = mtd->oobsize - offset;
928
929 if (len <= 0)
930 return;
931
932 if (*cur_off != offset)
933 nand->cmdfunc(mtd, NAND_CMD_RNDIN,
934 offset + mtd->writesize, -1);
935
936 sunxi_nfc_randomizer_write_buf(mtd, oob + offset, len, false, page);
937
938 *cur_off = mtd->oobsize + mtd->writesize;
939 }
940
941 static int sunxi_nfc_hw_ecc_read_page(struct mtd_info *mtd,
942 struct nand_chip *chip, uint8_t *buf,
943 int oob_required, int page)
944 {
945 struct nand_ecc_ctrl *ecc = &chip->ecc;
946 unsigned int max_bitflips = 0;
947 int ret, i, cur_off = 0;
948 bool raw_mode = false;
949
950 sunxi_nfc_hw_ecc_enable(mtd);
951
952 for (i = 0; i < ecc->steps; i++) {
953 int data_off = i * ecc->size;
954 int oob_off = i * (ecc->bytes + 4);
955 u8 *data = buf + data_off;
956 u8 *oob = chip->oob_poi + oob_off;
957
958 ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off, oob,
959 oob_off + mtd->writesize,
960 &cur_off, &max_bitflips,
961 !i, page);
962 if (ret < 0)
963 return ret;
964 else if (ret)
965 raw_mode = true;
966 }
967
968 if (oob_required)
969 sunxi_nfc_hw_ecc_read_extra_oob(mtd, chip->oob_poi, &cur_off,
970 !raw_mode, page);
971
972 sunxi_nfc_hw_ecc_disable(mtd);
973
974 return max_bitflips;
975 }
976
977 static int sunxi_nfc_hw_ecc_write_page(struct mtd_info *mtd,
978 struct nand_chip *chip,
979 const uint8_t *buf, int oob_required,
980 int page)
981 {
982 struct nand_ecc_ctrl *ecc = &chip->ecc;
983 int ret, i, cur_off = 0;
984
985 sunxi_nfc_hw_ecc_enable(mtd);
986
987 for (i = 0; i < ecc->steps; i++) {
988 int data_off = i * ecc->size;
989 int oob_off = i * (ecc->bytes + 4);
990 const u8 *data = buf + data_off;
991 const u8 *oob = chip->oob_poi + oob_off;
992
993 ret = sunxi_nfc_hw_ecc_write_chunk(mtd, data, data_off, oob,
994 oob_off + mtd->writesize,
995 &cur_off, !i, page);
996 if (ret)
997 return ret;
998 }
999
1000 if (oob_required || (chip->options & NAND_NEED_SCRAMBLING))
1001 sunxi_nfc_hw_ecc_write_extra_oob(mtd, chip->oob_poi,
1002 &cur_off, page);
1003
1004 sunxi_nfc_hw_ecc_disable(mtd);
1005
1006 return 0;
1007 }
1008
1009 static int sunxi_nfc_hw_syndrome_ecc_read_page(struct mtd_info *mtd,
1010 struct nand_chip *chip,
1011 uint8_t *buf, int oob_required,
1012 int page)
1013 {
1014 struct nand_ecc_ctrl *ecc = &chip->ecc;
1015 unsigned int max_bitflips = 0;
1016 int ret, i, cur_off = 0;
1017 bool raw_mode = false;
1018
1019 sunxi_nfc_hw_ecc_enable(mtd);
1020
1021 for (i = 0; i < ecc->steps; i++) {
1022 int data_off = i * (ecc->size + ecc->bytes + 4);
1023 int oob_off = data_off + ecc->size;
1024 u8 *data = buf + (i * ecc->size);
1025 u8 *oob = chip->oob_poi + (i * (ecc->bytes + 4));
1026
1027 ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off, oob,
1028 oob_off, &cur_off,
1029 &max_bitflips, !i, page);
1030 if (ret < 0)
1031 return ret;
1032 else if (ret)
1033 raw_mode = true;
1034 }
1035
1036 if (oob_required)
1037 sunxi_nfc_hw_ecc_read_extra_oob(mtd, chip->oob_poi, &cur_off,
1038 !raw_mode, page);
1039
1040 sunxi_nfc_hw_ecc_disable(mtd);
1041
1042 return max_bitflips;
1043 }
1044
1045 static int sunxi_nfc_hw_syndrome_ecc_write_page(struct mtd_info *mtd,
1046 struct nand_chip *chip,
1047 const uint8_t *buf,
1048 int oob_required, int page)
1049 {
1050 struct nand_ecc_ctrl *ecc = &chip->ecc;
1051 int ret, i, cur_off = 0;
1052
1053 sunxi_nfc_hw_ecc_enable(mtd);
1054
1055 for (i = 0; i < ecc->steps; i++) {
1056 int data_off = i * (ecc->size + ecc->bytes + 4);
1057 int oob_off = data_off + ecc->size;
1058 const u8 *data = buf + (i * ecc->size);
1059 const u8 *oob = chip->oob_poi + (i * (ecc->bytes + 4));
1060
1061 ret = sunxi_nfc_hw_ecc_write_chunk(mtd, data, data_off,
1062 oob, oob_off, &cur_off,
1063 false, page);
1064 if (ret)
1065 return ret;
1066 }
1067
1068 if (oob_required || (chip->options & NAND_NEED_SCRAMBLING))
1069 sunxi_nfc_hw_ecc_write_extra_oob(mtd, chip->oob_poi,
1070 &cur_off, page);
1071
1072 sunxi_nfc_hw_ecc_disable(mtd);
1073
1074 return 0;
1075 }
1076
1077 static const s32 tWB_lut[] = {6, 12, 16, 20};
1078 static const s32 tRHW_lut[] = {4, 8, 12, 20};
1079
1080 static int _sunxi_nand_lookup_timing(const s32 *lut, int lut_size, u32 duration,
1081 u32 clk_period)
1082 {
1083 u32 clk_cycles = DIV_ROUND_UP(duration, clk_period);
1084 int i;
1085
1086 for (i = 0; i < lut_size; i++) {
1087 if (clk_cycles <= lut[i])
1088 return i;
1089 }
1090
1091 /* Doesn't fit */
1092 return -EINVAL;
1093 }
1094
1095 #define sunxi_nand_lookup_timing(l, p, c) \
1096 _sunxi_nand_lookup_timing(l, ARRAY_SIZE(l), p, c)
1097
1098 static int sunxi_nand_chip_set_timings(struct sunxi_nand_chip *chip,
1099 const struct nand_sdr_timings *timings)
1100 {
1101 struct sunxi_nfc *nfc = to_sunxi_nfc(chip->nand.controller);
1102 u32 min_clk_period = 0;
1103 s32 tWB, tADL, tWHR, tRHW, tCAD;
1104
1105 /* T1 <=> tCLS */
1106 if (timings->tCLS_min > min_clk_period)
1107 min_clk_period = timings->tCLS_min;
1108
1109 /* T2 <=> tCLH */
1110 if (timings->tCLH_min > min_clk_period)
1111 min_clk_period = timings->tCLH_min;
1112
1113 /* T3 <=> tCS */
1114 if (timings->tCS_min > min_clk_period)
1115 min_clk_period = timings->tCS_min;
1116
1117 /* T4 <=> tCH */
1118 if (timings->tCH_min > min_clk_period)
1119 min_clk_period = timings->tCH_min;
1120
1121 /* T5 <=> tWP */
1122 if (timings->tWP_min > min_clk_period)
1123 min_clk_period = timings->tWP_min;
1124
1125 /* T6 <=> tWH */
1126 if (timings->tWH_min > min_clk_period)
1127 min_clk_period = timings->tWH_min;
1128
1129 /* T7 <=> tALS */
1130 if (timings->tALS_min > min_clk_period)
1131 min_clk_period = timings->tALS_min;
1132
1133 /* T8 <=> tDS */
1134 if (timings->tDS_min > min_clk_period)
1135 min_clk_period = timings->tDS_min;
1136
1137 /* T9 <=> tDH */
1138 if (timings->tDH_min > min_clk_period)
1139 min_clk_period = timings->tDH_min;
1140
1141 /* T10 <=> tRR */
1142 if (timings->tRR_min > (min_clk_period * 3))
1143 min_clk_period = DIV_ROUND_UP(timings->tRR_min, 3);
1144
1145 /* T11 <=> tALH */
1146 if (timings->tALH_min > min_clk_period)
1147 min_clk_period = timings->tALH_min;
1148
1149 /* T12 <=> tRP */
1150 if (timings->tRP_min > min_clk_period)
1151 min_clk_period = timings->tRP_min;
1152
1153 /* T13 <=> tREH */
1154 if (timings->tREH_min > min_clk_period)
1155 min_clk_period = timings->tREH_min;
1156
1157 /* T14 <=> tRC */
1158 if (timings->tRC_min > (min_clk_period * 2))
1159 min_clk_period = DIV_ROUND_UP(timings->tRC_min, 2);
1160
1161 /* T15 <=> tWC */
1162 if (timings->tWC_min > (min_clk_period * 2))
1163 min_clk_period = DIV_ROUND_UP(timings->tWC_min, 2);
1164
1165 /* T16 - T19 + tCAD */
1166 tWB = sunxi_nand_lookup_timing(tWB_lut, timings->tWB_max,
1167 min_clk_period);
1168 if (tWB < 0) {
1169 dev_err(nfc->dev, "unsupported tWB\n");
1170 return tWB;
1171 }
1172
1173 tADL = DIV_ROUND_UP(timings->tADL_min, min_clk_period) >> 3;
1174 if (tADL > 3) {
1175 dev_err(nfc->dev, "unsupported tADL\n");
1176 return -EINVAL;
1177 }
1178
1179 tWHR = DIV_ROUND_UP(timings->tWHR_min, min_clk_period) >> 3;
1180 if (tWHR > 3) {
1181 dev_err(nfc->dev, "unsupported tWHR\n");
1182 return -EINVAL;
1183 }
1184
1185 tRHW = sunxi_nand_lookup_timing(tRHW_lut, timings->tRHW_min,
1186 min_clk_period);
1187 if (tRHW < 0) {
1188 dev_err(nfc->dev, "unsupported tRHW\n");
1189 return tRHW;
1190 }
1191
1192 /*
1193 * TODO: according to ONFI specs this value only applies for DDR NAND,
1194 * but Allwinner seems to set this to 0x7. Mimic them for now.
1195 */
1196 tCAD = 0x7;
1197
1198 /* TODO: A83 has some more bits for CDQSS, CS, CLHZ, CCS, WC */
1199 chip->timing_cfg = NFC_TIMING_CFG(tWB, tADL, tWHR, tRHW, tCAD);
1200
1201 /*
1202 * ONFI specification 3.1, paragraph 4.15.2 dictates that EDO data
1203 * output cycle timings shall be used if the host drives tRC less than
1204 * 30 ns.
1205 */
1206 chip->timing_ctl = (timings->tRC_min < 30000) ? NFC_TIMING_CTL_EDO : 0;
1207
1208 /* Convert min_clk_period from picoseconds to nanoseconds */
1209 min_clk_period = DIV_ROUND_UP(min_clk_period, 1000);
1210
1211 /*
1212 * Convert min_clk_period into a clk frequency, then get the
1213 * appropriate rate for the NAND controller IP given this formula
1214 * (specified in the datasheet):
1215 * nand clk_rate = 2 * min_clk_rate
1216 */
1217 chip->clk_rate = (2 * NSEC_PER_SEC) / min_clk_period;
1218
1219 return 0;
1220 }
1221
1222 static int sunxi_nand_chip_init_timings(struct sunxi_nand_chip *chip,
1223 struct device_node *np)
1224 {
1225 struct mtd_info *mtd = nand_to_mtd(&chip->nand);
1226 const struct nand_sdr_timings *timings;
1227 int ret;
1228 int mode;
1229
1230 mode = onfi_get_async_timing_mode(&chip->nand);
1231 if (mode == ONFI_TIMING_MODE_UNKNOWN) {
1232 mode = chip->nand.onfi_timing_mode_default;
1233 } else {
1234 uint8_t feature[ONFI_SUBFEATURE_PARAM_LEN] = {};
1235 int i;
1236
1237 mode = fls(mode) - 1;
1238 if (mode < 0)
1239 mode = 0;
1240
1241 feature[0] = mode;
1242 for (i = 0; i < chip->nsels; i++) {
1243 chip->nand.select_chip(mtd, i);
1244 ret = chip->nand.onfi_set_features(mtd, &chip->nand,
1245 ONFI_FEATURE_ADDR_TIMING_MODE,
1246 feature);
1247 chip->nand.select_chip(mtd, -1);
1248 if (ret)
1249 return ret;
1250 }
1251 }
1252
1253 timings = onfi_async_timing_mode_to_sdr_timings(mode);
1254 if (IS_ERR(timings))
1255 return PTR_ERR(timings);
1256
1257 return sunxi_nand_chip_set_timings(chip, timings);
1258 }
1259
1260 static int sunxi_nand_hw_common_ecc_ctrl_init(struct mtd_info *mtd,
1261 struct nand_ecc_ctrl *ecc,
1262 struct device_node *np)
1263 {
1264 static const u8 strengths[] = { 16, 24, 28, 32, 40, 48, 56, 60, 64 };
1265 struct nand_chip *nand = mtd_to_nand(mtd);
1266 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
1267 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
1268 struct sunxi_nand_hw_ecc *data;
1269 struct nand_ecclayout *layout;
1270 int nsectors;
1271 int ret;
1272 int i;
1273
1274 data = kzalloc(sizeof(*data), GFP_KERNEL);
1275 if (!data)
1276 return -ENOMEM;
1277
1278 /* Add ECC info retrieval from DT */
1279 for (i = 0; i < ARRAY_SIZE(strengths); i++) {
1280 if (ecc->strength <= strengths[i])
1281 break;
1282 }
1283
1284 if (i >= ARRAY_SIZE(strengths)) {
1285 dev_err(nfc->dev, "unsupported strength\n");
1286 ret = -ENOTSUPP;
1287 goto err;
1288 }
1289
1290 data->mode = i;
1291
1292 /* HW ECC always request ECC bytes for 1024 bytes blocks */
1293 ecc->bytes = DIV_ROUND_UP(ecc->strength * fls(8 * 1024), 8);
1294
1295 /* HW ECC always work with even numbers of ECC bytes */
1296 ecc->bytes = ALIGN(ecc->bytes, 2);
1297
1298 layout = &data->layout;
1299 nsectors = mtd->writesize / ecc->size;
1300
1301 if (mtd->oobsize < ((ecc->bytes + 4) * nsectors)) {
1302 ret = -EINVAL;
1303 goto err;
1304 }
1305
1306 layout->eccbytes = (ecc->bytes * nsectors);
1307
1308 ecc->layout = layout;
1309 ecc->priv = data;
1310
1311 return 0;
1312
1313 err:
1314 kfree(data);
1315
1316 return ret;
1317 }
1318
1319 static void sunxi_nand_hw_common_ecc_ctrl_cleanup(struct nand_ecc_ctrl *ecc)
1320 {
1321 kfree(ecc->priv);
1322 }
1323
1324 static int sunxi_nand_hw_ecc_ctrl_init(struct mtd_info *mtd,
1325 struct nand_ecc_ctrl *ecc,
1326 struct device_node *np)
1327 {
1328 struct nand_ecclayout *layout;
1329 int nsectors;
1330 int i, j;
1331 int ret;
1332
1333 ret = sunxi_nand_hw_common_ecc_ctrl_init(mtd, ecc, np);
1334 if (ret)
1335 return ret;
1336
1337 ecc->read_page = sunxi_nfc_hw_ecc_read_page;
1338 ecc->write_page = sunxi_nfc_hw_ecc_write_page;
1339 layout = ecc->layout;
1340 nsectors = mtd->writesize / ecc->size;
1341
1342 for (i = 0; i < nsectors; i++) {
1343 if (i) {
1344 layout->oobfree[i].offset =
1345 layout->oobfree[i - 1].offset +
1346 layout->oobfree[i - 1].length +
1347 ecc->bytes;
1348 layout->oobfree[i].length = 4;
1349 } else {
1350 /*
1351 * The first 2 bytes are used for BB markers, hence we
1352 * only have 2 bytes available in the first user data
1353 * section.
1354 */
1355 layout->oobfree[i].length = 2;
1356 layout->oobfree[i].offset = 2;
1357 }
1358
1359 for (j = 0; j < ecc->bytes; j++)
1360 layout->eccpos[(ecc->bytes * i) + j] =
1361 layout->oobfree[i].offset +
1362 layout->oobfree[i].length + j;
1363 }
1364
1365 if (mtd->oobsize > (ecc->bytes + 4) * nsectors) {
1366 layout->oobfree[nsectors].offset =
1367 layout->oobfree[nsectors - 1].offset +
1368 layout->oobfree[nsectors - 1].length +
1369 ecc->bytes;
1370 layout->oobfree[nsectors].length = mtd->oobsize -
1371 ((ecc->bytes + 4) * nsectors);
1372 }
1373
1374 return 0;
1375 }
1376
1377 static int sunxi_nand_hw_syndrome_ecc_ctrl_init(struct mtd_info *mtd,
1378 struct nand_ecc_ctrl *ecc,
1379 struct device_node *np)
1380 {
1381 struct nand_ecclayout *layout;
1382 int nsectors;
1383 int i;
1384 int ret;
1385
1386 ret = sunxi_nand_hw_common_ecc_ctrl_init(mtd, ecc, np);
1387 if (ret)
1388 return ret;
1389
1390 ecc->prepad = 4;
1391 ecc->read_page = sunxi_nfc_hw_syndrome_ecc_read_page;
1392 ecc->write_page = sunxi_nfc_hw_syndrome_ecc_write_page;
1393
1394 layout = ecc->layout;
1395 nsectors = mtd->writesize / ecc->size;
1396
1397 for (i = 0; i < (ecc->bytes * nsectors); i++)
1398 layout->eccpos[i] = i;
1399
1400 layout->oobfree[0].length = mtd->oobsize - i;
1401 layout->oobfree[0].offset = i;
1402
1403 return 0;
1404 }
1405
1406 static void sunxi_nand_ecc_cleanup(struct nand_ecc_ctrl *ecc)
1407 {
1408 switch (ecc->mode) {
1409 case NAND_ECC_HW:
1410 case NAND_ECC_HW_SYNDROME:
1411 sunxi_nand_hw_common_ecc_ctrl_cleanup(ecc);
1412 break;
1413 case NAND_ECC_NONE:
1414 kfree(ecc->layout);
1415 default:
1416 break;
1417 }
1418 }
1419
1420 static int sunxi_nand_ecc_init(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc,
1421 struct device_node *np)
1422 {
1423 struct nand_chip *nand = mtd_to_nand(mtd);
1424 int ret;
1425
1426 if (!ecc->size) {
1427 ecc->size = nand->ecc_step_ds;
1428 ecc->strength = nand->ecc_strength_ds;
1429 }
1430
1431 if (!ecc->size || !ecc->strength)
1432 return -EINVAL;
1433
1434 switch (ecc->mode) {
1435 case NAND_ECC_SOFT_BCH:
1436 break;
1437 case NAND_ECC_HW:
1438 ret = sunxi_nand_hw_ecc_ctrl_init(mtd, ecc, np);
1439 if (ret)
1440 return ret;
1441 break;
1442 case NAND_ECC_HW_SYNDROME:
1443 ret = sunxi_nand_hw_syndrome_ecc_ctrl_init(mtd, ecc, np);
1444 if (ret)
1445 return ret;
1446 break;
1447 case NAND_ECC_NONE:
1448 ecc->layout = kzalloc(sizeof(*ecc->layout), GFP_KERNEL);
1449 if (!ecc->layout)
1450 return -ENOMEM;
1451 ecc->layout->oobfree[0].length = mtd->oobsize;
1452 case NAND_ECC_SOFT:
1453 break;
1454 default:
1455 return -EINVAL;
1456 }
1457
1458 return 0;
1459 }
1460
1461 static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc,
1462 struct device_node *np)
1463 {
1464 const struct nand_sdr_timings *timings;
1465 struct sunxi_nand_chip *chip;
1466 struct mtd_info *mtd;
1467 struct nand_chip *nand;
1468 int nsels;
1469 int ret;
1470 int i;
1471 u32 tmp;
1472
1473 if (!of_get_property(np, "reg", &nsels))
1474 return -EINVAL;
1475
1476 nsels /= sizeof(u32);
1477 if (!nsels) {
1478 dev_err(dev, "invalid reg property size\n");
1479 return -EINVAL;
1480 }
1481
1482 chip = devm_kzalloc(dev,
1483 sizeof(*chip) +
1484 (nsels * sizeof(struct sunxi_nand_chip_sel)),
1485 GFP_KERNEL);
1486 if (!chip) {
1487 dev_err(dev, "could not allocate chip\n");
1488 return -ENOMEM;
1489 }
1490
1491 chip->nsels = nsels;
1492 chip->selected = -1;
1493
1494 for (i = 0; i < nsels; i++) {
1495 ret = of_property_read_u32_index(np, "reg", i, &tmp);
1496 if (ret) {
1497 dev_err(dev, "could not retrieve reg property: %d\n",
1498 ret);
1499 return ret;
1500 }
1501
1502 if (tmp > NFC_MAX_CS) {
1503 dev_err(dev,
1504 "invalid reg value: %u (max CS = 7)\n",
1505 tmp);
1506 return -EINVAL;
1507 }
1508
1509 if (test_and_set_bit(tmp, &nfc->assigned_cs)) {
1510 dev_err(dev, "CS %d already assigned\n", tmp);
1511 return -EINVAL;
1512 }
1513
1514 chip->sels[i].cs = tmp;
1515
1516 if (!of_property_read_u32_index(np, "allwinner,rb", i, &tmp) &&
1517 tmp < 2) {
1518 chip->sels[i].rb.type = RB_NATIVE;
1519 chip->sels[i].rb.info.nativeid = tmp;
1520 } else {
1521 ret = of_get_named_gpio(np, "rb-gpios", i);
1522 if (ret >= 0) {
1523 tmp = ret;
1524 chip->sels[i].rb.type = RB_GPIO;
1525 chip->sels[i].rb.info.gpio = tmp;
1526 ret = devm_gpio_request(dev, tmp, "nand-rb");
1527 if (ret)
1528 return ret;
1529
1530 ret = gpio_direction_input(tmp);
1531 if (ret)
1532 return ret;
1533 } else {
1534 chip->sels[i].rb.type = RB_NONE;
1535 }
1536 }
1537 }
1538
1539 timings = onfi_async_timing_mode_to_sdr_timings(0);
1540 if (IS_ERR(timings)) {
1541 ret = PTR_ERR(timings);
1542 dev_err(dev,
1543 "could not retrieve timings for ONFI mode 0: %d\n",
1544 ret);
1545 return ret;
1546 }
1547
1548 ret = sunxi_nand_chip_set_timings(chip, timings);
1549 if (ret) {
1550 dev_err(dev, "could not configure chip timings: %d\n", ret);
1551 return ret;
1552 }
1553
1554 nand = &chip->nand;
1555 /* Default tR value specified in the ONFI spec (chapter 4.15.1) */
1556 nand->chip_delay = 200;
1557 nand->controller = &nfc->controller;
1558 /*
1559 * Set the ECC mode to the default value in case nothing is specified
1560 * in the DT.
1561 */
1562 nand->ecc.mode = NAND_ECC_HW;
1563 nand_set_flash_node(nand, np);
1564 nand->select_chip = sunxi_nfc_select_chip;
1565 nand->cmd_ctrl = sunxi_nfc_cmd_ctrl;
1566 nand->read_buf = sunxi_nfc_read_buf;
1567 nand->write_buf = sunxi_nfc_write_buf;
1568 nand->read_byte = sunxi_nfc_read_byte;
1569
1570 mtd = nand_to_mtd(nand);
1571 mtd->dev.parent = dev;
1572
1573 ret = nand_scan_ident(mtd, nsels, NULL);
1574 if (ret)
1575 return ret;
1576
1577 if (nand->bbt_options & NAND_BBT_USE_FLASH)
1578 nand->bbt_options |= NAND_BBT_NO_OOB;
1579
1580 if (nand->options & NAND_NEED_SCRAMBLING)
1581 nand->options |= NAND_NO_SUBPAGE_WRITE;
1582
1583 ret = sunxi_nand_chip_init_timings(chip, np);
1584 if (ret) {
1585 dev_err(dev, "could not configure chip timings: %d\n", ret);
1586 return ret;
1587 }
1588
1589 ret = sunxi_nand_ecc_init(mtd, &nand->ecc, np);
1590 if (ret) {
1591 dev_err(dev, "ECC init failed: %d\n", ret);
1592 return ret;
1593 }
1594
1595 ret = nand_scan_tail(mtd);
1596 if (ret) {
1597 dev_err(dev, "nand_scan_tail failed: %d\n", ret);
1598 return ret;
1599 }
1600
1601 ret = mtd_device_register(mtd, NULL, 0);
1602 if (ret) {
1603 dev_err(dev, "failed to register mtd device: %d\n", ret);
1604 nand_release(mtd);
1605 return ret;
1606 }
1607
1608 list_add_tail(&chip->node, &nfc->chips);
1609
1610 return 0;
1611 }
1612
1613 static int sunxi_nand_chips_init(struct device *dev, struct sunxi_nfc *nfc)
1614 {
1615 struct device_node *np = dev->of_node;
1616 struct device_node *nand_np;
1617 int nchips = of_get_child_count(np);
1618 int ret;
1619
1620 if (nchips > 8) {
1621 dev_err(dev, "too many NAND chips: %d (max = 8)\n", nchips);
1622 return -EINVAL;
1623 }
1624
1625 for_each_child_of_node(np, nand_np) {
1626 ret = sunxi_nand_chip_init(dev, nfc, nand_np);
1627 if (ret) {
1628 of_node_put(nand_np);
1629 return ret;
1630 }
1631 }
1632
1633 return 0;
1634 }
1635
1636 static void sunxi_nand_chips_cleanup(struct sunxi_nfc *nfc)
1637 {
1638 struct sunxi_nand_chip *chip;
1639
1640 while (!list_empty(&nfc->chips)) {
1641 chip = list_first_entry(&nfc->chips, struct sunxi_nand_chip,
1642 node);
1643 nand_release(nand_to_mtd(&chip->nand));
1644 sunxi_nand_ecc_cleanup(&chip->nand.ecc);
1645 list_del(&chip->node);
1646 }
1647 }
1648
1649 static int sunxi_nfc_probe(struct platform_device *pdev)
1650 {
1651 struct device *dev = &pdev->dev;
1652 struct resource *r;
1653 struct sunxi_nfc *nfc;
1654 int irq;
1655 int ret;
1656
1657 nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
1658 if (!nfc)
1659 return -ENOMEM;
1660
1661 nfc->dev = dev;
1662 spin_lock_init(&nfc->controller.lock);
1663 init_waitqueue_head(&nfc->controller.wq);
1664 INIT_LIST_HEAD(&nfc->chips);
1665
1666 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1667 nfc->regs = devm_ioremap_resource(dev, r);
1668 if (IS_ERR(nfc->regs))
1669 return PTR_ERR(nfc->regs);
1670
1671 irq = platform_get_irq(pdev, 0);
1672 if (irq < 0) {
1673 dev_err(dev, "failed to retrieve irq\n");
1674 return irq;
1675 }
1676
1677 nfc->ahb_clk = devm_clk_get(dev, "ahb");
1678 if (IS_ERR(nfc->ahb_clk)) {
1679 dev_err(dev, "failed to retrieve ahb clk\n");
1680 return PTR_ERR(nfc->ahb_clk);
1681 }
1682
1683 ret = clk_prepare_enable(nfc->ahb_clk);
1684 if (ret)
1685 return ret;
1686
1687 nfc->mod_clk = devm_clk_get(dev, "mod");
1688 if (IS_ERR(nfc->mod_clk)) {
1689 dev_err(dev, "failed to retrieve mod clk\n");
1690 ret = PTR_ERR(nfc->mod_clk);
1691 goto out_ahb_clk_unprepare;
1692 }
1693
1694 ret = clk_prepare_enable(nfc->mod_clk);
1695 if (ret)
1696 goto out_ahb_clk_unprepare;
1697
1698 ret = sunxi_nfc_rst(nfc);
1699 if (ret)
1700 goto out_mod_clk_unprepare;
1701
1702 writel(0, nfc->regs + NFC_REG_INT);
1703 ret = devm_request_irq(dev, irq, sunxi_nfc_interrupt,
1704 0, "sunxi-nand", nfc);
1705 if (ret)
1706 goto out_mod_clk_unprepare;
1707
1708 platform_set_drvdata(pdev, nfc);
1709
1710 ret = sunxi_nand_chips_init(dev, nfc);
1711 if (ret) {
1712 dev_err(dev, "failed to init nand chips\n");
1713 goto out_mod_clk_unprepare;
1714 }
1715
1716 return 0;
1717
1718 out_mod_clk_unprepare:
1719 clk_disable_unprepare(nfc->mod_clk);
1720 out_ahb_clk_unprepare:
1721 clk_disable_unprepare(nfc->ahb_clk);
1722
1723 return ret;
1724 }
1725
1726 static int sunxi_nfc_remove(struct platform_device *pdev)
1727 {
1728 struct sunxi_nfc *nfc = platform_get_drvdata(pdev);
1729
1730 sunxi_nand_chips_cleanup(nfc);
1731
1732 return 0;
1733 }
1734
1735 static const struct of_device_id sunxi_nfc_ids[] = {
1736 { .compatible = "allwinner,sun4i-a10-nand" },
1737 { /* sentinel */ }
1738 };
1739 MODULE_DEVICE_TABLE(of, sunxi_nfc_ids);
1740
1741 static struct platform_driver sunxi_nfc_driver = {
1742 .driver = {
1743 .name = "sunxi_nand",
1744 .of_match_table = sunxi_nfc_ids,
1745 },
1746 .probe = sunxi_nfc_probe,
1747 .remove = sunxi_nfc_remove,
1748 };
1749 module_platform_driver(sunxi_nfc_driver);
1750
1751 MODULE_LICENSE("GPL v2");
1752 MODULE_AUTHOR("Boris BREZILLON");
1753 MODULE_DESCRIPTION("Allwinner NAND Flash Controller driver");
1754 MODULE_ALIAS("platform:sunxi_nand");
This page took 0.064762 seconds and 6 git commands to generate.