blob: f8b3a7281af0aa8d3ff8ca1d5bea5e3e59ca5037 [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);
745 ecc_ctl |= NFC_ECC_EN | NFC_ECC_MODE(data->mode) | NFC_ECC_EXCEPTION;
746
747 writel(ecc_ctl, nfc->regs + NFC_REG_ECC_CTL);
748}
749
750static void sunxi_nfc_hw_ecc_disable(struct mtd_info *mtd)
751{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100752 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLONc9118ec2015-09-30 23:45:23 +0200753 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
754
755 writel(readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_ECC_EN,
756 nfc->regs + NFC_REG_ECC_CTL);
757}
758
Boris BREZILLONf363e0f2015-09-30 23:45:27 +0200759static inline void sunxi_nfc_user_data_to_buf(u32 user_data, u8 *buf)
760{
761 buf[0] = user_data;
762 buf[1] = user_data >> 8;
763 buf[2] = user_data >> 16;
764 buf[3] = user_data >> 24;
765}
766
Boris BREZILLON913821b2015-09-30 23:45:24 +0200767static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd,
768 u8 *data, int data_off,
769 u8 *oob, int oob_off,
770 int *cur_off,
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100771 unsigned int *max_bitflips,
772 bool bbm, int page)
Boris BREZILLON913821b2015-09-30 23:45:24 +0200773{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100774 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200775 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
776 struct nand_ecc_ctrl *ecc = &nand->ecc;
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100777 int raw_mode = 0;
Boris BREZILLON913821b2015-09-30 23:45:24 +0200778 u32 status;
779 int ret;
780
781 if (*cur_off != data_off)
782 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, data_off, -1);
783
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100784 sunxi_nfc_randomizer_read_buf(mtd, NULL, ecc->size, false, page);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200785
Boris BREZILLON74eb9ff2015-10-20 22:16:00 +0200786 if (data_off + ecc->size != oob_off)
Boris BREZILLON913821b2015-09-30 23:45:24 +0200787 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
788
789 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
790 if (ret)
791 return ret;
792
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100793 sunxi_nfc_randomizer_enable(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200794 writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_ECC_OP,
795 nfc->regs + NFC_REG_CMD);
796
797 ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100798 sunxi_nfc_randomizer_disable(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200799 if (ret)
800 return ret;
801
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100802 *cur_off = oob_off + ecc->bytes + 4;
803
Boris BREZILLON913821b2015-09-30 23:45:24 +0200804 status = readl(nfc->regs + NFC_REG_ECC_ST);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100805 if (status & NFC_ECC_PAT_FOUND(0)) {
806 u8 pattern = 0xff;
807
808 if (unlikely(!(readl(nfc->regs + NFC_REG_PAT_ID) & 0x1)))
809 pattern = 0x0;
810
811 memset(data, pattern, ecc->size);
812 memset(oob, pattern, ecc->bytes + 4);
813
814 return 1;
815 }
816
Boris BREZILLON913821b2015-09-30 23:45:24 +0200817 ret = NFC_ECC_ERR_CNT(0, readl(nfc->regs + NFC_REG_ECC_ERR_CNT(0)));
818
819 memcpy_fromio(data, nfc->regs + NFC_RAM0_BASE, ecc->size);
820
821 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100822 sunxi_nfc_randomizer_read_buf(mtd, oob, ecc->bytes + 4, true, page);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200823
Boris BREZILLONf363e0f2015-09-30 23:45:27 +0200824 if (status & NFC_ECC_ERR(0)) {
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100825 /*
826 * Re-read the data with the randomizer disabled to identify
827 * bitflips in erased pages.
828 */
829 if (nand->options & NAND_NEED_SCRAMBLING) {
830 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, data_off, -1);
831 nand->read_buf(mtd, data, ecc->size);
832 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
833 nand->read_buf(mtd, oob, ecc->bytes + 4);
834 }
835
Boris BREZILLON146b5032015-09-30 23:45:29 +0200836 ret = nand_check_erased_ecc_chunk(data, ecc->size,
837 oob, ecc->bytes + 4,
838 NULL, 0, ecc->strength);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100839 if (ret >= 0)
840 raw_mode = 1;
Boris BREZILLONf363e0f2015-09-30 23:45:27 +0200841 } else {
842 /*
843 * The engine protects 4 bytes of OOB data per chunk.
844 * Retrieve the corrected OOB bytes.
845 */
846 sunxi_nfc_user_data_to_buf(readl(nfc->regs + NFC_REG_USER_DATA(0)),
847 oob);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100848
849 /* De-randomize the Bad Block Marker. */
850 if (bbm && nand->options & NAND_NEED_SCRAMBLING)
851 sunxi_nfc_randomize_bbm(mtd, page, oob);
Boris BREZILLONf363e0f2015-09-30 23:45:27 +0200852 }
Boris BREZILLON913821b2015-09-30 23:45:24 +0200853
854 if (ret < 0) {
855 mtd->ecc_stats.failed++;
856 } else {
857 mtd->ecc_stats.corrected += ret;
858 *max_bitflips = max_t(unsigned int, *max_bitflips, ret);
859 }
860
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100861 return raw_mode;
Boris BREZILLON913821b2015-09-30 23:45:24 +0200862}
863
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200864static void sunxi_nfc_hw_ecc_read_extra_oob(struct mtd_info *mtd,
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100865 u8 *oob, int *cur_off,
866 bool randomize, int page)
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200867{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100868 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200869 struct nand_ecc_ctrl *ecc = &nand->ecc;
870 int offset = ((ecc->bytes + 4) * ecc->steps);
871 int len = mtd->oobsize - offset;
872
873 if (len <= 0)
874 return;
875
876 if (*cur_off != offset)
877 nand->cmdfunc(mtd, NAND_CMD_RNDOUT,
878 offset + mtd->writesize, -1);
879
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100880 if (!randomize)
881 sunxi_nfc_read_buf(mtd, oob + offset, len);
882 else
883 sunxi_nfc_randomizer_read_buf(mtd, oob + offset, len,
884 false, page);
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200885
886 *cur_off = mtd->oobsize + mtd->writesize;
887}
888
Boris BREZILLON23151fd2015-09-30 23:45:28 +0200889static inline u32 sunxi_nfc_buf_to_user_data(const u8 *buf)
890{
891 return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
892}
893
Boris BREZILLON913821b2015-09-30 23:45:24 +0200894static int sunxi_nfc_hw_ecc_write_chunk(struct mtd_info *mtd,
895 const u8 *data, int data_off,
896 const u8 *oob, int oob_off,
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100897 int *cur_off, bool bbm,
898 int page)
Boris BREZILLON913821b2015-09-30 23:45:24 +0200899{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100900 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200901 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
902 struct nand_ecc_ctrl *ecc = &nand->ecc;
903 int ret;
904
905 if (data_off != *cur_off)
906 nand->cmdfunc(mtd, NAND_CMD_RNDIN, data_off, -1);
907
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100908 sunxi_nfc_randomizer_write_buf(mtd, data, ecc->size, false, page);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200909
910 /* Fill OOB data in */
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100911 if ((nand->options & NAND_NEED_SCRAMBLING) && bbm) {
912 u8 user_data[4];
913
914 memcpy(user_data, oob, 4);
915 sunxi_nfc_randomize_bbm(mtd, page, user_data);
916 writel(sunxi_nfc_buf_to_user_data(user_data),
917 nfc->regs + NFC_REG_USER_DATA(0));
918 } else {
919 writel(sunxi_nfc_buf_to_user_data(oob),
920 nfc->regs + NFC_REG_USER_DATA(0));
921 }
Boris BREZILLON913821b2015-09-30 23:45:24 +0200922
Boris BREZILLON74eb9ff2015-10-20 22:16:00 +0200923 if (data_off + ecc->size != oob_off)
Boris BREZILLON913821b2015-09-30 23:45:24 +0200924 nand->cmdfunc(mtd, NAND_CMD_RNDIN, oob_off, -1);
925
926 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
927 if (ret)
928 return ret;
929
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100930 sunxi_nfc_randomizer_enable(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200931 writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD |
932 NFC_ACCESS_DIR | NFC_ECC_OP,
933 nfc->regs + NFC_REG_CMD);
934
935 ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100936 sunxi_nfc_randomizer_disable(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200937 if (ret)
938 return ret;
939
940 *cur_off = oob_off + ecc->bytes + 4;
941
942 return 0;
943}
944
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200945static void sunxi_nfc_hw_ecc_write_extra_oob(struct mtd_info *mtd,
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100946 u8 *oob, int *cur_off,
947 int page)
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200948{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100949 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200950 struct nand_ecc_ctrl *ecc = &nand->ecc;
951 int offset = ((ecc->bytes + 4) * ecc->steps);
952 int len = mtd->oobsize - offset;
953
954 if (len <= 0)
955 return;
956
957 if (*cur_off != offset)
958 nand->cmdfunc(mtd, NAND_CMD_RNDIN,
959 offset + mtd->writesize, -1);
960
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100961 sunxi_nfc_randomizer_write_buf(mtd, oob + offset, len, false, page);
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200962
963 *cur_off = mtd->oobsize + mtd->writesize;
964}
965
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200966static int sunxi_nfc_hw_ecc_read_page(struct mtd_info *mtd,
967 struct nand_chip *chip, uint8_t *buf,
968 int oob_required, int page)
969{
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200970 struct nand_ecc_ctrl *ecc = &chip->ecc;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200971 unsigned int max_bitflips = 0;
Boris BREZILLONb4625512015-09-30 23:45:25 +0200972 int ret, i, cur_off = 0;
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100973 bool raw_mode = false;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200974
Boris BREZILLONc9118ec2015-09-30 23:45:23 +0200975 sunxi_nfc_hw_ecc_enable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200976
977 for (i = 0; i < ecc->steps; i++) {
Boris BREZILLONb4625512015-09-30 23:45:25 +0200978 int data_off = i * ecc->size;
979 int oob_off = i * (ecc->bytes + 4);
980 u8 *data = buf + data_off;
981 u8 *oob = chip->oob_poi + oob_off;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200982
Boris BREZILLONb4625512015-09-30 23:45:25 +0200983 ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off, oob,
984 oob_off + mtd->writesize,
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100985 &cur_off, &max_bitflips,
986 !i, page);
987 if (ret < 0)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200988 return ret;
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100989 else if (ret)
990 raw_mode = true;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200991 }
992
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200993 if (oob_required)
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100994 sunxi_nfc_hw_ecc_read_extra_oob(mtd, chip->oob_poi, &cur_off,
995 !raw_mode, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200996
Boris BREZILLONc9118ec2015-09-30 23:45:23 +0200997 sunxi_nfc_hw_ecc_disable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200998
999 return max_bitflips;
1000}
1001
Boris Brezillonfe82cce2015-09-16 09:01:45 +02001002static int sunxi_nfc_hw_ecc_read_subpage(struct mtd_info *mtd,
1003 struct nand_chip *chip,
1004 u32 data_offs, u32 readlen,
1005 u8 *bufpoi, int page)
1006{
1007 struct nand_ecc_ctrl *ecc = &chip->ecc;
1008 int ret, i, cur_off = 0;
1009 unsigned int max_bitflips = 0;
1010
1011 sunxi_nfc_hw_ecc_enable(mtd);
1012
1013 chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
1014 for (i = data_offs / ecc->size;
1015 i < DIV_ROUND_UP(data_offs + readlen, ecc->size); i++) {
1016 int data_off = i * ecc->size;
1017 int oob_off = i * (ecc->bytes + 4);
1018 u8 *data = bufpoi + data_off;
1019 u8 *oob = chip->oob_poi + oob_off;
1020
1021 ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off,
1022 oob,
1023 oob_off + mtd->writesize,
1024 &cur_off, &max_bitflips,
1025 !i, page);
1026 if (ret < 0)
1027 return ret;
1028 }
1029
1030 sunxi_nfc_hw_ecc_disable(mtd);
1031
1032 return max_bitflips;
1033}
1034
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001035static int sunxi_nfc_hw_ecc_write_page(struct mtd_info *mtd,
1036 struct nand_chip *chip,
Boris BREZILLON45aaeff2015-10-13 11:22:18 +02001037 const uint8_t *buf, int oob_required,
1038 int page)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001039{
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001040 struct nand_ecc_ctrl *ecc = &chip->ecc;
Boris BREZILLONb4625512015-09-30 23:45:25 +02001041 int ret, i, cur_off = 0;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001042
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001043 sunxi_nfc_hw_ecc_enable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001044
1045 for (i = 0; i < ecc->steps; i++) {
Boris BREZILLONb4625512015-09-30 23:45:25 +02001046 int data_off = i * ecc->size;
1047 int oob_off = i * (ecc->bytes + 4);
1048 const u8 *data = buf + data_off;
1049 const u8 *oob = chip->oob_poi + oob_off;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001050
Boris BREZILLONb4625512015-09-30 23:45:25 +02001051 ret = sunxi_nfc_hw_ecc_write_chunk(mtd, data, data_off, oob,
1052 oob_off + mtd->writesize,
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001053 &cur_off, !i, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001054 if (ret)
1055 return ret;
1056 }
1057
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001058 if (oob_required || (chip->options & NAND_NEED_SCRAMBLING))
1059 sunxi_nfc_hw_ecc_write_extra_oob(mtd, chip->oob_poi,
1060 &cur_off, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001061
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001062 sunxi_nfc_hw_ecc_disable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001063
1064 return 0;
1065}
1066
1067static int sunxi_nfc_hw_syndrome_ecc_read_page(struct mtd_info *mtd,
1068 struct nand_chip *chip,
1069 uint8_t *buf, int oob_required,
1070 int page)
1071{
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001072 struct nand_ecc_ctrl *ecc = &chip->ecc;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001073 unsigned int max_bitflips = 0;
Boris BREZILLONb4625512015-09-30 23:45:25 +02001074 int ret, i, cur_off = 0;
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001075 bool raw_mode = false;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001076
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001077 sunxi_nfc_hw_ecc_enable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001078
1079 for (i = 0; i < ecc->steps; i++) {
Boris BREZILLONb4625512015-09-30 23:45:25 +02001080 int data_off = i * (ecc->size + ecc->bytes + 4);
1081 int oob_off = data_off + ecc->size;
1082 u8 *data = buf + (i * ecc->size);
1083 u8 *oob = chip->oob_poi + (i * (ecc->bytes + 4));
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001084
Boris BREZILLONb4625512015-09-30 23:45:25 +02001085 ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off, oob,
1086 oob_off, &cur_off,
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001087 &max_bitflips, !i, page);
1088 if (ret < 0)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001089 return ret;
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001090 else if (ret)
1091 raw_mode = true;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001092 }
1093
Boris BREZILLON35d0e242015-09-30 23:45:26 +02001094 if (oob_required)
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001095 sunxi_nfc_hw_ecc_read_extra_oob(mtd, chip->oob_poi, &cur_off,
1096 !raw_mode, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001097
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001098 sunxi_nfc_hw_ecc_disable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001099
1100 return max_bitflips;
1101}
1102
1103static int sunxi_nfc_hw_syndrome_ecc_write_page(struct mtd_info *mtd,
1104 struct nand_chip *chip,
1105 const uint8_t *buf,
Boris BREZILLON45aaeff2015-10-13 11:22:18 +02001106 int oob_required, int page)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001107{
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001108 struct nand_ecc_ctrl *ecc = &chip->ecc;
Boris BREZILLONb4625512015-09-30 23:45:25 +02001109 int ret, i, cur_off = 0;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001110
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001111 sunxi_nfc_hw_ecc_enable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001112
1113 for (i = 0; i < ecc->steps; i++) {
Boris BREZILLONb4625512015-09-30 23:45:25 +02001114 int data_off = i * (ecc->size + ecc->bytes + 4);
1115 int oob_off = data_off + ecc->size;
1116 const u8 *data = buf + (i * ecc->size);
1117 const u8 *oob = chip->oob_poi + (i * (ecc->bytes + 4));
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001118
Boris BREZILLONb4625512015-09-30 23:45:25 +02001119 ret = sunxi_nfc_hw_ecc_write_chunk(mtd, data, data_off,
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001120 oob, oob_off, &cur_off,
1121 false, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001122 if (ret)
1123 return ret;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001124 }
1125
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001126 if (oob_required || (chip->options & NAND_NEED_SCRAMBLING))
1127 sunxi_nfc_hw_ecc_write_extra_oob(mtd, chip->oob_poi,
1128 &cur_off, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001129
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001130 sunxi_nfc_hw_ecc_disable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001131
1132 return 0;
1133}
1134
Boris Brezillon1c1bdd62015-09-02 15:05:52 +02001135static int sunxi_nfc_hw_common_ecc_read_oob(struct mtd_info *mtd,
1136 struct nand_chip *chip,
1137 int page)
1138{
1139 chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
1140
1141 chip->pagebuf = -1;
1142
1143 return chip->ecc.read_page(mtd, chip, chip->buffers->databuf, 1, page);
1144}
1145
1146static int sunxi_nfc_hw_common_ecc_write_oob(struct mtd_info *mtd,
1147 struct nand_chip *chip,
1148 int page)
1149{
1150 int ret, status;
1151
1152 chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0, page);
1153
1154 chip->pagebuf = -1;
1155
1156 memset(chip->buffers->databuf, 0xff, mtd->writesize);
1157 ret = chip->ecc.write_page(mtd, chip, chip->buffers->databuf, 1, page);
1158 if (ret)
1159 return ret;
1160
1161 /* Send command to program the OOB data */
1162 chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
1163
1164 status = chip->waitfunc(mtd, chip);
1165
1166 return status & NAND_STATUS_FAIL ? -EIO : 0;
1167}
1168
Roy Spliet9c618292015-06-26 11:00:10 +02001169static const s32 tWB_lut[] = {6, 12, 16, 20};
1170static const s32 tRHW_lut[] = {4, 8, 12, 20};
1171
1172static int _sunxi_nand_lookup_timing(const s32 *lut, int lut_size, u32 duration,
1173 u32 clk_period)
1174{
1175 u32 clk_cycles = DIV_ROUND_UP(duration, clk_period);
1176 int i;
1177
1178 for (i = 0; i < lut_size; i++) {
1179 if (clk_cycles <= lut[i])
1180 return i;
1181 }
1182
1183 /* Doesn't fit */
1184 return -EINVAL;
1185}
1186
1187#define sunxi_nand_lookup_timing(l, p, c) \
1188 _sunxi_nand_lookup_timing(l, ARRAY_SIZE(l), p, c)
1189
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001190static int sunxi_nand_chip_set_timings(struct sunxi_nand_chip *chip,
1191 const struct nand_sdr_timings *timings)
1192{
Roy Spliet9c618292015-06-26 11:00:10 +02001193 struct sunxi_nfc *nfc = to_sunxi_nfc(chip->nand.controller);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001194 u32 min_clk_period = 0;
Roy Spliet9c618292015-06-26 11:00:10 +02001195 s32 tWB, tADL, tWHR, tRHW, tCAD;
Boris Brezillon2d434572015-12-02 15:57:20 +01001196 long real_clk_rate;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001197
1198 /* T1 <=> tCLS */
1199 if (timings->tCLS_min > min_clk_period)
1200 min_clk_period = timings->tCLS_min;
1201
1202 /* T2 <=> tCLH */
1203 if (timings->tCLH_min > min_clk_period)
1204 min_clk_period = timings->tCLH_min;
1205
1206 /* T3 <=> tCS */
1207 if (timings->tCS_min > min_clk_period)
1208 min_clk_period = timings->tCS_min;
1209
1210 /* T4 <=> tCH */
1211 if (timings->tCH_min > min_clk_period)
1212 min_clk_period = timings->tCH_min;
1213
1214 /* T5 <=> tWP */
1215 if (timings->tWP_min > min_clk_period)
1216 min_clk_period = timings->tWP_min;
1217
1218 /* T6 <=> tWH */
1219 if (timings->tWH_min > min_clk_period)
1220 min_clk_period = timings->tWH_min;
1221
1222 /* T7 <=> tALS */
1223 if (timings->tALS_min > min_clk_period)
1224 min_clk_period = timings->tALS_min;
1225
1226 /* T8 <=> tDS */
1227 if (timings->tDS_min > min_clk_period)
1228 min_clk_period = timings->tDS_min;
1229
1230 /* T9 <=> tDH */
1231 if (timings->tDH_min > min_clk_period)
1232 min_clk_period = timings->tDH_min;
1233
1234 /* T10 <=> tRR */
1235 if (timings->tRR_min > (min_clk_period * 3))
1236 min_clk_period = DIV_ROUND_UP(timings->tRR_min, 3);
1237
1238 /* T11 <=> tALH */
1239 if (timings->tALH_min > min_clk_period)
1240 min_clk_period = timings->tALH_min;
1241
1242 /* T12 <=> tRP */
1243 if (timings->tRP_min > min_clk_period)
1244 min_clk_period = timings->tRP_min;
1245
1246 /* T13 <=> tREH */
1247 if (timings->tREH_min > min_clk_period)
1248 min_clk_period = timings->tREH_min;
1249
1250 /* T14 <=> tRC */
1251 if (timings->tRC_min > (min_clk_period * 2))
1252 min_clk_period = DIV_ROUND_UP(timings->tRC_min, 2);
1253
1254 /* T15 <=> tWC */
1255 if (timings->tWC_min > (min_clk_period * 2))
1256 min_clk_period = DIV_ROUND_UP(timings->tWC_min, 2);
1257
Roy Spliet9c618292015-06-26 11:00:10 +02001258 /* T16 - T19 + tCAD */
Boris Brezillon5abcd952015-11-11 22:30:30 +01001259 if (timings->tWB_max > (min_clk_period * 20))
1260 min_clk_period = DIV_ROUND_UP(timings->tWB_max, 20);
1261
1262 if (timings->tADL_min > (min_clk_period * 32))
1263 min_clk_period = DIV_ROUND_UP(timings->tADL_min, 32);
1264
1265 if (timings->tWHR_min > (min_clk_period * 32))
1266 min_clk_period = DIV_ROUND_UP(timings->tWHR_min, 32);
1267
1268 if (timings->tRHW_min > (min_clk_period * 20))
1269 min_clk_period = DIV_ROUND_UP(timings->tRHW_min, 20);
1270
Roy Spliet9c618292015-06-26 11:00:10 +02001271 tWB = sunxi_nand_lookup_timing(tWB_lut, timings->tWB_max,
1272 min_clk_period);
1273 if (tWB < 0) {
1274 dev_err(nfc->dev, "unsupported tWB\n");
1275 return tWB;
1276 }
1277
1278 tADL = DIV_ROUND_UP(timings->tADL_min, min_clk_period) >> 3;
1279 if (tADL > 3) {
1280 dev_err(nfc->dev, "unsupported tADL\n");
1281 return -EINVAL;
1282 }
1283
1284 tWHR = DIV_ROUND_UP(timings->tWHR_min, min_clk_period) >> 3;
1285 if (tWHR > 3) {
1286 dev_err(nfc->dev, "unsupported tWHR\n");
1287 return -EINVAL;
1288 }
1289
1290 tRHW = sunxi_nand_lookup_timing(tRHW_lut, timings->tRHW_min,
1291 min_clk_period);
1292 if (tRHW < 0) {
1293 dev_err(nfc->dev, "unsupported tRHW\n");
1294 return tRHW;
1295 }
1296
1297 /*
1298 * TODO: according to ONFI specs this value only applies for DDR NAND,
1299 * but Allwinner seems to set this to 0x7. Mimic them for now.
1300 */
1301 tCAD = 0x7;
1302
1303 /* TODO: A83 has some more bits for CDQSS, CS, CLHZ, CCS, WC */
1304 chip->timing_cfg = NFC_TIMING_CFG(tWB, tADL, tWHR, tRHW, tCAD);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001305
1306 /* Convert min_clk_period from picoseconds to nanoseconds */
1307 min_clk_period = DIV_ROUND_UP(min_clk_period, 1000);
1308
1309 /*
Boris Brezillon2f9992e2015-12-02 15:10:40 +01001310 * Unlike what is stated in Allwinner datasheet, the clk_rate should
1311 * be set to (1 / min_clk_period), and not (2 / min_clk_period).
1312 * This new formula was verified with a scope and validated by
1313 * Allwinner engineers.
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001314 */
Boris Brezillon2f9992e2015-12-02 15:10:40 +01001315 chip->clk_rate = NSEC_PER_SEC / min_clk_period;
Boris Brezillon2d434572015-12-02 15:57:20 +01001316 real_clk_rate = clk_round_rate(nfc->mod_clk, chip->clk_rate);
1317
1318 /*
1319 * ONFI specification 3.1, paragraph 4.15.2 dictates that EDO data
1320 * output cycle timings shall be used if the host drives tRC less than
1321 * 30 ns.
1322 */
1323 min_clk_period = NSEC_PER_SEC / real_clk_rate;
1324 chip->timing_ctl = ((min_clk_period * 2) < 30) ?
1325 NFC_TIMING_CTL_EDO : 0;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001326
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001327 return 0;
1328}
1329
1330static int sunxi_nand_chip_init_timings(struct sunxi_nand_chip *chip,
1331 struct device_node *np)
1332{
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001333 struct mtd_info *mtd = nand_to_mtd(&chip->nand);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001334 const struct nand_sdr_timings *timings;
1335 int ret;
1336 int mode;
1337
1338 mode = onfi_get_async_timing_mode(&chip->nand);
1339 if (mode == ONFI_TIMING_MODE_UNKNOWN) {
1340 mode = chip->nand.onfi_timing_mode_default;
1341 } else {
1342 uint8_t feature[ONFI_SUBFEATURE_PARAM_LEN] = {};
Stefan Roese7eadd47f2015-08-28 14:45:21 +02001343 int i;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001344
1345 mode = fls(mode) - 1;
1346 if (mode < 0)
1347 mode = 0;
1348
1349 feature[0] = mode;
Stefan Roese7eadd47f2015-08-28 14:45:21 +02001350 for (i = 0; i < chip->nsels; i++) {
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001351 chip->nand.select_chip(mtd, i);
1352 ret = chip->nand.onfi_set_features(mtd, &chip->nand,
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001353 ONFI_FEATURE_ADDR_TIMING_MODE,
1354 feature);
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001355 chip->nand.select_chip(mtd, -1);
Stefan Roese7eadd47f2015-08-28 14:45:21 +02001356 if (ret)
1357 return ret;
1358 }
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001359 }
1360
1361 timings = onfi_async_timing_mode_to_sdr_timings(mode);
1362 if (IS_ERR(timings))
1363 return PTR_ERR(timings);
1364
1365 return sunxi_nand_chip_set_timings(chip, timings);
1366}
1367
1368static int sunxi_nand_hw_common_ecc_ctrl_init(struct mtd_info *mtd,
1369 struct nand_ecc_ctrl *ecc,
1370 struct device_node *np)
1371{
1372 static const u8 strengths[] = { 16, 24, 28, 32, 40, 48, 56, 60, 64 };
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +01001373 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001374 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
1375 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
1376 struct sunxi_nand_hw_ecc *data;
1377 struct nand_ecclayout *layout;
1378 int nsectors;
1379 int ret;
1380 int i;
1381
1382 data = kzalloc(sizeof(*data), GFP_KERNEL);
1383 if (!data)
1384 return -ENOMEM;
1385
1386 /* Add ECC info retrieval from DT */
1387 for (i = 0; i < ARRAY_SIZE(strengths); i++) {
1388 if (ecc->strength <= strengths[i])
1389 break;
1390 }
1391
1392 if (i >= ARRAY_SIZE(strengths)) {
1393 dev_err(nfc->dev, "unsupported strength\n");
1394 ret = -ENOTSUPP;
1395 goto err;
1396 }
1397
1398 data->mode = i;
1399
1400 /* HW ECC always request ECC bytes for 1024 bytes blocks */
1401 ecc->bytes = DIV_ROUND_UP(ecc->strength * fls(8 * 1024), 8);
1402
1403 /* HW ECC always work with even numbers of ECC bytes */
1404 ecc->bytes = ALIGN(ecc->bytes, 2);
1405
1406 layout = &data->layout;
1407 nsectors = mtd->writesize / ecc->size;
1408
1409 if (mtd->oobsize < ((ecc->bytes + 4) * nsectors)) {
1410 ret = -EINVAL;
1411 goto err;
1412 }
1413
1414 layout->eccbytes = (ecc->bytes * nsectors);
1415
Boris Brezillon1c1bdd62015-09-02 15:05:52 +02001416 ecc->read_oob = sunxi_nfc_hw_common_ecc_read_oob;
1417 ecc->write_oob = sunxi_nfc_hw_common_ecc_write_oob;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001418 ecc->layout = layout;
1419 ecc->priv = data;
1420
1421 return 0;
1422
1423err:
1424 kfree(data);
1425
1426 return ret;
1427}
1428
1429static void sunxi_nand_hw_common_ecc_ctrl_cleanup(struct nand_ecc_ctrl *ecc)
1430{
1431 kfree(ecc->priv);
1432}
1433
1434static int sunxi_nand_hw_ecc_ctrl_init(struct mtd_info *mtd,
1435 struct nand_ecc_ctrl *ecc,
1436 struct device_node *np)
1437{
1438 struct nand_ecclayout *layout;
1439 int nsectors;
1440 int i, j;
1441 int ret;
1442
1443 ret = sunxi_nand_hw_common_ecc_ctrl_init(mtd, ecc, np);
1444 if (ret)
1445 return ret;
1446
1447 ecc->read_page = sunxi_nfc_hw_ecc_read_page;
1448 ecc->write_page = sunxi_nfc_hw_ecc_write_page;
Boris Brezillon1c1bdd62015-09-02 15:05:52 +02001449 ecc->read_oob_raw = nand_read_oob_std;
1450 ecc->write_oob_raw = nand_write_oob_std;
Boris Brezillonfe82cce2015-09-16 09:01:45 +02001451 ecc->read_subpage = sunxi_nfc_hw_ecc_read_subpage;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001452 layout = ecc->layout;
1453 nsectors = mtd->writesize / ecc->size;
1454
1455 for (i = 0; i < nsectors; i++) {
1456 if (i) {
1457 layout->oobfree[i].offset =
1458 layout->oobfree[i - 1].offset +
1459 layout->oobfree[i - 1].length +
1460 ecc->bytes;
1461 layout->oobfree[i].length = 4;
1462 } else {
1463 /*
1464 * The first 2 bytes are used for BB markers, hence we
1465 * only have 2 bytes available in the first user data
1466 * section.
1467 */
1468 layout->oobfree[i].length = 2;
1469 layout->oobfree[i].offset = 2;
1470 }
1471
1472 for (j = 0; j < ecc->bytes; j++)
1473 layout->eccpos[(ecc->bytes * i) + j] =
1474 layout->oobfree[i].offset +
1475 layout->oobfree[i].length + j;
1476 }
1477
1478 if (mtd->oobsize > (ecc->bytes + 4) * nsectors) {
1479 layout->oobfree[nsectors].offset =
1480 layout->oobfree[nsectors - 1].offset +
1481 layout->oobfree[nsectors - 1].length +
1482 ecc->bytes;
1483 layout->oobfree[nsectors].length = mtd->oobsize -
1484 ((ecc->bytes + 4) * nsectors);
1485 }
1486
1487 return 0;
1488}
1489
1490static int sunxi_nand_hw_syndrome_ecc_ctrl_init(struct mtd_info *mtd,
1491 struct nand_ecc_ctrl *ecc,
1492 struct device_node *np)
1493{
1494 struct nand_ecclayout *layout;
1495 int nsectors;
1496 int i;
1497 int ret;
1498
1499 ret = sunxi_nand_hw_common_ecc_ctrl_init(mtd, ecc, np);
1500 if (ret)
1501 return ret;
1502
1503 ecc->prepad = 4;
1504 ecc->read_page = sunxi_nfc_hw_syndrome_ecc_read_page;
1505 ecc->write_page = sunxi_nfc_hw_syndrome_ecc_write_page;
Boris Brezillon1c1bdd62015-09-02 15:05:52 +02001506 ecc->read_oob_raw = nand_read_oob_syndrome;
1507 ecc->write_oob_raw = nand_write_oob_syndrome;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001508
1509 layout = ecc->layout;
1510 nsectors = mtd->writesize / ecc->size;
1511
1512 for (i = 0; i < (ecc->bytes * nsectors); i++)
1513 layout->eccpos[i] = i;
1514
1515 layout->oobfree[0].length = mtd->oobsize - i;
1516 layout->oobfree[0].offset = i;
1517
1518 return 0;
1519}
1520
1521static void sunxi_nand_ecc_cleanup(struct nand_ecc_ctrl *ecc)
1522{
1523 switch (ecc->mode) {
1524 case NAND_ECC_HW:
1525 case NAND_ECC_HW_SYNDROME:
1526 sunxi_nand_hw_common_ecc_ctrl_cleanup(ecc);
1527 break;
1528 case NAND_ECC_NONE:
1529 kfree(ecc->layout);
1530 default:
1531 break;
1532 }
1533}
1534
1535static int sunxi_nand_ecc_init(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc,
1536 struct device_node *np)
1537{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +01001538 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001539 int ret;
1540
Boris BREZILLONa3d22a52015-09-02 10:30:25 +02001541 if (!ecc->size) {
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001542 ecc->size = nand->ecc_step_ds;
1543 ecc->strength = nand->ecc_strength_ds;
1544 }
1545
1546 if (!ecc->size || !ecc->strength)
1547 return -EINVAL;
1548
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001549 switch (ecc->mode) {
1550 case NAND_ECC_SOFT_BCH:
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001551 break;
1552 case NAND_ECC_HW:
1553 ret = sunxi_nand_hw_ecc_ctrl_init(mtd, ecc, np);
1554 if (ret)
1555 return ret;
1556 break;
1557 case NAND_ECC_HW_SYNDROME:
1558 ret = sunxi_nand_hw_syndrome_ecc_ctrl_init(mtd, ecc, np);
1559 if (ret)
1560 return ret;
1561 break;
1562 case NAND_ECC_NONE:
1563 ecc->layout = kzalloc(sizeof(*ecc->layout), GFP_KERNEL);
1564 if (!ecc->layout)
1565 return -ENOMEM;
1566 ecc->layout->oobfree[0].length = mtd->oobsize;
1567 case NAND_ECC_SOFT:
1568 break;
1569 default:
1570 return -EINVAL;
1571 }
1572
1573 return 0;
1574}
1575
1576static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc,
1577 struct device_node *np)
1578{
1579 const struct nand_sdr_timings *timings;
1580 struct sunxi_nand_chip *chip;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001581 struct mtd_info *mtd;
1582 struct nand_chip *nand;
1583 int nsels;
1584 int ret;
1585 int i;
1586 u32 tmp;
1587
1588 if (!of_get_property(np, "reg", &nsels))
1589 return -EINVAL;
1590
1591 nsels /= sizeof(u32);
1592 if (!nsels) {
1593 dev_err(dev, "invalid reg property size\n");
1594 return -EINVAL;
1595 }
1596
1597 chip = devm_kzalloc(dev,
1598 sizeof(*chip) +
1599 (nsels * sizeof(struct sunxi_nand_chip_sel)),
1600 GFP_KERNEL);
1601 if (!chip) {
1602 dev_err(dev, "could not allocate chip\n");
1603 return -ENOMEM;
1604 }
1605
1606 chip->nsels = nsels;
1607 chip->selected = -1;
1608
1609 for (i = 0; i < nsels; i++) {
1610 ret = of_property_read_u32_index(np, "reg", i, &tmp);
1611 if (ret) {
1612 dev_err(dev, "could not retrieve reg property: %d\n",
1613 ret);
1614 return ret;
1615 }
1616
1617 if (tmp > NFC_MAX_CS) {
1618 dev_err(dev,
1619 "invalid reg value: %u (max CS = 7)\n",
1620 tmp);
1621 return -EINVAL;
1622 }
1623
1624 if (test_and_set_bit(tmp, &nfc->assigned_cs)) {
1625 dev_err(dev, "CS %d already assigned\n", tmp);
1626 return -EINVAL;
1627 }
1628
1629 chip->sels[i].cs = tmp;
1630
1631 if (!of_property_read_u32_index(np, "allwinner,rb", i, &tmp) &&
1632 tmp < 2) {
1633 chip->sels[i].rb.type = RB_NATIVE;
1634 chip->sels[i].rb.info.nativeid = tmp;
1635 } else {
1636 ret = of_get_named_gpio(np, "rb-gpios", i);
1637 if (ret >= 0) {
1638 tmp = ret;
1639 chip->sels[i].rb.type = RB_GPIO;
1640 chip->sels[i].rb.info.gpio = tmp;
1641 ret = devm_gpio_request(dev, tmp, "nand-rb");
1642 if (ret)
1643 return ret;
1644
1645 ret = gpio_direction_input(tmp);
1646 if (ret)
1647 return ret;
1648 } else {
1649 chip->sels[i].rb.type = RB_NONE;
1650 }
1651 }
1652 }
1653
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001654 nand = &chip->nand;
1655 /* Default tR value specified in the ONFI spec (chapter 4.15.1) */
1656 nand->chip_delay = 200;
1657 nand->controller = &nfc->controller;
Boris BREZILLONa3d22a52015-09-02 10:30:25 +02001658 /*
1659 * Set the ECC mode to the default value in case nothing is specified
1660 * in the DT.
1661 */
1662 nand->ecc.mode = NAND_ECC_HW;
Brian Norris63752192015-10-30 20:33:23 -07001663 nand_set_flash_node(nand, np);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001664 nand->select_chip = sunxi_nfc_select_chip;
1665 nand->cmd_ctrl = sunxi_nfc_cmd_ctrl;
1666 nand->read_buf = sunxi_nfc_read_buf;
1667 nand->write_buf = sunxi_nfc_write_buf;
1668 nand->read_byte = sunxi_nfc_read_byte;
1669
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001670 mtd = nand_to_mtd(nand);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001671 mtd->dev.parent = dev;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001672
Boris Brezillon9edb4702015-12-02 16:00:57 +01001673 timings = onfi_async_timing_mode_to_sdr_timings(0);
1674 if (IS_ERR(timings)) {
1675 ret = PTR_ERR(timings);
1676 dev_err(dev,
1677 "could not retrieve timings for ONFI mode 0: %d\n",
1678 ret);
1679 return ret;
1680 }
1681
1682 ret = sunxi_nand_chip_set_timings(chip, timings);
1683 if (ret) {
1684 dev_err(dev, "could not configure chip timings: %d\n", ret);
1685 return ret;
1686 }
1687
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001688 ret = nand_scan_ident(mtd, nsels, NULL);
1689 if (ret)
1690 return ret;
1691
Boris BREZILLONa3d22a52015-09-02 10:30:25 +02001692 if (nand->bbt_options & NAND_BBT_USE_FLASH)
1693 nand->bbt_options |= NAND_BBT_NO_OOB;
1694
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001695 if (nand->options & NAND_NEED_SCRAMBLING)
1696 nand->options |= NAND_NO_SUBPAGE_WRITE;
1697
Boris Brezillonfe82cce2015-09-16 09:01:45 +02001698 nand->options |= NAND_SUBPAGE_READ;
1699
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001700 ret = sunxi_nand_chip_init_timings(chip, np);
1701 if (ret) {
1702 dev_err(dev, "could not configure chip timings: %d\n", ret);
1703 return ret;
1704 }
1705
1706 ret = sunxi_nand_ecc_init(mtd, &nand->ecc, np);
1707 if (ret) {
1708 dev_err(dev, "ECC init failed: %d\n", ret);
1709 return ret;
1710 }
1711
1712 ret = nand_scan_tail(mtd);
1713 if (ret) {
1714 dev_err(dev, "nand_scan_tail failed: %d\n", ret);
1715 return ret;
1716 }
1717
Brian Norrisa61ae812015-10-30 20:33:25 -07001718 ret = mtd_device_register(mtd, NULL, 0);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001719 if (ret) {
1720 dev_err(dev, "failed to register mtd device: %d\n", ret);
1721 nand_release(mtd);
1722 return ret;
1723 }
1724
1725 list_add_tail(&chip->node, &nfc->chips);
1726
1727 return 0;
1728}
1729
1730static int sunxi_nand_chips_init(struct device *dev, struct sunxi_nfc *nfc)
1731{
1732 struct device_node *np = dev->of_node;
1733 struct device_node *nand_np;
1734 int nchips = of_get_child_count(np);
1735 int ret;
1736
1737 if (nchips > 8) {
1738 dev_err(dev, "too many NAND chips: %d (max = 8)\n", nchips);
1739 return -EINVAL;
1740 }
1741
1742 for_each_child_of_node(np, nand_np) {
1743 ret = sunxi_nand_chip_init(dev, nfc, nand_np);
Julia Lawalla81c0f02015-11-18 23:04:12 +01001744 if (ret) {
1745 of_node_put(nand_np);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001746 return ret;
Julia Lawalla81c0f02015-11-18 23:04:12 +01001747 }
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001748 }
1749
1750 return 0;
1751}
1752
1753static void sunxi_nand_chips_cleanup(struct sunxi_nfc *nfc)
1754{
1755 struct sunxi_nand_chip *chip;
1756
1757 while (!list_empty(&nfc->chips)) {
1758 chip = list_first_entry(&nfc->chips, struct sunxi_nand_chip,
1759 node);
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001760 nand_release(nand_to_mtd(&chip->nand));
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001761 sunxi_nand_ecc_cleanup(&chip->nand.ecc);
Boris BREZILLON8e375cc2015-09-13 18:14:43 +02001762 list_del(&chip->node);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001763 }
1764}
1765
1766static int sunxi_nfc_probe(struct platform_device *pdev)
1767{
1768 struct device *dev = &pdev->dev;
1769 struct resource *r;
1770 struct sunxi_nfc *nfc;
1771 int irq;
1772 int ret;
1773
1774 nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
1775 if (!nfc)
1776 return -ENOMEM;
1777
1778 nfc->dev = dev;
1779 spin_lock_init(&nfc->controller.lock);
1780 init_waitqueue_head(&nfc->controller.wq);
1781 INIT_LIST_HEAD(&nfc->chips);
1782
1783 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1784 nfc->regs = devm_ioremap_resource(dev, r);
1785 if (IS_ERR(nfc->regs))
1786 return PTR_ERR(nfc->regs);
1787
1788 irq = platform_get_irq(pdev, 0);
1789 if (irq < 0) {
1790 dev_err(dev, "failed to retrieve irq\n");
1791 return irq;
1792 }
1793
1794 nfc->ahb_clk = devm_clk_get(dev, "ahb");
1795 if (IS_ERR(nfc->ahb_clk)) {
1796 dev_err(dev, "failed to retrieve ahb clk\n");
1797 return PTR_ERR(nfc->ahb_clk);
1798 }
1799
1800 ret = clk_prepare_enable(nfc->ahb_clk);
1801 if (ret)
1802 return ret;
1803
1804 nfc->mod_clk = devm_clk_get(dev, "mod");
1805 if (IS_ERR(nfc->mod_clk)) {
1806 dev_err(dev, "failed to retrieve mod clk\n");
1807 ret = PTR_ERR(nfc->mod_clk);
1808 goto out_ahb_clk_unprepare;
1809 }
1810
1811 ret = clk_prepare_enable(nfc->mod_clk);
1812 if (ret)
1813 goto out_ahb_clk_unprepare;
1814
1815 ret = sunxi_nfc_rst(nfc);
1816 if (ret)
1817 goto out_mod_clk_unprepare;
1818
1819 writel(0, nfc->regs + NFC_REG_INT);
1820 ret = devm_request_irq(dev, irq, sunxi_nfc_interrupt,
1821 0, "sunxi-nand", nfc);
1822 if (ret)
1823 goto out_mod_clk_unprepare;
1824
1825 platform_set_drvdata(pdev, nfc);
1826
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001827 ret = sunxi_nand_chips_init(dev, nfc);
1828 if (ret) {
1829 dev_err(dev, "failed to init nand chips\n");
1830 goto out_mod_clk_unprepare;
1831 }
1832
1833 return 0;
1834
1835out_mod_clk_unprepare:
1836 clk_disable_unprepare(nfc->mod_clk);
1837out_ahb_clk_unprepare:
1838 clk_disable_unprepare(nfc->ahb_clk);
1839
1840 return ret;
1841}
1842
1843static int sunxi_nfc_remove(struct platform_device *pdev)
1844{
1845 struct sunxi_nfc *nfc = platform_get_drvdata(pdev);
1846
1847 sunxi_nand_chips_cleanup(nfc);
1848
1849 return 0;
1850}
1851
1852static const struct of_device_id sunxi_nfc_ids[] = {
1853 { .compatible = "allwinner,sun4i-a10-nand" },
1854 { /* sentinel */ }
1855};
1856MODULE_DEVICE_TABLE(of, sunxi_nfc_ids);
1857
1858static struct platform_driver sunxi_nfc_driver = {
1859 .driver = {
1860 .name = "sunxi_nand",
1861 .of_match_table = sunxi_nfc_ids,
1862 },
1863 .probe = sunxi_nfc_probe,
1864 .remove = sunxi_nfc_remove,
1865};
1866module_platform_driver(sunxi_nfc_driver);
1867
1868MODULE_LICENSE("GPL v2");
1869MODULE_AUTHOR("Boris BREZILLON");
1870MODULE_DESCRIPTION("Allwinner NAND Flash Controller driver");
1871MODULE_ALIAS("platform:sunxi_nand");