blob: ab572dd5ad3cb706f2b31e0e2b8869f88767f738 [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)
157#define NFC_ECC_ERR_CNT(b, x) (((x) >> ((b) * 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 |
413 NFC_PAGE_SHIFT(nand->page_shift - 10);
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;
517 u32 tmp;
518
519 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
520 if (ret)
521 return;
522
523 if (ctrl & NAND_CTRL_CHANGE) {
524 tmp = readl(nfc->regs + NFC_REG_CTL);
525 if (ctrl & NAND_NCE)
526 tmp |= NFC_CE_CTL;
527 else
528 tmp &= ~NFC_CE_CTL;
529 writel(tmp, nfc->regs + NFC_REG_CTL);
530 }
531
Boris Brezillone9aa6712015-09-16 09:05:31 +0200532 if (dat == NAND_CMD_NONE && (ctrl & NAND_NCE) &&
533 !(ctrl & (NAND_CLE | NAND_ALE))) {
534 u32 cmd = 0;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200535
Boris Brezillone9aa6712015-09-16 09:05:31 +0200536 if (!sunxi_nand->addr_cycles && !sunxi_nand->cmd_cycles)
537 return;
538
539 if (sunxi_nand->cmd_cycles--)
540 cmd |= NFC_SEND_CMD1 | sunxi_nand->cmd[0];
541
542 if (sunxi_nand->cmd_cycles--) {
543 cmd |= NFC_SEND_CMD2;
544 writel(sunxi_nand->cmd[1],
545 nfc->regs + NFC_REG_RCMD_SET);
546 }
547
548 sunxi_nand->cmd_cycles = 0;
549
550 if (sunxi_nand->addr_cycles) {
551 cmd |= NFC_SEND_ADR |
552 NFC_ADR_NUM(sunxi_nand->addr_cycles);
553 writel(sunxi_nand->addr[0],
554 nfc->regs + NFC_REG_ADDR_LOW);
555 }
556
557 if (sunxi_nand->addr_cycles > 4)
558 writel(sunxi_nand->addr[1],
559 nfc->regs + NFC_REG_ADDR_HIGH);
560
561 writel(cmd, nfc->regs + NFC_REG_CMD);
562 sunxi_nand->addr[0] = 0;
563 sunxi_nand->addr[1] = 0;
564 sunxi_nand->addr_cycles = 0;
565 sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200566 }
567
Boris Brezillone9aa6712015-09-16 09:05:31 +0200568 if (ctrl & NAND_CLE) {
569 sunxi_nand->cmd[sunxi_nand->cmd_cycles++] = dat;
570 } else if (ctrl & NAND_ALE) {
571 sunxi_nand->addr[sunxi_nand->addr_cycles / 4] |=
572 dat << ((sunxi_nand->addr_cycles % 4) * 8);
573 sunxi_nand->addr_cycles++;
574 }
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200575}
576
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100577/* These seed values have been extracted from Allwinner's BSP */
578static const u16 sunxi_nfc_randomizer_page_seeds[] = {
579 0x2b75, 0x0bd0, 0x5ca3, 0x62d1, 0x1c93, 0x07e9, 0x2162, 0x3a72,
580 0x0d67, 0x67f9, 0x1be7, 0x077d, 0x032f, 0x0dac, 0x2716, 0x2436,
581 0x7922, 0x1510, 0x3860, 0x5287, 0x480f, 0x4252, 0x1789, 0x5a2d,
582 0x2a49, 0x5e10, 0x437f, 0x4b4e, 0x2f45, 0x216e, 0x5cb7, 0x7130,
583 0x2a3f, 0x60e4, 0x4dc9, 0x0ef0, 0x0f52, 0x1bb9, 0x6211, 0x7a56,
584 0x226d, 0x4ea7, 0x6f36, 0x3692, 0x38bf, 0x0c62, 0x05eb, 0x4c55,
585 0x60f4, 0x728c, 0x3b6f, 0x2037, 0x7f69, 0x0936, 0x651a, 0x4ceb,
586 0x6218, 0x79f3, 0x383f, 0x18d9, 0x4f05, 0x5c82, 0x2912, 0x6f17,
587 0x6856, 0x5938, 0x1007, 0x61ab, 0x3e7f, 0x57c2, 0x542f, 0x4f62,
588 0x7454, 0x2eac, 0x7739, 0x42d4, 0x2f90, 0x435a, 0x2e52, 0x2064,
589 0x637c, 0x66ad, 0x2c90, 0x0bad, 0x759c, 0x0029, 0x0986, 0x7126,
590 0x1ca7, 0x1605, 0x386a, 0x27f5, 0x1380, 0x6d75, 0x24c3, 0x0f8e,
591 0x2b7a, 0x1418, 0x1fd1, 0x7dc1, 0x2d8e, 0x43af, 0x2267, 0x7da3,
592 0x4e3d, 0x1338, 0x50db, 0x454d, 0x764d, 0x40a3, 0x42e6, 0x262b,
593 0x2d2e, 0x1aea, 0x2e17, 0x173d, 0x3a6e, 0x71bf, 0x25f9, 0x0a5d,
594 0x7c57, 0x0fbe, 0x46ce, 0x4939, 0x6b17, 0x37bb, 0x3e91, 0x76db,
595};
596
597/*
598 * sunxi_nfc_randomizer_ecc512_seeds and sunxi_nfc_randomizer_ecc1024_seeds
599 * have been generated using
600 * sunxi_nfc_randomizer_step(seed, (step_size * 8) + 15), which is what
601 * the randomizer engine does internally before de/scrambling OOB data.
602 *
603 * Those tables are statically defined to avoid calculating randomizer state
604 * at runtime.
605 */
606static const u16 sunxi_nfc_randomizer_ecc512_seeds[] = {
607 0x3346, 0x367f, 0x1f18, 0x769a, 0x4f64, 0x068c, 0x2ef1, 0x6b64,
608 0x28a9, 0x15d7, 0x30f8, 0x3659, 0x53db, 0x7c5f, 0x71d4, 0x4409,
609 0x26eb, 0x03cc, 0x655d, 0x47d4, 0x4daa, 0x0877, 0x712d, 0x3617,
610 0x3264, 0x49aa, 0x7f9e, 0x588e, 0x4fbc, 0x7176, 0x7f91, 0x6c6d,
611 0x4b95, 0x5fb7, 0x3844, 0x4037, 0x0184, 0x081b, 0x0ee8, 0x5b91,
612 0x293d, 0x1f71, 0x0e6f, 0x402b, 0x5122, 0x1e52, 0x22be, 0x3d2d,
613 0x75bc, 0x7c60, 0x6291, 0x1a2f, 0x61d4, 0x74aa, 0x4140, 0x29ab,
614 0x472d, 0x2852, 0x017e, 0x15e8, 0x5ec2, 0x17cf, 0x7d0f, 0x06b8,
615 0x117a, 0x6b94, 0x789b, 0x3126, 0x6ac5, 0x5be7, 0x150f, 0x51f8,
616 0x7889, 0x0aa5, 0x663d, 0x77e8, 0x0b87, 0x3dcb, 0x360d, 0x218b,
617 0x512f, 0x7dc9, 0x6a4d, 0x630a, 0x3547, 0x1dd2, 0x5aea, 0x69a5,
618 0x7bfa, 0x5e4f, 0x1519, 0x6430, 0x3a0e, 0x5eb3, 0x5425, 0x0c7a,
619 0x5540, 0x3670, 0x63c1, 0x31e9, 0x5a39, 0x2de7, 0x5979, 0x2891,
620 0x1562, 0x014b, 0x5b05, 0x2756, 0x5a34, 0x13aa, 0x6cb5, 0x2c36,
621 0x5e72, 0x1306, 0x0861, 0x15ef, 0x1ee8, 0x5a37, 0x7ac4, 0x45dd,
622 0x44c4, 0x7266, 0x2f41, 0x3ccc, 0x045e, 0x7d40, 0x7c66, 0x0fa0,
623};
624
625static const u16 sunxi_nfc_randomizer_ecc1024_seeds[] = {
626 0x2cf5, 0x35f1, 0x63a4, 0x5274, 0x2bd2, 0x778b, 0x7285, 0x32b6,
627 0x6a5c, 0x70d6, 0x757d, 0x6769, 0x5375, 0x1e81, 0x0cf3, 0x3982,
628 0x6787, 0x042a, 0x6c49, 0x1925, 0x56a8, 0x40a9, 0x063e, 0x7bd9,
629 0x4dbf, 0x55ec, 0x672e, 0x7334, 0x5185, 0x4d00, 0x232a, 0x7e07,
630 0x445d, 0x6b92, 0x528f, 0x4255, 0x53ba, 0x7d82, 0x2a2e, 0x3a4e,
631 0x75eb, 0x450c, 0x6844, 0x1b5d, 0x581a, 0x4cc6, 0x0379, 0x37b2,
632 0x419f, 0x0e92, 0x6b27, 0x5624, 0x01e3, 0x07c1, 0x44a5, 0x130c,
633 0x13e8, 0x5910, 0x0876, 0x60c5, 0x54e3, 0x5b7f, 0x2269, 0x509f,
634 0x7665, 0x36fd, 0x3e9a, 0x0579, 0x6295, 0x14ef, 0x0a81, 0x1bcc,
635 0x4b16, 0x64db, 0x0514, 0x4f07, 0x0591, 0x3576, 0x6853, 0x0d9e,
636 0x259f, 0x38b7, 0x64fb, 0x3094, 0x4693, 0x6ddd, 0x29bb, 0x0bc8,
637 0x3f47, 0x490e, 0x0c0e, 0x7933, 0x3c9e, 0x5840, 0x398d, 0x3e68,
638 0x4af1, 0x71f5, 0x57cf, 0x1121, 0x64eb, 0x3579, 0x15ac, 0x584d,
639 0x5f2a, 0x47e2, 0x6528, 0x6eac, 0x196e, 0x6b96, 0x0450, 0x0179,
640 0x609c, 0x06e1, 0x4626, 0x42c7, 0x273e, 0x486f, 0x0705, 0x1601,
641 0x145b, 0x407e, 0x062b, 0x57a5, 0x53f9, 0x5659, 0x4410, 0x3ccd,
642};
643
644static u16 sunxi_nfc_randomizer_step(u16 state, int count)
645{
646 state &= 0x7fff;
647
648 /*
649 * This loop is just a simple implementation of a Fibonacci LFSR using
650 * the x16 + x15 + 1 polynomial.
651 */
652 while (count--)
653 state = ((state >> 1) |
654 (((state ^ (state >> 1)) & 1) << 14)) & 0x7fff;
655
656 return state;
657}
658
659static u16 sunxi_nfc_randomizer_state(struct mtd_info *mtd, int page, bool ecc)
660{
661 const u16 *seeds = sunxi_nfc_randomizer_page_seeds;
Brian Norris46c135c2016-01-22 18:57:13 -0800662 int mod = mtd_div_by_ws(mtd->erasesize, mtd);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100663
664 if (mod > ARRAY_SIZE(sunxi_nfc_randomizer_page_seeds))
665 mod = ARRAY_SIZE(sunxi_nfc_randomizer_page_seeds);
666
667 if (ecc) {
668 if (mtd->ecc_step_size == 512)
669 seeds = sunxi_nfc_randomizer_ecc512_seeds;
670 else
671 seeds = sunxi_nfc_randomizer_ecc1024_seeds;
672 }
673
674 return seeds[page % mod];
675}
676
677static void sunxi_nfc_randomizer_config(struct mtd_info *mtd,
678 int page, bool ecc)
679{
Boris BREZILLONf671a1f2016-03-05 00:21:20 +0100680 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100681 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
682 u32 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL);
683 u16 state;
684
685 if (!(nand->options & NAND_NEED_SCRAMBLING))
686 return;
687
688 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL);
689 state = sunxi_nfc_randomizer_state(mtd, page, ecc);
690 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_RANDOM_SEED_MSK;
691 writel(ecc_ctl | NFC_RANDOM_SEED(state), nfc->regs + NFC_REG_ECC_CTL);
692}
693
694static void sunxi_nfc_randomizer_enable(struct mtd_info *mtd)
695{
Boris BREZILLONf671a1f2016-03-05 00:21:20 +0100696 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100697 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
698
699 if (!(nand->options & NAND_NEED_SCRAMBLING))
700 return;
701
702 writel(readl(nfc->regs + NFC_REG_ECC_CTL) | NFC_RANDOM_EN,
703 nfc->regs + NFC_REG_ECC_CTL);
704}
705
706static void sunxi_nfc_randomizer_disable(struct mtd_info *mtd)
707{
Boris BREZILLONf671a1f2016-03-05 00:21:20 +0100708 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100709 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
710
711 if (!(nand->options & NAND_NEED_SCRAMBLING))
712 return;
713
714 writel(readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_RANDOM_EN,
715 nfc->regs + NFC_REG_ECC_CTL);
716}
717
718static void sunxi_nfc_randomize_bbm(struct mtd_info *mtd, int page, u8 *bbm)
719{
720 u16 state = sunxi_nfc_randomizer_state(mtd, page, true);
721
722 bbm[0] ^= state;
723 bbm[1] ^= sunxi_nfc_randomizer_step(state, 8);
724}
725
726static void sunxi_nfc_randomizer_write_buf(struct mtd_info *mtd,
727 const uint8_t *buf, int len,
728 bool ecc, int page)
729{
730 sunxi_nfc_randomizer_config(mtd, page, ecc);
731 sunxi_nfc_randomizer_enable(mtd);
732 sunxi_nfc_write_buf(mtd, buf, len);
733 sunxi_nfc_randomizer_disable(mtd);
734}
735
736static void sunxi_nfc_randomizer_read_buf(struct mtd_info *mtd, uint8_t *buf,
737 int len, bool ecc, int page)
738{
739 sunxi_nfc_randomizer_config(mtd, page, ecc);
740 sunxi_nfc_randomizer_enable(mtd);
741 sunxi_nfc_read_buf(mtd, buf, len);
742 sunxi_nfc_randomizer_disable(mtd);
743}
744
Boris BREZILLONc9118ec2015-09-30 23:45:23 +0200745static void sunxi_nfc_hw_ecc_enable(struct mtd_info *mtd)
746{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100747 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLONc9118ec2015-09-30 23:45:23 +0200748 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
749 struct sunxi_nand_hw_ecc *data = nand->ecc.priv;
750 u32 ecc_ctl;
751
752 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL);
753 ecc_ctl &= ~(NFC_ECC_MODE_MSK | NFC_ECC_PIPELINE |
754 NFC_ECC_BLOCK_SIZE_MSK);
755 ecc_ctl |= NFC_ECC_EN | NFC_ECC_MODE(data->mode) | NFC_ECC_EXCEPTION;
756
757 writel(ecc_ctl, nfc->regs + NFC_REG_ECC_CTL);
758}
759
760static void sunxi_nfc_hw_ecc_disable(struct mtd_info *mtd)
761{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100762 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLONc9118ec2015-09-30 23:45:23 +0200763 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
764
765 writel(readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_ECC_EN,
766 nfc->regs + NFC_REG_ECC_CTL);
767}
768
Boris BREZILLONf363e0f2015-09-30 23:45:27 +0200769static inline void sunxi_nfc_user_data_to_buf(u32 user_data, u8 *buf)
770{
771 buf[0] = user_data;
772 buf[1] = user_data >> 8;
773 buf[2] = user_data >> 16;
774 buf[3] = user_data >> 24;
775}
776
Boris BREZILLON913821b2015-09-30 23:45:24 +0200777static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd,
778 u8 *data, int data_off,
779 u8 *oob, int oob_off,
780 int *cur_off,
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100781 unsigned int *max_bitflips,
782 bool bbm, int page)
Boris BREZILLON913821b2015-09-30 23:45:24 +0200783{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100784 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200785 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
786 struct nand_ecc_ctrl *ecc = &nand->ecc;
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100787 int raw_mode = 0;
Boris BREZILLON913821b2015-09-30 23:45:24 +0200788 u32 status;
789 int ret;
790
791 if (*cur_off != data_off)
792 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, data_off, -1);
793
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100794 sunxi_nfc_randomizer_read_buf(mtd, NULL, ecc->size, false, page);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200795
Boris BREZILLON74eb9ff2015-10-20 22:16:00 +0200796 if (data_off + ecc->size != oob_off)
Boris BREZILLON913821b2015-09-30 23:45:24 +0200797 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
798
799 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
800 if (ret)
801 return ret;
802
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100803 sunxi_nfc_randomizer_enable(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200804 writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_ECC_OP,
805 nfc->regs + NFC_REG_CMD);
806
807 ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100808 sunxi_nfc_randomizer_disable(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200809 if (ret)
810 return ret;
811
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100812 *cur_off = oob_off + ecc->bytes + 4;
813
Boris BREZILLON913821b2015-09-30 23:45:24 +0200814 status = readl(nfc->regs + NFC_REG_ECC_ST);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100815 if (status & NFC_ECC_PAT_FOUND(0)) {
816 u8 pattern = 0xff;
817
818 if (unlikely(!(readl(nfc->regs + NFC_REG_PAT_ID) & 0x1)))
819 pattern = 0x0;
820
821 memset(data, pattern, ecc->size);
822 memset(oob, pattern, ecc->bytes + 4);
823
824 return 1;
825 }
826
Boris BREZILLON913821b2015-09-30 23:45:24 +0200827 ret = NFC_ECC_ERR_CNT(0, readl(nfc->regs + NFC_REG_ECC_ERR_CNT(0)));
828
829 memcpy_fromio(data, nfc->regs + NFC_RAM0_BASE, ecc->size);
830
831 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100832 sunxi_nfc_randomizer_read_buf(mtd, oob, ecc->bytes + 4, true, page);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200833
Boris BREZILLONf363e0f2015-09-30 23:45:27 +0200834 if (status & NFC_ECC_ERR(0)) {
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100835 /*
836 * Re-read the data with the randomizer disabled to identify
837 * bitflips in erased pages.
838 */
839 if (nand->options & NAND_NEED_SCRAMBLING) {
840 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, data_off, -1);
841 nand->read_buf(mtd, data, ecc->size);
842 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
843 nand->read_buf(mtd, oob, ecc->bytes + 4);
844 }
845
Boris BREZILLON146b5032015-09-30 23:45:29 +0200846 ret = nand_check_erased_ecc_chunk(data, ecc->size,
847 oob, ecc->bytes + 4,
848 NULL, 0, ecc->strength);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100849 if (ret >= 0)
850 raw_mode = 1;
Boris BREZILLONf363e0f2015-09-30 23:45:27 +0200851 } else {
852 /*
853 * The engine protects 4 bytes of OOB data per chunk.
854 * Retrieve the corrected OOB bytes.
855 */
856 sunxi_nfc_user_data_to_buf(readl(nfc->regs + NFC_REG_USER_DATA(0)),
857 oob);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100858
859 /* De-randomize the Bad Block Marker. */
860 if (bbm && nand->options & NAND_NEED_SCRAMBLING)
861 sunxi_nfc_randomize_bbm(mtd, page, oob);
Boris BREZILLONf363e0f2015-09-30 23:45:27 +0200862 }
Boris BREZILLON913821b2015-09-30 23:45:24 +0200863
864 if (ret < 0) {
865 mtd->ecc_stats.failed++;
866 } else {
867 mtd->ecc_stats.corrected += ret;
868 *max_bitflips = max_t(unsigned int, *max_bitflips, ret);
869 }
870
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100871 return raw_mode;
Boris BREZILLON913821b2015-09-30 23:45:24 +0200872}
873
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200874static void sunxi_nfc_hw_ecc_read_extra_oob(struct mtd_info *mtd,
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100875 u8 *oob, int *cur_off,
876 bool randomize, int page)
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200877{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100878 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200879 struct nand_ecc_ctrl *ecc = &nand->ecc;
880 int offset = ((ecc->bytes + 4) * ecc->steps);
881 int len = mtd->oobsize - offset;
882
883 if (len <= 0)
884 return;
885
886 if (*cur_off != offset)
887 nand->cmdfunc(mtd, NAND_CMD_RNDOUT,
888 offset + mtd->writesize, -1);
889
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100890 if (!randomize)
891 sunxi_nfc_read_buf(mtd, oob + offset, len);
892 else
893 sunxi_nfc_randomizer_read_buf(mtd, oob + offset, len,
894 false, page);
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200895
896 *cur_off = mtd->oobsize + mtd->writesize;
897}
898
Boris BREZILLON23151fd2015-09-30 23:45:28 +0200899static inline u32 sunxi_nfc_buf_to_user_data(const u8 *buf)
900{
901 return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
902}
903
Boris BREZILLON913821b2015-09-30 23:45:24 +0200904static int sunxi_nfc_hw_ecc_write_chunk(struct mtd_info *mtd,
905 const u8 *data, int data_off,
906 const u8 *oob, int oob_off,
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100907 int *cur_off, bool bbm,
908 int page)
Boris BREZILLON913821b2015-09-30 23:45:24 +0200909{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100910 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200911 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
912 struct nand_ecc_ctrl *ecc = &nand->ecc;
913 int ret;
914
915 if (data_off != *cur_off)
916 nand->cmdfunc(mtd, NAND_CMD_RNDIN, data_off, -1);
917
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100918 sunxi_nfc_randomizer_write_buf(mtd, data, ecc->size, false, page);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200919
920 /* Fill OOB data in */
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100921 if ((nand->options & NAND_NEED_SCRAMBLING) && bbm) {
922 u8 user_data[4];
923
924 memcpy(user_data, oob, 4);
925 sunxi_nfc_randomize_bbm(mtd, page, user_data);
926 writel(sunxi_nfc_buf_to_user_data(user_data),
927 nfc->regs + NFC_REG_USER_DATA(0));
928 } else {
929 writel(sunxi_nfc_buf_to_user_data(oob),
930 nfc->regs + NFC_REG_USER_DATA(0));
931 }
Boris BREZILLON913821b2015-09-30 23:45:24 +0200932
Boris BREZILLON74eb9ff2015-10-20 22:16:00 +0200933 if (data_off + ecc->size != oob_off)
Boris BREZILLON913821b2015-09-30 23:45:24 +0200934 nand->cmdfunc(mtd, NAND_CMD_RNDIN, oob_off, -1);
935
936 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
937 if (ret)
938 return ret;
939
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100940 sunxi_nfc_randomizer_enable(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200941 writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD |
942 NFC_ACCESS_DIR | NFC_ECC_OP,
943 nfc->regs + NFC_REG_CMD);
944
945 ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100946 sunxi_nfc_randomizer_disable(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200947 if (ret)
948 return ret;
949
950 *cur_off = oob_off + ecc->bytes + 4;
951
952 return 0;
953}
954
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200955static void sunxi_nfc_hw_ecc_write_extra_oob(struct mtd_info *mtd,
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100956 u8 *oob, int *cur_off,
957 int page)
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200958{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100959 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200960 struct nand_ecc_ctrl *ecc = &nand->ecc;
961 int offset = ((ecc->bytes + 4) * ecc->steps);
962 int len = mtd->oobsize - offset;
963
964 if (len <= 0)
965 return;
966
967 if (*cur_off != offset)
968 nand->cmdfunc(mtd, NAND_CMD_RNDIN,
969 offset + mtd->writesize, -1);
970
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100971 sunxi_nfc_randomizer_write_buf(mtd, oob + offset, len, false, page);
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200972
973 *cur_off = mtd->oobsize + mtd->writesize;
974}
975
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200976static int sunxi_nfc_hw_ecc_read_page(struct mtd_info *mtd,
977 struct nand_chip *chip, uint8_t *buf,
978 int oob_required, int page)
979{
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200980 struct nand_ecc_ctrl *ecc = &chip->ecc;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200981 unsigned int max_bitflips = 0;
Boris BREZILLONb4625512015-09-30 23:45:25 +0200982 int ret, i, cur_off = 0;
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100983 bool raw_mode = false;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200984
Boris BREZILLONc9118ec2015-09-30 23:45:23 +0200985 sunxi_nfc_hw_ecc_enable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200986
987 for (i = 0; i < ecc->steps; i++) {
Boris BREZILLONb4625512015-09-30 23:45:25 +0200988 int data_off = i * ecc->size;
989 int oob_off = i * (ecc->bytes + 4);
990 u8 *data = buf + data_off;
991 u8 *oob = chip->oob_poi + oob_off;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200992
Boris BREZILLONb4625512015-09-30 23:45:25 +0200993 ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off, oob,
994 oob_off + mtd->writesize,
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100995 &cur_off, &max_bitflips,
996 !i, page);
997 if (ret < 0)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200998 return ret;
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100999 else if (ret)
1000 raw_mode = true;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001001 }
1002
Boris BREZILLON35d0e242015-09-30 23:45:26 +02001003 if (oob_required)
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001004 sunxi_nfc_hw_ecc_read_extra_oob(mtd, chip->oob_poi, &cur_off,
1005 !raw_mode, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001006
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001007 sunxi_nfc_hw_ecc_disable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001008
1009 return max_bitflips;
1010}
1011
Boris Brezillonfe82cce2015-09-16 09:01:45 +02001012static int sunxi_nfc_hw_ecc_read_subpage(struct mtd_info *mtd,
1013 struct nand_chip *chip,
1014 u32 data_offs, u32 readlen,
1015 u8 *bufpoi, int page)
1016{
1017 struct nand_ecc_ctrl *ecc = &chip->ecc;
1018 int ret, i, cur_off = 0;
1019 unsigned int max_bitflips = 0;
1020
1021 sunxi_nfc_hw_ecc_enable(mtd);
1022
1023 chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
1024 for (i = data_offs / ecc->size;
1025 i < DIV_ROUND_UP(data_offs + readlen, ecc->size); i++) {
1026 int data_off = i * ecc->size;
1027 int oob_off = i * (ecc->bytes + 4);
1028 u8 *data = bufpoi + data_off;
1029 u8 *oob = chip->oob_poi + oob_off;
1030
1031 ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off,
1032 oob,
1033 oob_off + mtd->writesize,
1034 &cur_off, &max_bitflips,
1035 !i, page);
1036 if (ret < 0)
1037 return ret;
1038 }
1039
1040 sunxi_nfc_hw_ecc_disable(mtd);
1041
1042 return max_bitflips;
1043}
1044
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001045static int sunxi_nfc_hw_ecc_write_page(struct mtd_info *mtd,
1046 struct nand_chip *chip,
Boris BREZILLON45aaeff2015-10-13 11:22:18 +02001047 const uint8_t *buf, int oob_required,
1048 int page)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001049{
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001050 struct nand_ecc_ctrl *ecc = &chip->ecc;
Boris BREZILLONb4625512015-09-30 23:45:25 +02001051 int ret, i, cur_off = 0;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001052
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001053 sunxi_nfc_hw_ecc_enable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001054
1055 for (i = 0; i < ecc->steps; i++) {
Boris BREZILLONb4625512015-09-30 23:45:25 +02001056 int data_off = i * ecc->size;
1057 int oob_off = i * (ecc->bytes + 4);
1058 const u8 *data = buf + data_off;
1059 const u8 *oob = chip->oob_poi + oob_off;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001060
Boris BREZILLONb4625512015-09-30 23:45:25 +02001061 ret = sunxi_nfc_hw_ecc_write_chunk(mtd, data, data_off, oob,
1062 oob_off + mtd->writesize,
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001063 &cur_off, !i, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001064 if (ret)
1065 return ret;
1066 }
1067
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001068 if (oob_required || (chip->options & NAND_NEED_SCRAMBLING))
1069 sunxi_nfc_hw_ecc_write_extra_oob(mtd, chip->oob_poi,
1070 &cur_off, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001071
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001072 sunxi_nfc_hw_ecc_disable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001073
1074 return 0;
1075}
1076
1077static int sunxi_nfc_hw_syndrome_ecc_read_page(struct mtd_info *mtd,
1078 struct nand_chip *chip,
1079 uint8_t *buf, int oob_required,
1080 int page)
1081{
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001082 struct nand_ecc_ctrl *ecc = &chip->ecc;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001083 unsigned int max_bitflips = 0;
Boris BREZILLONb4625512015-09-30 23:45:25 +02001084 int ret, i, cur_off = 0;
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001085 bool raw_mode = false;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001086
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001087 sunxi_nfc_hw_ecc_enable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001088
1089 for (i = 0; i < ecc->steps; i++) {
Boris BREZILLONb4625512015-09-30 23:45:25 +02001090 int data_off = i * (ecc->size + ecc->bytes + 4);
1091 int oob_off = data_off + ecc->size;
1092 u8 *data = buf + (i * ecc->size);
1093 u8 *oob = chip->oob_poi + (i * (ecc->bytes + 4));
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001094
Boris BREZILLONb4625512015-09-30 23:45:25 +02001095 ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off, oob,
1096 oob_off, &cur_off,
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001097 &max_bitflips, !i, page);
1098 if (ret < 0)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001099 return ret;
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001100 else if (ret)
1101 raw_mode = true;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001102 }
1103
Boris BREZILLON35d0e242015-09-30 23:45:26 +02001104 if (oob_required)
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001105 sunxi_nfc_hw_ecc_read_extra_oob(mtd, chip->oob_poi, &cur_off,
1106 !raw_mode, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001107
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001108 sunxi_nfc_hw_ecc_disable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001109
1110 return max_bitflips;
1111}
1112
1113static int sunxi_nfc_hw_syndrome_ecc_write_page(struct mtd_info *mtd,
1114 struct nand_chip *chip,
1115 const uint8_t *buf,
Boris BREZILLON45aaeff2015-10-13 11:22:18 +02001116 int oob_required, int page)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001117{
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001118 struct nand_ecc_ctrl *ecc = &chip->ecc;
Boris BREZILLONb4625512015-09-30 23:45:25 +02001119 int ret, i, cur_off = 0;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001120
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001121 sunxi_nfc_hw_ecc_enable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001122
1123 for (i = 0; i < ecc->steps; i++) {
Boris BREZILLONb4625512015-09-30 23:45:25 +02001124 int data_off = i * (ecc->size + ecc->bytes + 4);
1125 int oob_off = data_off + ecc->size;
1126 const u8 *data = buf + (i * ecc->size);
1127 const u8 *oob = chip->oob_poi + (i * (ecc->bytes + 4));
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001128
Boris BREZILLONb4625512015-09-30 23:45:25 +02001129 ret = sunxi_nfc_hw_ecc_write_chunk(mtd, data, data_off,
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001130 oob, oob_off, &cur_off,
1131 false, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001132 if (ret)
1133 return ret;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001134 }
1135
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001136 if (oob_required || (chip->options & NAND_NEED_SCRAMBLING))
1137 sunxi_nfc_hw_ecc_write_extra_oob(mtd, chip->oob_poi,
1138 &cur_off, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001139
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001140 sunxi_nfc_hw_ecc_disable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001141
1142 return 0;
1143}
1144
Boris Brezillon1c1bdd62015-09-02 15:05:52 +02001145static int sunxi_nfc_hw_common_ecc_read_oob(struct mtd_info *mtd,
1146 struct nand_chip *chip,
1147 int page)
1148{
1149 chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
1150
1151 chip->pagebuf = -1;
1152
1153 return chip->ecc.read_page(mtd, chip, chip->buffers->databuf, 1, page);
1154}
1155
1156static int sunxi_nfc_hw_common_ecc_write_oob(struct mtd_info *mtd,
1157 struct nand_chip *chip,
1158 int page)
1159{
1160 int ret, status;
1161
1162 chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0, page);
1163
1164 chip->pagebuf = -1;
1165
1166 memset(chip->buffers->databuf, 0xff, mtd->writesize);
1167 ret = chip->ecc.write_page(mtd, chip, chip->buffers->databuf, 1, page);
1168 if (ret)
1169 return ret;
1170
1171 /* Send command to program the OOB data */
1172 chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
1173
1174 status = chip->waitfunc(mtd, chip);
1175
1176 return status & NAND_STATUS_FAIL ? -EIO : 0;
1177}
1178
Roy Spliet9c618292015-06-26 11:00:10 +02001179static const s32 tWB_lut[] = {6, 12, 16, 20};
1180static const s32 tRHW_lut[] = {4, 8, 12, 20};
1181
1182static int _sunxi_nand_lookup_timing(const s32 *lut, int lut_size, u32 duration,
1183 u32 clk_period)
1184{
1185 u32 clk_cycles = DIV_ROUND_UP(duration, clk_period);
1186 int i;
1187
1188 for (i = 0; i < lut_size; i++) {
1189 if (clk_cycles <= lut[i])
1190 return i;
1191 }
1192
1193 /* Doesn't fit */
1194 return -EINVAL;
1195}
1196
1197#define sunxi_nand_lookup_timing(l, p, c) \
1198 _sunxi_nand_lookup_timing(l, ARRAY_SIZE(l), p, c)
1199
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001200static int sunxi_nand_chip_set_timings(struct sunxi_nand_chip *chip,
1201 const struct nand_sdr_timings *timings)
1202{
Roy Spliet9c618292015-06-26 11:00:10 +02001203 struct sunxi_nfc *nfc = to_sunxi_nfc(chip->nand.controller);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001204 u32 min_clk_period = 0;
Roy Spliet9c618292015-06-26 11:00:10 +02001205 s32 tWB, tADL, tWHR, tRHW, tCAD;
Boris Brezillon2d434572015-12-02 15:57:20 +01001206 long real_clk_rate;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001207
1208 /* T1 <=> tCLS */
1209 if (timings->tCLS_min > min_clk_period)
1210 min_clk_period = timings->tCLS_min;
1211
1212 /* T2 <=> tCLH */
1213 if (timings->tCLH_min > min_clk_period)
1214 min_clk_period = timings->tCLH_min;
1215
1216 /* T3 <=> tCS */
1217 if (timings->tCS_min > min_clk_period)
1218 min_clk_period = timings->tCS_min;
1219
1220 /* T4 <=> tCH */
1221 if (timings->tCH_min > min_clk_period)
1222 min_clk_period = timings->tCH_min;
1223
1224 /* T5 <=> tWP */
1225 if (timings->tWP_min > min_clk_period)
1226 min_clk_period = timings->tWP_min;
1227
1228 /* T6 <=> tWH */
1229 if (timings->tWH_min > min_clk_period)
1230 min_clk_period = timings->tWH_min;
1231
1232 /* T7 <=> tALS */
1233 if (timings->tALS_min > min_clk_period)
1234 min_clk_period = timings->tALS_min;
1235
1236 /* T8 <=> tDS */
1237 if (timings->tDS_min > min_clk_period)
1238 min_clk_period = timings->tDS_min;
1239
1240 /* T9 <=> tDH */
1241 if (timings->tDH_min > min_clk_period)
1242 min_clk_period = timings->tDH_min;
1243
1244 /* T10 <=> tRR */
1245 if (timings->tRR_min > (min_clk_period * 3))
1246 min_clk_period = DIV_ROUND_UP(timings->tRR_min, 3);
1247
1248 /* T11 <=> tALH */
1249 if (timings->tALH_min > min_clk_period)
1250 min_clk_period = timings->tALH_min;
1251
1252 /* T12 <=> tRP */
1253 if (timings->tRP_min > min_clk_period)
1254 min_clk_period = timings->tRP_min;
1255
1256 /* T13 <=> tREH */
1257 if (timings->tREH_min > min_clk_period)
1258 min_clk_period = timings->tREH_min;
1259
1260 /* T14 <=> tRC */
1261 if (timings->tRC_min > (min_clk_period * 2))
1262 min_clk_period = DIV_ROUND_UP(timings->tRC_min, 2);
1263
1264 /* T15 <=> tWC */
1265 if (timings->tWC_min > (min_clk_period * 2))
1266 min_clk_period = DIV_ROUND_UP(timings->tWC_min, 2);
1267
Roy Spliet9c618292015-06-26 11:00:10 +02001268 /* T16 - T19 + tCAD */
Boris Brezillon5abcd952015-11-11 22:30:30 +01001269 if (timings->tWB_max > (min_clk_period * 20))
1270 min_clk_period = DIV_ROUND_UP(timings->tWB_max, 20);
1271
1272 if (timings->tADL_min > (min_clk_period * 32))
1273 min_clk_period = DIV_ROUND_UP(timings->tADL_min, 32);
1274
1275 if (timings->tWHR_min > (min_clk_period * 32))
1276 min_clk_period = DIV_ROUND_UP(timings->tWHR_min, 32);
1277
1278 if (timings->tRHW_min > (min_clk_period * 20))
1279 min_clk_period = DIV_ROUND_UP(timings->tRHW_min, 20);
1280
Roy Spliet9c618292015-06-26 11:00:10 +02001281 tWB = sunxi_nand_lookup_timing(tWB_lut, timings->tWB_max,
1282 min_clk_period);
1283 if (tWB < 0) {
1284 dev_err(nfc->dev, "unsupported tWB\n");
1285 return tWB;
1286 }
1287
1288 tADL = DIV_ROUND_UP(timings->tADL_min, min_clk_period) >> 3;
1289 if (tADL > 3) {
1290 dev_err(nfc->dev, "unsupported tADL\n");
1291 return -EINVAL;
1292 }
1293
1294 tWHR = DIV_ROUND_UP(timings->tWHR_min, min_clk_period) >> 3;
1295 if (tWHR > 3) {
1296 dev_err(nfc->dev, "unsupported tWHR\n");
1297 return -EINVAL;
1298 }
1299
1300 tRHW = sunxi_nand_lookup_timing(tRHW_lut, timings->tRHW_min,
1301 min_clk_period);
1302 if (tRHW < 0) {
1303 dev_err(nfc->dev, "unsupported tRHW\n");
1304 return tRHW;
1305 }
1306
1307 /*
1308 * TODO: according to ONFI specs this value only applies for DDR NAND,
1309 * but Allwinner seems to set this to 0x7. Mimic them for now.
1310 */
1311 tCAD = 0x7;
1312
1313 /* TODO: A83 has some more bits for CDQSS, CS, CLHZ, CCS, WC */
1314 chip->timing_cfg = NFC_TIMING_CFG(tWB, tADL, tWHR, tRHW, tCAD);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001315
1316 /* Convert min_clk_period from picoseconds to nanoseconds */
1317 min_clk_period = DIV_ROUND_UP(min_clk_period, 1000);
1318
1319 /*
Boris Brezillon2f9992e2015-12-02 15:10:40 +01001320 * Unlike what is stated in Allwinner datasheet, the clk_rate should
1321 * be set to (1 / min_clk_period), and not (2 / min_clk_period).
1322 * This new formula was verified with a scope and validated by
1323 * Allwinner engineers.
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001324 */
Boris Brezillon2f9992e2015-12-02 15:10:40 +01001325 chip->clk_rate = NSEC_PER_SEC / min_clk_period;
Boris Brezillon2d434572015-12-02 15:57:20 +01001326 real_clk_rate = clk_round_rate(nfc->mod_clk, chip->clk_rate);
1327
1328 /*
1329 * ONFI specification 3.1, paragraph 4.15.2 dictates that EDO data
1330 * output cycle timings shall be used if the host drives tRC less than
1331 * 30 ns.
1332 */
1333 min_clk_period = NSEC_PER_SEC / real_clk_rate;
1334 chip->timing_ctl = ((min_clk_period * 2) < 30) ?
1335 NFC_TIMING_CTL_EDO : 0;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001336
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001337 return 0;
1338}
1339
1340static int sunxi_nand_chip_init_timings(struct sunxi_nand_chip *chip,
1341 struct device_node *np)
1342{
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001343 struct mtd_info *mtd = nand_to_mtd(&chip->nand);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001344 const struct nand_sdr_timings *timings;
1345 int ret;
1346 int mode;
1347
1348 mode = onfi_get_async_timing_mode(&chip->nand);
1349 if (mode == ONFI_TIMING_MODE_UNKNOWN) {
1350 mode = chip->nand.onfi_timing_mode_default;
1351 } else {
1352 uint8_t feature[ONFI_SUBFEATURE_PARAM_LEN] = {};
Stefan Roese7eadd472015-08-28 14:45:21 +02001353 int i;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001354
1355 mode = fls(mode) - 1;
1356 if (mode < 0)
1357 mode = 0;
1358
1359 feature[0] = mode;
Stefan Roese7eadd472015-08-28 14:45:21 +02001360 for (i = 0; i < chip->nsels; i++) {
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001361 chip->nand.select_chip(mtd, i);
1362 ret = chip->nand.onfi_set_features(mtd, &chip->nand,
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001363 ONFI_FEATURE_ADDR_TIMING_MODE,
1364 feature);
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001365 chip->nand.select_chip(mtd, -1);
Stefan Roese7eadd472015-08-28 14:45:21 +02001366 if (ret)
1367 return ret;
1368 }
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001369 }
1370
1371 timings = onfi_async_timing_mode_to_sdr_timings(mode);
1372 if (IS_ERR(timings))
1373 return PTR_ERR(timings);
1374
1375 return sunxi_nand_chip_set_timings(chip, timings);
1376}
1377
1378static int sunxi_nand_hw_common_ecc_ctrl_init(struct mtd_info *mtd,
1379 struct nand_ecc_ctrl *ecc,
1380 struct device_node *np)
1381{
1382 static const u8 strengths[] = { 16, 24, 28, 32, 40, 48, 56, 60, 64 };
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +01001383 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001384 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
1385 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
1386 struct sunxi_nand_hw_ecc *data;
1387 struct nand_ecclayout *layout;
1388 int nsectors;
1389 int ret;
1390 int i;
1391
1392 data = kzalloc(sizeof(*data), GFP_KERNEL);
1393 if (!data)
1394 return -ENOMEM;
1395
1396 /* Add ECC info retrieval from DT */
1397 for (i = 0; i < ARRAY_SIZE(strengths); i++) {
1398 if (ecc->strength <= strengths[i])
1399 break;
1400 }
1401
1402 if (i >= ARRAY_SIZE(strengths)) {
1403 dev_err(nfc->dev, "unsupported strength\n");
1404 ret = -ENOTSUPP;
1405 goto err;
1406 }
1407
1408 data->mode = i;
1409
1410 /* HW ECC always request ECC bytes for 1024 bytes blocks */
1411 ecc->bytes = DIV_ROUND_UP(ecc->strength * fls(8 * 1024), 8);
1412
1413 /* HW ECC always work with even numbers of ECC bytes */
1414 ecc->bytes = ALIGN(ecc->bytes, 2);
1415
1416 layout = &data->layout;
1417 nsectors = mtd->writesize / ecc->size;
1418
1419 if (mtd->oobsize < ((ecc->bytes + 4) * nsectors)) {
1420 ret = -EINVAL;
1421 goto err;
1422 }
1423
1424 layout->eccbytes = (ecc->bytes * nsectors);
1425
Boris Brezillon1c1bdd62015-09-02 15:05:52 +02001426 ecc->read_oob = sunxi_nfc_hw_common_ecc_read_oob;
1427 ecc->write_oob = sunxi_nfc_hw_common_ecc_write_oob;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001428 ecc->layout = layout;
1429 ecc->priv = data;
1430
1431 return 0;
1432
1433err:
1434 kfree(data);
1435
1436 return ret;
1437}
1438
1439static void sunxi_nand_hw_common_ecc_ctrl_cleanup(struct nand_ecc_ctrl *ecc)
1440{
1441 kfree(ecc->priv);
1442}
1443
1444static int sunxi_nand_hw_ecc_ctrl_init(struct mtd_info *mtd,
1445 struct nand_ecc_ctrl *ecc,
1446 struct device_node *np)
1447{
1448 struct nand_ecclayout *layout;
1449 int nsectors;
1450 int i, j;
1451 int ret;
1452
1453 ret = sunxi_nand_hw_common_ecc_ctrl_init(mtd, ecc, np);
1454 if (ret)
1455 return ret;
1456
1457 ecc->read_page = sunxi_nfc_hw_ecc_read_page;
1458 ecc->write_page = sunxi_nfc_hw_ecc_write_page;
Boris Brezillon1c1bdd62015-09-02 15:05:52 +02001459 ecc->read_oob_raw = nand_read_oob_std;
1460 ecc->write_oob_raw = nand_write_oob_std;
Boris Brezillonfe82cce2015-09-16 09:01:45 +02001461 ecc->read_subpage = sunxi_nfc_hw_ecc_read_subpage;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001462 layout = ecc->layout;
1463 nsectors = mtd->writesize / ecc->size;
1464
1465 for (i = 0; i < nsectors; i++) {
1466 if (i) {
1467 layout->oobfree[i].offset =
1468 layout->oobfree[i - 1].offset +
1469 layout->oobfree[i - 1].length +
1470 ecc->bytes;
1471 layout->oobfree[i].length = 4;
1472 } else {
1473 /*
1474 * The first 2 bytes are used for BB markers, hence we
1475 * only have 2 bytes available in the first user data
1476 * section.
1477 */
1478 layout->oobfree[i].length = 2;
1479 layout->oobfree[i].offset = 2;
1480 }
1481
1482 for (j = 0; j < ecc->bytes; j++)
1483 layout->eccpos[(ecc->bytes * i) + j] =
1484 layout->oobfree[i].offset +
1485 layout->oobfree[i].length + j;
1486 }
1487
1488 if (mtd->oobsize > (ecc->bytes + 4) * nsectors) {
1489 layout->oobfree[nsectors].offset =
1490 layout->oobfree[nsectors - 1].offset +
1491 layout->oobfree[nsectors - 1].length +
1492 ecc->bytes;
1493 layout->oobfree[nsectors].length = mtd->oobsize -
1494 ((ecc->bytes + 4) * nsectors);
1495 }
1496
1497 return 0;
1498}
1499
1500static int sunxi_nand_hw_syndrome_ecc_ctrl_init(struct mtd_info *mtd,
1501 struct nand_ecc_ctrl *ecc,
1502 struct device_node *np)
1503{
1504 struct nand_ecclayout *layout;
1505 int nsectors;
1506 int i;
1507 int ret;
1508
1509 ret = sunxi_nand_hw_common_ecc_ctrl_init(mtd, ecc, np);
1510 if (ret)
1511 return ret;
1512
1513 ecc->prepad = 4;
1514 ecc->read_page = sunxi_nfc_hw_syndrome_ecc_read_page;
1515 ecc->write_page = sunxi_nfc_hw_syndrome_ecc_write_page;
Boris Brezillon1c1bdd62015-09-02 15:05:52 +02001516 ecc->read_oob_raw = nand_read_oob_syndrome;
1517 ecc->write_oob_raw = nand_write_oob_syndrome;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001518
1519 layout = ecc->layout;
1520 nsectors = mtd->writesize / ecc->size;
1521
1522 for (i = 0; i < (ecc->bytes * nsectors); i++)
1523 layout->eccpos[i] = i;
1524
1525 layout->oobfree[0].length = mtd->oobsize - i;
1526 layout->oobfree[0].offset = i;
1527
1528 return 0;
1529}
1530
1531static void sunxi_nand_ecc_cleanup(struct nand_ecc_ctrl *ecc)
1532{
1533 switch (ecc->mode) {
1534 case NAND_ECC_HW:
1535 case NAND_ECC_HW_SYNDROME:
1536 sunxi_nand_hw_common_ecc_ctrl_cleanup(ecc);
1537 break;
1538 case NAND_ECC_NONE:
1539 kfree(ecc->layout);
1540 default:
1541 break;
1542 }
1543}
1544
1545static int sunxi_nand_ecc_init(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc,
1546 struct device_node *np)
1547{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +01001548 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001549 int ret;
1550
Boris BREZILLONa3d22a52015-09-02 10:30:25 +02001551 if (!ecc->size) {
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001552 ecc->size = nand->ecc_step_ds;
1553 ecc->strength = nand->ecc_strength_ds;
1554 }
1555
1556 if (!ecc->size || !ecc->strength)
1557 return -EINVAL;
1558
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001559 switch (ecc->mode) {
1560 case NAND_ECC_SOFT_BCH:
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001561 break;
1562 case NAND_ECC_HW:
1563 ret = sunxi_nand_hw_ecc_ctrl_init(mtd, ecc, np);
1564 if (ret)
1565 return ret;
1566 break;
1567 case NAND_ECC_HW_SYNDROME:
1568 ret = sunxi_nand_hw_syndrome_ecc_ctrl_init(mtd, ecc, np);
1569 if (ret)
1570 return ret;
1571 break;
1572 case NAND_ECC_NONE:
1573 ecc->layout = kzalloc(sizeof(*ecc->layout), GFP_KERNEL);
1574 if (!ecc->layout)
1575 return -ENOMEM;
1576 ecc->layout->oobfree[0].length = mtd->oobsize;
1577 case NAND_ECC_SOFT:
1578 break;
1579 default:
1580 return -EINVAL;
1581 }
1582
1583 return 0;
1584}
1585
1586static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc,
1587 struct device_node *np)
1588{
1589 const struct nand_sdr_timings *timings;
1590 struct sunxi_nand_chip *chip;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001591 struct mtd_info *mtd;
1592 struct nand_chip *nand;
1593 int nsels;
1594 int ret;
1595 int i;
1596 u32 tmp;
1597
1598 if (!of_get_property(np, "reg", &nsels))
1599 return -EINVAL;
1600
1601 nsels /= sizeof(u32);
1602 if (!nsels) {
1603 dev_err(dev, "invalid reg property size\n");
1604 return -EINVAL;
1605 }
1606
1607 chip = devm_kzalloc(dev,
1608 sizeof(*chip) +
1609 (nsels * sizeof(struct sunxi_nand_chip_sel)),
1610 GFP_KERNEL);
1611 if (!chip) {
1612 dev_err(dev, "could not allocate chip\n");
1613 return -ENOMEM;
1614 }
1615
1616 chip->nsels = nsels;
1617 chip->selected = -1;
1618
1619 for (i = 0; i < nsels; i++) {
1620 ret = of_property_read_u32_index(np, "reg", i, &tmp);
1621 if (ret) {
1622 dev_err(dev, "could not retrieve reg property: %d\n",
1623 ret);
1624 return ret;
1625 }
1626
1627 if (tmp > NFC_MAX_CS) {
1628 dev_err(dev,
1629 "invalid reg value: %u (max CS = 7)\n",
1630 tmp);
1631 return -EINVAL;
1632 }
1633
1634 if (test_and_set_bit(tmp, &nfc->assigned_cs)) {
1635 dev_err(dev, "CS %d already assigned\n", tmp);
1636 return -EINVAL;
1637 }
1638
1639 chip->sels[i].cs = tmp;
1640
1641 if (!of_property_read_u32_index(np, "allwinner,rb", i, &tmp) &&
1642 tmp < 2) {
1643 chip->sels[i].rb.type = RB_NATIVE;
1644 chip->sels[i].rb.info.nativeid = tmp;
1645 } else {
1646 ret = of_get_named_gpio(np, "rb-gpios", i);
1647 if (ret >= 0) {
1648 tmp = ret;
1649 chip->sels[i].rb.type = RB_GPIO;
1650 chip->sels[i].rb.info.gpio = tmp;
1651 ret = devm_gpio_request(dev, tmp, "nand-rb");
1652 if (ret)
1653 return ret;
1654
1655 ret = gpio_direction_input(tmp);
1656 if (ret)
1657 return ret;
1658 } else {
1659 chip->sels[i].rb.type = RB_NONE;
1660 }
1661 }
1662 }
1663
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001664 nand = &chip->nand;
1665 /* Default tR value specified in the ONFI spec (chapter 4.15.1) */
1666 nand->chip_delay = 200;
1667 nand->controller = &nfc->controller;
Boris BREZILLONa3d22a52015-09-02 10:30:25 +02001668 /*
1669 * Set the ECC mode to the default value in case nothing is specified
1670 * in the DT.
1671 */
1672 nand->ecc.mode = NAND_ECC_HW;
Brian Norris63752192015-10-30 20:33:23 -07001673 nand_set_flash_node(nand, np);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001674 nand->select_chip = sunxi_nfc_select_chip;
1675 nand->cmd_ctrl = sunxi_nfc_cmd_ctrl;
1676 nand->read_buf = sunxi_nfc_read_buf;
1677 nand->write_buf = sunxi_nfc_write_buf;
1678 nand->read_byte = sunxi_nfc_read_byte;
1679
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001680 mtd = nand_to_mtd(nand);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001681 mtd->dev.parent = dev;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001682
Boris Brezillon9edb4702015-12-02 16:00:57 +01001683 timings = onfi_async_timing_mode_to_sdr_timings(0);
1684 if (IS_ERR(timings)) {
1685 ret = PTR_ERR(timings);
1686 dev_err(dev,
1687 "could not retrieve timings for ONFI mode 0: %d\n",
1688 ret);
1689 return ret;
1690 }
1691
1692 ret = sunxi_nand_chip_set_timings(chip, timings);
1693 if (ret) {
1694 dev_err(dev, "could not configure chip timings: %d\n", ret);
1695 return ret;
1696 }
1697
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001698 ret = nand_scan_ident(mtd, nsels, NULL);
1699 if (ret)
1700 return ret;
1701
Boris BREZILLONa3d22a52015-09-02 10:30:25 +02001702 if (nand->bbt_options & NAND_BBT_USE_FLASH)
1703 nand->bbt_options |= NAND_BBT_NO_OOB;
1704
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001705 if (nand->options & NAND_NEED_SCRAMBLING)
1706 nand->options |= NAND_NO_SUBPAGE_WRITE;
1707
Boris Brezillonfe82cce2015-09-16 09:01:45 +02001708 nand->options |= NAND_SUBPAGE_READ;
1709
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001710 ret = sunxi_nand_chip_init_timings(chip, np);
1711 if (ret) {
1712 dev_err(dev, "could not configure chip timings: %d\n", ret);
1713 return ret;
1714 }
1715
1716 ret = sunxi_nand_ecc_init(mtd, &nand->ecc, np);
1717 if (ret) {
1718 dev_err(dev, "ECC init failed: %d\n", ret);
1719 return ret;
1720 }
1721
1722 ret = nand_scan_tail(mtd);
1723 if (ret) {
1724 dev_err(dev, "nand_scan_tail failed: %d\n", ret);
1725 return ret;
1726 }
1727
Brian Norrisa61ae812015-10-30 20:33:25 -07001728 ret = mtd_device_register(mtd, NULL, 0);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001729 if (ret) {
1730 dev_err(dev, "failed to register mtd device: %d\n", ret);
1731 nand_release(mtd);
1732 return ret;
1733 }
1734
1735 list_add_tail(&chip->node, &nfc->chips);
1736
1737 return 0;
1738}
1739
1740static int sunxi_nand_chips_init(struct device *dev, struct sunxi_nfc *nfc)
1741{
1742 struct device_node *np = dev->of_node;
1743 struct device_node *nand_np;
1744 int nchips = of_get_child_count(np);
1745 int ret;
1746
1747 if (nchips > 8) {
1748 dev_err(dev, "too many NAND chips: %d (max = 8)\n", nchips);
1749 return -EINVAL;
1750 }
1751
1752 for_each_child_of_node(np, nand_np) {
1753 ret = sunxi_nand_chip_init(dev, nfc, nand_np);
Julia Lawalla81c0f02015-11-18 23:04:12 +01001754 if (ret) {
1755 of_node_put(nand_np);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001756 return ret;
Julia Lawalla81c0f02015-11-18 23:04:12 +01001757 }
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001758 }
1759
1760 return 0;
1761}
1762
1763static void sunxi_nand_chips_cleanup(struct sunxi_nfc *nfc)
1764{
1765 struct sunxi_nand_chip *chip;
1766
1767 while (!list_empty(&nfc->chips)) {
1768 chip = list_first_entry(&nfc->chips, struct sunxi_nand_chip,
1769 node);
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001770 nand_release(nand_to_mtd(&chip->nand));
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001771 sunxi_nand_ecc_cleanup(&chip->nand.ecc);
Boris BREZILLON8e375cc2015-09-13 18:14:43 +02001772 list_del(&chip->node);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001773 }
1774}
1775
1776static int sunxi_nfc_probe(struct platform_device *pdev)
1777{
1778 struct device *dev = &pdev->dev;
1779 struct resource *r;
1780 struct sunxi_nfc *nfc;
1781 int irq;
1782 int ret;
1783
1784 nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
1785 if (!nfc)
1786 return -ENOMEM;
1787
1788 nfc->dev = dev;
1789 spin_lock_init(&nfc->controller.lock);
1790 init_waitqueue_head(&nfc->controller.wq);
1791 INIT_LIST_HEAD(&nfc->chips);
1792
1793 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1794 nfc->regs = devm_ioremap_resource(dev, r);
1795 if (IS_ERR(nfc->regs))
1796 return PTR_ERR(nfc->regs);
1797
1798 irq = platform_get_irq(pdev, 0);
1799 if (irq < 0) {
1800 dev_err(dev, "failed to retrieve irq\n");
1801 return irq;
1802 }
1803
1804 nfc->ahb_clk = devm_clk_get(dev, "ahb");
1805 if (IS_ERR(nfc->ahb_clk)) {
1806 dev_err(dev, "failed to retrieve ahb clk\n");
1807 return PTR_ERR(nfc->ahb_clk);
1808 }
1809
1810 ret = clk_prepare_enable(nfc->ahb_clk);
1811 if (ret)
1812 return ret;
1813
1814 nfc->mod_clk = devm_clk_get(dev, "mod");
1815 if (IS_ERR(nfc->mod_clk)) {
1816 dev_err(dev, "failed to retrieve mod clk\n");
1817 ret = PTR_ERR(nfc->mod_clk);
1818 goto out_ahb_clk_unprepare;
1819 }
1820
1821 ret = clk_prepare_enable(nfc->mod_clk);
1822 if (ret)
1823 goto out_ahb_clk_unprepare;
1824
1825 ret = sunxi_nfc_rst(nfc);
1826 if (ret)
1827 goto out_mod_clk_unprepare;
1828
1829 writel(0, nfc->regs + NFC_REG_INT);
1830 ret = devm_request_irq(dev, irq, sunxi_nfc_interrupt,
1831 0, "sunxi-nand", nfc);
1832 if (ret)
1833 goto out_mod_clk_unprepare;
1834
1835 platform_set_drvdata(pdev, nfc);
1836
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001837 ret = sunxi_nand_chips_init(dev, nfc);
1838 if (ret) {
1839 dev_err(dev, "failed to init nand chips\n");
1840 goto out_mod_clk_unprepare;
1841 }
1842
1843 return 0;
1844
1845out_mod_clk_unprepare:
1846 clk_disable_unprepare(nfc->mod_clk);
1847out_ahb_clk_unprepare:
1848 clk_disable_unprepare(nfc->ahb_clk);
1849
1850 return ret;
1851}
1852
1853static int sunxi_nfc_remove(struct platform_device *pdev)
1854{
1855 struct sunxi_nfc *nfc = platform_get_drvdata(pdev);
1856
1857 sunxi_nand_chips_cleanup(nfc);
1858
1859 return 0;
1860}
1861
1862static const struct of_device_id sunxi_nfc_ids[] = {
1863 { .compatible = "allwinner,sun4i-a10-nand" },
1864 { /* sentinel */ }
1865};
1866MODULE_DEVICE_TABLE(of, sunxi_nfc_ids);
1867
1868static struct platform_driver sunxi_nfc_driver = {
1869 .driver = {
1870 .name = "sunxi_nand",
1871 .of_match_table = sunxi_nfc_ids,
1872 },
1873 .probe = sunxi_nfc_probe,
1874 .remove = sunxi_nfc_remove,
1875};
1876module_platform_driver(sunxi_nfc_driver);
1877
1878MODULE_LICENSE("GPL v2");
1879MODULE_AUTHOR("Boris BREZILLON");
1880MODULE_DESCRIPTION("Allwinner NAND Flash Controller driver");
1881MODULE_ALIAS("platform:sunxi_nand");