blob: fff28512cd71489a067cdbd387a591f51f02884b [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;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200360 int ret;
361
362 if (sunxi_nand->selected < 0)
363 return 0;
364
365 rb = &sunxi_nand->sels[sunxi_nand->selected].rb;
366
367 switch (rb->type) {
368 case RB_NATIVE:
369 ret = !!(readl(nfc->regs + NFC_REG_ST) &
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200370 NFC_RB_STATE(rb->info.nativeid));
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200371 break;
372 case RB_GPIO:
373 ret = gpio_get_value(rb->info.gpio);
374 break;
375 case RB_NONE:
376 default:
377 ret = 0;
378 dev_err(nfc->dev, "cannot check R/B NAND status!\n");
379 break;
380 }
381
382 return ret;
383}
384
385static void sunxi_nfc_select_chip(struct mtd_info *mtd, int chip)
386{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100387 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200388 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
389 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
390 struct sunxi_nand_chip_sel *sel;
391 u32 ctl;
392
393 if (chip > 0 && chip >= sunxi_nand->nsels)
394 return;
395
396 if (chip == sunxi_nand->selected)
397 return;
398
399 ctl = readl(nfc->regs + NFC_REG_CTL) &
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200400 ~(NFC_PAGE_SHIFT_MSK | NFC_CE_SEL_MSK | NFC_RB_SEL_MSK | NFC_EN);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200401
402 if (chip >= 0) {
403 sel = &sunxi_nand->sels[chip];
404
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200405 ctl |= NFC_CE_SEL(sel->cs) | NFC_EN |
Boris Brezillon68ffbf72016-03-04 17:29:20 +0100406 NFC_PAGE_SHIFT(nand->page_shift);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200407 if (sel->rb.type == RB_NONE) {
408 nand->dev_ready = NULL;
409 } else {
410 nand->dev_ready = sunxi_nfc_dev_ready;
411 if (sel->rb.type == RB_NATIVE)
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200412 ctl |= NFC_RB_SEL(sel->rb.info.nativeid);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200413 }
414
415 writel(mtd->writesize, nfc->regs + NFC_REG_SPARE_AREA);
416
417 if (nfc->clk_rate != sunxi_nand->clk_rate) {
418 clk_set_rate(nfc->mod_clk, sunxi_nand->clk_rate);
419 nfc->clk_rate = sunxi_nand->clk_rate;
420 }
421 }
422
Roy Splietd052e502015-06-26 11:00:11 +0200423 writel(sunxi_nand->timing_ctl, nfc->regs + NFC_REG_TIMING_CTL);
Roy Spliet9c618292015-06-26 11:00:10 +0200424 writel(sunxi_nand->timing_cfg, nfc->regs + NFC_REG_TIMING_CFG);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200425 writel(ctl, nfc->regs + NFC_REG_CTL);
426
427 sunxi_nand->selected = chip;
428}
429
430static void sunxi_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
431{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100432 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200433 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
434 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
435 int ret;
436 int cnt;
437 int offs = 0;
438 u32 tmp;
439
440 while (len > offs) {
441 cnt = min(len - offs, NFC_SRAM_SIZE);
442
443 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
444 if (ret)
445 break;
446
447 writel(cnt, nfc->regs + NFC_REG_CNT);
448 tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD;
449 writel(tmp, nfc->regs + NFC_REG_CMD);
450
451 ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
452 if (ret)
453 break;
454
455 if (buf)
456 memcpy_fromio(buf + offs, nfc->regs + NFC_RAM0_BASE,
457 cnt);
458 offs += cnt;
459 }
460}
461
462static void sunxi_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf,
463 int len)
464{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100465 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200466 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
467 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
468 int ret;
469 int cnt;
470 int offs = 0;
471 u32 tmp;
472
473 while (len > offs) {
474 cnt = min(len - offs, NFC_SRAM_SIZE);
475
476 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
477 if (ret)
478 break;
479
480 writel(cnt, nfc->regs + NFC_REG_CNT);
481 memcpy_toio(nfc->regs + NFC_RAM0_BASE, buf + offs, cnt);
482 tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD |
483 NFC_ACCESS_DIR;
484 writel(tmp, nfc->regs + NFC_REG_CMD);
485
486 ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
487 if (ret)
488 break;
489
490 offs += cnt;
491 }
492}
493
494static uint8_t sunxi_nfc_read_byte(struct mtd_info *mtd)
495{
496 uint8_t ret;
497
498 sunxi_nfc_read_buf(mtd, &ret, 1);
499
500 return ret;
501}
502
503static void sunxi_nfc_cmd_ctrl(struct mtd_info *mtd, int dat,
504 unsigned int ctrl)
505{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100506 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200507 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
508 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
509 int ret;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200510
511 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
512 if (ret)
513 return;
514
Boris Brezillone9aa6712015-09-16 09:05:31 +0200515 if (dat == NAND_CMD_NONE && (ctrl & NAND_NCE) &&
516 !(ctrl & (NAND_CLE | NAND_ALE))) {
517 u32 cmd = 0;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200518
Boris Brezillone9aa6712015-09-16 09:05:31 +0200519 if (!sunxi_nand->addr_cycles && !sunxi_nand->cmd_cycles)
520 return;
521
522 if (sunxi_nand->cmd_cycles--)
523 cmd |= NFC_SEND_CMD1 | sunxi_nand->cmd[0];
524
525 if (sunxi_nand->cmd_cycles--) {
526 cmd |= NFC_SEND_CMD2;
527 writel(sunxi_nand->cmd[1],
528 nfc->regs + NFC_REG_RCMD_SET);
529 }
530
531 sunxi_nand->cmd_cycles = 0;
532
533 if (sunxi_nand->addr_cycles) {
534 cmd |= NFC_SEND_ADR |
535 NFC_ADR_NUM(sunxi_nand->addr_cycles);
536 writel(sunxi_nand->addr[0],
537 nfc->regs + NFC_REG_ADDR_LOW);
538 }
539
540 if (sunxi_nand->addr_cycles > 4)
541 writel(sunxi_nand->addr[1],
542 nfc->regs + NFC_REG_ADDR_HIGH);
543
544 writel(cmd, nfc->regs + NFC_REG_CMD);
545 sunxi_nand->addr[0] = 0;
546 sunxi_nand->addr[1] = 0;
547 sunxi_nand->addr_cycles = 0;
548 sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200549 }
550
Boris Brezillone9aa6712015-09-16 09:05:31 +0200551 if (ctrl & NAND_CLE) {
552 sunxi_nand->cmd[sunxi_nand->cmd_cycles++] = dat;
553 } else if (ctrl & NAND_ALE) {
554 sunxi_nand->addr[sunxi_nand->addr_cycles / 4] |=
555 dat << ((sunxi_nand->addr_cycles % 4) * 8);
556 sunxi_nand->addr_cycles++;
557 }
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200558}
559
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100560/* These seed values have been extracted from Allwinner's BSP */
561static const u16 sunxi_nfc_randomizer_page_seeds[] = {
562 0x2b75, 0x0bd0, 0x5ca3, 0x62d1, 0x1c93, 0x07e9, 0x2162, 0x3a72,
563 0x0d67, 0x67f9, 0x1be7, 0x077d, 0x032f, 0x0dac, 0x2716, 0x2436,
564 0x7922, 0x1510, 0x3860, 0x5287, 0x480f, 0x4252, 0x1789, 0x5a2d,
565 0x2a49, 0x5e10, 0x437f, 0x4b4e, 0x2f45, 0x216e, 0x5cb7, 0x7130,
566 0x2a3f, 0x60e4, 0x4dc9, 0x0ef0, 0x0f52, 0x1bb9, 0x6211, 0x7a56,
567 0x226d, 0x4ea7, 0x6f36, 0x3692, 0x38bf, 0x0c62, 0x05eb, 0x4c55,
568 0x60f4, 0x728c, 0x3b6f, 0x2037, 0x7f69, 0x0936, 0x651a, 0x4ceb,
569 0x6218, 0x79f3, 0x383f, 0x18d9, 0x4f05, 0x5c82, 0x2912, 0x6f17,
570 0x6856, 0x5938, 0x1007, 0x61ab, 0x3e7f, 0x57c2, 0x542f, 0x4f62,
571 0x7454, 0x2eac, 0x7739, 0x42d4, 0x2f90, 0x435a, 0x2e52, 0x2064,
572 0x637c, 0x66ad, 0x2c90, 0x0bad, 0x759c, 0x0029, 0x0986, 0x7126,
573 0x1ca7, 0x1605, 0x386a, 0x27f5, 0x1380, 0x6d75, 0x24c3, 0x0f8e,
574 0x2b7a, 0x1418, 0x1fd1, 0x7dc1, 0x2d8e, 0x43af, 0x2267, 0x7da3,
575 0x4e3d, 0x1338, 0x50db, 0x454d, 0x764d, 0x40a3, 0x42e6, 0x262b,
576 0x2d2e, 0x1aea, 0x2e17, 0x173d, 0x3a6e, 0x71bf, 0x25f9, 0x0a5d,
577 0x7c57, 0x0fbe, 0x46ce, 0x4939, 0x6b17, 0x37bb, 0x3e91, 0x76db,
578};
579
580/*
581 * sunxi_nfc_randomizer_ecc512_seeds and sunxi_nfc_randomizer_ecc1024_seeds
582 * have been generated using
583 * sunxi_nfc_randomizer_step(seed, (step_size * 8) + 15), which is what
584 * the randomizer engine does internally before de/scrambling OOB data.
585 *
586 * Those tables are statically defined to avoid calculating randomizer state
587 * at runtime.
588 */
589static const u16 sunxi_nfc_randomizer_ecc512_seeds[] = {
590 0x3346, 0x367f, 0x1f18, 0x769a, 0x4f64, 0x068c, 0x2ef1, 0x6b64,
591 0x28a9, 0x15d7, 0x30f8, 0x3659, 0x53db, 0x7c5f, 0x71d4, 0x4409,
592 0x26eb, 0x03cc, 0x655d, 0x47d4, 0x4daa, 0x0877, 0x712d, 0x3617,
593 0x3264, 0x49aa, 0x7f9e, 0x588e, 0x4fbc, 0x7176, 0x7f91, 0x6c6d,
594 0x4b95, 0x5fb7, 0x3844, 0x4037, 0x0184, 0x081b, 0x0ee8, 0x5b91,
595 0x293d, 0x1f71, 0x0e6f, 0x402b, 0x5122, 0x1e52, 0x22be, 0x3d2d,
596 0x75bc, 0x7c60, 0x6291, 0x1a2f, 0x61d4, 0x74aa, 0x4140, 0x29ab,
597 0x472d, 0x2852, 0x017e, 0x15e8, 0x5ec2, 0x17cf, 0x7d0f, 0x06b8,
598 0x117a, 0x6b94, 0x789b, 0x3126, 0x6ac5, 0x5be7, 0x150f, 0x51f8,
599 0x7889, 0x0aa5, 0x663d, 0x77e8, 0x0b87, 0x3dcb, 0x360d, 0x218b,
600 0x512f, 0x7dc9, 0x6a4d, 0x630a, 0x3547, 0x1dd2, 0x5aea, 0x69a5,
601 0x7bfa, 0x5e4f, 0x1519, 0x6430, 0x3a0e, 0x5eb3, 0x5425, 0x0c7a,
602 0x5540, 0x3670, 0x63c1, 0x31e9, 0x5a39, 0x2de7, 0x5979, 0x2891,
603 0x1562, 0x014b, 0x5b05, 0x2756, 0x5a34, 0x13aa, 0x6cb5, 0x2c36,
604 0x5e72, 0x1306, 0x0861, 0x15ef, 0x1ee8, 0x5a37, 0x7ac4, 0x45dd,
605 0x44c4, 0x7266, 0x2f41, 0x3ccc, 0x045e, 0x7d40, 0x7c66, 0x0fa0,
606};
607
608static const u16 sunxi_nfc_randomizer_ecc1024_seeds[] = {
609 0x2cf5, 0x35f1, 0x63a4, 0x5274, 0x2bd2, 0x778b, 0x7285, 0x32b6,
610 0x6a5c, 0x70d6, 0x757d, 0x6769, 0x5375, 0x1e81, 0x0cf3, 0x3982,
611 0x6787, 0x042a, 0x6c49, 0x1925, 0x56a8, 0x40a9, 0x063e, 0x7bd9,
612 0x4dbf, 0x55ec, 0x672e, 0x7334, 0x5185, 0x4d00, 0x232a, 0x7e07,
613 0x445d, 0x6b92, 0x528f, 0x4255, 0x53ba, 0x7d82, 0x2a2e, 0x3a4e,
614 0x75eb, 0x450c, 0x6844, 0x1b5d, 0x581a, 0x4cc6, 0x0379, 0x37b2,
615 0x419f, 0x0e92, 0x6b27, 0x5624, 0x01e3, 0x07c1, 0x44a5, 0x130c,
616 0x13e8, 0x5910, 0x0876, 0x60c5, 0x54e3, 0x5b7f, 0x2269, 0x509f,
617 0x7665, 0x36fd, 0x3e9a, 0x0579, 0x6295, 0x14ef, 0x0a81, 0x1bcc,
618 0x4b16, 0x64db, 0x0514, 0x4f07, 0x0591, 0x3576, 0x6853, 0x0d9e,
619 0x259f, 0x38b7, 0x64fb, 0x3094, 0x4693, 0x6ddd, 0x29bb, 0x0bc8,
620 0x3f47, 0x490e, 0x0c0e, 0x7933, 0x3c9e, 0x5840, 0x398d, 0x3e68,
621 0x4af1, 0x71f5, 0x57cf, 0x1121, 0x64eb, 0x3579, 0x15ac, 0x584d,
622 0x5f2a, 0x47e2, 0x6528, 0x6eac, 0x196e, 0x6b96, 0x0450, 0x0179,
623 0x609c, 0x06e1, 0x4626, 0x42c7, 0x273e, 0x486f, 0x0705, 0x1601,
624 0x145b, 0x407e, 0x062b, 0x57a5, 0x53f9, 0x5659, 0x4410, 0x3ccd,
625};
626
627static u16 sunxi_nfc_randomizer_step(u16 state, int count)
628{
629 state &= 0x7fff;
630
631 /*
632 * This loop is just a simple implementation of a Fibonacci LFSR using
633 * the x16 + x15 + 1 polynomial.
634 */
635 while (count--)
636 state = ((state >> 1) |
637 (((state ^ (state >> 1)) & 1) << 14)) & 0x7fff;
638
639 return state;
640}
641
642static u16 sunxi_nfc_randomizer_state(struct mtd_info *mtd, int page, bool ecc)
643{
644 const u16 *seeds = sunxi_nfc_randomizer_page_seeds;
Brian Norris46c135c2016-01-22 18:57:13 -0800645 int mod = mtd_div_by_ws(mtd->erasesize, mtd);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100646
647 if (mod > ARRAY_SIZE(sunxi_nfc_randomizer_page_seeds))
648 mod = ARRAY_SIZE(sunxi_nfc_randomizer_page_seeds);
649
650 if (ecc) {
651 if (mtd->ecc_step_size == 512)
652 seeds = sunxi_nfc_randomizer_ecc512_seeds;
653 else
654 seeds = sunxi_nfc_randomizer_ecc1024_seeds;
655 }
656
657 return seeds[page % mod];
658}
659
660static void sunxi_nfc_randomizer_config(struct mtd_info *mtd,
661 int page, bool ecc)
662{
Boris BREZILLONf671a1f2016-03-05 00:21:20 +0100663 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100664 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
665 u32 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL);
666 u16 state;
667
668 if (!(nand->options & NAND_NEED_SCRAMBLING))
669 return;
670
671 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL);
672 state = sunxi_nfc_randomizer_state(mtd, page, ecc);
673 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_RANDOM_SEED_MSK;
674 writel(ecc_ctl | NFC_RANDOM_SEED(state), nfc->regs + NFC_REG_ECC_CTL);
675}
676
677static void sunxi_nfc_randomizer_enable(struct mtd_info *mtd)
678{
Boris BREZILLONf671a1f2016-03-05 00:21:20 +0100679 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100680 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
681
682 if (!(nand->options & NAND_NEED_SCRAMBLING))
683 return;
684
685 writel(readl(nfc->regs + NFC_REG_ECC_CTL) | NFC_RANDOM_EN,
686 nfc->regs + NFC_REG_ECC_CTL);
687}
688
689static void sunxi_nfc_randomizer_disable(struct mtd_info *mtd)
690{
Boris BREZILLONf671a1f2016-03-05 00:21:20 +0100691 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100692 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
693
694 if (!(nand->options & NAND_NEED_SCRAMBLING))
695 return;
696
697 writel(readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_RANDOM_EN,
698 nfc->regs + NFC_REG_ECC_CTL);
699}
700
701static void sunxi_nfc_randomize_bbm(struct mtd_info *mtd, int page, u8 *bbm)
702{
703 u16 state = sunxi_nfc_randomizer_state(mtd, page, true);
704
705 bbm[0] ^= state;
706 bbm[1] ^= sunxi_nfc_randomizer_step(state, 8);
707}
708
709static void sunxi_nfc_randomizer_write_buf(struct mtd_info *mtd,
710 const uint8_t *buf, int len,
711 bool ecc, int page)
712{
713 sunxi_nfc_randomizer_config(mtd, page, ecc);
714 sunxi_nfc_randomizer_enable(mtd);
715 sunxi_nfc_write_buf(mtd, buf, len);
716 sunxi_nfc_randomizer_disable(mtd);
717}
718
719static void sunxi_nfc_randomizer_read_buf(struct mtd_info *mtd, uint8_t *buf,
720 int len, bool ecc, int page)
721{
722 sunxi_nfc_randomizer_config(mtd, page, ecc);
723 sunxi_nfc_randomizer_enable(mtd);
724 sunxi_nfc_read_buf(mtd, buf, len);
725 sunxi_nfc_randomizer_disable(mtd);
726}
727
Boris BREZILLONc9118ec2015-09-30 23:45:23 +0200728static void sunxi_nfc_hw_ecc_enable(struct mtd_info *mtd)
729{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100730 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLONc9118ec2015-09-30 23:45:23 +0200731 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
732 struct sunxi_nand_hw_ecc *data = nand->ecc.priv;
733 u32 ecc_ctl;
734
735 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL);
736 ecc_ctl &= ~(NFC_ECC_MODE_MSK | NFC_ECC_PIPELINE |
737 NFC_ECC_BLOCK_SIZE_MSK);
Boris Brezillon336de7b2016-03-04 17:33:10 +0100738 ecc_ctl |= NFC_ECC_EN | NFC_ECC_MODE(data->mode) | NFC_ECC_EXCEPTION |
739 NFC_ECC_PIPELINE;
Boris BREZILLONc9118ec2015-09-30 23:45:23 +0200740
741 writel(ecc_ctl, nfc->regs + NFC_REG_ECC_CTL);
742}
743
744static void sunxi_nfc_hw_ecc_disable(struct mtd_info *mtd)
745{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100746 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLONc9118ec2015-09-30 23:45:23 +0200747 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
748
749 writel(readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_ECC_EN,
750 nfc->regs + NFC_REG_ECC_CTL);
751}
752
Boris BREZILLONf363e0f2015-09-30 23:45:27 +0200753static inline void sunxi_nfc_user_data_to_buf(u32 user_data, u8 *buf)
754{
755 buf[0] = user_data;
756 buf[1] = user_data >> 8;
757 buf[2] = user_data >> 16;
758 buf[3] = user_data >> 24;
759}
760
Boris BREZILLON913821b2015-09-30 23:45:24 +0200761static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd,
762 u8 *data, int data_off,
763 u8 *oob, int oob_off,
764 int *cur_off,
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100765 unsigned int *max_bitflips,
766 bool bbm, int page)
Boris BREZILLON913821b2015-09-30 23:45:24 +0200767{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100768 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200769 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
770 struct nand_ecc_ctrl *ecc = &nand->ecc;
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100771 int raw_mode = 0;
Boris BREZILLON913821b2015-09-30 23:45:24 +0200772 u32 status;
773 int ret;
774
775 if (*cur_off != data_off)
776 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, data_off, -1);
777
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100778 sunxi_nfc_randomizer_read_buf(mtd, NULL, ecc->size, false, page);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200779
Boris BREZILLON74eb9ff2015-10-20 22:16:00 +0200780 if (data_off + ecc->size != oob_off)
Boris BREZILLON913821b2015-09-30 23:45:24 +0200781 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
782
783 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
784 if (ret)
785 return ret;
786
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100787 sunxi_nfc_randomizer_enable(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200788 writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_ECC_OP,
789 nfc->regs + NFC_REG_CMD);
790
791 ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100792 sunxi_nfc_randomizer_disable(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200793 if (ret)
794 return ret;
795
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100796 *cur_off = oob_off + ecc->bytes + 4;
797
Boris BREZILLON913821b2015-09-30 23:45:24 +0200798 status = readl(nfc->regs + NFC_REG_ECC_ST);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100799 if (status & NFC_ECC_PAT_FOUND(0)) {
800 u8 pattern = 0xff;
801
802 if (unlikely(!(readl(nfc->regs + NFC_REG_PAT_ID) & 0x1)))
803 pattern = 0x0;
804
805 memset(data, pattern, ecc->size);
806 memset(oob, pattern, ecc->bytes + 4);
807
808 return 1;
809 }
810
Boris BREZILLON913821b2015-09-30 23:45:24 +0200811 ret = NFC_ECC_ERR_CNT(0, readl(nfc->regs + NFC_REG_ECC_ERR_CNT(0)));
812
813 memcpy_fromio(data, nfc->regs + NFC_RAM0_BASE, ecc->size);
814
815 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100816 sunxi_nfc_randomizer_read_buf(mtd, oob, ecc->bytes + 4, true, page);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200817
Boris BREZILLONf363e0f2015-09-30 23:45:27 +0200818 if (status & NFC_ECC_ERR(0)) {
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100819 /*
820 * Re-read the data with the randomizer disabled to identify
821 * bitflips in erased pages.
822 */
823 if (nand->options & NAND_NEED_SCRAMBLING) {
824 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, data_off, -1);
825 nand->read_buf(mtd, data, ecc->size);
826 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
827 nand->read_buf(mtd, oob, ecc->bytes + 4);
828 }
829
Boris BREZILLON146b5032015-09-30 23:45:29 +0200830 ret = nand_check_erased_ecc_chunk(data, ecc->size,
831 oob, ecc->bytes + 4,
832 NULL, 0, ecc->strength);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100833 if (ret >= 0)
834 raw_mode = 1;
Boris BREZILLONf363e0f2015-09-30 23:45:27 +0200835 } else {
836 /*
837 * The engine protects 4 bytes of OOB data per chunk.
838 * Retrieve the corrected OOB bytes.
839 */
840 sunxi_nfc_user_data_to_buf(readl(nfc->regs + NFC_REG_USER_DATA(0)),
841 oob);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100842
843 /* De-randomize the Bad Block Marker. */
844 if (bbm && nand->options & NAND_NEED_SCRAMBLING)
845 sunxi_nfc_randomize_bbm(mtd, page, oob);
Boris BREZILLONf363e0f2015-09-30 23:45:27 +0200846 }
Boris BREZILLON913821b2015-09-30 23:45:24 +0200847
848 if (ret < 0) {
849 mtd->ecc_stats.failed++;
850 } else {
851 mtd->ecc_stats.corrected += ret;
852 *max_bitflips = max_t(unsigned int, *max_bitflips, ret);
853 }
854
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100855 return raw_mode;
Boris BREZILLON913821b2015-09-30 23:45:24 +0200856}
857
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200858static void sunxi_nfc_hw_ecc_read_extra_oob(struct mtd_info *mtd,
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100859 u8 *oob, int *cur_off,
860 bool randomize, int page)
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200861{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100862 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200863 struct nand_ecc_ctrl *ecc = &nand->ecc;
864 int offset = ((ecc->bytes + 4) * ecc->steps);
865 int len = mtd->oobsize - offset;
866
867 if (len <= 0)
868 return;
869
870 if (*cur_off != offset)
871 nand->cmdfunc(mtd, NAND_CMD_RNDOUT,
872 offset + mtd->writesize, -1);
873
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100874 if (!randomize)
875 sunxi_nfc_read_buf(mtd, oob + offset, len);
876 else
877 sunxi_nfc_randomizer_read_buf(mtd, oob + offset, len,
878 false, page);
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200879
880 *cur_off = mtd->oobsize + mtd->writesize;
881}
882
Boris BREZILLON23151fd2015-09-30 23:45:28 +0200883static inline u32 sunxi_nfc_buf_to_user_data(const u8 *buf)
884{
885 return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
886}
887
Boris BREZILLON913821b2015-09-30 23:45:24 +0200888static int sunxi_nfc_hw_ecc_write_chunk(struct mtd_info *mtd,
889 const u8 *data, int data_off,
890 const u8 *oob, int oob_off,
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100891 int *cur_off, bool bbm,
892 int page)
Boris BREZILLON913821b2015-09-30 23:45:24 +0200893{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100894 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200895 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
896 struct nand_ecc_ctrl *ecc = &nand->ecc;
897 int ret;
898
899 if (data_off != *cur_off)
900 nand->cmdfunc(mtd, NAND_CMD_RNDIN, data_off, -1);
901
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100902 sunxi_nfc_randomizer_write_buf(mtd, data, ecc->size, false, page);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200903
904 /* Fill OOB data in */
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100905 if ((nand->options & NAND_NEED_SCRAMBLING) && bbm) {
906 u8 user_data[4];
907
908 memcpy(user_data, oob, 4);
909 sunxi_nfc_randomize_bbm(mtd, page, user_data);
910 writel(sunxi_nfc_buf_to_user_data(user_data),
911 nfc->regs + NFC_REG_USER_DATA(0));
912 } else {
913 writel(sunxi_nfc_buf_to_user_data(oob),
914 nfc->regs + NFC_REG_USER_DATA(0));
915 }
Boris BREZILLON913821b2015-09-30 23:45:24 +0200916
Boris BREZILLON74eb9ff2015-10-20 22:16:00 +0200917 if (data_off + ecc->size != oob_off)
Boris BREZILLON913821b2015-09-30 23:45:24 +0200918 nand->cmdfunc(mtd, NAND_CMD_RNDIN, oob_off, -1);
919
920 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
921 if (ret)
922 return ret;
923
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100924 sunxi_nfc_randomizer_enable(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200925 writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD |
926 NFC_ACCESS_DIR | NFC_ECC_OP,
927 nfc->regs + NFC_REG_CMD);
928
929 ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100930 sunxi_nfc_randomizer_disable(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200931 if (ret)
932 return ret;
933
934 *cur_off = oob_off + ecc->bytes + 4;
935
936 return 0;
937}
938
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200939static void sunxi_nfc_hw_ecc_write_extra_oob(struct mtd_info *mtd,
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100940 u8 *oob, int *cur_off,
941 int page)
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200942{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100943 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200944 struct nand_ecc_ctrl *ecc = &nand->ecc;
945 int offset = ((ecc->bytes + 4) * ecc->steps);
946 int len = mtd->oobsize - offset;
947
948 if (len <= 0)
949 return;
950
951 if (*cur_off != offset)
952 nand->cmdfunc(mtd, NAND_CMD_RNDIN,
953 offset + mtd->writesize, -1);
954
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100955 sunxi_nfc_randomizer_write_buf(mtd, oob + offset, len, false, page);
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200956
957 *cur_off = mtd->oobsize + mtd->writesize;
958}
959
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200960static int sunxi_nfc_hw_ecc_read_page(struct mtd_info *mtd,
961 struct nand_chip *chip, uint8_t *buf,
962 int oob_required, int page)
963{
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200964 struct nand_ecc_ctrl *ecc = &chip->ecc;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200965 unsigned int max_bitflips = 0;
Boris BREZILLONb4625512015-09-30 23:45:25 +0200966 int ret, i, cur_off = 0;
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100967 bool raw_mode = false;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200968
Boris BREZILLONc9118ec2015-09-30 23:45:23 +0200969 sunxi_nfc_hw_ecc_enable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200970
971 for (i = 0; i < ecc->steps; i++) {
Boris BREZILLONb4625512015-09-30 23:45:25 +0200972 int data_off = i * ecc->size;
973 int oob_off = i * (ecc->bytes + 4);
974 u8 *data = buf + data_off;
975 u8 *oob = chip->oob_poi + oob_off;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200976
Boris BREZILLONb4625512015-09-30 23:45:25 +0200977 ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off, oob,
978 oob_off + mtd->writesize,
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100979 &cur_off, &max_bitflips,
980 !i, page);
981 if (ret < 0)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200982 return ret;
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100983 else if (ret)
984 raw_mode = true;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200985 }
986
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200987 if (oob_required)
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100988 sunxi_nfc_hw_ecc_read_extra_oob(mtd, chip->oob_poi, &cur_off,
989 !raw_mode, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200990
Boris BREZILLONc9118ec2015-09-30 23:45:23 +0200991 sunxi_nfc_hw_ecc_disable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200992
993 return max_bitflips;
994}
995
Boris Brezillonfe82cce2015-09-16 09:01:45 +0200996static int sunxi_nfc_hw_ecc_read_subpage(struct mtd_info *mtd,
997 struct nand_chip *chip,
998 u32 data_offs, u32 readlen,
999 u8 *bufpoi, int page)
1000{
1001 struct nand_ecc_ctrl *ecc = &chip->ecc;
1002 int ret, i, cur_off = 0;
1003 unsigned int max_bitflips = 0;
1004
1005 sunxi_nfc_hw_ecc_enable(mtd);
1006
1007 chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
1008 for (i = data_offs / ecc->size;
1009 i < DIV_ROUND_UP(data_offs + readlen, ecc->size); i++) {
1010 int data_off = i * ecc->size;
1011 int oob_off = i * (ecc->bytes + 4);
1012 u8 *data = bufpoi + data_off;
1013 u8 *oob = chip->oob_poi + oob_off;
1014
1015 ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off,
1016 oob,
1017 oob_off + mtd->writesize,
1018 &cur_off, &max_bitflips,
1019 !i, page);
1020 if (ret < 0)
1021 return ret;
1022 }
1023
1024 sunxi_nfc_hw_ecc_disable(mtd);
1025
1026 return max_bitflips;
1027}
1028
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001029static int sunxi_nfc_hw_ecc_write_page(struct mtd_info *mtd,
1030 struct nand_chip *chip,
Boris BREZILLON45aaeff2015-10-13 11:22:18 +02001031 const uint8_t *buf, int oob_required,
1032 int page)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001033{
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001034 struct nand_ecc_ctrl *ecc = &chip->ecc;
Boris BREZILLONb4625512015-09-30 23:45:25 +02001035 int ret, i, cur_off = 0;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001036
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001037 sunxi_nfc_hw_ecc_enable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001038
1039 for (i = 0; i < ecc->steps; i++) {
Boris BREZILLONb4625512015-09-30 23:45:25 +02001040 int data_off = i * ecc->size;
1041 int oob_off = i * (ecc->bytes + 4);
1042 const u8 *data = buf + data_off;
1043 const u8 *oob = chip->oob_poi + oob_off;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001044
Boris BREZILLONb4625512015-09-30 23:45:25 +02001045 ret = sunxi_nfc_hw_ecc_write_chunk(mtd, data, data_off, oob,
1046 oob_off + mtd->writesize,
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001047 &cur_off, !i, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001048 if (ret)
1049 return ret;
1050 }
1051
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001052 if (oob_required || (chip->options & NAND_NEED_SCRAMBLING))
1053 sunxi_nfc_hw_ecc_write_extra_oob(mtd, chip->oob_poi,
1054 &cur_off, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001055
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001056 sunxi_nfc_hw_ecc_disable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001057
1058 return 0;
1059}
1060
1061static int sunxi_nfc_hw_syndrome_ecc_read_page(struct mtd_info *mtd,
1062 struct nand_chip *chip,
1063 uint8_t *buf, int oob_required,
1064 int page)
1065{
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001066 struct nand_ecc_ctrl *ecc = &chip->ecc;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001067 unsigned int max_bitflips = 0;
Boris BREZILLONb4625512015-09-30 23:45:25 +02001068 int ret, i, cur_off = 0;
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001069 bool raw_mode = false;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001070
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001071 sunxi_nfc_hw_ecc_enable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001072
1073 for (i = 0; i < ecc->steps; i++) {
Boris BREZILLONb4625512015-09-30 23:45:25 +02001074 int data_off = i * (ecc->size + ecc->bytes + 4);
1075 int oob_off = data_off + ecc->size;
1076 u8 *data = buf + (i * ecc->size);
1077 u8 *oob = chip->oob_poi + (i * (ecc->bytes + 4));
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001078
Boris BREZILLONb4625512015-09-30 23:45:25 +02001079 ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off, oob,
1080 oob_off, &cur_off,
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001081 &max_bitflips, !i, page);
1082 if (ret < 0)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001083 return ret;
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001084 else if (ret)
1085 raw_mode = true;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001086 }
1087
Boris BREZILLON35d0e242015-09-30 23:45:26 +02001088 if (oob_required)
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001089 sunxi_nfc_hw_ecc_read_extra_oob(mtd, chip->oob_poi, &cur_off,
1090 !raw_mode, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001091
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001092 sunxi_nfc_hw_ecc_disable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001093
1094 return max_bitflips;
1095}
1096
1097static int sunxi_nfc_hw_syndrome_ecc_write_page(struct mtd_info *mtd,
1098 struct nand_chip *chip,
1099 const uint8_t *buf,
Boris BREZILLON45aaeff2015-10-13 11:22:18 +02001100 int oob_required, int page)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001101{
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001102 struct nand_ecc_ctrl *ecc = &chip->ecc;
Boris BREZILLONb4625512015-09-30 23:45:25 +02001103 int ret, i, cur_off = 0;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001104
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001105 sunxi_nfc_hw_ecc_enable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001106
1107 for (i = 0; i < ecc->steps; i++) {
Boris BREZILLONb4625512015-09-30 23:45:25 +02001108 int data_off = i * (ecc->size + ecc->bytes + 4);
1109 int oob_off = data_off + ecc->size;
1110 const u8 *data = buf + (i * ecc->size);
1111 const u8 *oob = chip->oob_poi + (i * (ecc->bytes + 4));
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001112
Boris BREZILLONb4625512015-09-30 23:45:25 +02001113 ret = sunxi_nfc_hw_ecc_write_chunk(mtd, data, data_off,
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001114 oob, oob_off, &cur_off,
1115 false, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001116 if (ret)
1117 return ret;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001118 }
1119
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001120 if (oob_required || (chip->options & NAND_NEED_SCRAMBLING))
1121 sunxi_nfc_hw_ecc_write_extra_oob(mtd, chip->oob_poi,
1122 &cur_off, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001123
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001124 sunxi_nfc_hw_ecc_disable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001125
1126 return 0;
1127}
1128
Boris Brezillon1c1bdd62015-09-02 15:05:52 +02001129static int sunxi_nfc_hw_common_ecc_read_oob(struct mtd_info *mtd,
1130 struct nand_chip *chip,
1131 int page)
1132{
1133 chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
1134
1135 chip->pagebuf = -1;
1136
1137 return chip->ecc.read_page(mtd, chip, chip->buffers->databuf, 1, page);
1138}
1139
1140static int sunxi_nfc_hw_common_ecc_write_oob(struct mtd_info *mtd,
1141 struct nand_chip *chip,
1142 int page)
1143{
1144 int ret, status;
1145
1146 chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0, page);
1147
1148 chip->pagebuf = -1;
1149
1150 memset(chip->buffers->databuf, 0xff, mtd->writesize);
1151 ret = chip->ecc.write_page(mtd, chip, chip->buffers->databuf, 1, page);
1152 if (ret)
1153 return ret;
1154
1155 /* Send command to program the OOB data */
1156 chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
1157
1158 status = chip->waitfunc(mtd, chip);
1159
1160 return status & NAND_STATUS_FAIL ? -EIO : 0;
1161}
1162
Roy Spliet9c618292015-06-26 11:00:10 +02001163static const s32 tWB_lut[] = {6, 12, 16, 20};
1164static const s32 tRHW_lut[] = {4, 8, 12, 20};
1165
1166static int _sunxi_nand_lookup_timing(const s32 *lut, int lut_size, u32 duration,
1167 u32 clk_period)
1168{
1169 u32 clk_cycles = DIV_ROUND_UP(duration, clk_period);
1170 int i;
1171
1172 for (i = 0; i < lut_size; i++) {
1173 if (clk_cycles <= lut[i])
1174 return i;
1175 }
1176
1177 /* Doesn't fit */
1178 return -EINVAL;
1179}
1180
1181#define sunxi_nand_lookup_timing(l, p, c) \
1182 _sunxi_nand_lookup_timing(l, ARRAY_SIZE(l), p, c)
1183
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001184static int sunxi_nand_chip_set_timings(struct sunxi_nand_chip *chip,
1185 const struct nand_sdr_timings *timings)
1186{
Roy Spliet9c618292015-06-26 11:00:10 +02001187 struct sunxi_nfc *nfc = to_sunxi_nfc(chip->nand.controller);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001188 u32 min_clk_period = 0;
Roy Spliet9c618292015-06-26 11:00:10 +02001189 s32 tWB, tADL, tWHR, tRHW, tCAD;
Boris Brezillon2d434572015-12-02 15:57:20 +01001190 long real_clk_rate;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001191
1192 /* T1 <=> tCLS */
1193 if (timings->tCLS_min > min_clk_period)
1194 min_clk_period = timings->tCLS_min;
1195
1196 /* T2 <=> tCLH */
1197 if (timings->tCLH_min > min_clk_period)
1198 min_clk_period = timings->tCLH_min;
1199
1200 /* T3 <=> tCS */
1201 if (timings->tCS_min > min_clk_period)
1202 min_clk_period = timings->tCS_min;
1203
1204 /* T4 <=> tCH */
1205 if (timings->tCH_min > min_clk_period)
1206 min_clk_period = timings->tCH_min;
1207
1208 /* T5 <=> tWP */
1209 if (timings->tWP_min > min_clk_period)
1210 min_clk_period = timings->tWP_min;
1211
1212 /* T6 <=> tWH */
1213 if (timings->tWH_min > min_clk_period)
1214 min_clk_period = timings->tWH_min;
1215
1216 /* T7 <=> tALS */
1217 if (timings->tALS_min > min_clk_period)
1218 min_clk_period = timings->tALS_min;
1219
1220 /* T8 <=> tDS */
1221 if (timings->tDS_min > min_clk_period)
1222 min_clk_period = timings->tDS_min;
1223
1224 /* T9 <=> tDH */
1225 if (timings->tDH_min > min_clk_period)
1226 min_clk_period = timings->tDH_min;
1227
1228 /* T10 <=> tRR */
1229 if (timings->tRR_min > (min_clk_period * 3))
1230 min_clk_period = DIV_ROUND_UP(timings->tRR_min, 3);
1231
1232 /* T11 <=> tALH */
1233 if (timings->tALH_min > min_clk_period)
1234 min_clk_period = timings->tALH_min;
1235
1236 /* T12 <=> tRP */
1237 if (timings->tRP_min > min_clk_period)
1238 min_clk_period = timings->tRP_min;
1239
1240 /* T13 <=> tREH */
1241 if (timings->tREH_min > min_clk_period)
1242 min_clk_period = timings->tREH_min;
1243
1244 /* T14 <=> tRC */
1245 if (timings->tRC_min > (min_clk_period * 2))
1246 min_clk_period = DIV_ROUND_UP(timings->tRC_min, 2);
1247
1248 /* T15 <=> tWC */
1249 if (timings->tWC_min > (min_clk_period * 2))
1250 min_clk_period = DIV_ROUND_UP(timings->tWC_min, 2);
1251
Roy Spliet9c618292015-06-26 11:00:10 +02001252 /* T16 - T19 + tCAD */
Boris Brezillon5abcd952015-11-11 22:30:30 +01001253 if (timings->tWB_max > (min_clk_period * 20))
1254 min_clk_period = DIV_ROUND_UP(timings->tWB_max, 20);
1255
1256 if (timings->tADL_min > (min_clk_period * 32))
1257 min_clk_period = DIV_ROUND_UP(timings->tADL_min, 32);
1258
1259 if (timings->tWHR_min > (min_clk_period * 32))
1260 min_clk_period = DIV_ROUND_UP(timings->tWHR_min, 32);
1261
1262 if (timings->tRHW_min > (min_clk_period * 20))
1263 min_clk_period = DIV_ROUND_UP(timings->tRHW_min, 20);
1264
Roy Spliet9c618292015-06-26 11:00:10 +02001265 tWB = sunxi_nand_lookup_timing(tWB_lut, timings->tWB_max,
1266 min_clk_period);
1267 if (tWB < 0) {
1268 dev_err(nfc->dev, "unsupported tWB\n");
1269 return tWB;
1270 }
1271
1272 tADL = DIV_ROUND_UP(timings->tADL_min, min_clk_period) >> 3;
1273 if (tADL > 3) {
1274 dev_err(nfc->dev, "unsupported tADL\n");
1275 return -EINVAL;
1276 }
1277
1278 tWHR = DIV_ROUND_UP(timings->tWHR_min, min_clk_period) >> 3;
1279 if (tWHR > 3) {
1280 dev_err(nfc->dev, "unsupported tWHR\n");
1281 return -EINVAL;
1282 }
1283
1284 tRHW = sunxi_nand_lookup_timing(tRHW_lut, timings->tRHW_min,
1285 min_clk_period);
1286 if (tRHW < 0) {
1287 dev_err(nfc->dev, "unsupported tRHW\n");
1288 return tRHW;
1289 }
1290
1291 /*
1292 * TODO: according to ONFI specs this value only applies for DDR NAND,
1293 * but Allwinner seems to set this to 0x7. Mimic them for now.
1294 */
1295 tCAD = 0x7;
1296
1297 /* TODO: A83 has some more bits for CDQSS, CS, CLHZ, CCS, WC */
1298 chip->timing_cfg = NFC_TIMING_CFG(tWB, tADL, tWHR, tRHW, tCAD);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001299
1300 /* Convert min_clk_period from picoseconds to nanoseconds */
1301 min_clk_period = DIV_ROUND_UP(min_clk_period, 1000);
1302
1303 /*
Boris Brezillon2f9992e2015-12-02 15:10:40 +01001304 * Unlike what is stated in Allwinner datasheet, the clk_rate should
1305 * be set to (1 / min_clk_period), and not (2 / min_clk_period).
1306 * This new formula was verified with a scope and validated by
1307 * Allwinner engineers.
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001308 */
Boris Brezillon2f9992e2015-12-02 15:10:40 +01001309 chip->clk_rate = NSEC_PER_SEC / min_clk_period;
Boris Brezillon2d434572015-12-02 15:57:20 +01001310 real_clk_rate = clk_round_rate(nfc->mod_clk, chip->clk_rate);
1311
1312 /*
1313 * ONFI specification 3.1, paragraph 4.15.2 dictates that EDO data
1314 * output cycle timings shall be used if the host drives tRC less than
1315 * 30 ns.
1316 */
1317 min_clk_period = NSEC_PER_SEC / real_clk_rate;
1318 chip->timing_ctl = ((min_clk_period * 2) < 30) ?
1319 NFC_TIMING_CTL_EDO : 0;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001320
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001321 return 0;
1322}
1323
1324static int sunxi_nand_chip_init_timings(struct sunxi_nand_chip *chip,
1325 struct device_node *np)
1326{
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001327 struct mtd_info *mtd = nand_to_mtd(&chip->nand);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001328 const struct nand_sdr_timings *timings;
1329 int ret;
1330 int mode;
1331
1332 mode = onfi_get_async_timing_mode(&chip->nand);
1333 if (mode == ONFI_TIMING_MODE_UNKNOWN) {
1334 mode = chip->nand.onfi_timing_mode_default;
1335 } else {
1336 uint8_t feature[ONFI_SUBFEATURE_PARAM_LEN] = {};
Stefan Roese7eadd472015-08-28 14:45:21 +02001337 int i;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001338
1339 mode = fls(mode) - 1;
1340 if (mode < 0)
1341 mode = 0;
1342
1343 feature[0] = mode;
Stefan Roese7eadd472015-08-28 14:45:21 +02001344 for (i = 0; i < chip->nsels; i++) {
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001345 chip->nand.select_chip(mtd, i);
1346 ret = chip->nand.onfi_set_features(mtd, &chip->nand,
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001347 ONFI_FEATURE_ADDR_TIMING_MODE,
1348 feature);
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001349 chip->nand.select_chip(mtd, -1);
Stefan Roese7eadd472015-08-28 14:45:21 +02001350 if (ret)
1351 return ret;
1352 }
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001353 }
1354
1355 timings = onfi_async_timing_mode_to_sdr_timings(mode);
1356 if (IS_ERR(timings))
1357 return PTR_ERR(timings);
1358
1359 return sunxi_nand_chip_set_timings(chip, timings);
1360}
1361
1362static int sunxi_nand_hw_common_ecc_ctrl_init(struct mtd_info *mtd,
1363 struct nand_ecc_ctrl *ecc,
1364 struct device_node *np)
1365{
1366 static const u8 strengths[] = { 16, 24, 28, 32, 40, 48, 56, 60, 64 };
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +01001367 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001368 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
1369 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
1370 struct sunxi_nand_hw_ecc *data;
1371 struct nand_ecclayout *layout;
1372 int nsectors;
1373 int ret;
1374 int i;
1375
1376 data = kzalloc(sizeof(*data), GFP_KERNEL);
1377 if (!data)
1378 return -ENOMEM;
1379
1380 /* Add ECC info retrieval from DT */
1381 for (i = 0; i < ARRAY_SIZE(strengths); i++) {
1382 if (ecc->strength <= strengths[i])
1383 break;
1384 }
1385
1386 if (i >= ARRAY_SIZE(strengths)) {
1387 dev_err(nfc->dev, "unsupported strength\n");
1388 ret = -ENOTSUPP;
1389 goto err;
1390 }
1391
1392 data->mode = i;
1393
1394 /* HW ECC always request ECC bytes for 1024 bytes blocks */
1395 ecc->bytes = DIV_ROUND_UP(ecc->strength * fls(8 * 1024), 8);
1396
1397 /* HW ECC always work with even numbers of ECC bytes */
1398 ecc->bytes = ALIGN(ecc->bytes, 2);
1399
1400 layout = &data->layout;
1401 nsectors = mtd->writesize / ecc->size;
1402
1403 if (mtd->oobsize < ((ecc->bytes + 4) * nsectors)) {
1404 ret = -EINVAL;
1405 goto err;
1406 }
1407
1408 layout->eccbytes = (ecc->bytes * nsectors);
1409
Boris Brezillon1c1bdd62015-09-02 15:05:52 +02001410 ecc->read_oob = sunxi_nfc_hw_common_ecc_read_oob;
1411 ecc->write_oob = sunxi_nfc_hw_common_ecc_write_oob;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001412 ecc->layout = layout;
1413 ecc->priv = data;
1414
1415 return 0;
1416
1417err:
1418 kfree(data);
1419
1420 return ret;
1421}
1422
1423static void sunxi_nand_hw_common_ecc_ctrl_cleanup(struct nand_ecc_ctrl *ecc)
1424{
1425 kfree(ecc->priv);
1426}
1427
1428static int sunxi_nand_hw_ecc_ctrl_init(struct mtd_info *mtd,
1429 struct nand_ecc_ctrl *ecc,
1430 struct device_node *np)
1431{
1432 struct nand_ecclayout *layout;
1433 int nsectors;
1434 int i, j;
1435 int ret;
1436
1437 ret = sunxi_nand_hw_common_ecc_ctrl_init(mtd, ecc, np);
1438 if (ret)
1439 return ret;
1440
1441 ecc->read_page = sunxi_nfc_hw_ecc_read_page;
1442 ecc->write_page = sunxi_nfc_hw_ecc_write_page;
Boris Brezillon1c1bdd62015-09-02 15:05:52 +02001443 ecc->read_oob_raw = nand_read_oob_std;
1444 ecc->write_oob_raw = nand_write_oob_std;
Boris Brezillonfe82cce2015-09-16 09:01:45 +02001445 ecc->read_subpage = sunxi_nfc_hw_ecc_read_subpage;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001446 layout = ecc->layout;
1447 nsectors = mtd->writesize / ecc->size;
1448
1449 for (i = 0; i < nsectors; i++) {
1450 if (i) {
1451 layout->oobfree[i].offset =
1452 layout->oobfree[i - 1].offset +
1453 layout->oobfree[i - 1].length +
1454 ecc->bytes;
1455 layout->oobfree[i].length = 4;
1456 } else {
1457 /*
1458 * The first 2 bytes are used for BB markers, hence we
1459 * only have 2 bytes available in the first user data
1460 * section.
1461 */
1462 layout->oobfree[i].length = 2;
1463 layout->oobfree[i].offset = 2;
1464 }
1465
1466 for (j = 0; j < ecc->bytes; j++)
1467 layout->eccpos[(ecc->bytes * i) + j] =
1468 layout->oobfree[i].offset +
1469 layout->oobfree[i].length + j;
1470 }
1471
1472 if (mtd->oobsize > (ecc->bytes + 4) * nsectors) {
1473 layout->oobfree[nsectors].offset =
1474 layout->oobfree[nsectors - 1].offset +
1475 layout->oobfree[nsectors - 1].length +
1476 ecc->bytes;
1477 layout->oobfree[nsectors].length = mtd->oobsize -
1478 ((ecc->bytes + 4) * nsectors);
1479 }
1480
1481 return 0;
1482}
1483
1484static int sunxi_nand_hw_syndrome_ecc_ctrl_init(struct mtd_info *mtd,
1485 struct nand_ecc_ctrl *ecc,
1486 struct device_node *np)
1487{
1488 struct nand_ecclayout *layout;
1489 int nsectors;
1490 int i;
1491 int ret;
1492
1493 ret = sunxi_nand_hw_common_ecc_ctrl_init(mtd, ecc, np);
1494 if (ret)
1495 return ret;
1496
1497 ecc->prepad = 4;
1498 ecc->read_page = sunxi_nfc_hw_syndrome_ecc_read_page;
1499 ecc->write_page = sunxi_nfc_hw_syndrome_ecc_write_page;
Boris Brezillon1c1bdd62015-09-02 15:05:52 +02001500 ecc->read_oob_raw = nand_read_oob_syndrome;
1501 ecc->write_oob_raw = nand_write_oob_syndrome;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001502
1503 layout = ecc->layout;
1504 nsectors = mtd->writesize / ecc->size;
1505
1506 for (i = 0; i < (ecc->bytes * nsectors); i++)
1507 layout->eccpos[i] = i;
1508
1509 layout->oobfree[0].length = mtd->oobsize - i;
1510 layout->oobfree[0].offset = i;
1511
1512 return 0;
1513}
1514
1515static void sunxi_nand_ecc_cleanup(struct nand_ecc_ctrl *ecc)
1516{
1517 switch (ecc->mode) {
1518 case NAND_ECC_HW:
1519 case NAND_ECC_HW_SYNDROME:
1520 sunxi_nand_hw_common_ecc_ctrl_cleanup(ecc);
1521 break;
1522 case NAND_ECC_NONE:
1523 kfree(ecc->layout);
1524 default:
1525 break;
1526 }
1527}
1528
1529static int sunxi_nand_ecc_init(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc,
1530 struct device_node *np)
1531{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +01001532 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001533 int ret;
1534
Boris BREZILLONa3d22a52015-09-02 10:30:25 +02001535 if (!ecc->size) {
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001536 ecc->size = nand->ecc_step_ds;
1537 ecc->strength = nand->ecc_strength_ds;
1538 }
1539
1540 if (!ecc->size || !ecc->strength)
1541 return -EINVAL;
1542
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001543 switch (ecc->mode) {
1544 case NAND_ECC_SOFT_BCH:
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001545 break;
1546 case NAND_ECC_HW:
1547 ret = sunxi_nand_hw_ecc_ctrl_init(mtd, ecc, np);
1548 if (ret)
1549 return ret;
1550 break;
1551 case NAND_ECC_HW_SYNDROME:
1552 ret = sunxi_nand_hw_syndrome_ecc_ctrl_init(mtd, ecc, np);
1553 if (ret)
1554 return ret;
1555 break;
1556 case NAND_ECC_NONE:
1557 ecc->layout = kzalloc(sizeof(*ecc->layout), GFP_KERNEL);
1558 if (!ecc->layout)
1559 return -ENOMEM;
1560 ecc->layout->oobfree[0].length = mtd->oobsize;
1561 case NAND_ECC_SOFT:
1562 break;
1563 default:
1564 return -EINVAL;
1565 }
1566
1567 return 0;
1568}
1569
1570static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc,
1571 struct device_node *np)
1572{
1573 const struct nand_sdr_timings *timings;
1574 struct sunxi_nand_chip *chip;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001575 struct mtd_info *mtd;
1576 struct nand_chip *nand;
1577 int nsels;
1578 int ret;
1579 int i;
1580 u32 tmp;
1581
1582 if (!of_get_property(np, "reg", &nsels))
1583 return -EINVAL;
1584
1585 nsels /= sizeof(u32);
1586 if (!nsels) {
1587 dev_err(dev, "invalid reg property size\n");
1588 return -EINVAL;
1589 }
1590
1591 chip = devm_kzalloc(dev,
1592 sizeof(*chip) +
1593 (nsels * sizeof(struct sunxi_nand_chip_sel)),
1594 GFP_KERNEL);
1595 if (!chip) {
1596 dev_err(dev, "could not allocate chip\n");
1597 return -ENOMEM;
1598 }
1599
1600 chip->nsels = nsels;
1601 chip->selected = -1;
1602
1603 for (i = 0; i < nsels; i++) {
1604 ret = of_property_read_u32_index(np, "reg", i, &tmp);
1605 if (ret) {
1606 dev_err(dev, "could not retrieve reg property: %d\n",
1607 ret);
1608 return ret;
1609 }
1610
1611 if (tmp > NFC_MAX_CS) {
1612 dev_err(dev,
1613 "invalid reg value: %u (max CS = 7)\n",
1614 tmp);
1615 return -EINVAL;
1616 }
1617
1618 if (test_and_set_bit(tmp, &nfc->assigned_cs)) {
1619 dev_err(dev, "CS %d already assigned\n", tmp);
1620 return -EINVAL;
1621 }
1622
1623 chip->sels[i].cs = tmp;
1624
1625 if (!of_property_read_u32_index(np, "allwinner,rb", i, &tmp) &&
1626 tmp < 2) {
1627 chip->sels[i].rb.type = RB_NATIVE;
1628 chip->sels[i].rb.info.nativeid = tmp;
1629 } else {
1630 ret = of_get_named_gpio(np, "rb-gpios", i);
1631 if (ret >= 0) {
1632 tmp = ret;
1633 chip->sels[i].rb.type = RB_GPIO;
1634 chip->sels[i].rb.info.gpio = tmp;
1635 ret = devm_gpio_request(dev, tmp, "nand-rb");
1636 if (ret)
1637 return ret;
1638
1639 ret = gpio_direction_input(tmp);
1640 if (ret)
1641 return ret;
1642 } else {
1643 chip->sels[i].rb.type = RB_NONE;
1644 }
1645 }
1646 }
1647
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001648 nand = &chip->nand;
1649 /* Default tR value specified in the ONFI spec (chapter 4.15.1) */
1650 nand->chip_delay = 200;
1651 nand->controller = &nfc->controller;
Boris BREZILLONa3d22a52015-09-02 10:30:25 +02001652 /*
1653 * Set the ECC mode to the default value in case nothing is specified
1654 * in the DT.
1655 */
1656 nand->ecc.mode = NAND_ECC_HW;
Brian Norris63752192015-10-30 20:33:23 -07001657 nand_set_flash_node(nand, np);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001658 nand->select_chip = sunxi_nfc_select_chip;
1659 nand->cmd_ctrl = sunxi_nfc_cmd_ctrl;
1660 nand->read_buf = sunxi_nfc_read_buf;
1661 nand->write_buf = sunxi_nfc_write_buf;
1662 nand->read_byte = sunxi_nfc_read_byte;
1663
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001664 mtd = nand_to_mtd(nand);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001665 mtd->dev.parent = dev;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001666
Boris Brezillon9edb4702015-12-02 16:00:57 +01001667 timings = onfi_async_timing_mode_to_sdr_timings(0);
1668 if (IS_ERR(timings)) {
1669 ret = PTR_ERR(timings);
1670 dev_err(dev,
1671 "could not retrieve timings for ONFI mode 0: %d\n",
1672 ret);
1673 return ret;
1674 }
1675
1676 ret = sunxi_nand_chip_set_timings(chip, timings);
1677 if (ret) {
1678 dev_err(dev, "could not configure chip timings: %d\n", ret);
1679 return ret;
1680 }
1681
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001682 ret = nand_scan_ident(mtd, nsels, NULL);
1683 if (ret)
1684 return ret;
1685
Boris BREZILLONa3d22a52015-09-02 10:30:25 +02001686 if (nand->bbt_options & NAND_BBT_USE_FLASH)
1687 nand->bbt_options |= NAND_BBT_NO_OOB;
1688
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001689 if (nand->options & NAND_NEED_SCRAMBLING)
1690 nand->options |= NAND_NO_SUBPAGE_WRITE;
1691
Boris Brezillonfe82cce2015-09-16 09:01:45 +02001692 nand->options |= NAND_SUBPAGE_READ;
1693
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001694 ret = sunxi_nand_chip_init_timings(chip, np);
1695 if (ret) {
1696 dev_err(dev, "could not configure chip timings: %d\n", ret);
1697 return ret;
1698 }
1699
1700 ret = sunxi_nand_ecc_init(mtd, &nand->ecc, np);
1701 if (ret) {
1702 dev_err(dev, "ECC init failed: %d\n", ret);
1703 return ret;
1704 }
1705
1706 ret = nand_scan_tail(mtd);
1707 if (ret) {
1708 dev_err(dev, "nand_scan_tail failed: %d\n", ret);
1709 return ret;
1710 }
1711
Brian Norrisa61ae812015-10-30 20:33:25 -07001712 ret = mtd_device_register(mtd, NULL, 0);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001713 if (ret) {
1714 dev_err(dev, "failed to register mtd device: %d\n", ret);
1715 nand_release(mtd);
1716 return ret;
1717 }
1718
1719 list_add_tail(&chip->node, &nfc->chips);
1720
1721 return 0;
1722}
1723
1724static int sunxi_nand_chips_init(struct device *dev, struct sunxi_nfc *nfc)
1725{
1726 struct device_node *np = dev->of_node;
1727 struct device_node *nand_np;
1728 int nchips = of_get_child_count(np);
1729 int ret;
1730
1731 if (nchips > 8) {
1732 dev_err(dev, "too many NAND chips: %d (max = 8)\n", nchips);
1733 return -EINVAL;
1734 }
1735
1736 for_each_child_of_node(np, nand_np) {
1737 ret = sunxi_nand_chip_init(dev, nfc, nand_np);
Julia Lawalla81c0f02015-11-18 23:04:12 +01001738 if (ret) {
1739 of_node_put(nand_np);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001740 return ret;
Julia Lawalla81c0f02015-11-18 23:04:12 +01001741 }
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001742 }
1743
1744 return 0;
1745}
1746
1747static void sunxi_nand_chips_cleanup(struct sunxi_nfc *nfc)
1748{
1749 struct sunxi_nand_chip *chip;
1750
1751 while (!list_empty(&nfc->chips)) {
1752 chip = list_first_entry(&nfc->chips, struct sunxi_nand_chip,
1753 node);
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001754 nand_release(nand_to_mtd(&chip->nand));
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001755 sunxi_nand_ecc_cleanup(&chip->nand.ecc);
Boris BREZILLON8e375cc2015-09-13 18:14:43 +02001756 list_del(&chip->node);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001757 }
1758}
1759
1760static int sunxi_nfc_probe(struct platform_device *pdev)
1761{
1762 struct device *dev = &pdev->dev;
1763 struct resource *r;
1764 struct sunxi_nfc *nfc;
1765 int irq;
1766 int ret;
1767
1768 nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
1769 if (!nfc)
1770 return -ENOMEM;
1771
1772 nfc->dev = dev;
1773 spin_lock_init(&nfc->controller.lock);
1774 init_waitqueue_head(&nfc->controller.wq);
1775 INIT_LIST_HEAD(&nfc->chips);
1776
1777 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1778 nfc->regs = devm_ioremap_resource(dev, r);
1779 if (IS_ERR(nfc->regs))
1780 return PTR_ERR(nfc->regs);
1781
1782 irq = platform_get_irq(pdev, 0);
1783 if (irq < 0) {
1784 dev_err(dev, "failed to retrieve irq\n");
1785 return irq;
1786 }
1787
1788 nfc->ahb_clk = devm_clk_get(dev, "ahb");
1789 if (IS_ERR(nfc->ahb_clk)) {
1790 dev_err(dev, "failed to retrieve ahb clk\n");
1791 return PTR_ERR(nfc->ahb_clk);
1792 }
1793
1794 ret = clk_prepare_enable(nfc->ahb_clk);
1795 if (ret)
1796 return ret;
1797
1798 nfc->mod_clk = devm_clk_get(dev, "mod");
1799 if (IS_ERR(nfc->mod_clk)) {
1800 dev_err(dev, "failed to retrieve mod clk\n");
1801 ret = PTR_ERR(nfc->mod_clk);
1802 goto out_ahb_clk_unprepare;
1803 }
1804
1805 ret = clk_prepare_enable(nfc->mod_clk);
1806 if (ret)
1807 goto out_ahb_clk_unprepare;
1808
1809 ret = sunxi_nfc_rst(nfc);
1810 if (ret)
1811 goto out_mod_clk_unprepare;
1812
1813 writel(0, nfc->regs + NFC_REG_INT);
1814 ret = devm_request_irq(dev, irq, sunxi_nfc_interrupt,
1815 0, "sunxi-nand", nfc);
1816 if (ret)
1817 goto out_mod_clk_unprepare;
1818
1819 platform_set_drvdata(pdev, nfc);
1820
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001821 ret = sunxi_nand_chips_init(dev, nfc);
1822 if (ret) {
1823 dev_err(dev, "failed to init nand chips\n");
1824 goto out_mod_clk_unprepare;
1825 }
1826
1827 return 0;
1828
1829out_mod_clk_unprepare:
1830 clk_disable_unprepare(nfc->mod_clk);
1831out_ahb_clk_unprepare:
1832 clk_disable_unprepare(nfc->ahb_clk);
1833
1834 return ret;
1835}
1836
1837static int sunxi_nfc_remove(struct platform_device *pdev)
1838{
1839 struct sunxi_nfc *nfc = platform_get_drvdata(pdev);
1840
1841 sunxi_nand_chips_cleanup(nfc);
Boris Brezillondd26a452016-03-04 18:26:40 +01001842 clk_disable_unprepare(nfc->mod_clk);
1843 clk_disable_unprepare(nfc->ahb_clk);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001844
1845 return 0;
1846}
1847
1848static const struct of_device_id sunxi_nfc_ids[] = {
1849 { .compatible = "allwinner,sun4i-a10-nand" },
1850 { /* sentinel */ }
1851};
1852MODULE_DEVICE_TABLE(of, sunxi_nfc_ids);
1853
1854static struct platform_driver sunxi_nfc_driver = {
1855 .driver = {
1856 .name = "sunxi_nand",
1857 .of_match_table = sunxi_nfc_ids,
1858 },
1859 .probe = sunxi_nfc_probe,
1860 .remove = sunxi_nfc_remove,
1861};
1862module_platform_driver(sunxi_nfc_driver);
1863
1864MODULE_LICENSE("GPL v2");
1865MODULE_AUTHOR("Boris BREZILLON");
1866MODULE_DESCRIPTION("Allwinner NAND Flash Controller driver");
1867MODULE_ALIAS("platform:sunxi_nand");