blob: fe3730a6ba54bc1b87165a393433757492edcb7c [file] [log] [blame]
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001/*
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>
Boris BREZILLON1fef62c2014-10-21 15:08:41 +020033#include <linux/mtd/mtd.h>
34#include <linux/mtd/nand.h>
35#include <linux/mtd/partitions.h>
36#include <linux/clk.h>
37#include <linux/delay.h>
38#include <linux/dmaengine.h>
39#include <linux/gpio.h>
40#include <linux/interrupt.h>
41#include <linux/io.h>
42
43#define NFC_REG_CTL 0x0000
44#define NFC_REG_ST 0x0004
45#define NFC_REG_INT 0x0008
46#define NFC_REG_TIMING_CTL 0x000C
47#define NFC_REG_TIMING_CFG 0x0010
48#define NFC_REG_ADDR_LOW 0x0014
49#define NFC_REG_ADDR_HIGH 0x0018
50#define NFC_REG_SECTOR_NUM 0x001C
51#define NFC_REG_CNT 0x0020
52#define NFC_REG_CMD 0x0024
53#define NFC_REG_RCMD_SET 0x0028
54#define NFC_REG_WCMD_SET 0x002C
55#define NFC_REG_IO_DATA 0x0030
56#define NFC_REG_ECC_CTL 0x0034
57#define NFC_REG_ECC_ST 0x0038
58#define NFC_REG_DEBUG 0x003C
Boris BREZILLONb6a02c02015-09-16 09:46:36 +020059#define NFC_REG_ECC_ERR_CNT(x) ((0x0040 + (x)) & ~0x3)
60#define NFC_REG_USER_DATA(x) (0x0050 + ((x) * 4))
Boris BREZILLON1fef62c2014-10-21 15:08:41 +020061#define NFC_REG_SPARE_AREA 0x00A0
Boris BREZILLON4be4e032015-12-02 12:01:07 +010062#define NFC_REG_PAT_ID 0x00A4
Boris BREZILLON1fef62c2014-10-21 15:08:41 +020063#define NFC_RAM0_BASE 0x0400
64#define NFC_RAM1_BASE 0x0800
65
66/* define bit use in NFC_CTL */
67#define NFC_EN BIT(0)
68#define NFC_RESET BIT(1)
Boris BREZILLONb6a02c02015-09-16 09:46:36 +020069#define NFC_BUS_WIDTH_MSK BIT(2)
70#define NFC_BUS_WIDTH_8 (0 << 2)
71#define NFC_BUS_WIDTH_16 (1 << 2)
72#define NFC_RB_SEL_MSK BIT(3)
73#define NFC_RB_SEL(x) ((x) << 3)
74#define NFC_CE_SEL_MSK GENMASK(26, 24)
75#define NFC_CE_SEL(x) ((x) << 24)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +020076#define NFC_CE_CTL BIT(6)
Boris BREZILLONb6a02c02015-09-16 09:46:36 +020077#define NFC_PAGE_SHIFT_MSK GENMASK(11, 8)
78#define NFC_PAGE_SHIFT(x) (((x) < 10 ? 0 : (x) - 10) << 8)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +020079#define NFC_SAM BIT(12)
80#define NFC_RAM_METHOD BIT(14)
81#define NFC_DEBUG_CTL BIT(31)
82
83/* define bit use in NFC_ST */
84#define NFC_RB_B2R BIT(0)
85#define NFC_CMD_INT_FLAG BIT(1)
86#define NFC_DMA_INT_FLAG BIT(2)
87#define NFC_CMD_FIFO_STATUS BIT(3)
88#define NFC_STA BIT(4)
89#define NFC_NATCH_INT_FLAG BIT(5)
Boris BREZILLONb6a02c02015-09-16 09:46:36 +020090#define NFC_RB_STATE(x) BIT(x + 8)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +020091
92/* define bit use in NFC_INT */
93#define NFC_B2R_INT_ENABLE BIT(0)
94#define NFC_CMD_INT_ENABLE BIT(1)
95#define NFC_DMA_INT_ENABLE BIT(2)
96#define NFC_INT_MASK (NFC_B2R_INT_ENABLE | \
97 NFC_CMD_INT_ENABLE | \
98 NFC_DMA_INT_ENABLE)
99
Roy Splietd052e502015-06-26 11:00:11 +0200100/* define bit use in NFC_TIMING_CTL */
101#define NFC_TIMING_CTL_EDO BIT(8)
102
Roy Spliet9c618292015-06-26 11:00:10 +0200103/* define NFC_TIMING_CFG register layout */
104#define NFC_TIMING_CFG(tWB, tADL, tWHR, tRHW, tCAD) \
105 (((tWB) & 0x3) | (((tADL) & 0x3) << 2) | \
106 (((tWHR) & 0x3) << 4) | (((tRHW) & 0x3) << 6) | \
107 (((tCAD) & 0x7) << 8))
108
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200109/* define bit use in NFC_CMD */
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200110#define NFC_CMD_LOW_BYTE_MSK GENMASK(7, 0)
111#define NFC_CMD_HIGH_BYTE_MSK GENMASK(15, 8)
112#define NFC_CMD(x) (x)
113#define NFC_ADR_NUM_MSK GENMASK(18, 16)
114#define NFC_ADR_NUM(x) (((x) - 1) << 16)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200115#define NFC_SEND_ADR BIT(19)
116#define NFC_ACCESS_DIR BIT(20)
117#define NFC_DATA_TRANS BIT(21)
118#define NFC_SEND_CMD1 BIT(22)
119#define NFC_WAIT_FLAG BIT(23)
120#define NFC_SEND_CMD2 BIT(24)
121#define NFC_SEQ BIT(25)
122#define NFC_DATA_SWAP_METHOD BIT(26)
123#define NFC_ROW_AUTO_INC BIT(27)
124#define NFC_SEND_CMD3 BIT(28)
125#define NFC_SEND_CMD4 BIT(29)
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200126#define NFC_CMD_TYPE_MSK GENMASK(31, 30)
127#define NFC_NORMAL_OP (0 << 30)
128#define NFC_ECC_OP (1 << 30)
129#define NFC_PAGE_OP (2 << 30)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200130
131/* define bit use in NFC_RCMD_SET */
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200132#define NFC_READ_CMD_MSK GENMASK(7, 0)
133#define NFC_RND_READ_CMD0_MSK GENMASK(15, 8)
134#define NFC_RND_READ_CMD1_MSK GENMASK(23, 16)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200135
136/* define bit use in NFC_WCMD_SET */
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200137#define NFC_PROGRAM_CMD_MSK GENMASK(7, 0)
138#define NFC_RND_WRITE_CMD_MSK GENMASK(15, 8)
139#define NFC_READ_CMD0_MSK GENMASK(23, 16)
140#define NFC_READ_CMD1_MSK GENMASK(31, 24)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200141
142/* define bit use in NFC_ECC_CTL */
143#define NFC_ECC_EN BIT(0)
144#define NFC_ECC_PIPELINE BIT(3)
145#define NFC_ECC_EXCEPTION BIT(4)
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200146#define NFC_ECC_BLOCK_SIZE_MSK BIT(5)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200147#define NFC_RANDOM_EN BIT(9)
148#define NFC_RANDOM_DIRECTION BIT(10)
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200149#define NFC_ECC_MODE_MSK GENMASK(15, 12)
150#define NFC_ECC_MODE(x) ((x) << 12)
151#define NFC_RANDOM_SEED_MSK GENMASK(30, 16)
152#define NFC_RANDOM_SEED(x) ((x) << 16)
153
154/* define bit use in NFC_ECC_ST */
155#define NFC_ECC_ERR(x) BIT(x)
156#define NFC_ECC_PAT_FOUND(x) BIT(x + 16)
Boris Brezillonf8b04742016-03-04 17:25:08 +0100157#define NFC_ECC_ERR_CNT(b, x) (((x) >> (((b) % 4) * 8)) & 0xff)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200158
159#define NFC_DEFAULT_TIMEOUT_MS 1000
160
161#define NFC_SRAM_SIZE 1024
162
163#define NFC_MAX_CS 7
164
165/*
166 * Ready/Busy detection type: describes the Ready/Busy detection modes
167 *
168 * @RB_NONE: no external detection available, rely on STATUS command
169 * and software timeouts
170 * @RB_NATIVE: use sunxi NAND controller Ready/Busy support. The Ready/Busy
171 * pin of the NAND flash chip must be connected to one of the
172 * native NAND R/B pins (those which can be muxed to the NAND
173 * Controller)
174 * @RB_GPIO: use a simple GPIO to handle Ready/Busy status. The Ready/Busy
175 * pin of the NAND flash chip must be connected to a GPIO capable
176 * pin.
177 */
178enum sunxi_nand_rb_type {
179 RB_NONE,
180 RB_NATIVE,
181 RB_GPIO,
182};
183
184/*
185 * Ready/Busy structure: stores information related to Ready/Busy detection
186 *
187 * @type: the Ready/Busy detection mode
188 * @info: information related to the R/B detection mode. Either a gpio
189 * id or a native R/B id (those supported by the NAND controller).
190 */
191struct sunxi_nand_rb {
192 enum sunxi_nand_rb_type type;
193 union {
194 int gpio;
195 int nativeid;
196 } info;
197};
198
199/*
200 * Chip Select structure: stores information related to NAND Chip Select
201 *
202 * @cs: the NAND CS id used to communicate with a NAND Chip
203 * @rb: the Ready/Busy description
204 */
205struct sunxi_nand_chip_sel {
206 u8 cs;
207 struct sunxi_nand_rb rb;
208};
209
210/*
211 * sunxi HW ECC infos: stores information related to HW ECC support
212 *
213 * @mode: the sunxi ECC mode field deduced from ECC requirements
214 * @layout: the OOB layout depending on the ECC requirements and the
215 * selected ECC mode
216 */
217struct sunxi_nand_hw_ecc {
218 int mode;
219 struct nand_ecclayout layout;
220};
221
222/*
223 * NAND chip structure: stores NAND chip device related information
224 *
225 * @node: used to store NAND chips into a list
226 * @nand: base NAND chip structure
227 * @mtd: base MTD structure
228 * @clk_rate: clk_rate required for this NAND chip
Roy Spliet9c618292015-06-26 11:00:10 +0200229 * @timing_cfg TIMING_CFG register value for this NAND chip
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200230 * @selected: current active CS
231 * @nsels: number of CS lines required by the NAND chip
232 * @sels: array of CS lines descriptions
233 */
234struct sunxi_nand_chip {
235 struct list_head node;
236 struct nand_chip nand;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200237 unsigned long clk_rate;
Roy Spliet9c618292015-06-26 11:00:10 +0200238 u32 timing_cfg;
Roy Splietd052e502015-06-26 11:00:11 +0200239 u32 timing_ctl;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200240 int selected;
Boris Brezillone9aa6712015-09-16 09:05:31 +0200241 int addr_cycles;
242 u32 addr[2];
243 int cmd_cycles;
244 u8 cmd[2];
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200245 int nsels;
246 struct sunxi_nand_chip_sel sels[0];
247};
248
249static inline struct sunxi_nand_chip *to_sunxi_nand(struct nand_chip *nand)
250{
251 return container_of(nand, struct sunxi_nand_chip, nand);
252}
253
254/*
255 * NAND Controller structure: stores sunxi NAND controller information
256 *
257 * @controller: base controller structure
258 * @dev: parent device (used to print error messages)
259 * @regs: NAND controller registers
260 * @ahb_clk: NAND Controller AHB clock
261 * @mod_clk: NAND Controller mod clock
262 * @assigned_cs: bitmask describing already assigned CS lines
263 * @clk_rate: NAND controller current clock rate
264 * @chips: a list containing all the NAND chips attached to
265 * this NAND controller
266 * @complete: a completion object used to wait for NAND
267 * controller events
268 */
269struct sunxi_nfc {
270 struct nand_hw_control controller;
271 struct device *dev;
272 void __iomem *regs;
273 struct clk *ahb_clk;
274 struct clk *mod_clk;
275 unsigned long assigned_cs;
276 unsigned long clk_rate;
277 struct list_head chips;
278 struct completion complete;
279};
280
281static inline struct sunxi_nfc *to_sunxi_nfc(struct nand_hw_control *ctrl)
282{
283 return container_of(ctrl, struct sunxi_nfc, controller);
284}
285
286static irqreturn_t sunxi_nfc_interrupt(int irq, void *dev_id)
287{
288 struct sunxi_nfc *nfc = dev_id;
289 u32 st = readl(nfc->regs + NFC_REG_ST);
290 u32 ien = readl(nfc->regs + NFC_REG_INT);
291
292 if (!(ien & st))
293 return IRQ_NONE;
294
295 if ((ien & st) == ien)
296 complete(&nfc->complete);
297
298 writel(st & NFC_INT_MASK, nfc->regs + NFC_REG_ST);
299 writel(~st & ien & NFC_INT_MASK, nfc->regs + NFC_REG_INT);
300
301 return IRQ_HANDLED;
302}
303
304static int sunxi_nfc_wait_int(struct sunxi_nfc *nfc, u32 flags,
305 unsigned int timeout_ms)
306{
307 init_completion(&nfc->complete);
308
309 writel(flags, nfc->regs + NFC_REG_INT);
310
311 if (!timeout_ms)
312 timeout_ms = NFC_DEFAULT_TIMEOUT_MS;
313
314 if (!wait_for_completion_timeout(&nfc->complete,
315 msecs_to_jiffies(timeout_ms))) {
316 dev_err(nfc->dev, "wait interrupt timedout\n");
317 return -ETIMEDOUT;
318 }
319
320 return 0;
321}
322
323static int sunxi_nfc_wait_cmd_fifo_empty(struct sunxi_nfc *nfc)
324{
325 unsigned long timeout = jiffies +
326 msecs_to_jiffies(NFC_DEFAULT_TIMEOUT_MS);
327
328 do {
329 if (!(readl(nfc->regs + NFC_REG_ST) & NFC_CMD_FIFO_STATUS))
330 return 0;
331 } while (time_before(jiffies, timeout));
332
333 dev_err(nfc->dev, "wait for empty cmd FIFO timedout\n");
334 return -ETIMEDOUT;
335}
336
337static int sunxi_nfc_rst(struct sunxi_nfc *nfc)
338{
339 unsigned long timeout = jiffies +
340 msecs_to_jiffies(NFC_DEFAULT_TIMEOUT_MS);
341
342 writel(0, nfc->regs + NFC_REG_ECC_CTL);
343 writel(NFC_RESET, nfc->regs + NFC_REG_CTL);
344
345 do {
346 if (!(readl(nfc->regs + NFC_REG_CTL) & NFC_RESET))
347 return 0;
348 } while (time_before(jiffies, timeout));
349
350 dev_err(nfc->dev, "wait for NAND controller reset timedout\n");
351 return -ETIMEDOUT;
352}
353
354static int sunxi_nfc_dev_ready(struct mtd_info *mtd)
355{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100356 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200357 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
358 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
359 struct sunxi_nand_rb *rb;
360 unsigned long timeo = (sunxi_nand->nand.state == FL_ERASING ? 400 : 20);
361 int ret;
362
363 if (sunxi_nand->selected < 0)
364 return 0;
365
366 rb = &sunxi_nand->sels[sunxi_nand->selected].rb;
367
368 switch (rb->type) {
369 case RB_NATIVE:
370 ret = !!(readl(nfc->regs + NFC_REG_ST) &
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200371 NFC_RB_STATE(rb->info.nativeid));
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200372 if (ret)
373 break;
374
375 sunxi_nfc_wait_int(nfc, NFC_RB_B2R, timeo);
376 ret = !!(readl(nfc->regs + NFC_REG_ST) &
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200377 NFC_RB_STATE(rb->info.nativeid));
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200378 break;
379 case RB_GPIO:
380 ret = gpio_get_value(rb->info.gpio);
381 break;
382 case RB_NONE:
383 default:
384 ret = 0;
385 dev_err(nfc->dev, "cannot check R/B NAND status!\n");
386 break;
387 }
388
389 return ret;
390}
391
392static void sunxi_nfc_select_chip(struct mtd_info *mtd, int chip)
393{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100394 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200395 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
396 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
397 struct sunxi_nand_chip_sel *sel;
398 u32 ctl;
399
400 if (chip > 0 && chip >= sunxi_nand->nsels)
401 return;
402
403 if (chip == sunxi_nand->selected)
404 return;
405
406 ctl = readl(nfc->regs + NFC_REG_CTL) &
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200407 ~(NFC_PAGE_SHIFT_MSK | NFC_CE_SEL_MSK | NFC_RB_SEL_MSK | NFC_EN);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200408
409 if (chip >= 0) {
410 sel = &sunxi_nand->sels[chip];
411
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200412 ctl |= NFC_CE_SEL(sel->cs) | NFC_EN |
Boris Brezillon68ffbf72016-03-04 17:29:20 +0100413 NFC_PAGE_SHIFT(nand->page_shift);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200414 if (sel->rb.type == RB_NONE) {
415 nand->dev_ready = NULL;
416 } else {
417 nand->dev_ready = sunxi_nfc_dev_ready;
418 if (sel->rb.type == RB_NATIVE)
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200419 ctl |= NFC_RB_SEL(sel->rb.info.nativeid);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200420 }
421
422 writel(mtd->writesize, nfc->regs + NFC_REG_SPARE_AREA);
423
424 if (nfc->clk_rate != sunxi_nand->clk_rate) {
425 clk_set_rate(nfc->mod_clk, sunxi_nand->clk_rate);
426 nfc->clk_rate = sunxi_nand->clk_rate;
427 }
428 }
429
Roy Splietd052e502015-06-26 11:00:11 +0200430 writel(sunxi_nand->timing_ctl, nfc->regs + NFC_REG_TIMING_CTL);
Roy Spliet9c618292015-06-26 11:00:10 +0200431 writel(sunxi_nand->timing_cfg, nfc->regs + NFC_REG_TIMING_CFG);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200432 writel(ctl, nfc->regs + NFC_REG_CTL);
433
434 sunxi_nand->selected = chip;
435}
436
437static void sunxi_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
438{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100439 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200440 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
441 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
442 int ret;
443 int cnt;
444 int offs = 0;
445 u32 tmp;
446
447 while (len > offs) {
448 cnt = min(len - offs, NFC_SRAM_SIZE);
449
450 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
451 if (ret)
452 break;
453
454 writel(cnt, nfc->regs + NFC_REG_CNT);
455 tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD;
456 writel(tmp, nfc->regs + NFC_REG_CMD);
457
458 ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
459 if (ret)
460 break;
461
462 if (buf)
463 memcpy_fromio(buf + offs, nfc->regs + NFC_RAM0_BASE,
464 cnt);
465 offs += cnt;
466 }
467}
468
469static void sunxi_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf,
470 int len)
471{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100472 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200473 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
474 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
475 int ret;
476 int cnt;
477 int offs = 0;
478 u32 tmp;
479
480 while (len > offs) {
481 cnt = min(len - offs, NFC_SRAM_SIZE);
482
483 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
484 if (ret)
485 break;
486
487 writel(cnt, nfc->regs + NFC_REG_CNT);
488 memcpy_toio(nfc->regs + NFC_RAM0_BASE, buf + offs, cnt);
489 tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD |
490 NFC_ACCESS_DIR;
491 writel(tmp, nfc->regs + NFC_REG_CMD);
492
493 ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
494 if (ret)
495 break;
496
497 offs += cnt;
498 }
499}
500
501static uint8_t sunxi_nfc_read_byte(struct mtd_info *mtd)
502{
503 uint8_t ret;
504
505 sunxi_nfc_read_buf(mtd, &ret, 1);
506
507 return ret;
508}
509
510static void sunxi_nfc_cmd_ctrl(struct mtd_info *mtd, int dat,
511 unsigned int ctrl)
512{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100513 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200514 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
515 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
516 int ret;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200517
518 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
519 if (ret)
520 return;
521
Boris Brezillone9aa6712015-09-16 09:05:31 +0200522 if (dat == NAND_CMD_NONE && (ctrl & NAND_NCE) &&
523 !(ctrl & (NAND_CLE | NAND_ALE))) {
524 u32 cmd = 0;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200525
Boris Brezillone9aa6712015-09-16 09:05:31 +0200526 if (!sunxi_nand->addr_cycles && !sunxi_nand->cmd_cycles)
527 return;
528
529 if (sunxi_nand->cmd_cycles--)
530 cmd |= NFC_SEND_CMD1 | sunxi_nand->cmd[0];
531
532 if (sunxi_nand->cmd_cycles--) {
533 cmd |= NFC_SEND_CMD2;
534 writel(sunxi_nand->cmd[1],
535 nfc->regs + NFC_REG_RCMD_SET);
536 }
537
538 sunxi_nand->cmd_cycles = 0;
539
540 if (sunxi_nand->addr_cycles) {
541 cmd |= NFC_SEND_ADR |
542 NFC_ADR_NUM(sunxi_nand->addr_cycles);
543 writel(sunxi_nand->addr[0],
544 nfc->regs + NFC_REG_ADDR_LOW);
545 }
546
547 if (sunxi_nand->addr_cycles > 4)
548 writel(sunxi_nand->addr[1],
549 nfc->regs + NFC_REG_ADDR_HIGH);
550
551 writel(cmd, nfc->regs + NFC_REG_CMD);
552 sunxi_nand->addr[0] = 0;
553 sunxi_nand->addr[1] = 0;
554 sunxi_nand->addr_cycles = 0;
555 sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200556 }
557
Boris Brezillone9aa6712015-09-16 09:05:31 +0200558 if (ctrl & NAND_CLE) {
559 sunxi_nand->cmd[sunxi_nand->cmd_cycles++] = dat;
560 } else if (ctrl & NAND_ALE) {
561 sunxi_nand->addr[sunxi_nand->addr_cycles / 4] |=
562 dat << ((sunxi_nand->addr_cycles % 4) * 8);
563 sunxi_nand->addr_cycles++;
564 }
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200565}
566
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100567/* These seed values have been extracted from Allwinner's BSP */
568static const u16 sunxi_nfc_randomizer_page_seeds[] = {
569 0x2b75, 0x0bd0, 0x5ca3, 0x62d1, 0x1c93, 0x07e9, 0x2162, 0x3a72,
570 0x0d67, 0x67f9, 0x1be7, 0x077d, 0x032f, 0x0dac, 0x2716, 0x2436,
571 0x7922, 0x1510, 0x3860, 0x5287, 0x480f, 0x4252, 0x1789, 0x5a2d,
572 0x2a49, 0x5e10, 0x437f, 0x4b4e, 0x2f45, 0x216e, 0x5cb7, 0x7130,
573 0x2a3f, 0x60e4, 0x4dc9, 0x0ef0, 0x0f52, 0x1bb9, 0x6211, 0x7a56,
574 0x226d, 0x4ea7, 0x6f36, 0x3692, 0x38bf, 0x0c62, 0x05eb, 0x4c55,
575 0x60f4, 0x728c, 0x3b6f, 0x2037, 0x7f69, 0x0936, 0x651a, 0x4ceb,
576 0x6218, 0x79f3, 0x383f, 0x18d9, 0x4f05, 0x5c82, 0x2912, 0x6f17,
577 0x6856, 0x5938, 0x1007, 0x61ab, 0x3e7f, 0x57c2, 0x542f, 0x4f62,
578 0x7454, 0x2eac, 0x7739, 0x42d4, 0x2f90, 0x435a, 0x2e52, 0x2064,
579 0x637c, 0x66ad, 0x2c90, 0x0bad, 0x759c, 0x0029, 0x0986, 0x7126,
580 0x1ca7, 0x1605, 0x386a, 0x27f5, 0x1380, 0x6d75, 0x24c3, 0x0f8e,
581 0x2b7a, 0x1418, 0x1fd1, 0x7dc1, 0x2d8e, 0x43af, 0x2267, 0x7da3,
582 0x4e3d, 0x1338, 0x50db, 0x454d, 0x764d, 0x40a3, 0x42e6, 0x262b,
583 0x2d2e, 0x1aea, 0x2e17, 0x173d, 0x3a6e, 0x71bf, 0x25f9, 0x0a5d,
584 0x7c57, 0x0fbe, 0x46ce, 0x4939, 0x6b17, 0x37bb, 0x3e91, 0x76db,
585};
586
587/*
588 * sunxi_nfc_randomizer_ecc512_seeds and sunxi_nfc_randomizer_ecc1024_seeds
589 * have been generated using
590 * sunxi_nfc_randomizer_step(seed, (step_size * 8) + 15), which is what
591 * the randomizer engine does internally before de/scrambling OOB data.
592 *
593 * Those tables are statically defined to avoid calculating randomizer state
594 * at runtime.
595 */
596static const u16 sunxi_nfc_randomizer_ecc512_seeds[] = {
597 0x3346, 0x367f, 0x1f18, 0x769a, 0x4f64, 0x068c, 0x2ef1, 0x6b64,
598 0x28a9, 0x15d7, 0x30f8, 0x3659, 0x53db, 0x7c5f, 0x71d4, 0x4409,
599 0x26eb, 0x03cc, 0x655d, 0x47d4, 0x4daa, 0x0877, 0x712d, 0x3617,
600 0x3264, 0x49aa, 0x7f9e, 0x588e, 0x4fbc, 0x7176, 0x7f91, 0x6c6d,
601 0x4b95, 0x5fb7, 0x3844, 0x4037, 0x0184, 0x081b, 0x0ee8, 0x5b91,
602 0x293d, 0x1f71, 0x0e6f, 0x402b, 0x5122, 0x1e52, 0x22be, 0x3d2d,
603 0x75bc, 0x7c60, 0x6291, 0x1a2f, 0x61d4, 0x74aa, 0x4140, 0x29ab,
604 0x472d, 0x2852, 0x017e, 0x15e8, 0x5ec2, 0x17cf, 0x7d0f, 0x06b8,
605 0x117a, 0x6b94, 0x789b, 0x3126, 0x6ac5, 0x5be7, 0x150f, 0x51f8,
606 0x7889, 0x0aa5, 0x663d, 0x77e8, 0x0b87, 0x3dcb, 0x360d, 0x218b,
607 0x512f, 0x7dc9, 0x6a4d, 0x630a, 0x3547, 0x1dd2, 0x5aea, 0x69a5,
608 0x7bfa, 0x5e4f, 0x1519, 0x6430, 0x3a0e, 0x5eb3, 0x5425, 0x0c7a,
609 0x5540, 0x3670, 0x63c1, 0x31e9, 0x5a39, 0x2de7, 0x5979, 0x2891,
610 0x1562, 0x014b, 0x5b05, 0x2756, 0x5a34, 0x13aa, 0x6cb5, 0x2c36,
611 0x5e72, 0x1306, 0x0861, 0x15ef, 0x1ee8, 0x5a37, 0x7ac4, 0x45dd,
612 0x44c4, 0x7266, 0x2f41, 0x3ccc, 0x045e, 0x7d40, 0x7c66, 0x0fa0,
613};
614
615static const u16 sunxi_nfc_randomizer_ecc1024_seeds[] = {
616 0x2cf5, 0x35f1, 0x63a4, 0x5274, 0x2bd2, 0x778b, 0x7285, 0x32b6,
617 0x6a5c, 0x70d6, 0x757d, 0x6769, 0x5375, 0x1e81, 0x0cf3, 0x3982,
618 0x6787, 0x042a, 0x6c49, 0x1925, 0x56a8, 0x40a9, 0x063e, 0x7bd9,
619 0x4dbf, 0x55ec, 0x672e, 0x7334, 0x5185, 0x4d00, 0x232a, 0x7e07,
620 0x445d, 0x6b92, 0x528f, 0x4255, 0x53ba, 0x7d82, 0x2a2e, 0x3a4e,
621 0x75eb, 0x450c, 0x6844, 0x1b5d, 0x581a, 0x4cc6, 0x0379, 0x37b2,
622 0x419f, 0x0e92, 0x6b27, 0x5624, 0x01e3, 0x07c1, 0x44a5, 0x130c,
623 0x13e8, 0x5910, 0x0876, 0x60c5, 0x54e3, 0x5b7f, 0x2269, 0x509f,
624 0x7665, 0x36fd, 0x3e9a, 0x0579, 0x6295, 0x14ef, 0x0a81, 0x1bcc,
625 0x4b16, 0x64db, 0x0514, 0x4f07, 0x0591, 0x3576, 0x6853, 0x0d9e,
626 0x259f, 0x38b7, 0x64fb, 0x3094, 0x4693, 0x6ddd, 0x29bb, 0x0bc8,
627 0x3f47, 0x490e, 0x0c0e, 0x7933, 0x3c9e, 0x5840, 0x398d, 0x3e68,
628 0x4af1, 0x71f5, 0x57cf, 0x1121, 0x64eb, 0x3579, 0x15ac, 0x584d,
629 0x5f2a, 0x47e2, 0x6528, 0x6eac, 0x196e, 0x6b96, 0x0450, 0x0179,
630 0x609c, 0x06e1, 0x4626, 0x42c7, 0x273e, 0x486f, 0x0705, 0x1601,
631 0x145b, 0x407e, 0x062b, 0x57a5, 0x53f9, 0x5659, 0x4410, 0x3ccd,
632};
633
634static u16 sunxi_nfc_randomizer_step(u16 state, int count)
635{
636 state &= 0x7fff;
637
638 /*
639 * This loop is just a simple implementation of a Fibonacci LFSR using
640 * the x16 + x15 + 1 polynomial.
641 */
642 while (count--)
643 state = ((state >> 1) |
644 (((state ^ (state >> 1)) & 1) << 14)) & 0x7fff;
645
646 return state;
647}
648
649static u16 sunxi_nfc_randomizer_state(struct mtd_info *mtd, int page, bool ecc)
650{
651 const u16 *seeds = sunxi_nfc_randomizer_page_seeds;
Brian Norris46c135c2016-01-22 18:57:13 -0800652 int mod = mtd_div_by_ws(mtd->erasesize, mtd);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100653
654 if (mod > ARRAY_SIZE(sunxi_nfc_randomizer_page_seeds))
655 mod = ARRAY_SIZE(sunxi_nfc_randomizer_page_seeds);
656
657 if (ecc) {
658 if (mtd->ecc_step_size == 512)
659 seeds = sunxi_nfc_randomizer_ecc512_seeds;
660 else
661 seeds = sunxi_nfc_randomizer_ecc1024_seeds;
662 }
663
664 return seeds[page % mod];
665}
666
667static void sunxi_nfc_randomizer_config(struct mtd_info *mtd,
668 int page, bool ecc)
669{
Boris BREZILLONf671a1f2016-03-05 00:21:20 +0100670 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100671 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
672 u32 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL);
673 u16 state;
674
675 if (!(nand->options & NAND_NEED_SCRAMBLING))
676 return;
677
678 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL);
679 state = sunxi_nfc_randomizer_state(mtd, page, ecc);
680 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_RANDOM_SEED_MSK;
681 writel(ecc_ctl | NFC_RANDOM_SEED(state), nfc->regs + NFC_REG_ECC_CTL);
682}
683
684static void sunxi_nfc_randomizer_enable(struct mtd_info *mtd)
685{
Boris BREZILLONf671a1f2016-03-05 00:21:20 +0100686 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100687 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
688
689 if (!(nand->options & NAND_NEED_SCRAMBLING))
690 return;
691
692 writel(readl(nfc->regs + NFC_REG_ECC_CTL) | NFC_RANDOM_EN,
693 nfc->regs + NFC_REG_ECC_CTL);
694}
695
696static void sunxi_nfc_randomizer_disable(struct mtd_info *mtd)
697{
Boris BREZILLONf671a1f2016-03-05 00:21:20 +0100698 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100699 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
700
701 if (!(nand->options & NAND_NEED_SCRAMBLING))
702 return;
703
704 writel(readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_RANDOM_EN,
705 nfc->regs + NFC_REG_ECC_CTL);
706}
707
708static void sunxi_nfc_randomize_bbm(struct mtd_info *mtd, int page, u8 *bbm)
709{
710 u16 state = sunxi_nfc_randomizer_state(mtd, page, true);
711
712 bbm[0] ^= state;
713 bbm[1] ^= sunxi_nfc_randomizer_step(state, 8);
714}
715
716static void sunxi_nfc_randomizer_write_buf(struct mtd_info *mtd,
717 const uint8_t *buf, int len,
718 bool ecc, int page)
719{
720 sunxi_nfc_randomizer_config(mtd, page, ecc);
721 sunxi_nfc_randomizer_enable(mtd);
722 sunxi_nfc_write_buf(mtd, buf, len);
723 sunxi_nfc_randomizer_disable(mtd);
724}
725
726static void sunxi_nfc_randomizer_read_buf(struct mtd_info *mtd, uint8_t *buf,
727 int len, bool ecc, int page)
728{
729 sunxi_nfc_randomizer_config(mtd, page, ecc);
730 sunxi_nfc_randomizer_enable(mtd);
731 sunxi_nfc_read_buf(mtd, buf, len);
732 sunxi_nfc_randomizer_disable(mtd);
733}
734
Boris BREZILLONc9118ec2015-09-30 23:45:23 +0200735static void sunxi_nfc_hw_ecc_enable(struct mtd_info *mtd)
736{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100737 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLONc9118ec2015-09-30 23:45:23 +0200738 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
739 struct sunxi_nand_hw_ecc *data = nand->ecc.priv;
740 u32 ecc_ctl;
741
742 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL);
743 ecc_ctl &= ~(NFC_ECC_MODE_MSK | NFC_ECC_PIPELINE |
744 NFC_ECC_BLOCK_SIZE_MSK);
Boris Brezillon336de7b2016-03-04 17:33:10 +0100745 ecc_ctl |= NFC_ECC_EN | NFC_ECC_MODE(data->mode) | NFC_ECC_EXCEPTION |
746 NFC_ECC_PIPELINE;
Boris BREZILLONc9118ec2015-09-30 23:45:23 +0200747
748 writel(ecc_ctl, nfc->regs + NFC_REG_ECC_CTL);
749}
750
751static void sunxi_nfc_hw_ecc_disable(struct mtd_info *mtd)
752{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100753 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLONc9118ec2015-09-30 23:45:23 +0200754 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
755
756 writel(readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_ECC_EN,
757 nfc->regs + NFC_REG_ECC_CTL);
758}
759
Boris BREZILLONf363e0f2015-09-30 23:45:27 +0200760static inline void sunxi_nfc_user_data_to_buf(u32 user_data, u8 *buf)
761{
762 buf[0] = user_data;
763 buf[1] = user_data >> 8;
764 buf[2] = user_data >> 16;
765 buf[3] = user_data >> 24;
766}
767
Boris BREZILLON913821b2015-09-30 23:45:24 +0200768static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd,
769 u8 *data, int data_off,
770 u8 *oob, int oob_off,
771 int *cur_off,
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100772 unsigned int *max_bitflips,
773 bool bbm, int page)
Boris BREZILLON913821b2015-09-30 23:45:24 +0200774{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100775 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200776 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
777 struct nand_ecc_ctrl *ecc = &nand->ecc;
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100778 int raw_mode = 0;
Boris BREZILLON913821b2015-09-30 23:45:24 +0200779 u32 status;
780 int ret;
781
782 if (*cur_off != data_off)
783 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, data_off, -1);
784
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100785 sunxi_nfc_randomizer_read_buf(mtd, NULL, ecc->size, false, page);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200786
Boris BREZILLON74eb9ff2015-10-20 22:16:00 +0200787 if (data_off + ecc->size != oob_off)
Boris BREZILLON913821b2015-09-30 23:45:24 +0200788 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
789
790 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
791 if (ret)
792 return ret;
793
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100794 sunxi_nfc_randomizer_enable(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200795 writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_ECC_OP,
796 nfc->regs + NFC_REG_CMD);
797
798 ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100799 sunxi_nfc_randomizer_disable(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200800 if (ret)
801 return ret;
802
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100803 *cur_off = oob_off + ecc->bytes + 4;
804
Boris BREZILLON913821b2015-09-30 23:45:24 +0200805 status = readl(nfc->regs + NFC_REG_ECC_ST);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100806 if (status & NFC_ECC_PAT_FOUND(0)) {
807 u8 pattern = 0xff;
808
809 if (unlikely(!(readl(nfc->regs + NFC_REG_PAT_ID) & 0x1)))
810 pattern = 0x0;
811
812 memset(data, pattern, ecc->size);
813 memset(oob, pattern, ecc->bytes + 4);
814
815 return 1;
816 }
817
Boris BREZILLON913821b2015-09-30 23:45:24 +0200818 ret = NFC_ECC_ERR_CNT(0, readl(nfc->regs + NFC_REG_ECC_ERR_CNT(0)));
819
820 memcpy_fromio(data, nfc->regs + NFC_RAM0_BASE, ecc->size);
821
822 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100823 sunxi_nfc_randomizer_read_buf(mtd, oob, ecc->bytes + 4, true, page);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200824
Boris BREZILLONf363e0f2015-09-30 23:45:27 +0200825 if (status & NFC_ECC_ERR(0)) {
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100826 /*
827 * Re-read the data with the randomizer disabled to identify
828 * bitflips in erased pages.
829 */
830 if (nand->options & NAND_NEED_SCRAMBLING) {
831 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, data_off, -1);
832 nand->read_buf(mtd, data, ecc->size);
833 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
834 nand->read_buf(mtd, oob, ecc->bytes + 4);
835 }
836
Boris BREZILLON146b5032015-09-30 23:45:29 +0200837 ret = nand_check_erased_ecc_chunk(data, ecc->size,
838 oob, ecc->bytes + 4,
839 NULL, 0, ecc->strength);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100840 if (ret >= 0)
841 raw_mode = 1;
Boris BREZILLONf363e0f2015-09-30 23:45:27 +0200842 } else {
843 /*
844 * The engine protects 4 bytes of OOB data per chunk.
845 * Retrieve the corrected OOB bytes.
846 */
847 sunxi_nfc_user_data_to_buf(readl(nfc->regs + NFC_REG_USER_DATA(0)),
848 oob);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100849
850 /* De-randomize the Bad Block Marker. */
851 if (bbm && nand->options & NAND_NEED_SCRAMBLING)
852 sunxi_nfc_randomize_bbm(mtd, page, oob);
Boris BREZILLONf363e0f2015-09-30 23:45:27 +0200853 }
Boris BREZILLON913821b2015-09-30 23:45:24 +0200854
855 if (ret < 0) {
856 mtd->ecc_stats.failed++;
857 } else {
858 mtd->ecc_stats.corrected += ret;
859 *max_bitflips = max_t(unsigned int, *max_bitflips, ret);
860 }
861
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100862 return raw_mode;
Boris BREZILLON913821b2015-09-30 23:45:24 +0200863}
864
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200865static void sunxi_nfc_hw_ecc_read_extra_oob(struct mtd_info *mtd,
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100866 u8 *oob, int *cur_off,
867 bool randomize, int page)
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200868{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100869 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200870 struct nand_ecc_ctrl *ecc = &nand->ecc;
871 int offset = ((ecc->bytes + 4) * ecc->steps);
872 int len = mtd->oobsize - offset;
873
874 if (len <= 0)
875 return;
876
877 if (*cur_off != offset)
878 nand->cmdfunc(mtd, NAND_CMD_RNDOUT,
879 offset + mtd->writesize, -1);
880
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100881 if (!randomize)
882 sunxi_nfc_read_buf(mtd, oob + offset, len);
883 else
884 sunxi_nfc_randomizer_read_buf(mtd, oob + offset, len,
885 false, page);
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200886
887 *cur_off = mtd->oobsize + mtd->writesize;
888}
889
Boris BREZILLON23151fd2015-09-30 23:45:28 +0200890static inline u32 sunxi_nfc_buf_to_user_data(const u8 *buf)
891{
892 return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
893}
894
Boris BREZILLON913821b2015-09-30 23:45:24 +0200895static int sunxi_nfc_hw_ecc_write_chunk(struct mtd_info *mtd,
896 const u8 *data, int data_off,
897 const u8 *oob, int oob_off,
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100898 int *cur_off, bool bbm,
899 int page)
Boris BREZILLON913821b2015-09-30 23:45:24 +0200900{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100901 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200902 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
903 struct nand_ecc_ctrl *ecc = &nand->ecc;
904 int ret;
905
906 if (data_off != *cur_off)
907 nand->cmdfunc(mtd, NAND_CMD_RNDIN, data_off, -1);
908
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100909 sunxi_nfc_randomizer_write_buf(mtd, data, ecc->size, false, page);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200910
911 /* Fill OOB data in */
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100912 if ((nand->options & NAND_NEED_SCRAMBLING) && bbm) {
913 u8 user_data[4];
914
915 memcpy(user_data, oob, 4);
916 sunxi_nfc_randomize_bbm(mtd, page, user_data);
917 writel(sunxi_nfc_buf_to_user_data(user_data),
918 nfc->regs + NFC_REG_USER_DATA(0));
919 } else {
920 writel(sunxi_nfc_buf_to_user_data(oob),
921 nfc->regs + NFC_REG_USER_DATA(0));
922 }
Boris BREZILLON913821b2015-09-30 23:45:24 +0200923
Boris BREZILLON74eb9ff2015-10-20 22:16:00 +0200924 if (data_off + ecc->size != oob_off)
Boris BREZILLON913821b2015-09-30 23:45:24 +0200925 nand->cmdfunc(mtd, NAND_CMD_RNDIN, oob_off, -1);
926
927 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
928 if (ret)
929 return ret;
930
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100931 sunxi_nfc_randomizer_enable(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200932 writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD |
933 NFC_ACCESS_DIR | NFC_ECC_OP,
934 nfc->regs + NFC_REG_CMD);
935
936 ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100937 sunxi_nfc_randomizer_disable(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200938 if (ret)
939 return ret;
940
941 *cur_off = oob_off + ecc->bytes + 4;
942
943 return 0;
944}
945
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200946static void sunxi_nfc_hw_ecc_write_extra_oob(struct mtd_info *mtd,
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100947 u8 *oob, int *cur_off,
948 int page)
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200949{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100950 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200951 struct nand_ecc_ctrl *ecc = &nand->ecc;
952 int offset = ((ecc->bytes + 4) * ecc->steps);
953 int len = mtd->oobsize - offset;
954
955 if (len <= 0)
956 return;
957
958 if (*cur_off != offset)
959 nand->cmdfunc(mtd, NAND_CMD_RNDIN,
960 offset + mtd->writesize, -1);
961
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100962 sunxi_nfc_randomizer_write_buf(mtd, oob + offset, len, false, page);
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200963
964 *cur_off = mtd->oobsize + mtd->writesize;
965}
966
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200967static int sunxi_nfc_hw_ecc_read_page(struct mtd_info *mtd,
968 struct nand_chip *chip, uint8_t *buf,
969 int oob_required, int page)
970{
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200971 struct nand_ecc_ctrl *ecc = &chip->ecc;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200972 unsigned int max_bitflips = 0;
Boris BREZILLONb4625512015-09-30 23:45:25 +0200973 int ret, i, cur_off = 0;
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100974 bool raw_mode = false;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200975
Boris BREZILLONc9118ec2015-09-30 23:45:23 +0200976 sunxi_nfc_hw_ecc_enable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200977
978 for (i = 0; i < ecc->steps; i++) {
Boris BREZILLONb4625512015-09-30 23:45:25 +0200979 int data_off = i * ecc->size;
980 int oob_off = i * (ecc->bytes + 4);
981 u8 *data = buf + data_off;
982 u8 *oob = chip->oob_poi + oob_off;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200983
Boris BREZILLONb4625512015-09-30 23:45:25 +0200984 ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off, oob,
985 oob_off + mtd->writesize,
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100986 &cur_off, &max_bitflips,
987 !i, page);
988 if (ret < 0)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200989 return ret;
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100990 else if (ret)
991 raw_mode = true;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200992 }
993
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200994 if (oob_required)
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100995 sunxi_nfc_hw_ecc_read_extra_oob(mtd, chip->oob_poi, &cur_off,
996 !raw_mode, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200997
Boris BREZILLONc9118ec2015-09-30 23:45:23 +0200998 sunxi_nfc_hw_ecc_disable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200999
1000 return max_bitflips;
1001}
1002
Boris Brezillonfe82cce2015-09-16 09:01:45 +02001003static int sunxi_nfc_hw_ecc_read_subpage(struct mtd_info *mtd,
1004 struct nand_chip *chip,
1005 u32 data_offs, u32 readlen,
1006 u8 *bufpoi, int page)
1007{
1008 struct nand_ecc_ctrl *ecc = &chip->ecc;
1009 int ret, i, cur_off = 0;
1010 unsigned int max_bitflips = 0;
1011
1012 sunxi_nfc_hw_ecc_enable(mtd);
1013
1014 chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
1015 for (i = data_offs / ecc->size;
1016 i < DIV_ROUND_UP(data_offs + readlen, ecc->size); i++) {
1017 int data_off = i * ecc->size;
1018 int oob_off = i * (ecc->bytes + 4);
1019 u8 *data = bufpoi + data_off;
1020 u8 *oob = chip->oob_poi + oob_off;
1021
1022 ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off,
1023 oob,
1024 oob_off + mtd->writesize,
1025 &cur_off, &max_bitflips,
1026 !i, page);
1027 if (ret < 0)
1028 return ret;
1029 }
1030
1031 sunxi_nfc_hw_ecc_disable(mtd);
1032
1033 return max_bitflips;
1034}
1035
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001036static int sunxi_nfc_hw_ecc_write_page(struct mtd_info *mtd,
1037 struct nand_chip *chip,
Boris BREZILLON45aaeff2015-10-13 11:22:18 +02001038 const uint8_t *buf, int oob_required,
1039 int page)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001040{
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001041 struct nand_ecc_ctrl *ecc = &chip->ecc;
Boris BREZILLONb4625512015-09-30 23:45:25 +02001042 int ret, i, cur_off = 0;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001043
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001044 sunxi_nfc_hw_ecc_enable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001045
1046 for (i = 0; i < ecc->steps; i++) {
Boris BREZILLONb4625512015-09-30 23:45:25 +02001047 int data_off = i * ecc->size;
1048 int oob_off = i * (ecc->bytes + 4);
1049 const u8 *data = buf + data_off;
1050 const u8 *oob = chip->oob_poi + oob_off;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001051
Boris BREZILLONb4625512015-09-30 23:45:25 +02001052 ret = sunxi_nfc_hw_ecc_write_chunk(mtd, data, data_off, oob,
1053 oob_off + mtd->writesize,
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001054 &cur_off, !i, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001055 if (ret)
1056 return ret;
1057 }
1058
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001059 if (oob_required || (chip->options & NAND_NEED_SCRAMBLING))
1060 sunxi_nfc_hw_ecc_write_extra_oob(mtd, chip->oob_poi,
1061 &cur_off, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001062
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001063 sunxi_nfc_hw_ecc_disable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001064
1065 return 0;
1066}
1067
1068static int sunxi_nfc_hw_syndrome_ecc_read_page(struct mtd_info *mtd,
1069 struct nand_chip *chip,
1070 uint8_t *buf, int oob_required,
1071 int page)
1072{
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001073 struct nand_ecc_ctrl *ecc = &chip->ecc;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001074 unsigned int max_bitflips = 0;
Boris BREZILLONb4625512015-09-30 23:45:25 +02001075 int ret, i, cur_off = 0;
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001076 bool raw_mode = false;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001077
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001078 sunxi_nfc_hw_ecc_enable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001079
1080 for (i = 0; i < ecc->steps; i++) {
Boris BREZILLONb4625512015-09-30 23:45:25 +02001081 int data_off = i * (ecc->size + ecc->bytes + 4);
1082 int oob_off = data_off + ecc->size;
1083 u8 *data = buf + (i * ecc->size);
1084 u8 *oob = chip->oob_poi + (i * (ecc->bytes + 4));
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001085
Boris BREZILLONb4625512015-09-30 23:45:25 +02001086 ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off, oob,
1087 oob_off, &cur_off,
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001088 &max_bitflips, !i, page);
1089 if (ret < 0)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001090 return ret;
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001091 else if (ret)
1092 raw_mode = true;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001093 }
1094
Boris BREZILLON35d0e242015-09-30 23:45:26 +02001095 if (oob_required)
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001096 sunxi_nfc_hw_ecc_read_extra_oob(mtd, chip->oob_poi, &cur_off,
1097 !raw_mode, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001098
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001099 sunxi_nfc_hw_ecc_disable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001100
1101 return max_bitflips;
1102}
1103
1104static int sunxi_nfc_hw_syndrome_ecc_write_page(struct mtd_info *mtd,
1105 struct nand_chip *chip,
1106 const uint8_t *buf,
Boris BREZILLON45aaeff2015-10-13 11:22:18 +02001107 int oob_required, int page)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001108{
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001109 struct nand_ecc_ctrl *ecc = &chip->ecc;
Boris BREZILLONb4625512015-09-30 23:45:25 +02001110 int ret, i, cur_off = 0;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001111
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001112 sunxi_nfc_hw_ecc_enable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001113
1114 for (i = 0; i < ecc->steps; i++) {
Boris BREZILLONb4625512015-09-30 23:45:25 +02001115 int data_off = i * (ecc->size + ecc->bytes + 4);
1116 int oob_off = data_off + ecc->size;
1117 const u8 *data = buf + (i * ecc->size);
1118 const u8 *oob = chip->oob_poi + (i * (ecc->bytes + 4));
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001119
Boris BREZILLONb4625512015-09-30 23:45:25 +02001120 ret = sunxi_nfc_hw_ecc_write_chunk(mtd, data, data_off,
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001121 oob, oob_off, &cur_off,
1122 false, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001123 if (ret)
1124 return ret;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001125 }
1126
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001127 if (oob_required || (chip->options & NAND_NEED_SCRAMBLING))
1128 sunxi_nfc_hw_ecc_write_extra_oob(mtd, chip->oob_poi,
1129 &cur_off, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001130
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001131 sunxi_nfc_hw_ecc_disable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001132
1133 return 0;
1134}
1135
Boris Brezillon1c1bdd62015-09-02 15:05:52 +02001136static int sunxi_nfc_hw_common_ecc_read_oob(struct mtd_info *mtd,
1137 struct nand_chip *chip,
1138 int page)
1139{
1140 chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
1141
1142 chip->pagebuf = -1;
1143
1144 return chip->ecc.read_page(mtd, chip, chip->buffers->databuf, 1, page);
1145}
1146
1147static int sunxi_nfc_hw_common_ecc_write_oob(struct mtd_info *mtd,
1148 struct nand_chip *chip,
1149 int page)
1150{
1151 int ret, status;
1152
1153 chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0, page);
1154
1155 chip->pagebuf = -1;
1156
1157 memset(chip->buffers->databuf, 0xff, mtd->writesize);
1158 ret = chip->ecc.write_page(mtd, chip, chip->buffers->databuf, 1, page);
1159 if (ret)
1160 return ret;
1161
1162 /* Send command to program the OOB data */
1163 chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
1164
1165 status = chip->waitfunc(mtd, chip);
1166
1167 return status & NAND_STATUS_FAIL ? -EIO : 0;
1168}
1169
Roy Spliet9c618292015-06-26 11:00:10 +02001170static const s32 tWB_lut[] = {6, 12, 16, 20};
1171static const s32 tRHW_lut[] = {4, 8, 12, 20};
1172
1173static int _sunxi_nand_lookup_timing(const s32 *lut, int lut_size, u32 duration,
1174 u32 clk_period)
1175{
1176 u32 clk_cycles = DIV_ROUND_UP(duration, clk_period);
1177 int i;
1178
1179 for (i = 0; i < lut_size; i++) {
1180 if (clk_cycles <= lut[i])
1181 return i;
1182 }
1183
1184 /* Doesn't fit */
1185 return -EINVAL;
1186}
1187
1188#define sunxi_nand_lookup_timing(l, p, c) \
1189 _sunxi_nand_lookup_timing(l, ARRAY_SIZE(l), p, c)
1190
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001191static int sunxi_nand_chip_set_timings(struct sunxi_nand_chip *chip,
1192 const struct nand_sdr_timings *timings)
1193{
Roy Spliet9c618292015-06-26 11:00:10 +02001194 struct sunxi_nfc *nfc = to_sunxi_nfc(chip->nand.controller);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001195 u32 min_clk_period = 0;
Roy Spliet9c618292015-06-26 11:00:10 +02001196 s32 tWB, tADL, tWHR, tRHW, tCAD;
Boris Brezillon2d434572015-12-02 15:57:20 +01001197 long real_clk_rate;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001198
1199 /* T1 <=> tCLS */
1200 if (timings->tCLS_min > min_clk_period)
1201 min_clk_period = timings->tCLS_min;
1202
1203 /* T2 <=> tCLH */
1204 if (timings->tCLH_min > min_clk_period)
1205 min_clk_period = timings->tCLH_min;
1206
1207 /* T3 <=> tCS */
1208 if (timings->tCS_min > min_clk_period)
1209 min_clk_period = timings->tCS_min;
1210
1211 /* T4 <=> tCH */
1212 if (timings->tCH_min > min_clk_period)
1213 min_clk_period = timings->tCH_min;
1214
1215 /* T5 <=> tWP */
1216 if (timings->tWP_min > min_clk_period)
1217 min_clk_period = timings->tWP_min;
1218
1219 /* T6 <=> tWH */
1220 if (timings->tWH_min > min_clk_period)
1221 min_clk_period = timings->tWH_min;
1222
1223 /* T7 <=> tALS */
1224 if (timings->tALS_min > min_clk_period)
1225 min_clk_period = timings->tALS_min;
1226
1227 /* T8 <=> tDS */
1228 if (timings->tDS_min > min_clk_period)
1229 min_clk_period = timings->tDS_min;
1230
1231 /* T9 <=> tDH */
1232 if (timings->tDH_min > min_clk_period)
1233 min_clk_period = timings->tDH_min;
1234
1235 /* T10 <=> tRR */
1236 if (timings->tRR_min > (min_clk_period * 3))
1237 min_clk_period = DIV_ROUND_UP(timings->tRR_min, 3);
1238
1239 /* T11 <=> tALH */
1240 if (timings->tALH_min > min_clk_period)
1241 min_clk_period = timings->tALH_min;
1242
1243 /* T12 <=> tRP */
1244 if (timings->tRP_min > min_clk_period)
1245 min_clk_period = timings->tRP_min;
1246
1247 /* T13 <=> tREH */
1248 if (timings->tREH_min > min_clk_period)
1249 min_clk_period = timings->tREH_min;
1250
1251 /* T14 <=> tRC */
1252 if (timings->tRC_min > (min_clk_period * 2))
1253 min_clk_period = DIV_ROUND_UP(timings->tRC_min, 2);
1254
1255 /* T15 <=> tWC */
1256 if (timings->tWC_min > (min_clk_period * 2))
1257 min_clk_period = DIV_ROUND_UP(timings->tWC_min, 2);
1258
Roy Spliet9c618292015-06-26 11:00:10 +02001259 /* T16 - T19 + tCAD */
Boris Brezillon5abcd952015-11-11 22:30:30 +01001260 if (timings->tWB_max > (min_clk_period * 20))
1261 min_clk_period = DIV_ROUND_UP(timings->tWB_max, 20);
1262
1263 if (timings->tADL_min > (min_clk_period * 32))
1264 min_clk_period = DIV_ROUND_UP(timings->tADL_min, 32);
1265
1266 if (timings->tWHR_min > (min_clk_period * 32))
1267 min_clk_period = DIV_ROUND_UP(timings->tWHR_min, 32);
1268
1269 if (timings->tRHW_min > (min_clk_period * 20))
1270 min_clk_period = DIV_ROUND_UP(timings->tRHW_min, 20);
1271
Roy Spliet9c618292015-06-26 11:00:10 +02001272 tWB = sunxi_nand_lookup_timing(tWB_lut, timings->tWB_max,
1273 min_clk_period);
1274 if (tWB < 0) {
1275 dev_err(nfc->dev, "unsupported tWB\n");
1276 return tWB;
1277 }
1278
1279 tADL = DIV_ROUND_UP(timings->tADL_min, min_clk_period) >> 3;
1280 if (tADL > 3) {
1281 dev_err(nfc->dev, "unsupported tADL\n");
1282 return -EINVAL;
1283 }
1284
1285 tWHR = DIV_ROUND_UP(timings->tWHR_min, min_clk_period) >> 3;
1286 if (tWHR > 3) {
1287 dev_err(nfc->dev, "unsupported tWHR\n");
1288 return -EINVAL;
1289 }
1290
1291 tRHW = sunxi_nand_lookup_timing(tRHW_lut, timings->tRHW_min,
1292 min_clk_period);
1293 if (tRHW < 0) {
1294 dev_err(nfc->dev, "unsupported tRHW\n");
1295 return tRHW;
1296 }
1297
1298 /*
1299 * TODO: according to ONFI specs this value only applies for DDR NAND,
1300 * but Allwinner seems to set this to 0x7. Mimic them for now.
1301 */
1302 tCAD = 0x7;
1303
1304 /* TODO: A83 has some more bits for CDQSS, CS, CLHZ, CCS, WC */
1305 chip->timing_cfg = NFC_TIMING_CFG(tWB, tADL, tWHR, tRHW, tCAD);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001306
1307 /* Convert min_clk_period from picoseconds to nanoseconds */
1308 min_clk_period = DIV_ROUND_UP(min_clk_period, 1000);
1309
1310 /*
Boris Brezillon2f9992e2015-12-02 15:10:40 +01001311 * Unlike what is stated in Allwinner datasheet, the clk_rate should
1312 * be set to (1 / min_clk_period), and not (2 / min_clk_period).
1313 * This new formula was verified with a scope and validated by
1314 * Allwinner engineers.
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001315 */
Boris Brezillon2f9992e2015-12-02 15:10:40 +01001316 chip->clk_rate = NSEC_PER_SEC / min_clk_period;
Boris Brezillon2d434572015-12-02 15:57:20 +01001317 real_clk_rate = clk_round_rate(nfc->mod_clk, chip->clk_rate);
1318
1319 /*
1320 * ONFI specification 3.1, paragraph 4.15.2 dictates that EDO data
1321 * output cycle timings shall be used if the host drives tRC less than
1322 * 30 ns.
1323 */
1324 min_clk_period = NSEC_PER_SEC / real_clk_rate;
1325 chip->timing_ctl = ((min_clk_period * 2) < 30) ?
1326 NFC_TIMING_CTL_EDO : 0;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001327
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001328 return 0;
1329}
1330
1331static int sunxi_nand_chip_init_timings(struct sunxi_nand_chip *chip,
1332 struct device_node *np)
1333{
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001334 struct mtd_info *mtd = nand_to_mtd(&chip->nand);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001335 const struct nand_sdr_timings *timings;
1336 int ret;
1337 int mode;
1338
1339 mode = onfi_get_async_timing_mode(&chip->nand);
1340 if (mode == ONFI_TIMING_MODE_UNKNOWN) {
1341 mode = chip->nand.onfi_timing_mode_default;
1342 } else {
1343 uint8_t feature[ONFI_SUBFEATURE_PARAM_LEN] = {};
Stefan Roese7eadd47f2015-08-28 14:45:21 +02001344 int i;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001345
1346 mode = fls(mode) - 1;
1347 if (mode < 0)
1348 mode = 0;
1349
1350 feature[0] = mode;
Stefan Roese7eadd47f2015-08-28 14:45:21 +02001351 for (i = 0; i < chip->nsels; i++) {
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001352 chip->nand.select_chip(mtd, i);
1353 ret = chip->nand.onfi_set_features(mtd, &chip->nand,
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001354 ONFI_FEATURE_ADDR_TIMING_MODE,
1355 feature);
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001356 chip->nand.select_chip(mtd, -1);
Stefan Roese7eadd47f2015-08-28 14:45:21 +02001357 if (ret)
1358 return ret;
1359 }
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001360 }
1361
1362 timings = onfi_async_timing_mode_to_sdr_timings(mode);
1363 if (IS_ERR(timings))
1364 return PTR_ERR(timings);
1365
1366 return sunxi_nand_chip_set_timings(chip, timings);
1367}
1368
1369static int sunxi_nand_hw_common_ecc_ctrl_init(struct mtd_info *mtd,
1370 struct nand_ecc_ctrl *ecc,
1371 struct device_node *np)
1372{
1373 static const u8 strengths[] = { 16, 24, 28, 32, 40, 48, 56, 60, 64 };
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +01001374 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001375 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
1376 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
1377 struct sunxi_nand_hw_ecc *data;
1378 struct nand_ecclayout *layout;
1379 int nsectors;
1380 int ret;
1381 int i;
1382
1383 data = kzalloc(sizeof(*data), GFP_KERNEL);
1384 if (!data)
1385 return -ENOMEM;
1386
1387 /* Add ECC info retrieval from DT */
1388 for (i = 0; i < ARRAY_SIZE(strengths); i++) {
1389 if (ecc->strength <= strengths[i])
1390 break;
1391 }
1392
1393 if (i >= ARRAY_SIZE(strengths)) {
1394 dev_err(nfc->dev, "unsupported strength\n");
1395 ret = -ENOTSUPP;
1396 goto err;
1397 }
1398
1399 data->mode = i;
1400
1401 /* HW ECC always request ECC bytes for 1024 bytes blocks */
1402 ecc->bytes = DIV_ROUND_UP(ecc->strength * fls(8 * 1024), 8);
1403
1404 /* HW ECC always work with even numbers of ECC bytes */
1405 ecc->bytes = ALIGN(ecc->bytes, 2);
1406
1407 layout = &data->layout;
1408 nsectors = mtd->writesize / ecc->size;
1409
1410 if (mtd->oobsize < ((ecc->bytes + 4) * nsectors)) {
1411 ret = -EINVAL;
1412 goto err;
1413 }
1414
1415 layout->eccbytes = (ecc->bytes * nsectors);
1416
Boris Brezillon1c1bdd62015-09-02 15:05:52 +02001417 ecc->read_oob = sunxi_nfc_hw_common_ecc_read_oob;
1418 ecc->write_oob = sunxi_nfc_hw_common_ecc_write_oob;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001419 ecc->layout = layout;
1420 ecc->priv = data;
1421
1422 return 0;
1423
1424err:
1425 kfree(data);
1426
1427 return ret;
1428}
1429
1430static void sunxi_nand_hw_common_ecc_ctrl_cleanup(struct nand_ecc_ctrl *ecc)
1431{
1432 kfree(ecc->priv);
1433}
1434
1435static int sunxi_nand_hw_ecc_ctrl_init(struct mtd_info *mtd,
1436 struct nand_ecc_ctrl *ecc,
1437 struct device_node *np)
1438{
1439 struct nand_ecclayout *layout;
1440 int nsectors;
1441 int i, j;
1442 int ret;
1443
1444 ret = sunxi_nand_hw_common_ecc_ctrl_init(mtd, ecc, np);
1445 if (ret)
1446 return ret;
1447
1448 ecc->read_page = sunxi_nfc_hw_ecc_read_page;
1449 ecc->write_page = sunxi_nfc_hw_ecc_write_page;
Boris Brezillon1c1bdd62015-09-02 15:05:52 +02001450 ecc->read_oob_raw = nand_read_oob_std;
1451 ecc->write_oob_raw = nand_write_oob_std;
Boris Brezillonfe82cce2015-09-16 09:01:45 +02001452 ecc->read_subpage = sunxi_nfc_hw_ecc_read_subpage;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001453 layout = ecc->layout;
1454 nsectors = mtd->writesize / ecc->size;
1455
1456 for (i = 0; i < nsectors; i++) {
1457 if (i) {
1458 layout->oobfree[i].offset =
1459 layout->oobfree[i - 1].offset +
1460 layout->oobfree[i - 1].length +
1461 ecc->bytes;
1462 layout->oobfree[i].length = 4;
1463 } else {
1464 /*
1465 * The first 2 bytes are used for BB markers, hence we
1466 * only have 2 bytes available in the first user data
1467 * section.
1468 */
1469 layout->oobfree[i].length = 2;
1470 layout->oobfree[i].offset = 2;
1471 }
1472
1473 for (j = 0; j < ecc->bytes; j++)
1474 layout->eccpos[(ecc->bytes * i) + j] =
1475 layout->oobfree[i].offset +
1476 layout->oobfree[i].length + j;
1477 }
1478
1479 if (mtd->oobsize > (ecc->bytes + 4) * nsectors) {
1480 layout->oobfree[nsectors].offset =
1481 layout->oobfree[nsectors - 1].offset +
1482 layout->oobfree[nsectors - 1].length +
1483 ecc->bytes;
1484 layout->oobfree[nsectors].length = mtd->oobsize -
1485 ((ecc->bytes + 4) * nsectors);
1486 }
1487
1488 return 0;
1489}
1490
1491static int sunxi_nand_hw_syndrome_ecc_ctrl_init(struct mtd_info *mtd,
1492 struct nand_ecc_ctrl *ecc,
1493 struct device_node *np)
1494{
1495 struct nand_ecclayout *layout;
1496 int nsectors;
1497 int i;
1498 int ret;
1499
1500 ret = sunxi_nand_hw_common_ecc_ctrl_init(mtd, ecc, np);
1501 if (ret)
1502 return ret;
1503
1504 ecc->prepad = 4;
1505 ecc->read_page = sunxi_nfc_hw_syndrome_ecc_read_page;
1506 ecc->write_page = sunxi_nfc_hw_syndrome_ecc_write_page;
Boris Brezillon1c1bdd62015-09-02 15:05:52 +02001507 ecc->read_oob_raw = nand_read_oob_syndrome;
1508 ecc->write_oob_raw = nand_write_oob_syndrome;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001509
1510 layout = ecc->layout;
1511 nsectors = mtd->writesize / ecc->size;
1512
1513 for (i = 0; i < (ecc->bytes * nsectors); i++)
1514 layout->eccpos[i] = i;
1515
1516 layout->oobfree[0].length = mtd->oobsize - i;
1517 layout->oobfree[0].offset = i;
1518
1519 return 0;
1520}
1521
1522static void sunxi_nand_ecc_cleanup(struct nand_ecc_ctrl *ecc)
1523{
1524 switch (ecc->mode) {
1525 case NAND_ECC_HW:
1526 case NAND_ECC_HW_SYNDROME:
1527 sunxi_nand_hw_common_ecc_ctrl_cleanup(ecc);
1528 break;
1529 case NAND_ECC_NONE:
1530 kfree(ecc->layout);
1531 default:
1532 break;
1533 }
1534}
1535
1536static int sunxi_nand_ecc_init(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc,
1537 struct device_node *np)
1538{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +01001539 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001540 int ret;
1541
Boris BREZILLONa3d22a52015-09-02 10:30:25 +02001542 if (!ecc->size) {
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001543 ecc->size = nand->ecc_step_ds;
1544 ecc->strength = nand->ecc_strength_ds;
1545 }
1546
1547 if (!ecc->size || !ecc->strength)
1548 return -EINVAL;
1549
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001550 switch (ecc->mode) {
1551 case NAND_ECC_SOFT_BCH:
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001552 break;
1553 case NAND_ECC_HW:
1554 ret = sunxi_nand_hw_ecc_ctrl_init(mtd, ecc, np);
1555 if (ret)
1556 return ret;
1557 break;
1558 case NAND_ECC_HW_SYNDROME:
1559 ret = sunxi_nand_hw_syndrome_ecc_ctrl_init(mtd, ecc, np);
1560 if (ret)
1561 return ret;
1562 break;
1563 case NAND_ECC_NONE:
1564 ecc->layout = kzalloc(sizeof(*ecc->layout), GFP_KERNEL);
1565 if (!ecc->layout)
1566 return -ENOMEM;
1567 ecc->layout->oobfree[0].length = mtd->oobsize;
1568 case NAND_ECC_SOFT:
1569 break;
1570 default:
1571 return -EINVAL;
1572 }
1573
1574 return 0;
1575}
1576
1577static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc,
1578 struct device_node *np)
1579{
1580 const struct nand_sdr_timings *timings;
1581 struct sunxi_nand_chip *chip;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001582 struct mtd_info *mtd;
1583 struct nand_chip *nand;
1584 int nsels;
1585 int ret;
1586 int i;
1587 u32 tmp;
1588
1589 if (!of_get_property(np, "reg", &nsels))
1590 return -EINVAL;
1591
1592 nsels /= sizeof(u32);
1593 if (!nsels) {
1594 dev_err(dev, "invalid reg property size\n");
1595 return -EINVAL;
1596 }
1597
1598 chip = devm_kzalloc(dev,
1599 sizeof(*chip) +
1600 (nsels * sizeof(struct sunxi_nand_chip_sel)),
1601 GFP_KERNEL);
1602 if (!chip) {
1603 dev_err(dev, "could not allocate chip\n");
1604 return -ENOMEM;
1605 }
1606
1607 chip->nsels = nsels;
1608 chip->selected = -1;
1609
1610 for (i = 0; i < nsels; i++) {
1611 ret = of_property_read_u32_index(np, "reg", i, &tmp);
1612 if (ret) {
1613 dev_err(dev, "could not retrieve reg property: %d\n",
1614 ret);
1615 return ret;
1616 }
1617
1618 if (tmp > NFC_MAX_CS) {
1619 dev_err(dev,
1620 "invalid reg value: %u (max CS = 7)\n",
1621 tmp);
1622 return -EINVAL;
1623 }
1624
1625 if (test_and_set_bit(tmp, &nfc->assigned_cs)) {
1626 dev_err(dev, "CS %d already assigned\n", tmp);
1627 return -EINVAL;
1628 }
1629
1630 chip->sels[i].cs = tmp;
1631
1632 if (!of_property_read_u32_index(np, "allwinner,rb", i, &tmp) &&
1633 tmp < 2) {
1634 chip->sels[i].rb.type = RB_NATIVE;
1635 chip->sels[i].rb.info.nativeid = tmp;
1636 } else {
1637 ret = of_get_named_gpio(np, "rb-gpios", i);
1638 if (ret >= 0) {
1639 tmp = ret;
1640 chip->sels[i].rb.type = RB_GPIO;
1641 chip->sels[i].rb.info.gpio = tmp;
1642 ret = devm_gpio_request(dev, tmp, "nand-rb");
1643 if (ret)
1644 return ret;
1645
1646 ret = gpio_direction_input(tmp);
1647 if (ret)
1648 return ret;
1649 } else {
1650 chip->sels[i].rb.type = RB_NONE;
1651 }
1652 }
1653 }
1654
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001655 nand = &chip->nand;
1656 /* Default tR value specified in the ONFI spec (chapter 4.15.1) */
1657 nand->chip_delay = 200;
1658 nand->controller = &nfc->controller;
Boris BREZILLONa3d22a52015-09-02 10:30:25 +02001659 /*
1660 * Set the ECC mode to the default value in case nothing is specified
1661 * in the DT.
1662 */
1663 nand->ecc.mode = NAND_ECC_HW;
Brian Norris63752192015-10-30 20:33:23 -07001664 nand_set_flash_node(nand, np);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001665 nand->select_chip = sunxi_nfc_select_chip;
1666 nand->cmd_ctrl = sunxi_nfc_cmd_ctrl;
1667 nand->read_buf = sunxi_nfc_read_buf;
1668 nand->write_buf = sunxi_nfc_write_buf;
1669 nand->read_byte = sunxi_nfc_read_byte;
1670
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001671 mtd = nand_to_mtd(nand);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001672 mtd->dev.parent = dev;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001673
Boris Brezillon9edb4702015-12-02 16:00:57 +01001674 timings = onfi_async_timing_mode_to_sdr_timings(0);
1675 if (IS_ERR(timings)) {
1676 ret = PTR_ERR(timings);
1677 dev_err(dev,
1678 "could not retrieve timings for ONFI mode 0: %d\n",
1679 ret);
1680 return ret;
1681 }
1682
1683 ret = sunxi_nand_chip_set_timings(chip, timings);
1684 if (ret) {
1685 dev_err(dev, "could not configure chip timings: %d\n", ret);
1686 return ret;
1687 }
1688
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001689 ret = nand_scan_ident(mtd, nsels, NULL);
1690 if (ret)
1691 return ret;
1692
Boris BREZILLONa3d22a52015-09-02 10:30:25 +02001693 if (nand->bbt_options & NAND_BBT_USE_FLASH)
1694 nand->bbt_options |= NAND_BBT_NO_OOB;
1695
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001696 if (nand->options & NAND_NEED_SCRAMBLING)
1697 nand->options |= NAND_NO_SUBPAGE_WRITE;
1698
Boris Brezillonfe82cce2015-09-16 09:01:45 +02001699 nand->options |= NAND_SUBPAGE_READ;
1700
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001701 ret = sunxi_nand_chip_init_timings(chip, np);
1702 if (ret) {
1703 dev_err(dev, "could not configure chip timings: %d\n", ret);
1704 return ret;
1705 }
1706
1707 ret = sunxi_nand_ecc_init(mtd, &nand->ecc, np);
1708 if (ret) {
1709 dev_err(dev, "ECC init failed: %d\n", ret);
1710 return ret;
1711 }
1712
1713 ret = nand_scan_tail(mtd);
1714 if (ret) {
1715 dev_err(dev, "nand_scan_tail failed: %d\n", ret);
1716 return ret;
1717 }
1718
Brian Norrisa61ae812015-10-30 20:33:25 -07001719 ret = mtd_device_register(mtd, NULL, 0);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001720 if (ret) {
1721 dev_err(dev, "failed to register mtd device: %d\n", ret);
1722 nand_release(mtd);
1723 return ret;
1724 }
1725
1726 list_add_tail(&chip->node, &nfc->chips);
1727
1728 return 0;
1729}
1730
1731static int sunxi_nand_chips_init(struct device *dev, struct sunxi_nfc *nfc)
1732{
1733 struct device_node *np = dev->of_node;
1734 struct device_node *nand_np;
1735 int nchips = of_get_child_count(np);
1736 int ret;
1737
1738 if (nchips > 8) {
1739 dev_err(dev, "too many NAND chips: %d (max = 8)\n", nchips);
1740 return -EINVAL;
1741 }
1742
1743 for_each_child_of_node(np, nand_np) {
1744 ret = sunxi_nand_chip_init(dev, nfc, nand_np);
Julia Lawalla81c0f02015-11-18 23:04:12 +01001745 if (ret) {
1746 of_node_put(nand_np);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001747 return ret;
Julia Lawalla81c0f02015-11-18 23:04:12 +01001748 }
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001749 }
1750
1751 return 0;
1752}
1753
1754static void sunxi_nand_chips_cleanup(struct sunxi_nfc *nfc)
1755{
1756 struct sunxi_nand_chip *chip;
1757
1758 while (!list_empty(&nfc->chips)) {
1759 chip = list_first_entry(&nfc->chips, struct sunxi_nand_chip,
1760 node);
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001761 nand_release(nand_to_mtd(&chip->nand));
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001762 sunxi_nand_ecc_cleanup(&chip->nand.ecc);
Boris BREZILLON8e375cc2015-09-13 18:14:43 +02001763 list_del(&chip->node);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001764 }
1765}
1766
1767static int sunxi_nfc_probe(struct platform_device *pdev)
1768{
1769 struct device *dev = &pdev->dev;
1770 struct resource *r;
1771 struct sunxi_nfc *nfc;
1772 int irq;
1773 int ret;
1774
1775 nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
1776 if (!nfc)
1777 return -ENOMEM;
1778
1779 nfc->dev = dev;
1780 spin_lock_init(&nfc->controller.lock);
1781 init_waitqueue_head(&nfc->controller.wq);
1782 INIT_LIST_HEAD(&nfc->chips);
1783
1784 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1785 nfc->regs = devm_ioremap_resource(dev, r);
1786 if (IS_ERR(nfc->regs))
1787 return PTR_ERR(nfc->regs);
1788
1789 irq = platform_get_irq(pdev, 0);
1790 if (irq < 0) {
1791 dev_err(dev, "failed to retrieve irq\n");
1792 return irq;
1793 }
1794
1795 nfc->ahb_clk = devm_clk_get(dev, "ahb");
1796 if (IS_ERR(nfc->ahb_clk)) {
1797 dev_err(dev, "failed to retrieve ahb clk\n");
1798 return PTR_ERR(nfc->ahb_clk);
1799 }
1800
1801 ret = clk_prepare_enable(nfc->ahb_clk);
1802 if (ret)
1803 return ret;
1804
1805 nfc->mod_clk = devm_clk_get(dev, "mod");
1806 if (IS_ERR(nfc->mod_clk)) {
1807 dev_err(dev, "failed to retrieve mod clk\n");
1808 ret = PTR_ERR(nfc->mod_clk);
1809 goto out_ahb_clk_unprepare;
1810 }
1811
1812 ret = clk_prepare_enable(nfc->mod_clk);
1813 if (ret)
1814 goto out_ahb_clk_unprepare;
1815
1816 ret = sunxi_nfc_rst(nfc);
1817 if (ret)
1818 goto out_mod_clk_unprepare;
1819
1820 writel(0, nfc->regs + NFC_REG_INT);
1821 ret = devm_request_irq(dev, irq, sunxi_nfc_interrupt,
1822 0, "sunxi-nand", nfc);
1823 if (ret)
1824 goto out_mod_clk_unprepare;
1825
1826 platform_set_drvdata(pdev, nfc);
1827
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001828 ret = sunxi_nand_chips_init(dev, nfc);
1829 if (ret) {
1830 dev_err(dev, "failed to init nand chips\n");
1831 goto out_mod_clk_unprepare;
1832 }
1833
1834 return 0;
1835
1836out_mod_clk_unprepare:
1837 clk_disable_unprepare(nfc->mod_clk);
1838out_ahb_clk_unprepare:
1839 clk_disable_unprepare(nfc->ahb_clk);
1840
1841 return ret;
1842}
1843
1844static int sunxi_nfc_remove(struct platform_device *pdev)
1845{
1846 struct sunxi_nfc *nfc = platform_get_drvdata(pdev);
1847
1848 sunxi_nand_chips_cleanup(nfc);
Boris Brezillondd26a452016-03-04 18:26:40 +01001849 clk_disable_unprepare(nfc->mod_clk);
1850 clk_disable_unprepare(nfc->ahb_clk);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001851
1852 return 0;
1853}
1854
1855static const struct of_device_id sunxi_nfc_ids[] = {
1856 { .compatible = "allwinner,sun4i-a10-nand" },
1857 { /* sentinel */ }
1858};
1859MODULE_DEVICE_TABLE(of, sunxi_nfc_ids);
1860
1861static struct platform_driver sunxi_nfc_driver = {
1862 .driver = {
1863 .name = "sunxi_nand",
1864 .of_match_table = sunxi_nfc_ids,
1865 },
1866 .probe = sunxi_nfc_probe,
1867 .remove = sunxi_nfc_remove,
1868};
1869module_platform_driver(sunxi_nfc_driver);
1870
1871MODULE_LICENSE("GPL v2");
1872MODULE_AUTHOR("Boris BREZILLON");
1873MODULE_DESCRIPTION("Allwinner NAND Flash Controller driver");
1874MODULE_ALIAS("platform:sunxi_nand");