blob: e30276d9a9e3cd4edc08a55cf986b043acba81c8 [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;
241 int nsels;
242 struct sunxi_nand_chip_sel sels[0];
243};
244
245static inline struct sunxi_nand_chip *to_sunxi_nand(struct nand_chip *nand)
246{
247 return container_of(nand, struct sunxi_nand_chip, nand);
248}
249
250/*
251 * NAND Controller structure: stores sunxi NAND controller information
252 *
253 * @controller: base controller structure
254 * @dev: parent device (used to print error messages)
255 * @regs: NAND controller registers
256 * @ahb_clk: NAND Controller AHB clock
257 * @mod_clk: NAND Controller mod clock
258 * @assigned_cs: bitmask describing already assigned CS lines
259 * @clk_rate: NAND controller current clock rate
260 * @chips: a list containing all the NAND chips attached to
261 * this NAND controller
262 * @complete: a completion object used to wait for NAND
263 * controller events
264 */
265struct sunxi_nfc {
266 struct nand_hw_control controller;
267 struct device *dev;
268 void __iomem *regs;
269 struct clk *ahb_clk;
270 struct clk *mod_clk;
271 unsigned long assigned_cs;
272 unsigned long clk_rate;
273 struct list_head chips;
274 struct completion complete;
275};
276
277static inline struct sunxi_nfc *to_sunxi_nfc(struct nand_hw_control *ctrl)
278{
279 return container_of(ctrl, struct sunxi_nfc, controller);
280}
281
282static irqreturn_t sunxi_nfc_interrupt(int irq, void *dev_id)
283{
284 struct sunxi_nfc *nfc = dev_id;
285 u32 st = readl(nfc->regs + NFC_REG_ST);
286 u32 ien = readl(nfc->regs + NFC_REG_INT);
287
288 if (!(ien & st))
289 return IRQ_NONE;
290
291 if ((ien & st) == ien)
292 complete(&nfc->complete);
293
294 writel(st & NFC_INT_MASK, nfc->regs + NFC_REG_ST);
295 writel(~st & ien & NFC_INT_MASK, nfc->regs + NFC_REG_INT);
296
297 return IRQ_HANDLED;
298}
299
300static int sunxi_nfc_wait_int(struct sunxi_nfc *nfc, u32 flags,
301 unsigned int timeout_ms)
302{
303 init_completion(&nfc->complete);
304
305 writel(flags, nfc->regs + NFC_REG_INT);
306
307 if (!timeout_ms)
308 timeout_ms = NFC_DEFAULT_TIMEOUT_MS;
309
310 if (!wait_for_completion_timeout(&nfc->complete,
311 msecs_to_jiffies(timeout_ms))) {
312 dev_err(nfc->dev, "wait interrupt timedout\n");
313 return -ETIMEDOUT;
314 }
315
316 return 0;
317}
318
319static int sunxi_nfc_wait_cmd_fifo_empty(struct sunxi_nfc *nfc)
320{
321 unsigned long timeout = jiffies +
322 msecs_to_jiffies(NFC_DEFAULT_TIMEOUT_MS);
323
324 do {
325 if (!(readl(nfc->regs + NFC_REG_ST) & NFC_CMD_FIFO_STATUS))
326 return 0;
327 } while (time_before(jiffies, timeout));
328
329 dev_err(nfc->dev, "wait for empty cmd FIFO timedout\n");
330 return -ETIMEDOUT;
331}
332
333static int sunxi_nfc_rst(struct sunxi_nfc *nfc)
334{
335 unsigned long timeout = jiffies +
336 msecs_to_jiffies(NFC_DEFAULT_TIMEOUT_MS);
337
338 writel(0, nfc->regs + NFC_REG_ECC_CTL);
339 writel(NFC_RESET, nfc->regs + NFC_REG_CTL);
340
341 do {
342 if (!(readl(nfc->regs + NFC_REG_CTL) & NFC_RESET))
343 return 0;
344 } while (time_before(jiffies, timeout));
345
346 dev_err(nfc->dev, "wait for NAND controller reset timedout\n");
347 return -ETIMEDOUT;
348}
349
350static int sunxi_nfc_dev_ready(struct mtd_info *mtd)
351{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100352 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200353 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
354 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
355 struct sunxi_nand_rb *rb;
356 unsigned long timeo = (sunxi_nand->nand.state == FL_ERASING ? 400 : 20);
357 int ret;
358
359 if (sunxi_nand->selected < 0)
360 return 0;
361
362 rb = &sunxi_nand->sels[sunxi_nand->selected].rb;
363
364 switch (rb->type) {
365 case RB_NATIVE:
366 ret = !!(readl(nfc->regs + NFC_REG_ST) &
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200367 NFC_RB_STATE(rb->info.nativeid));
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200368 if (ret)
369 break;
370
371 sunxi_nfc_wait_int(nfc, NFC_RB_B2R, timeo);
372 ret = !!(readl(nfc->regs + NFC_REG_ST) &
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200373 NFC_RB_STATE(rb->info.nativeid));
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200374 break;
375 case RB_GPIO:
376 ret = gpio_get_value(rb->info.gpio);
377 break;
378 case RB_NONE:
379 default:
380 ret = 0;
381 dev_err(nfc->dev, "cannot check R/B NAND status!\n");
382 break;
383 }
384
385 return ret;
386}
387
388static void sunxi_nfc_select_chip(struct mtd_info *mtd, int chip)
389{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100390 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200391 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
392 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
393 struct sunxi_nand_chip_sel *sel;
394 u32 ctl;
395
396 if (chip > 0 && chip >= sunxi_nand->nsels)
397 return;
398
399 if (chip == sunxi_nand->selected)
400 return;
401
402 ctl = readl(nfc->regs + NFC_REG_CTL) &
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200403 ~(NFC_PAGE_SHIFT_MSK | NFC_CE_SEL_MSK | NFC_RB_SEL_MSK | NFC_EN);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200404
405 if (chip >= 0) {
406 sel = &sunxi_nand->sels[chip];
407
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200408 ctl |= NFC_CE_SEL(sel->cs) | NFC_EN |
409 NFC_PAGE_SHIFT(nand->page_shift - 10);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200410 if (sel->rb.type == RB_NONE) {
411 nand->dev_ready = NULL;
412 } else {
413 nand->dev_ready = sunxi_nfc_dev_ready;
414 if (sel->rb.type == RB_NATIVE)
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200415 ctl |= NFC_RB_SEL(sel->rb.info.nativeid);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200416 }
417
418 writel(mtd->writesize, nfc->regs + NFC_REG_SPARE_AREA);
419
420 if (nfc->clk_rate != sunxi_nand->clk_rate) {
421 clk_set_rate(nfc->mod_clk, sunxi_nand->clk_rate);
422 nfc->clk_rate = sunxi_nand->clk_rate;
423 }
424 }
425
Roy Splietd052e502015-06-26 11:00:11 +0200426 writel(sunxi_nand->timing_ctl, nfc->regs + NFC_REG_TIMING_CTL);
Roy Spliet9c618292015-06-26 11:00:10 +0200427 writel(sunxi_nand->timing_cfg, nfc->regs + NFC_REG_TIMING_CFG);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200428 writel(ctl, nfc->regs + NFC_REG_CTL);
429
430 sunxi_nand->selected = chip;
431}
432
433static void sunxi_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
434{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100435 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200436 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
437 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
438 int ret;
439 int cnt;
440 int offs = 0;
441 u32 tmp;
442
443 while (len > offs) {
444 cnt = min(len - offs, NFC_SRAM_SIZE);
445
446 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
447 if (ret)
448 break;
449
450 writel(cnt, nfc->regs + NFC_REG_CNT);
451 tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD;
452 writel(tmp, nfc->regs + NFC_REG_CMD);
453
454 ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
455 if (ret)
456 break;
457
458 if (buf)
459 memcpy_fromio(buf + offs, nfc->regs + NFC_RAM0_BASE,
460 cnt);
461 offs += cnt;
462 }
463}
464
465static void sunxi_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf,
466 int len)
467{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100468 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200469 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
470 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
471 int ret;
472 int cnt;
473 int offs = 0;
474 u32 tmp;
475
476 while (len > offs) {
477 cnt = min(len - offs, NFC_SRAM_SIZE);
478
479 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
480 if (ret)
481 break;
482
483 writel(cnt, nfc->regs + NFC_REG_CNT);
484 memcpy_toio(nfc->regs + NFC_RAM0_BASE, buf + offs, cnt);
485 tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD |
486 NFC_ACCESS_DIR;
487 writel(tmp, nfc->regs + NFC_REG_CMD);
488
489 ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
490 if (ret)
491 break;
492
493 offs += cnt;
494 }
495}
496
497static uint8_t sunxi_nfc_read_byte(struct mtd_info *mtd)
498{
499 uint8_t ret;
500
501 sunxi_nfc_read_buf(mtd, &ret, 1);
502
503 return ret;
504}
505
506static void sunxi_nfc_cmd_ctrl(struct mtd_info *mtd, int dat,
507 unsigned int ctrl)
508{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100509 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200510 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
511 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
512 int ret;
513 u32 tmp;
514
515 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
516 if (ret)
517 return;
518
519 if (ctrl & NAND_CTRL_CHANGE) {
520 tmp = readl(nfc->regs + NFC_REG_CTL);
521 if (ctrl & NAND_NCE)
522 tmp |= NFC_CE_CTL;
523 else
524 tmp &= ~NFC_CE_CTL;
525 writel(tmp, nfc->regs + NFC_REG_CTL);
526 }
527
528 if (dat == NAND_CMD_NONE)
529 return;
530
531 if (ctrl & NAND_CLE) {
532 writel(NFC_SEND_CMD1 | dat, nfc->regs + NFC_REG_CMD);
533 } else {
534 writel(dat, nfc->regs + NFC_REG_ADDR_LOW);
535 writel(NFC_SEND_ADR, nfc->regs + NFC_REG_CMD);
536 }
537
538 sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
539}
540
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100541/* These seed values have been extracted from Allwinner's BSP */
542static const u16 sunxi_nfc_randomizer_page_seeds[] = {
543 0x2b75, 0x0bd0, 0x5ca3, 0x62d1, 0x1c93, 0x07e9, 0x2162, 0x3a72,
544 0x0d67, 0x67f9, 0x1be7, 0x077d, 0x032f, 0x0dac, 0x2716, 0x2436,
545 0x7922, 0x1510, 0x3860, 0x5287, 0x480f, 0x4252, 0x1789, 0x5a2d,
546 0x2a49, 0x5e10, 0x437f, 0x4b4e, 0x2f45, 0x216e, 0x5cb7, 0x7130,
547 0x2a3f, 0x60e4, 0x4dc9, 0x0ef0, 0x0f52, 0x1bb9, 0x6211, 0x7a56,
548 0x226d, 0x4ea7, 0x6f36, 0x3692, 0x38bf, 0x0c62, 0x05eb, 0x4c55,
549 0x60f4, 0x728c, 0x3b6f, 0x2037, 0x7f69, 0x0936, 0x651a, 0x4ceb,
550 0x6218, 0x79f3, 0x383f, 0x18d9, 0x4f05, 0x5c82, 0x2912, 0x6f17,
551 0x6856, 0x5938, 0x1007, 0x61ab, 0x3e7f, 0x57c2, 0x542f, 0x4f62,
552 0x7454, 0x2eac, 0x7739, 0x42d4, 0x2f90, 0x435a, 0x2e52, 0x2064,
553 0x637c, 0x66ad, 0x2c90, 0x0bad, 0x759c, 0x0029, 0x0986, 0x7126,
554 0x1ca7, 0x1605, 0x386a, 0x27f5, 0x1380, 0x6d75, 0x24c3, 0x0f8e,
555 0x2b7a, 0x1418, 0x1fd1, 0x7dc1, 0x2d8e, 0x43af, 0x2267, 0x7da3,
556 0x4e3d, 0x1338, 0x50db, 0x454d, 0x764d, 0x40a3, 0x42e6, 0x262b,
557 0x2d2e, 0x1aea, 0x2e17, 0x173d, 0x3a6e, 0x71bf, 0x25f9, 0x0a5d,
558 0x7c57, 0x0fbe, 0x46ce, 0x4939, 0x6b17, 0x37bb, 0x3e91, 0x76db,
559};
560
561/*
562 * sunxi_nfc_randomizer_ecc512_seeds and sunxi_nfc_randomizer_ecc1024_seeds
563 * have been generated using
564 * sunxi_nfc_randomizer_step(seed, (step_size * 8) + 15), which is what
565 * the randomizer engine does internally before de/scrambling OOB data.
566 *
567 * Those tables are statically defined to avoid calculating randomizer state
568 * at runtime.
569 */
570static const u16 sunxi_nfc_randomizer_ecc512_seeds[] = {
571 0x3346, 0x367f, 0x1f18, 0x769a, 0x4f64, 0x068c, 0x2ef1, 0x6b64,
572 0x28a9, 0x15d7, 0x30f8, 0x3659, 0x53db, 0x7c5f, 0x71d4, 0x4409,
573 0x26eb, 0x03cc, 0x655d, 0x47d4, 0x4daa, 0x0877, 0x712d, 0x3617,
574 0x3264, 0x49aa, 0x7f9e, 0x588e, 0x4fbc, 0x7176, 0x7f91, 0x6c6d,
575 0x4b95, 0x5fb7, 0x3844, 0x4037, 0x0184, 0x081b, 0x0ee8, 0x5b91,
576 0x293d, 0x1f71, 0x0e6f, 0x402b, 0x5122, 0x1e52, 0x22be, 0x3d2d,
577 0x75bc, 0x7c60, 0x6291, 0x1a2f, 0x61d4, 0x74aa, 0x4140, 0x29ab,
578 0x472d, 0x2852, 0x017e, 0x15e8, 0x5ec2, 0x17cf, 0x7d0f, 0x06b8,
579 0x117a, 0x6b94, 0x789b, 0x3126, 0x6ac5, 0x5be7, 0x150f, 0x51f8,
580 0x7889, 0x0aa5, 0x663d, 0x77e8, 0x0b87, 0x3dcb, 0x360d, 0x218b,
581 0x512f, 0x7dc9, 0x6a4d, 0x630a, 0x3547, 0x1dd2, 0x5aea, 0x69a5,
582 0x7bfa, 0x5e4f, 0x1519, 0x6430, 0x3a0e, 0x5eb3, 0x5425, 0x0c7a,
583 0x5540, 0x3670, 0x63c1, 0x31e9, 0x5a39, 0x2de7, 0x5979, 0x2891,
584 0x1562, 0x014b, 0x5b05, 0x2756, 0x5a34, 0x13aa, 0x6cb5, 0x2c36,
585 0x5e72, 0x1306, 0x0861, 0x15ef, 0x1ee8, 0x5a37, 0x7ac4, 0x45dd,
586 0x44c4, 0x7266, 0x2f41, 0x3ccc, 0x045e, 0x7d40, 0x7c66, 0x0fa0,
587};
588
589static const u16 sunxi_nfc_randomizer_ecc1024_seeds[] = {
590 0x2cf5, 0x35f1, 0x63a4, 0x5274, 0x2bd2, 0x778b, 0x7285, 0x32b6,
591 0x6a5c, 0x70d6, 0x757d, 0x6769, 0x5375, 0x1e81, 0x0cf3, 0x3982,
592 0x6787, 0x042a, 0x6c49, 0x1925, 0x56a8, 0x40a9, 0x063e, 0x7bd9,
593 0x4dbf, 0x55ec, 0x672e, 0x7334, 0x5185, 0x4d00, 0x232a, 0x7e07,
594 0x445d, 0x6b92, 0x528f, 0x4255, 0x53ba, 0x7d82, 0x2a2e, 0x3a4e,
595 0x75eb, 0x450c, 0x6844, 0x1b5d, 0x581a, 0x4cc6, 0x0379, 0x37b2,
596 0x419f, 0x0e92, 0x6b27, 0x5624, 0x01e3, 0x07c1, 0x44a5, 0x130c,
597 0x13e8, 0x5910, 0x0876, 0x60c5, 0x54e3, 0x5b7f, 0x2269, 0x509f,
598 0x7665, 0x36fd, 0x3e9a, 0x0579, 0x6295, 0x14ef, 0x0a81, 0x1bcc,
599 0x4b16, 0x64db, 0x0514, 0x4f07, 0x0591, 0x3576, 0x6853, 0x0d9e,
600 0x259f, 0x38b7, 0x64fb, 0x3094, 0x4693, 0x6ddd, 0x29bb, 0x0bc8,
601 0x3f47, 0x490e, 0x0c0e, 0x7933, 0x3c9e, 0x5840, 0x398d, 0x3e68,
602 0x4af1, 0x71f5, 0x57cf, 0x1121, 0x64eb, 0x3579, 0x15ac, 0x584d,
603 0x5f2a, 0x47e2, 0x6528, 0x6eac, 0x196e, 0x6b96, 0x0450, 0x0179,
604 0x609c, 0x06e1, 0x4626, 0x42c7, 0x273e, 0x486f, 0x0705, 0x1601,
605 0x145b, 0x407e, 0x062b, 0x57a5, 0x53f9, 0x5659, 0x4410, 0x3ccd,
606};
607
608static u16 sunxi_nfc_randomizer_step(u16 state, int count)
609{
610 state &= 0x7fff;
611
612 /*
613 * This loop is just a simple implementation of a Fibonacci LFSR using
614 * the x16 + x15 + 1 polynomial.
615 */
616 while (count--)
617 state = ((state >> 1) |
618 (((state ^ (state >> 1)) & 1) << 14)) & 0x7fff;
619
620 return state;
621}
622
623static u16 sunxi_nfc_randomizer_state(struct mtd_info *mtd, int page, bool ecc)
624{
625 const u16 *seeds = sunxi_nfc_randomizer_page_seeds;
Brian Norris46c135c2016-01-22 18:57:13 -0800626 int mod = mtd_div_by_ws(mtd->erasesize, mtd);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100627
628 if (mod > ARRAY_SIZE(sunxi_nfc_randomizer_page_seeds))
629 mod = ARRAY_SIZE(sunxi_nfc_randomizer_page_seeds);
630
631 if (ecc) {
632 if (mtd->ecc_step_size == 512)
633 seeds = sunxi_nfc_randomizer_ecc512_seeds;
634 else
635 seeds = sunxi_nfc_randomizer_ecc1024_seeds;
636 }
637
638 return seeds[page % mod];
639}
640
641static void sunxi_nfc_randomizer_config(struct mtd_info *mtd,
642 int page, bool ecc)
643{
Boris BREZILLONf671a1f2016-03-05 00:21:20 +0100644 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100645 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
646 u32 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL);
647 u16 state;
648
649 if (!(nand->options & NAND_NEED_SCRAMBLING))
650 return;
651
652 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL);
653 state = sunxi_nfc_randomizer_state(mtd, page, ecc);
654 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_RANDOM_SEED_MSK;
655 writel(ecc_ctl | NFC_RANDOM_SEED(state), nfc->regs + NFC_REG_ECC_CTL);
656}
657
658static void sunxi_nfc_randomizer_enable(struct mtd_info *mtd)
659{
Boris BREZILLONf671a1f2016-03-05 00:21:20 +0100660 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100661 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
662
663 if (!(nand->options & NAND_NEED_SCRAMBLING))
664 return;
665
666 writel(readl(nfc->regs + NFC_REG_ECC_CTL) | NFC_RANDOM_EN,
667 nfc->regs + NFC_REG_ECC_CTL);
668}
669
670static void sunxi_nfc_randomizer_disable(struct mtd_info *mtd)
671{
Boris BREZILLONf671a1f2016-03-05 00:21:20 +0100672 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100673 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
674
675 if (!(nand->options & NAND_NEED_SCRAMBLING))
676 return;
677
678 writel(readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_RANDOM_EN,
679 nfc->regs + NFC_REG_ECC_CTL);
680}
681
682static void sunxi_nfc_randomize_bbm(struct mtd_info *mtd, int page, u8 *bbm)
683{
684 u16 state = sunxi_nfc_randomizer_state(mtd, page, true);
685
686 bbm[0] ^= state;
687 bbm[1] ^= sunxi_nfc_randomizer_step(state, 8);
688}
689
690static void sunxi_nfc_randomizer_write_buf(struct mtd_info *mtd,
691 const uint8_t *buf, int len,
692 bool ecc, int page)
693{
694 sunxi_nfc_randomizer_config(mtd, page, ecc);
695 sunxi_nfc_randomizer_enable(mtd);
696 sunxi_nfc_write_buf(mtd, buf, len);
697 sunxi_nfc_randomizer_disable(mtd);
698}
699
700static void sunxi_nfc_randomizer_read_buf(struct mtd_info *mtd, uint8_t *buf,
701 int len, bool ecc, int page)
702{
703 sunxi_nfc_randomizer_config(mtd, page, ecc);
704 sunxi_nfc_randomizer_enable(mtd);
705 sunxi_nfc_read_buf(mtd, buf, len);
706 sunxi_nfc_randomizer_disable(mtd);
707}
708
Boris BREZILLONc9118ec2015-09-30 23:45:23 +0200709static void sunxi_nfc_hw_ecc_enable(struct mtd_info *mtd)
710{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100711 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLONc9118ec2015-09-30 23:45:23 +0200712 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
713 struct sunxi_nand_hw_ecc *data = nand->ecc.priv;
714 u32 ecc_ctl;
715
716 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL);
717 ecc_ctl &= ~(NFC_ECC_MODE_MSK | NFC_ECC_PIPELINE |
718 NFC_ECC_BLOCK_SIZE_MSK);
719 ecc_ctl |= NFC_ECC_EN | NFC_ECC_MODE(data->mode) | NFC_ECC_EXCEPTION;
720
721 writel(ecc_ctl, nfc->regs + NFC_REG_ECC_CTL);
722}
723
724static void sunxi_nfc_hw_ecc_disable(struct mtd_info *mtd)
725{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100726 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLONc9118ec2015-09-30 23:45:23 +0200727 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
728
729 writel(readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_ECC_EN,
730 nfc->regs + NFC_REG_ECC_CTL);
731}
732
Boris BREZILLONf363e0f2015-09-30 23:45:27 +0200733static inline void sunxi_nfc_user_data_to_buf(u32 user_data, u8 *buf)
734{
735 buf[0] = user_data;
736 buf[1] = user_data >> 8;
737 buf[2] = user_data >> 16;
738 buf[3] = user_data >> 24;
739}
740
Boris BREZILLON913821b2015-09-30 23:45:24 +0200741static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd,
742 u8 *data, int data_off,
743 u8 *oob, int oob_off,
744 int *cur_off,
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100745 unsigned int *max_bitflips,
746 bool bbm, int page)
Boris BREZILLON913821b2015-09-30 23:45:24 +0200747{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100748 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200749 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
750 struct nand_ecc_ctrl *ecc = &nand->ecc;
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100751 int raw_mode = 0;
Boris BREZILLON913821b2015-09-30 23:45:24 +0200752 u32 status;
753 int ret;
754
755 if (*cur_off != data_off)
756 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, data_off, -1);
757
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100758 sunxi_nfc_randomizer_read_buf(mtd, NULL, ecc->size, false, page);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200759
Boris BREZILLON74eb9ff2015-10-20 22:16:00 +0200760 if (data_off + ecc->size != oob_off)
Boris BREZILLON913821b2015-09-30 23:45:24 +0200761 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
762
763 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
764 if (ret)
765 return ret;
766
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100767 sunxi_nfc_randomizer_enable(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200768 writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_ECC_OP,
769 nfc->regs + NFC_REG_CMD);
770
771 ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100772 sunxi_nfc_randomizer_disable(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200773 if (ret)
774 return ret;
775
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100776 *cur_off = oob_off + ecc->bytes + 4;
777
Boris BREZILLON913821b2015-09-30 23:45:24 +0200778 status = readl(nfc->regs + NFC_REG_ECC_ST);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100779 if (status & NFC_ECC_PAT_FOUND(0)) {
780 u8 pattern = 0xff;
781
782 if (unlikely(!(readl(nfc->regs + NFC_REG_PAT_ID) & 0x1)))
783 pattern = 0x0;
784
785 memset(data, pattern, ecc->size);
786 memset(oob, pattern, ecc->bytes + 4);
787
788 return 1;
789 }
790
Boris BREZILLON913821b2015-09-30 23:45:24 +0200791 ret = NFC_ECC_ERR_CNT(0, readl(nfc->regs + NFC_REG_ECC_ERR_CNT(0)));
792
793 memcpy_fromio(data, nfc->regs + NFC_RAM0_BASE, ecc->size);
794
795 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100796 sunxi_nfc_randomizer_read_buf(mtd, oob, ecc->bytes + 4, true, page);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200797
Boris BREZILLONf363e0f2015-09-30 23:45:27 +0200798 if (status & NFC_ECC_ERR(0)) {
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100799 /*
800 * Re-read the data with the randomizer disabled to identify
801 * bitflips in erased pages.
802 */
803 if (nand->options & NAND_NEED_SCRAMBLING) {
804 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, data_off, -1);
805 nand->read_buf(mtd, data, ecc->size);
806 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
807 nand->read_buf(mtd, oob, ecc->bytes + 4);
808 }
809
Boris BREZILLON146b5032015-09-30 23:45:29 +0200810 ret = nand_check_erased_ecc_chunk(data, ecc->size,
811 oob, ecc->bytes + 4,
812 NULL, 0, ecc->strength);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100813 if (ret >= 0)
814 raw_mode = 1;
Boris BREZILLONf363e0f2015-09-30 23:45:27 +0200815 } else {
816 /*
817 * The engine protects 4 bytes of OOB data per chunk.
818 * Retrieve the corrected OOB bytes.
819 */
820 sunxi_nfc_user_data_to_buf(readl(nfc->regs + NFC_REG_USER_DATA(0)),
821 oob);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100822
823 /* De-randomize the Bad Block Marker. */
824 if (bbm && nand->options & NAND_NEED_SCRAMBLING)
825 sunxi_nfc_randomize_bbm(mtd, page, oob);
Boris BREZILLONf363e0f2015-09-30 23:45:27 +0200826 }
Boris BREZILLON913821b2015-09-30 23:45:24 +0200827
828 if (ret < 0) {
829 mtd->ecc_stats.failed++;
830 } else {
831 mtd->ecc_stats.corrected += ret;
832 *max_bitflips = max_t(unsigned int, *max_bitflips, ret);
833 }
834
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100835 return raw_mode;
Boris BREZILLON913821b2015-09-30 23:45:24 +0200836}
837
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200838static void sunxi_nfc_hw_ecc_read_extra_oob(struct mtd_info *mtd,
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100839 u8 *oob, int *cur_off,
840 bool randomize, int page)
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200841{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100842 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200843 struct nand_ecc_ctrl *ecc = &nand->ecc;
844 int offset = ((ecc->bytes + 4) * ecc->steps);
845 int len = mtd->oobsize - offset;
846
847 if (len <= 0)
848 return;
849
850 if (*cur_off != offset)
851 nand->cmdfunc(mtd, NAND_CMD_RNDOUT,
852 offset + mtd->writesize, -1);
853
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100854 if (!randomize)
855 sunxi_nfc_read_buf(mtd, oob + offset, len);
856 else
857 sunxi_nfc_randomizer_read_buf(mtd, oob + offset, len,
858 false, page);
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200859
860 *cur_off = mtd->oobsize + mtd->writesize;
861}
862
Boris BREZILLON23151fd2015-09-30 23:45:28 +0200863static inline u32 sunxi_nfc_buf_to_user_data(const u8 *buf)
864{
865 return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
866}
867
Boris BREZILLON913821b2015-09-30 23:45:24 +0200868static int sunxi_nfc_hw_ecc_write_chunk(struct mtd_info *mtd,
869 const u8 *data, int data_off,
870 const u8 *oob, int oob_off,
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100871 int *cur_off, bool bbm,
872 int page)
Boris BREZILLON913821b2015-09-30 23:45:24 +0200873{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100874 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200875 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
876 struct nand_ecc_ctrl *ecc = &nand->ecc;
877 int ret;
878
879 if (data_off != *cur_off)
880 nand->cmdfunc(mtd, NAND_CMD_RNDIN, data_off, -1);
881
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100882 sunxi_nfc_randomizer_write_buf(mtd, data, ecc->size, false, page);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200883
884 /* Fill OOB data in */
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100885 if ((nand->options & NAND_NEED_SCRAMBLING) && bbm) {
886 u8 user_data[4];
887
888 memcpy(user_data, oob, 4);
889 sunxi_nfc_randomize_bbm(mtd, page, user_data);
890 writel(sunxi_nfc_buf_to_user_data(user_data),
891 nfc->regs + NFC_REG_USER_DATA(0));
892 } else {
893 writel(sunxi_nfc_buf_to_user_data(oob),
894 nfc->regs + NFC_REG_USER_DATA(0));
895 }
Boris BREZILLON913821b2015-09-30 23:45:24 +0200896
Boris BREZILLON74eb9ff2015-10-20 22:16:00 +0200897 if (data_off + ecc->size != oob_off)
Boris BREZILLON913821b2015-09-30 23:45:24 +0200898 nand->cmdfunc(mtd, NAND_CMD_RNDIN, oob_off, -1);
899
900 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
901 if (ret)
902 return ret;
903
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100904 sunxi_nfc_randomizer_enable(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200905 writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD |
906 NFC_ACCESS_DIR | NFC_ECC_OP,
907 nfc->regs + NFC_REG_CMD);
908
909 ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100910 sunxi_nfc_randomizer_disable(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200911 if (ret)
912 return ret;
913
914 *cur_off = oob_off + ecc->bytes + 4;
915
916 return 0;
917}
918
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200919static void sunxi_nfc_hw_ecc_write_extra_oob(struct mtd_info *mtd,
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100920 u8 *oob, int *cur_off,
921 int page)
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200922{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100923 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200924 struct nand_ecc_ctrl *ecc = &nand->ecc;
925 int offset = ((ecc->bytes + 4) * ecc->steps);
926 int len = mtd->oobsize - offset;
927
928 if (len <= 0)
929 return;
930
931 if (*cur_off != offset)
932 nand->cmdfunc(mtd, NAND_CMD_RNDIN,
933 offset + mtd->writesize, -1);
934
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100935 sunxi_nfc_randomizer_write_buf(mtd, oob + offset, len, false, page);
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200936
937 *cur_off = mtd->oobsize + mtd->writesize;
938}
939
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200940static int sunxi_nfc_hw_ecc_read_page(struct mtd_info *mtd,
941 struct nand_chip *chip, uint8_t *buf,
942 int oob_required, int page)
943{
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200944 struct nand_ecc_ctrl *ecc = &chip->ecc;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200945 unsigned int max_bitflips = 0;
Boris BREZILLONb4625512015-09-30 23:45:25 +0200946 int ret, i, cur_off = 0;
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100947 bool raw_mode = false;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200948
Boris BREZILLONc9118ec2015-09-30 23:45:23 +0200949 sunxi_nfc_hw_ecc_enable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200950
951 for (i = 0; i < ecc->steps; i++) {
Boris BREZILLONb4625512015-09-30 23:45:25 +0200952 int data_off = i * ecc->size;
953 int oob_off = i * (ecc->bytes + 4);
954 u8 *data = buf + data_off;
955 u8 *oob = chip->oob_poi + oob_off;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200956
Boris BREZILLONb4625512015-09-30 23:45:25 +0200957 ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off, oob,
958 oob_off + mtd->writesize,
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100959 &cur_off, &max_bitflips,
960 !i, page);
961 if (ret < 0)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200962 return ret;
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100963 else if (ret)
964 raw_mode = true;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200965 }
966
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200967 if (oob_required)
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100968 sunxi_nfc_hw_ecc_read_extra_oob(mtd, chip->oob_poi, &cur_off,
969 !raw_mode, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200970
Boris BREZILLONc9118ec2015-09-30 23:45:23 +0200971 sunxi_nfc_hw_ecc_disable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200972
973 return max_bitflips;
974}
975
976static int sunxi_nfc_hw_ecc_write_page(struct mtd_info *mtd,
977 struct nand_chip *chip,
Boris BREZILLON45aaeff2015-10-13 11:22:18 +0200978 const uint8_t *buf, int oob_required,
979 int page)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200980{
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200981 struct nand_ecc_ctrl *ecc = &chip->ecc;
Boris BREZILLONb4625512015-09-30 23:45:25 +0200982 int ret, i, cur_off = 0;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200983
Boris BREZILLONc9118ec2015-09-30 23:45:23 +0200984 sunxi_nfc_hw_ecc_enable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200985
986 for (i = 0; i < ecc->steps; i++) {
Boris BREZILLONb4625512015-09-30 23:45:25 +0200987 int data_off = i * ecc->size;
988 int oob_off = i * (ecc->bytes + 4);
989 const u8 *data = buf + data_off;
990 const u8 *oob = chip->oob_poi + oob_off;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200991
Boris BREZILLONb4625512015-09-30 23:45:25 +0200992 ret = sunxi_nfc_hw_ecc_write_chunk(mtd, data, data_off, oob,
993 oob_off + mtd->writesize,
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100994 &cur_off, !i, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200995 if (ret)
996 return ret;
997 }
998
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100999 if (oob_required || (chip->options & NAND_NEED_SCRAMBLING))
1000 sunxi_nfc_hw_ecc_write_extra_oob(mtd, chip->oob_poi,
1001 &cur_off, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001002
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001003 sunxi_nfc_hw_ecc_disable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001004
1005 return 0;
1006}
1007
1008static int sunxi_nfc_hw_syndrome_ecc_read_page(struct mtd_info *mtd,
1009 struct nand_chip *chip,
1010 uint8_t *buf, int oob_required,
1011 int page)
1012{
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001013 struct nand_ecc_ctrl *ecc = &chip->ecc;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001014 unsigned int max_bitflips = 0;
Boris BREZILLONb4625512015-09-30 23:45:25 +02001015 int ret, i, cur_off = 0;
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001016 bool raw_mode = false;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001017
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001018 sunxi_nfc_hw_ecc_enable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001019
1020 for (i = 0; i < ecc->steps; i++) {
Boris BREZILLONb4625512015-09-30 23:45:25 +02001021 int data_off = i * (ecc->size + ecc->bytes + 4);
1022 int oob_off = data_off + ecc->size;
1023 u8 *data = buf + (i * ecc->size);
1024 u8 *oob = chip->oob_poi + (i * (ecc->bytes + 4));
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001025
Boris BREZILLONb4625512015-09-30 23:45:25 +02001026 ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off, oob,
1027 oob_off, &cur_off,
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001028 &max_bitflips, !i, page);
1029 if (ret < 0)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001030 return ret;
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001031 else if (ret)
1032 raw_mode = true;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001033 }
1034
Boris BREZILLON35d0e242015-09-30 23:45:26 +02001035 if (oob_required)
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001036 sunxi_nfc_hw_ecc_read_extra_oob(mtd, chip->oob_poi, &cur_off,
1037 !raw_mode, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001038
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001039 sunxi_nfc_hw_ecc_disable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001040
1041 return max_bitflips;
1042}
1043
1044static int sunxi_nfc_hw_syndrome_ecc_write_page(struct mtd_info *mtd,
1045 struct nand_chip *chip,
1046 const uint8_t *buf,
Boris BREZILLON45aaeff2015-10-13 11:22:18 +02001047 int oob_required, int page)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001048{
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001049 struct nand_ecc_ctrl *ecc = &chip->ecc;
Boris BREZILLONb4625512015-09-30 23:45:25 +02001050 int ret, i, cur_off = 0;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001051
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001052 sunxi_nfc_hw_ecc_enable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001053
1054 for (i = 0; i < ecc->steps; i++) {
Boris BREZILLONb4625512015-09-30 23:45:25 +02001055 int data_off = i * (ecc->size + ecc->bytes + 4);
1056 int oob_off = data_off + ecc->size;
1057 const u8 *data = buf + (i * ecc->size);
1058 const u8 *oob = chip->oob_poi + (i * (ecc->bytes + 4));
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001059
Boris BREZILLONb4625512015-09-30 23:45:25 +02001060 ret = sunxi_nfc_hw_ecc_write_chunk(mtd, data, data_off,
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001061 oob, oob_off, &cur_off,
1062 false, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001063 if (ret)
1064 return ret;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001065 }
1066
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001067 if (oob_required || (chip->options & NAND_NEED_SCRAMBLING))
1068 sunxi_nfc_hw_ecc_write_extra_oob(mtd, chip->oob_poi,
1069 &cur_off, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001070
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001071 sunxi_nfc_hw_ecc_disable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001072
1073 return 0;
1074}
1075
Roy Spliet9c618292015-06-26 11:00:10 +02001076static const s32 tWB_lut[] = {6, 12, 16, 20};
1077static const s32 tRHW_lut[] = {4, 8, 12, 20};
1078
1079static int _sunxi_nand_lookup_timing(const s32 *lut, int lut_size, u32 duration,
1080 u32 clk_period)
1081{
1082 u32 clk_cycles = DIV_ROUND_UP(duration, clk_period);
1083 int i;
1084
1085 for (i = 0; i < lut_size; i++) {
1086 if (clk_cycles <= lut[i])
1087 return i;
1088 }
1089
1090 /* Doesn't fit */
1091 return -EINVAL;
1092}
1093
1094#define sunxi_nand_lookup_timing(l, p, c) \
1095 _sunxi_nand_lookup_timing(l, ARRAY_SIZE(l), p, c)
1096
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001097static int sunxi_nand_chip_set_timings(struct sunxi_nand_chip *chip,
1098 const struct nand_sdr_timings *timings)
1099{
Roy Spliet9c618292015-06-26 11:00:10 +02001100 struct sunxi_nfc *nfc = to_sunxi_nfc(chip->nand.controller);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001101 u32 min_clk_period = 0;
Roy Spliet9c618292015-06-26 11:00:10 +02001102 s32 tWB, tADL, tWHR, tRHW, tCAD;
Boris Brezillon2d434572015-12-02 15:57:20 +01001103 long real_clk_rate;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001104
1105 /* T1 <=> tCLS */
1106 if (timings->tCLS_min > min_clk_period)
1107 min_clk_period = timings->tCLS_min;
1108
1109 /* T2 <=> tCLH */
1110 if (timings->tCLH_min > min_clk_period)
1111 min_clk_period = timings->tCLH_min;
1112
1113 /* T3 <=> tCS */
1114 if (timings->tCS_min > min_clk_period)
1115 min_clk_period = timings->tCS_min;
1116
1117 /* T4 <=> tCH */
1118 if (timings->tCH_min > min_clk_period)
1119 min_clk_period = timings->tCH_min;
1120
1121 /* T5 <=> tWP */
1122 if (timings->tWP_min > min_clk_period)
1123 min_clk_period = timings->tWP_min;
1124
1125 /* T6 <=> tWH */
1126 if (timings->tWH_min > min_clk_period)
1127 min_clk_period = timings->tWH_min;
1128
1129 /* T7 <=> tALS */
1130 if (timings->tALS_min > min_clk_period)
1131 min_clk_period = timings->tALS_min;
1132
1133 /* T8 <=> tDS */
1134 if (timings->tDS_min > min_clk_period)
1135 min_clk_period = timings->tDS_min;
1136
1137 /* T9 <=> tDH */
1138 if (timings->tDH_min > min_clk_period)
1139 min_clk_period = timings->tDH_min;
1140
1141 /* T10 <=> tRR */
1142 if (timings->tRR_min > (min_clk_period * 3))
1143 min_clk_period = DIV_ROUND_UP(timings->tRR_min, 3);
1144
1145 /* T11 <=> tALH */
1146 if (timings->tALH_min > min_clk_period)
1147 min_clk_period = timings->tALH_min;
1148
1149 /* T12 <=> tRP */
1150 if (timings->tRP_min > min_clk_period)
1151 min_clk_period = timings->tRP_min;
1152
1153 /* T13 <=> tREH */
1154 if (timings->tREH_min > min_clk_period)
1155 min_clk_period = timings->tREH_min;
1156
1157 /* T14 <=> tRC */
1158 if (timings->tRC_min > (min_clk_period * 2))
1159 min_clk_period = DIV_ROUND_UP(timings->tRC_min, 2);
1160
1161 /* T15 <=> tWC */
1162 if (timings->tWC_min > (min_clk_period * 2))
1163 min_clk_period = DIV_ROUND_UP(timings->tWC_min, 2);
1164
Roy Spliet9c618292015-06-26 11:00:10 +02001165 /* T16 - T19 + tCAD */
Boris Brezillon5abcd952015-11-11 22:30:30 +01001166 if (timings->tWB_max > (min_clk_period * 20))
1167 min_clk_period = DIV_ROUND_UP(timings->tWB_max, 20);
1168
1169 if (timings->tADL_min > (min_clk_period * 32))
1170 min_clk_period = DIV_ROUND_UP(timings->tADL_min, 32);
1171
1172 if (timings->tWHR_min > (min_clk_period * 32))
1173 min_clk_period = DIV_ROUND_UP(timings->tWHR_min, 32);
1174
1175 if (timings->tRHW_min > (min_clk_period * 20))
1176 min_clk_period = DIV_ROUND_UP(timings->tRHW_min, 20);
1177
Roy Spliet9c618292015-06-26 11:00:10 +02001178 tWB = sunxi_nand_lookup_timing(tWB_lut, timings->tWB_max,
1179 min_clk_period);
1180 if (tWB < 0) {
1181 dev_err(nfc->dev, "unsupported tWB\n");
1182 return tWB;
1183 }
1184
1185 tADL = DIV_ROUND_UP(timings->tADL_min, min_clk_period) >> 3;
1186 if (tADL > 3) {
1187 dev_err(nfc->dev, "unsupported tADL\n");
1188 return -EINVAL;
1189 }
1190
1191 tWHR = DIV_ROUND_UP(timings->tWHR_min, min_clk_period) >> 3;
1192 if (tWHR > 3) {
1193 dev_err(nfc->dev, "unsupported tWHR\n");
1194 return -EINVAL;
1195 }
1196
1197 tRHW = sunxi_nand_lookup_timing(tRHW_lut, timings->tRHW_min,
1198 min_clk_period);
1199 if (tRHW < 0) {
1200 dev_err(nfc->dev, "unsupported tRHW\n");
1201 return tRHW;
1202 }
1203
1204 /*
1205 * TODO: according to ONFI specs this value only applies for DDR NAND,
1206 * but Allwinner seems to set this to 0x7. Mimic them for now.
1207 */
1208 tCAD = 0x7;
1209
1210 /* TODO: A83 has some more bits for CDQSS, CS, CLHZ, CCS, WC */
1211 chip->timing_cfg = NFC_TIMING_CFG(tWB, tADL, tWHR, tRHW, tCAD);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001212
1213 /* Convert min_clk_period from picoseconds to nanoseconds */
1214 min_clk_period = DIV_ROUND_UP(min_clk_period, 1000);
1215
1216 /*
Boris Brezillon2f9992e2015-12-02 15:10:40 +01001217 * Unlike what is stated in Allwinner datasheet, the clk_rate should
1218 * be set to (1 / min_clk_period), and not (2 / min_clk_period).
1219 * This new formula was verified with a scope and validated by
1220 * Allwinner engineers.
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001221 */
Boris Brezillon2f9992e2015-12-02 15:10:40 +01001222 chip->clk_rate = NSEC_PER_SEC / min_clk_period;
Boris Brezillon2d434572015-12-02 15:57:20 +01001223 real_clk_rate = clk_round_rate(nfc->mod_clk, chip->clk_rate);
1224
1225 /*
1226 * ONFI specification 3.1, paragraph 4.15.2 dictates that EDO data
1227 * output cycle timings shall be used if the host drives tRC less than
1228 * 30 ns.
1229 */
1230 min_clk_period = NSEC_PER_SEC / real_clk_rate;
1231 chip->timing_ctl = ((min_clk_period * 2) < 30) ?
1232 NFC_TIMING_CTL_EDO : 0;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001233
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001234 return 0;
1235}
1236
1237static int sunxi_nand_chip_init_timings(struct sunxi_nand_chip *chip,
1238 struct device_node *np)
1239{
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001240 struct mtd_info *mtd = nand_to_mtd(&chip->nand);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001241 const struct nand_sdr_timings *timings;
1242 int ret;
1243 int mode;
1244
1245 mode = onfi_get_async_timing_mode(&chip->nand);
1246 if (mode == ONFI_TIMING_MODE_UNKNOWN) {
1247 mode = chip->nand.onfi_timing_mode_default;
1248 } else {
1249 uint8_t feature[ONFI_SUBFEATURE_PARAM_LEN] = {};
Stefan Roese7eadd47f2015-08-28 14:45:21 +02001250 int i;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001251
1252 mode = fls(mode) - 1;
1253 if (mode < 0)
1254 mode = 0;
1255
1256 feature[0] = mode;
Stefan Roese7eadd47f2015-08-28 14:45:21 +02001257 for (i = 0; i < chip->nsels; i++) {
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001258 chip->nand.select_chip(mtd, i);
1259 ret = chip->nand.onfi_set_features(mtd, &chip->nand,
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001260 ONFI_FEATURE_ADDR_TIMING_MODE,
1261 feature);
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001262 chip->nand.select_chip(mtd, -1);
Stefan Roese7eadd47f2015-08-28 14:45:21 +02001263 if (ret)
1264 return ret;
1265 }
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001266 }
1267
1268 timings = onfi_async_timing_mode_to_sdr_timings(mode);
1269 if (IS_ERR(timings))
1270 return PTR_ERR(timings);
1271
1272 return sunxi_nand_chip_set_timings(chip, timings);
1273}
1274
1275static int sunxi_nand_hw_common_ecc_ctrl_init(struct mtd_info *mtd,
1276 struct nand_ecc_ctrl *ecc,
1277 struct device_node *np)
1278{
1279 static const u8 strengths[] = { 16, 24, 28, 32, 40, 48, 56, 60, 64 };
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +01001280 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001281 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
1282 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
1283 struct sunxi_nand_hw_ecc *data;
1284 struct nand_ecclayout *layout;
1285 int nsectors;
1286 int ret;
1287 int i;
1288
1289 data = kzalloc(sizeof(*data), GFP_KERNEL);
1290 if (!data)
1291 return -ENOMEM;
1292
1293 /* Add ECC info retrieval from DT */
1294 for (i = 0; i < ARRAY_SIZE(strengths); i++) {
1295 if (ecc->strength <= strengths[i])
1296 break;
1297 }
1298
1299 if (i >= ARRAY_SIZE(strengths)) {
1300 dev_err(nfc->dev, "unsupported strength\n");
1301 ret = -ENOTSUPP;
1302 goto err;
1303 }
1304
1305 data->mode = i;
1306
1307 /* HW ECC always request ECC bytes for 1024 bytes blocks */
1308 ecc->bytes = DIV_ROUND_UP(ecc->strength * fls(8 * 1024), 8);
1309
1310 /* HW ECC always work with even numbers of ECC bytes */
1311 ecc->bytes = ALIGN(ecc->bytes, 2);
1312
1313 layout = &data->layout;
1314 nsectors = mtd->writesize / ecc->size;
1315
1316 if (mtd->oobsize < ((ecc->bytes + 4) * nsectors)) {
1317 ret = -EINVAL;
1318 goto err;
1319 }
1320
1321 layout->eccbytes = (ecc->bytes * nsectors);
1322
1323 ecc->layout = layout;
1324 ecc->priv = data;
1325
1326 return 0;
1327
1328err:
1329 kfree(data);
1330
1331 return ret;
1332}
1333
1334static void sunxi_nand_hw_common_ecc_ctrl_cleanup(struct nand_ecc_ctrl *ecc)
1335{
1336 kfree(ecc->priv);
1337}
1338
1339static int sunxi_nand_hw_ecc_ctrl_init(struct mtd_info *mtd,
1340 struct nand_ecc_ctrl *ecc,
1341 struct device_node *np)
1342{
1343 struct nand_ecclayout *layout;
1344 int nsectors;
1345 int i, j;
1346 int ret;
1347
1348 ret = sunxi_nand_hw_common_ecc_ctrl_init(mtd, ecc, np);
1349 if (ret)
1350 return ret;
1351
1352 ecc->read_page = sunxi_nfc_hw_ecc_read_page;
1353 ecc->write_page = sunxi_nfc_hw_ecc_write_page;
1354 layout = ecc->layout;
1355 nsectors = mtd->writesize / ecc->size;
1356
1357 for (i = 0; i < nsectors; i++) {
1358 if (i) {
1359 layout->oobfree[i].offset =
1360 layout->oobfree[i - 1].offset +
1361 layout->oobfree[i - 1].length +
1362 ecc->bytes;
1363 layout->oobfree[i].length = 4;
1364 } else {
1365 /*
1366 * The first 2 bytes are used for BB markers, hence we
1367 * only have 2 bytes available in the first user data
1368 * section.
1369 */
1370 layout->oobfree[i].length = 2;
1371 layout->oobfree[i].offset = 2;
1372 }
1373
1374 for (j = 0; j < ecc->bytes; j++)
1375 layout->eccpos[(ecc->bytes * i) + j] =
1376 layout->oobfree[i].offset +
1377 layout->oobfree[i].length + j;
1378 }
1379
1380 if (mtd->oobsize > (ecc->bytes + 4) * nsectors) {
1381 layout->oobfree[nsectors].offset =
1382 layout->oobfree[nsectors - 1].offset +
1383 layout->oobfree[nsectors - 1].length +
1384 ecc->bytes;
1385 layout->oobfree[nsectors].length = mtd->oobsize -
1386 ((ecc->bytes + 4) * nsectors);
1387 }
1388
1389 return 0;
1390}
1391
1392static int sunxi_nand_hw_syndrome_ecc_ctrl_init(struct mtd_info *mtd,
1393 struct nand_ecc_ctrl *ecc,
1394 struct device_node *np)
1395{
1396 struct nand_ecclayout *layout;
1397 int nsectors;
1398 int i;
1399 int ret;
1400
1401 ret = sunxi_nand_hw_common_ecc_ctrl_init(mtd, ecc, np);
1402 if (ret)
1403 return ret;
1404
1405 ecc->prepad = 4;
1406 ecc->read_page = sunxi_nfc_hw_syndrome_ecc_read_page;
1407 ecc->write_page = sunxi_nfc_hw_syndrome_ecc_write_page;
1408
1409 layout = ecc->layout;
1410 nsectors = mtd->writesize / ecc->size;
1411
1412 for (i = 0; i < (ecc->bytes * nsectors); i++)
1413 layout->eccpos[i] = i;
1414
1415 layout->oobfree[0].length = mtd->oobsize - i;
1416 layout->oobfree[0].offset = i;
1417
1418 return 0;
1419}
1420
1421static void sunxi_nand_ecc_cleanup(struct nand_ecc_ctrl *ecc)
1422{
1423 switch (ecc->mode) {
1424 case NAND_ECC_HW:
1425 case NAND_ECC_HW_SYNDROME:
1426 sunxi_nand_hw_common_ecc_ctrl_cleanup(ecc);
1427 break;
1428 case NAND_ECC_NONE:
1429 kfree(ecc->layout);
1430 default:
1431 break;
1432 }
1433}
1434
1435static int sunxi_nand_ecc_init(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc,
1436 struct device_node *np)
1437{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +01001438 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001439 int ret;
1440
Boris BREZILLONa3d22a52015-09-02 10:30:25 +02001441 if (!ecc->size) {
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001442 ecc->size = nand->ecc_step_ds;
1443 ecc->strength = nand->ecc_strength_ds;
1444 }
1445
1446 if (!ecc->size || !ecc->strength)
1447 return -EINVAL;
1448
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001449 switch (ecc->mode) {
1450 case NAND_ECC_SOFT_BCH:
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001451 break;
1452 case NAND_ECC_HW:
1453 ret = sunxi_nand_hw_ecc_ctrl_init(mtd, ecc, np);
1454 if (ret)
1455 return ret;
1456 break;
1457 case NAND_ECC_HW_SYNDROME:
1458 ret = sunxi_nand_hw_syndrome_ecc_ctrl_init(mtd, ecc, np);
1459 if (ret)
1460 return ret;
1461 break;
1462 case NAND_ECC_NONE:
1463 ecc->layout = kzalloc(sizeof(*ecc->layout), GFP_KERNEL);
1464 if (!ecc->layout)
1465 return -ENOMEM;
1466 ecc->layout->oobfree[0].length = mtd->oobsize;
1467 case NAND_ECC_SOFT:
1468 break;
1469 default:
1470 return -EINVAL;
1471 }
1472
1473 return 0;
1474}
1475
1476static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc,
1477 struct device_node *np)
1478{
1479 const struct nand_sdr_timings *timings;
1480 struct sunxi_nand_chip *chip;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001481 struct mtd_info *mtd;
1482 struct nand_chip *nand;
1483 int nsels;
1484 int ret;
1485 int i;
1486 u32 tmp;
1487
1488 if (!of_get_property(np, "reg", &nsels))
1489 return -EINVAL;
1490
1491 nsels /= sizeof(u32);
1492 if (!nsels) {
1493 dev_err(dev, "invalid reg property size\n");
1494 return -EINVAL;
1495 }
1496
1497 chip = devm_kzalloc(dev,
1498 sizeof(*chip) +
1499 (nsels * sizeof(struct sunxi_nand_chip_sel)),
1500 GFP_KERNEL);
1501 if (!chip) {
1502 dev_err(dev, "could not allocate chip\n");
1503 return -ENOMEM;
1504 }
1505
1506 chip->nsels = nsels;
1507 chip->selected = -1;
1508
1509 for (i = 0; i < nsels; i++) {
1510 ret = of_property_read_u32_index(np, "reg", i, &tmp);
1511 if (ret) {
1512 dev_err(dev, "could not retrieve reg property: %d\n",
1513 ret);
1514 return ret;
1515 }
1516
1517 if (tmp > NFC_MAX_CS) {
1518 dev_err(dev,
1519 "invalid reg value: %u (max CS = 7)\n",
1520 tmp);
1521 return -EINVAL;
1522 }
1523
1524 if (test_and_set_bit(tmp, &nfc->assigned_cs)) {
1525 dev_err(dev, "CS %d already assigned\n", tmp);
1526 return -EINVAL;
1527 }
1528
1529 chip->sels[i].cs = tmp;
1530
1531 if (!of_property_read_u32_index(np, "allwinner,rb", i, &tmp) &&
1532 tmp < 2) {
1533 chip->sels[i].rb.type = RB_NATIVE;
1534 chip->sels[i].rb.info.nativeid = tmp;
1535 } else {
1536 ret = of_get_named_gpio(np, "rb-gpios", i);
1537 if (ret >= 0) {
1538 tmp = ret;
1539 chip->sels[i].rb.type = RB_GPIO;
1540 chip->sels[i].rb.info.gpio = tmp;
1541 ret = devm_gpio_request(dev, tmp, "nand-rb");
1542 if (ret)
1543 return ret;
1544
1545 ret = gpio_direction_input(tmp);
1546 if (ret)
1547 return ret;
1548 } else {
1549 chip->sels[i].rb.type = RB_NONE;
1550 }
1551 }
1552 }
1553
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001554 nand = &chip->nand;
1555 /* Default tR value specified in the ONFI spec (chapter 4.15.1) */
1556 nand->chip_delay = 200;
1557 nand->controller = &nfc->controller;
Boris BREZILLONa3d22a52015-09-02 10:30:25 +02001558 /*
1559 * Set the ECC mode to the default value in case nothing is specified
1560 * in the DT.
1561 */
1562 nand->ecc.mode = NAND_ECC_HW;
Brian Norris63752192015-10-30 20:33:23 -07001563 nand_set_flash_node(nand, np);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001564 nand->select_chip = sunxi_nfc_select_chip;
1565 nand->cmd_ctrl = sunxi_nfc_cmd_ctrl;
1566 nand->read_buf = sunxi_nfc_read_buf;
1567 nand->write_buf = sunxi_nfc_write_buf;
1568 nand->read_byte = sunxi_nfc_read_byte;
1569
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001570 mtd = nand_to_mtd(nand);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001571 mtd->dev.parent = dev;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001572
Boris Brezillon9edb4702015-12-02 16:00:57 +01001573 timings = onfi_async_timing_mode_to_sdr_timings(0);
1574 if (IS_ERR(timings)) {
1575 ret = PTR_ERR(timings);
1576 dev_err(dev,
1577 "could not retrieve timings for ONFI mode 0: %d\n",
1578 ret);
1579 return ret;
1580 }
1581
1582 ret = sunxi_nand_chip_set_timings(chip, timings);
1583 if (ret) {
1584 dev_err(dev, "could not configure chip timings: %d\n", ret);
1585 return ret;
1586 }
1587
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001588 ret = nand_scan_ident(mtd, nsels, NULL);
1589 if (ret)
1590 return ret;
1591
Boris BREZILLONa3d22a52015-09-02 10:30:25 +02001592 if (nand->bbt_options & NAND_BBT_USE_FLASH)
1593 nand->bbt_options |= NAND_BBT_NO_OOB;
1594
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001595 if (nand->options & NAND_NEED_SCRAMBLING)
1596 nand->options |= NAND_NO_SUBPAGE_WRITE;
1597
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001598 ret = sunxi_nand_chip_init_timings(chip, np);
1599 if (ret) {
1600 dev_err(dev, "could not configure chip timings: %d\n", ret);
1601 return ret;
1602 }
1603
1604 ret = sunxi_nand_ecc_init(mtd, &nand->ecc, np);
1605 if (ret) {
1606 dev_err(dev, "ECC init failed: %d\n", ret);
1607 return ret;
1608 }
1609
1610 ret = nand_scan_tail(mtd);
1611 if (ret) {
1612 dev_err(dev, "nand_scan_tail failed: %d\n", ret);
1613 return ret;
1614 }
1615
Brian Norrisa61ae812015-10-30 20:33:25 -07001616 ret = mtd_device_register(mtd, NULL, 0);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001617 if (ret) {
1618 dev_err(dev, "failed to register mtd device: %d\n", ret);
1619 nand_release(mtd);
1620 return ret;
1621 }
1622
1623 list_add_tail(&chip->node, &nfc->chips);
1624
1625 return 0;
1626}
1627
1628static int sunxi_nand_chips_init(struct device *dev, struct sunxi_nfc *nfc)
1629{
1630 struct device_node *np = dev->of_node;
1631 struct device_node *nand_np;
1632 int nchips = of_get_child_count(np);
1633 int ret;
1634
1635 if (nchips > 8) {
1636 dev_err(dev, "too many NAND chips: %d (max = 8)\n", nchips);
1637 return -EINVAL;
1638 }
1639
1640 for_each_child_of_node(np, nand_np) {
1641 ret = sunxi_nand_chip_init(dev, nfc, nand_np);
Julia Lawalla81c0f02015-11-18 23:04:12 +01001642 if (ret) {
1643 of_node_put(nand_np);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001644 return ret;
Julia Lawalla81c0f02015-11-18 23:04:12 +01001645 }
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001646 }
1647
1648 return 0;
1649}
1650
1651static void sunxi_nand_chips_cleanup(struct sunxi_nfc *nfc)
1652{
1653 struct sunxi_nand_chip *chip;
1654
1655 while (!list_empty(&nfc->chips)) {
1656 chip = list_first_entry(&nfc->chips, struct sunxi_nand_chip,
1657 node);
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001658 nand_release(nand_to_mtd(&chip->nand));
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001659 sunxi_nand_ecc_cleanup(&chip->nand.ecc);
Boris BREZILLON8e375cc2015-09-13 18:14:43 +02001660 list_del(&chip->node);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001661 }
1662}
1663
1664static int sunxi_nfc_probe(struct platform_device *pdev)
1665{
1666 struct device *dev = &pdev->dev;
1667 struct resource *r;
1668 struct sunxi_nfc *nfc;
1669 int irq;
1670 int ret;
1671
1672 nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
1673 if (!nfc)
1674 return -ENOMEM;
1675
1676 nfc->dev = dev;
1677 spin_lock_init(&nfc->controller.lock);
1678 init_waitqueue_head(&nfc->controller.wq);
1679 INIT_LIST_HEAD(&nfc->chips);
1680
1681 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1682 nfc->regs = devm_ioremap_resource(dev, r);
1683 if (IS_ERR(nfc->regs))
1684 return PTR_ERR(nfc->regs);
1685
1686 irq = platform_get_irq(pdev, 0);
1687 if (irq < 0) {
1688 dev_err(dev, "failed to retrieve irq\n");
1689 return irq;
1690 }
1691
1692 nfc->ahb_clk = devm_clk_get(dev, "ahb");
1693 if (IS_ERR(nfc->ahb_clk)) {
1694 dev_err(dev, "failed to retrieve ahb clk\n");
1695 return PTR_ERR(nfc->ahb_clk);
1696 }
1697
1698 ret = clk_prepare_enable(nfc->ahb_clk);
1699 if (ret)
1700 return ret;
1701
1702 nfc->mod_clk = devm_clk_get(dev, "mod");
1703 if (IS_ERR(nfc->mod_clk)) {
1704 dev_err(dev, "failed to retrieve mod clk\n");
1705 ret = PTR_ERR(nfc->mod_clk);
1706 goto out_ahb_clk_unprepare;
1707 }
1708
1709 ret = clk_prepare_enable(nfc->mod_clk);
1710 if (ret)
1711 goto out_ahb_clk_unprepare;
1712
1713 ret = sunxi_nfc_rst(nfc);
1714 if (ret)
1715 goto out_mod_clk_unprepare;
1716
1717 writel(0, nfc->regs + NFC_REG_INT);
1718 ret = devm_request_irq(dev, irq, sunxi_nfc_interrupt,
1719 0, "sunxi-nand", nfc);
1720 if (ret)
1721 goto out_mod_clk_unprepare;
1722
1723 platform_set_drvdata(pdev, nfc);
1724
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001725 ret = sunxi_nand_chips_init(dev, nfc);
1726 if (ret) {
1727 dev_err(dev, "failed to init nand chips\n");
1728 goto out_mod_clk_unprepare;
1729 }
1730
1731 return 0;
1732
1733out_mod_clk_unprepare:
1734 clk_disable_unprepare(nfc->mod_clk);
1735out_ahb_clk_unprepare:
1736 clk_disable_unprepare(nfc->ahb_clk);
1737
1738 return ret;
1739}
1740
1741static int sunxi_nfc_remove(struct platform_device *pdev)
1742{
1743 struct sunxi_nfc *nfc = platform_get_drvdata(pdev);
1744
1745 sunxi_nand_chips_cleanup(nfc);
1746
1747 return 0;
1748}
1749
1750static const struct of_device_id sunxi_nfc_ids[] = {
1751 { .compatible = "allwinner,sun4i-a10-nand" },
1752 { /* sentinel */ }
1753};
1754MODULE_DEVICE_TABLE(of, sunxi_nfc_ids);
1755
1756static struct platform_driver sunxi_nfc_driver = {
1757 .driver = {
1758 .name = "sunxi_nand",
1759 .of_match_table = sunxi_nfc_ids,
1760 },
1761 .probe = sunxi_nfc_probe,
1762 .remove = sunxi_nfc_remove,
1763};
1764module_platform_driver(sunxi_nfc_driver);
1765
1766MODULE_LICENSE("GPL v2");
1767MODULE_AUTHOR("Boris BREZILLON");
1768MODULE_DESCRIPTION("Allwinner NAND Flash Controller driver");
1769MODULE_ALIAS("platform:sunxi_nand");