blob: 05b33035f6510263d207cc36d272ce847355841d [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 BREZILLON1fef62c2014-10-21 15:08:41 +02001103
1104 /* T1 <=> tCLS */
1105 if (timings->tCLS_min > min_clk_period)
1106 min_clk_period = timings->tCLS_min;
1107
1108 /* T2 <=> tCLH */
1109 if (timings->tCLH_min > min_clk_period)
1110 min_clk_period = timings->tCLH_min;
1111
1112 /* T3 <=> tCS */
1113 if (timings->tCS_min > min_clk_period)
1114 min_clk_period = timings->tCS_min;
1115
1116 /* T4 <=> tCH */
1117 if (timings->tCH_min > min_clk_period)
1118 min_clk_period = timings->tCH_min;
1119
1120 /* T5 <=> tWP */
1121 if (timings->tWP_min > min_clk_period)
1122 min_clk_period = timings->tWP_min;
1123
1124 /* T6 <=> tWH */
1125 if (timings->tWH_min > min_clk_period)
1126 min_clk_period = timings->tWH_min;
1127
1128 /* T7 <=> tALS */
1129 if (timings->tALS_min > min_clk_period)
1130 min_clk_period = timings->tALS_min;
1131
1132 /* T8 <=> tDS */
1133 if (timings->tDS_min > min_clk_period)
1134 min_clk_period = timings->tDS_min;
1135
1136 /* T9 <=> tDH */
1137 if (timings->tDH_min > min_clk_period)
1138 min_clk_period = timings->tDH_min;
1139
1140 /* T10 <=> tRR */
1141 if (timings->tRR_min > (min_clk_period * 3))
1142 min_clk_period = DIV_ROUND_UP(timings->tRR_min, 3);
1143
1144 /* T11 <=> tALH */
1145 if (timings->tALH_min > min_clk_period)
1146 min_clk_period = timings->tALH_min;
1147
1148 /* T12 <=> tRP */
1149 if (timings->tRP_min > min_clk_period)
1150 min_clk_period = timings->tRP_min;
1151
1152 /* T13 <=> tREH */
1153 if (timings->tREH_min > min_clk_period)
1154 min_clk_period = timings->tREH_min;
1155
1156 /* T14 <=> tRC */
1157 if (timings->tRC_min > (min_clk_period * 2))
1158 min_clk_period = DIV_ROUND_UP(timings->tRC_min, 2);
1159
1160 /* T15 <=> tWC */
1161 if (timings->tWC_min > (min_clk_period * 2))
1162 min_clk_period = DIV_ROUND_UP(timings->tWC_min, 2);
1163
Roy Spliet9c618292015-06-26 11:00:10 +02001164 /* T16 - T19 + tCAD */
1165 tWB = sunxi_nand_lookup_timing(tWB_lut, timings->tWB_max,
1166 min_clk_period);
1167 if (tWB < 0) {
1168 dev_err(nfc->dev, "unsupported tWB\n");
1169 return tWB;
1170 }
1171
1172 tADL = DIV_ROUND_UP(timings->tADL_min, min_clk_period) >> 3;
1173 if (tADL > 3) {
1174 dev_err(nfc->dev, "unsupported tADL\n");
1175 return -EINVAL;
1176 }
1177
1178 tWHR = DIV_ROUND_UP(timings->tWHR_min, min_clk_period) >> 3;
1179 if (tWHR > 3) {
1180 dev_err(nfc->dev, "unsupported tWHR\n");
1181 return -EINVAL;
1182 }
1183
1184 tRHW = sunxi_nand_lookup_timing(tRHW_lut, timings->tRHW_min,
1185 min_clk_period);
1186 if (tRHW < 0) {
1187 dev_err(nfc->dev, "unsupported tRHW\n");
1188 return tRHW;
1189 }
1190
1191 /*
1192 * TODO: according to ONFI specs this value only applies for DDR NAND,
1193 * but Allwinner seems to set this to 0x7. Mimic them for now.
1194 */
1195 tCAD = 0x7;
1196
1197 /* TODO: A83 has some more bits for CDQSS, CS, CLHZ, CCS, WC */
1198 chip->timing_cfg = NFC_TIMING_CFG(tWB, tADL, tWHR, tRHW, tCAD);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001199
Roy Splietd052e502015-06-26 11:00:11 +02001200 /*
1201 * ONFI specification 3.1, paragraph 4.15.2 dictates that EDO data
1202 * output cycle timings shall be used if the host drives tRC less than
1203 * 30 ns.
1204 */
1205 chip->timing_ctl = (timings->tRC_min < 30000) ? NFC_TIMING_CTL_EDO : 0;
1206
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001207 /* Convert min_clk_period from picoseconds to nanoseconds */
1208 min_clk_period = DIV_ROUND_UP(min_clk_period, 1000);
1209
1210 /*
Boris Brezillon2f9992e2015-12-02 15:10:40 +01001211 * Unlike what is stated in Allwinner datasheet, the clk_rate should
1212 * be set to (1 / min_clk_period), and not (2 / min_clk_period).
1213 * This new formula was verified with a scope and validated by
1214 * Allwinner engineers.
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001215 */
Boris Brezillon2f9992e2015-12-02 15:10:40 +01001216 chip->clk_rate = NSEC_PER_SEC / min_clk_period;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001217
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001218 return 0;
1219}
1220
1221static int sunxi_nand_chip_init_timings(struct sunxi_nand_chip *chip,
1222 struct device_node *np)
1223{
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001224 struct mtd_info *mtd = nand_to_mtd(&chip->nand);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001225 const struct nand_sdr_timings *timings;
1226 int ret;
1227 int mode;
1228
1229 mode = onfi_get_async_timing_mode(&chip->nand);
1230 if (mode == ONFI_TIMING_MODE_UNKNOWN) {
1231 mode = chip->nand.onfi_timing_mode_default;
1232 } else {
1233 uint8_t feature[ONFI_SUBFEATURE_PARAM_LEN] = {};
Stefan Roese7eadd472015-08-28 14:45:21 +02001234 int i;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001235
1236 mode = fls(mode) - 1;
1237 if (mode < 0)
1238 mode = 0;
1239
1240 feature[0] = mode;
Stefan Roese7eadd472015-08-28 14:45:21 +02001241 for (i = 0; i < chip->nsels; i++) {
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001242 chip->nand.select_chip(mtd, i);
1243 ret = chip->nand.onfi_set_features(mtd, &chip->nand,
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001244 ONFI_FEATURE_ADDR_TIMING_MODE,
1245 feature);
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001246 chip->nand.select_chip(mtd, -1);
Stefan Roese7eadd472015-08-28 14:45:21 +02001247 if (ret)
1248 return ret;
1249 }
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001250 }
1251
1252 timings = onfi_async_timing_mode_to_sdr_timings(mode);
1253 if (IS_ERR(timings))
1254 return PTR_ERR(timings);
1255
1256 return sunxi_nand_chip_set_timings(chip, timings);
1257}
1258
1259static int sunxi_nand_hw_common_ecc_ctrl_init(struct mtd_info *mtd,
1260 struct nand_ecc_ctrl *ecc,
1261 struct device_node *np)
1262{
1263 static const u8 strengths[] = { 16, 24, 28, 32, 40, 48, 56, 60, 64 };
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +01001264 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001265 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
1266 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
1267 struct sunxi_nand_hw_ecc *data;
1268 struct nand_ecclayout *layout;
1269 int nsectors;
1270 int ret;
1271 int i;
1272
1273 data = kzalloc(sizeof(*data), GFP_KERNEL);
1274 if (!data)
1275 return -ENOMEM;
1276
1277 /* Add ECC info retrieval from DT */
1278 for (i = 0; i < ARRAY_SIZE(strengths); i++) {
1279 if (ecc->strength <= strengths[i])
1280 break;
1281 }
1282
1283 if (i >= ARRAY_SIZE(strengths)) {
1284 dev_err(nfc->dev, "unsupported strength\n");
1285 ret = -ENOTSUPP;
1286 goto err;
1287 }
1288
1289 data->mode = i;
1290
1291 /* HW ECC always request ECC bytes for 1024 bytes blocks */
1292 ecc->bytes = DIV_ROUND_UP(ecc->strength * fls(8 * 1024), 8);
1293
1294 /* HW ECC always work with even numbers of ECC bytes */
1295 ecc->bytes = ALIGN(ecc->bytes, 2);
1296
1297 layout = &data->layout;
1298 nsectors = mtd->writesize / ecc->size;
1299
1300 if (mtd->oobsize < ((ecc->bytes + 4) * nsectors)) {
1301 ret = -EINVAL;
1302 goto err;
1303 }
1304
1305 layout->eccbytes = (ecc->bytes * nsectors);
1306
1307 ecc->layout = layout;
1308 ecc->priv = data;
1309
1310 return 0;
1311
1312err:
1313 kfree(data);
1314
1315 return ret;
1316}
1317
1318static void sunxi_nand_hw_common_ecc_ctrl_cleanup(struct nand_ecc_ctrl *ecc)
1319{
1320 kfree(ecc->priv);
1321}
1322
1323static int sunxi_nand_hw_ecc_ctrl_init(struct mtd_info *mtd,
1324 struct nand_ecc_ctrl *ecc,
1325 struct device_node *np)
1326{
1327 struct nand_ecclayout *layout;
1328 int nsectors;
1329 int i, j;
1330 int ret;
1331
1332 ret = sunxi_nand_hw_common_ecc_ctrl_init(mtd, ecc, np);
1333 if (ret)
1334 return ret;
1335
1336 ecc->read_page = sunxi_nfc_hw_ecc_read_page;
1337 ecc->write_page = sunxi_nfc_hw_ecc_write_page;
1338 layout = ecc->layout;
1339 nsectors = mtd->writesize / ecc->size;
1340
1341 for (i = 0; i < nsectors; i++) {
1342 if (i) {
1343 layout->oobfree[i].offset =
1344 layout->oobfree[i - 1].offset +
1345 layout->oobfree[i - 1].length +
1346 ecc->bytes;
1347 layout->oobfree[i].length = 4;
1348 } else {
1349 /*
1350 * The first 2 bytes are used for BB markers, hence we
1351 * only have 2 bytes available in the first user data
1352 * section.
1353 */
1354 layout->oobfree[i].length = 2;
1355 layout->oobfree[i].offset = 2;
1356 }
1357
1358 for (j = 0; j < ecc->bytes; j++)
1359 layout->eccpos[(ecc->bytes * i) + j] =
1360 layout->oobfree[i].offset +
1361 layout->oobfree[i].length + j;
1362 }
1363
1364 if (mtd->oobsize > (ecc->bytes + 4) * nsectors) {
1365 layout->oobfree[nsectors].offset =
1366 layout->oobfree[nsectors - 1].offset +
1367 layout->oobfree[nsectors - 1].length +
1368 ecc->bytes;
1369 layout->oobfree[nsectors].length = mtd->oobsize -
1370 ((ecc->bytes + 4) * nsectors);
1371 }
1372
1373 return 0;
1374}
1375
1376static int sunxi_nand_hw_syndrome_ecc_ctrl_init(struct mtd_info *mtd,
1377 struct nand_ecc_ctrl *ecc,
1378 struct device_node *np)
1379{
1380 struct nand_ecclayout *layout;
1381 int nsectors;
1382 int i;
1383 int ret;
1384
1385 ret = sunxi_nand_hw_common_ecc_ctrl_init(mtd, ecc, np);
1386 if (ret)
1387 return ret;
1388
1389 ecc->prepad = 4;
1390 ecc->read_page = sunxi_nfc_hw_syndrome_ecc_read_page;
1391 ecc->write_page = sunxi_nfc_hw_syndrome_ecc_write_page;
1392
1393 layout = ecc->layout;
1394 nsectors = mtd->writesize / ecc->size;
1395
1396 for (i = 0; i < (ecc->bytes * nsectors); i++)
1397 layout->eccpos[i] = i;
1398
1399 layout->oobfree[0].length = mtd->oobsize - i;
1400 layout->oobfree[0].offset = i;
1401
1402 return 0;
1403}
1404
1405static void sunxi_nand_ecc_cleanup(struct nand_ecc_ctrl *ecc)
1406{
1407 switch (ecc->mode) {
1408 case NAND_ECC_HW:
1409 case NAND_ECC_HW_SYNDROME:
1410 sunxi_nand_hw_common_ecc_ctrl_cleanup(ecc);
1411 break;
1412 case NAND_ECC_NONE:
1413 kfree(ecc->layout);
1414 default:
1415 break;
1416 }
1417}
1418
1419static int sunxi_nand_ecc_init(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc,
1420 struct device_node *np)
1421{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +01001422 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001423 int ret;
1424
Boris BREZILLONa3d22a52015-09-02 10:30:25 +02001425 if (!ecc->size) {
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001426 ecc->size = nand->ecc_step_ds;
1427 ecc->strength = nand->ecc_strength_ds;
1428 }
1429
1430 if (!ecc->size || !ecc->strength)
1431 return -EINVAL;
1432
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001433 switch (ecc->mode) {
1434 case NAND_ECC_SOFT_BCH:
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001435 break;
1436 case NAND_ECC_HW:
1437 ret = sunxi_nand_hw_ecc_ctrl_init(mtd, ecc, np);
1438 if (ret)
1439 return ret;
1440 break;
1441 case NAND_ECC_HW_SYNDROME:
1442 ret = sunxi_nand_hw_syndrome_ecc_ctrl_init(mtd, ecc, np);
1443 if (ret)
1444 return ret;
1445 break;
1446 case NAND_ECC_NONE:
1447 ecc->layout = kzalloc(sizeof(*ecc->layout), GFP_KERNEL);
1448 if (!ecc->layout)
1449 return -ENOMEM;
1450 ecc->layout->oobfree[0].length = mtd->oobsize;
1451 case NAND_ECC_SOFT:
1452 break;
1453 default:
1454 return -EINVAL;
1455 }
1456
1457 return 0;
1458}
1459
1460static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc,
1461 struct device_node *np)
1462{
1463 const struct nand_sdr_timings *timings;
1464 struct sunxi_nand_chip *chip;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001465 struct mtd_info *mtd;
1466 struct nand_chip *nand;
1467 int nsels;
1468 int ret;
1469 int i;
1470 u32 tmp;
1471
1472 if (!of_get_property(np, "reg", &nsels))
1473 return -EINVAL;
1474
1475 nsels /= sizeof(u32);
1476 if (!nsels) {
1477 dev_err(dev, "invalid reg property size\n");
1478 return -EINVAL;
1479 }
1480
1481 chip = devm_kzalloc(dev,
1482 sizeof(*chip) +
1483 (nsels * sizeof(struct sunxi_nand_chip_sel)),
1484 GFP_KERNEL);
1485 if (!chip) {
1486 dev_err(dev, "could not allocate chip\n");
1487 return -ENOMEM;
1488 }
1489
1490 chip->nsels = nsels;
1491 chip->selected = -1;
1492
1493 for (i = 0; i < nsels; i++) {
1494 ret = of_property_read_u32_index(np, "reg", i, &tmp);
1495 if (ret) {
1496 dev_err(dev, "could not retrieve reg property: %d\n",
1497 ret);
1498 return ret;
1499 }
1500
1501 if (tmp > NFC_MAX_CS) {
1502 dev_err(dev,
1503 "invalid reg value: %u (max CS = 7)\n",
1504 tmp);
1505 return -EINVAL;
1506 }
1507
1508 if (test_and_set_bit(tmp, &nfc->assigned_cs)) {
1509 dev_err(dev, "CS %d already assigned\n", tmp);
1510 return -EINVAL;
1511 }
1512
1513 chip->sels[i].cs = tmp;
1514
1515 if (!of_property_read_u32_index(np, "allwinner,rb", i, &tmp) &&
1516 tmp < 2) {
1517 chip->sels[i].rb.type = RB_NATIVE;
1518 chip->sels[i].rb.info.nativeid = tmp;
1519 } else {
1520 ret = of_get_named_gpio(np, "rb-gpios", i);
1521 if (ret >= 0) {
1522 tmp = ret;
1523 chip->sels[i].rb.type = RB_GPIO;
1524 chip->sels[i].rb.info.gpio = tmp;
1525 ret = devm_gpio_request(dev, tmp, "nand-rb");
1526 if (ret)
1527 return ret;
1528
1529 ret = gpio_direction_input(tmp);
1530 if (ret)
1531 return ret;
1532 } else {
1533 chip->sels[i].rb.type = RB_NONE;
1534 }
1535 }
1536 }
1537
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001538 nand = &chip->nand;
1539 /* Default tR value specified in the ONFI spec (chapter 4.15.1) */
1540 nand->chip_delay = 200;
1541 nand->controller = &nfc->controller;
Boris BREZILLONa3d22a52015-09-02 10:30:25 +02001542 /*
1543 * Set the ECC mode to the default value in case nothing is specified
1544 * in the DT.
1545 */
1546 nand->ecc.mode = NAND_ECC_HW;
Brian Norris63752192015-10-30 20:33:23 -07001547 nand_set_flash_node(nand, np);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001548 nand->select_chip = sunxi_nfc_select_chip;
1549 nand->cmd_ctrl = sunxi_nfc_cmd_ctrl;
1550 nand->read_buf = sunxi_nfc_read_buf;
1551 nand->write_buf = sunxi_nfc_write_buf;
1552 nand->read_byte = sunxi_nfc_read_byte;
1553
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001554 mtd = nand_to_mtd(nand);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001555 mtd->dev.parent = dev;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001556
Boris Brezillon9edb4702015-12-02 16:00:57 +01001557 timings = onfi_async_timing_mode_to_sdr_timings(0);
1558 if (IS_ERR(timings)) {
1559 ret = PTR_ERR(timings);
1560 dev_err(dev,
1561 "could not retrieve timings for ONFI mode 0: %d\n",
1562 ret);
1563 return ret;
1564 }
1565
1566 ret = sunxi_nand_chip_set_timings(chip, timings);
1567 if (ret) {
1568 dev_err(dev, "could not configure chip timings: %d\n", ret);
1569 return ret;
1570 }
1571
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001572 ret = nand_scan_ident(mtd, nsels, NULL);
1573 if (ret)
1574 return ret;
1575
Boris BREZILLONa3d22a52015-09-02 10:30:25 +02001576 if (nand->bbt_options & NAND_BBT_USE_FLASH)
1577 nand->bbt_options |= NAND_BBT_NO_OOB;
1578
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001579 if (nand->options & NAND_NEED_SCRAMBLING)
1580 nand->options |= NAND_NO_SUBPAGE_WRITE;
1581
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001582 ret = sunxi_nand_chip_init_timings(chip, np);
1583 if (ret) {
1584 dev_err(dev, "could not configure chip timings: %d\n", ret);
1585 return ret;
1586 }
1587
1588 ret = sunxi_nand_ecc_init(mtd, &nand->ecc, np);
1589 if (ret) {
1590 dev_err(dev, "ECC init failed: %d\n", ret);
1591 return ret;
1592 }
1593
1594 ret = nand_scan_tail(mtd);
1595 if (ret) {
1596 dev_err(dev, "nand_scan_tail failed: %d\n", ret);
1597 return ret;
1598 }
1599
Brian Norrisa61ae812015-10-30 20:33:25 -07001600 ret = mtd_device_register(mtd, NULL, 0);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001601 if (ret) {
1602 dev_err(dev, "failed to register mtd device: %d\n", ret);
1603 nand_release(mtd);
1604 return ret;
1605 }
1606
1607 list_add_tail(&chip->node, &nfc->chips);
1608
1609 return 0;
1610}
1611
1612static int sunxi_nand_chips_init(struct device *dev, struct sunxi_nfc *nfc)
1613{
1614 struct device_node *np = dev->of_node;
1615 struct device_node *nand_np;
1616 int nchips = of_get_child_count(np);
1617 int ret;
1618
1619 if (nchips > 8) {
1620 dev_err(dev, "too many NAND chips: %d (max = 8)\n", nchips);
1621 return -EINVAL;
1622 }
1623
1624 for_each_child_of_node(np, nand_np) {
1625 ret = sunxi_nand_chip_init(dev, nfc, nand_np);
Julia Lawalla81c0f02015-11-18 23:04:12 +01001626 if (ret) {
1627 of_node_put(nand_np);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001628 return ret;
Julia Lawalla81c0f02015-11-18 23:04:12 +01001629 }
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001630 }
1631
1632 return 0;
1633}
1634
1635static void sunxi_nand_chips_cleanup(struct sunxi_nfc *nfc)
1636{
1637 struct sunxi_nand_chip *chip;
1638
1639 while (!list_empty(&nfc->chips)) {
1640 chip = list_first_entry(&nfc->chips, struct sunxi_nand_chip,
1641 node);
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001642 nand_release(nand_to_mtd(&chip->nand));
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001643 sunxi_nand_ecc_cleanup(&chip->nand.ecc);
Boris BREZILLON8e375cc2015-09-13 18:14:43 +02001644 list_del(&chip->node);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001645 }
1646}
1647
1648static int sunxi_nfc_probe(struct platform_device *pdev)
1649{
1650 struct device *dev = &pdev->dev;
1651 struct resource *r;
1652 struct sunxi_nfc *nfc;
1653 int irq;
1654 int ret;
1655
1656 nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
1657 if (!nfc)
1658 return -ENOMEM;
1659
1660 nfc->dev = dev;
1661 spin_lock_init(&nfc->controller.lock);
1662 init_waitqueue_head(&nfc->controller.wq);
1663 INIT_LIST_HEAD(&nfc->chips);
1664
1665 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1666 nfc->regs = devm_ioremap_resource(dev, r);
1667 if (IS_ERR(nfc->regs))
1668 return PTR_ERR(nfc->regs);
1669
1670 irq = platform_get_irq(pdev, 0);
1671 if (irq < 0) {
1672 dev_err(dev, "failed to retrieve irq\n");
1673 return irq;
1674 }
1675
1676 nfc->ahb_clk = devm_clk_get(dev, "ahb");
1677 if (IS_ERR(nfc->ahb_clk)) {
1678 dev_err(dev, "failed to retrieve ahb clk\n");
1679 return PTR_ERR(nfc->ahb_clk);
1680 }
1681
1682 ret = clk_prepare_enable(nfc->ahb_clk);
1683 if (ret)
1684 return ret;
1685
1686 nfc->mod_clk = devm_clk_get(dev, "mod");
1687 if (IS_ERR(nfc->mod_clk)) {
1688 dev_err(dev, "failed to retrieve mod clk\n");
1689 ret = PTR_ERR(nfc->mod_clk);
1690 goto out_ahb_clk_unprepare;
1691 }
1692
1693 ret = clk_prepare_enable(nfc->mod_clk);
1694 if (ret)
1695 goto out_ahb_clk_unprepare;
1696
1697 ret = sunxi_nfc_rst(nfc);
1698 if (ret)
1699 goto out_mod_clk_unprepare;
1700
1701 writel(0, nfc->regs + NFC_REG_INT);
1702 ret = devm_request_irq(dev, irq, sunxi_nfc_interrupt,
1703 0, "sunxi-nand", nfc);
1704 if (ret)
1705 goto out_mod_clk_unprepare;
1706
1707 platform_set_drvdata(pdev, nfc);
1708
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001709 ret = sunxi_nand_chips_init(dev, nfc);
1710 if (ret) {
1711 dev_err(dev, "failed to init nand chips\n");
1712 goto out_mod_clk_unprepare;
1713 }
1714
1715 return 0;
1716
1717out_mod_clk_unprepare:
1718 clk_disable_unprepare(nfc->mod_clk);
1719out_ahb_clk_unprepare:
1720 clk_disable_unprepare(nfc->ahb_clk);
1721
1722 return ret;
1723}
1724
1725static int sunxi_nfc_remove(struct platform_device *pdev)
1726{
1727 struct sunxi_nfc *nfc = platform_get_drvdata(pdev);
1728
1729 sunxi_nand_chips_cleanup(nfc);
1730
1731 return 0;
1732}
1733
1734static const struct of_device_id sunxi_nfc_ids[] = {
1735 { .compatible = "allwinner,sun4i-a10-nand" },
1736 { /* sentinel */ }
1737};
1738MODULE_DEVICE_TABLE(of, sunxi_nfc_ids);
1739
1740static struct platform_driver sunxi_nfc_driver = {
1741 .driver = {
1742 .name = "sunxi_nand",
1743 .of_match_table = sunxi_nfc_ids,
1744 },
1745 .probe = sunxi_nfc_probe,
1746 .remove = sunxi_nfc_remove,
1747};
1748module_platform_driver(sunxi_nfc_driver);
1749
1750MODULE_LICENSE("GPL v2");
1751MODULE_AUTHOR("Boris BREZILLON");
1752MODULE_DESCRIPTION("Allwinner NAND Flash Controller driver");
1753MODULE_ALIAS("platform:sunxi_nand");