blob: c20bf59141b07c4c01e74afd2fdd21671956278d [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>
Boris Brezillon166f08c2016-03-07 15:25:17 +010041#include <linux/iopoll.h>
Boris BREZILLON1fef62c2014-10-21 15:08:41 +020042
43#define NFC_REG_CTL 0x0000
44#define NFC_REG_ST 0x0004
45#define NFC_REG_INT 0x0008
46#define NFC_REG_TIMING_CTL 0x000C
47#define NFC_REG_TIMING_CFG 0x0010
48#define NFC_REG_ADDR_LOW 0x0014
49#define NFC_REG_ADDR_HIGH 0x0018
50#define NFC_REG_SECTOR_NUM 0x001C
51#define NFC_REG_CNT 0x0020
52#define NFC_REG_CMD 0x0024
53#define NFC_REG_RCMD_SET 0x0028
54#define NFC_REG_WCMD_SET 0x002C
55#define NFC_REG_IO_DATA 0x0030
56#define NFC_REG_ECC_CTL 0x0034
57#define NFC_REG_ECC_ST 0x0038
58#define NFC_REG_DEBUG 0x003C
Boris BREZILLONb6a02c02015-09-16 09:46:36 +020059#define NFC_REG_ECC_ERR_CNT(x) ((0x0040 + (x)) & ~0x3)
60#define NFC_REG_USER_DATA(x) (0x0050 + ((x) * 4))
Boris BREZILLON1fef62c2014-10-21 15:08:41 +020061#define NFC_REG_SPARE_AREA 0x00A0
Boris BREZILLON4be4e032015-12-02 12:01:07 +010062#define NFC_REG_PAT_ID 0x00A4
Boris BREZILLON1fef62c2014-10-21 15:08:41 +020063#define NFC_RAM0_BASE 0x0400
64#define NFC_RAM1_BASE 0x0800
65
66/* define bit use in NFC_CTL */
67#define NFC_EN BIT(0)
68#define NFC_RESET BIT(1)
Boris BREZILLONb6a02c02015-09-16 09:46:36 +020069#define NFC_BUS_WIDTH_MSK BIT(2)
70#define NFC_BUS_WIDTH_8 (0 << 2)
71#define NFC_BUS_WIDTH_16 (1 << 2)
72#define NFC_RB_SEL_MSK BIT(3)
73#define NFC_RB_SEL(x) ((x) << 3)
74#define NFC_CE_SEL_MSK GENMASK(26, 24)
75#define NFC_CE_SEL(x) ((x) << 24)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +020076#define NFC_CE_CTL BIT(6)
Boris BREZILLONb6a02c02015-09-16 09:46:36 +020077#define NFC_PAGE_SHIFT_MSK GENMASK(11, 8)
78#define NFC_PAGE_SHIFT(x) (((x) < 10 ? 0 : (x) - 10) << 8)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +020079#define NFC_SAM BIT(12)
80#define NFC_RAM_METHOD BIT(14)
81#define NFC_DEBUG_CTL BIT(31)
82
83/* define bit use in NFC_ST */
84#define NFC_RB_B2R BIT(0)
85#define NFC_CMD_INT_FLAG BIT(1)
86#define NFC_DMA_INT_FLAG BIT(2)
87#define NFC_CMD_FIFO_STATUS BIT(3)
88#define NFC_STA BIT(4)
89#define NFC_NATCH_INT_FLAG BIT(5)
Boris BREZILLONb6a02c02015-09-16 09:46:36 +020090#define NFC_RB_STATE(x) BIT(x + 8)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +020091
92/* define bit use in NFC_INT */
93#define NFC_B2R_INT_ENABLE BIT(0)
94#define NFC_CMD_INT_ENABLE BIT(1)
95#define NFC_DMA_INT_ENABLE BIT(2)
96#define NFC_INT_MASK (NFC_B2R_INT_ENABLE | \
97 NFC_CMD_INT_ENABLE | \
98 NFC_DMA_INT_ENABLE)
99
Roy Splietd052e502015-06-26 11:00:11 +0200100/* define bit use in NFC_TIMING_CTL */
101#define NFC_TIMING_CTL_EDO BIT(8)
102
Roy Spliet9c618292015-06-26 11:00:10 +0200103/* define NFC_TIMING_CFG register layout */
104#define NFC_TIMING_CFG(tWB, tADL, tWHR, tRHW, tCAD) \
105 (((tWB) & 0x3) | (((tADL) & 0x3) << 2) | \
106 (((tWHR) & 0x3) << 4) | (((tRHW) & 0x3) << 6) | \
107 (((tCAD) & 0x7) << 8))
108
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200109/* define bit use in NFC_CMD */
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200110#define NFC_CMD_LOW_BYTE_MSK GENMASK(7, 0)
111#define NFC_CMD_HIGH_BYTE_MSK GENMASK(15, 8)
112#define NFC_CMD(x) (x)
113#define NFC_ADR_NUM_MSK GENMASK(18, 16)
114#define NFC_ADR_NUM(x) (((x) - 1) << 16)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200115#define NFC_SEND_ADR BIT(19)
116#define NFC_ACCESS_DIR BIT(20)
117#define NFC_DATA_TRANS BIT(21)
118#define NFC_SEND_CMD1 BIT(22)
119#define NFC_WAIT_FLAG BIT(23)
120#define NFC_SEND_CMD2 BIT(24)
121#define NFC_SEQ BIT(25)
122#define NFC_DATA_SWAP_METHOD BIT(26)
123#define NFC_ROW_AUTO_INC BIT(27)
124#define NFC_SEND_CMD3 BIT(28)
125#define NFC_SEND_CMD4 BIT(29)
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200126#define NFC_CMD_TYPE_MSK GENMASK(31, 30)
127#define NFC_NORMAL_OP (0 << 30)
128#define NFC_ECC_OP (1 << 30)
129#define NFC_PAGE_OP (2 << 30)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200130
131/* define bit use in NFC_RCMD_SET */
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200132#define NFC_READ_CMD_MSK GENMASK(7, 0)
133#define NFC_RND_READ_CMD0_MSK GENMASK(15, 8)
134#define NFC_RND_READ_CMD1_MSK GENMASK(23, 16)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200135
136/* define bit use in NFC_WCMD_SET */
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200137#define NFC_PROGRAM_CMD_MSK GENMASK(7, 0)
138#define NFC_RND_WRITE_CMD_MSK GENMASK(15, 8)
139#define NFC_READ_CMD0_MSK GENMASK(23, 16)
140#define NFC_READ_CMD1_MSK GENMASK(31, 24)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200141
142/* define bit use in NFC_ECC_CTL */
143#define NFC_ECC_EN BIT(0)
144#define NFC_ECC_PIPELINE BIT(3)
145#define NFC_ECC_EXCEPTION BIT(4)
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200146#define NFC_ECC_BLOCK_SIZE_MSK BIT(5)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200147#define NFC_RANDOM_EN BIT(9)
148#define NFC_RANDOM_DIRECTION BIT(10)
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200149#define NFC_ECC_MODE_MSK GENMASK(15, 12)
150#define NFC_ECC_MODE(x) ((x) << 12)
151#define NFC_RANDOM_SEED_MSK GENMASK(30, 16)
152#define NFC_RANDOM_SEED(x) ((x) << 16)
153
154/* define bit use in NFC_ECC_ST */
155#define NFC_ECC_ERR(x) BIT(x)
156#define NFC_ECC_PAT_FOUND(x) BIT(x + 16)
Boris Brezillonf8b04742016-03-04 17:25:08 +0100157#define NFC_ECC_ERR_CNT(b, x) (((x) >> (((b) % 4) * 8)) & 0xff)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200158
159#define NFC_DEFAULT_TIMEOUT_MS 1000
160
161#define NFC_SRAM_SIZE 1024
162
163#define NFC_MAX_CS 7
164
165/*
166 * Ready/Busy detection type: describes the Ready/Busy detection modes
167 *
168 * @RB_NONE: no external detection available, rely on STATUS command
169 * and software timeouts
170 * @RB_NATIVE: use sunxi NAND controller Ready/Busy support. The Ready/Busy
171 * pin of the NAND flash chip must be connected to one of the
172 * native NAND R/B pins (those which can be muxed to the NAND
173 * Controller)
174 * @RB_GPIO: use a simple GPIO to handle Ready/Busy status. The Ready/Busy
175 * pin of the NAND flash chip must be connected to a GPIO capable
176 * pin.
177 */
178enum sunxi_nand_rb_type {
179 RB_NONE,
180 RB_NATIVE,
181 RB_GPIO,
182};
183
184/*
185 * Ready/Busy structure: stores information related to Ready/Busy detection
186 *
187 * @type: the Ready/Busy detection mode
188 * @info: information related to the R/B detection mode. Either a gpio
189 * id or a native R/B id (those supported by the NAND controller).
190 */
191struct sunxi_nand_rb {
192 enum sunxi_nand_rb_type type;
193 union {
194 int gpio;
195 int nativeid;
196 } info;
197};
198
199/*
200 * Chip Select structure: stores information related to NAND Chip Select
201 *
202 * @cs: the NAND CS id used to communicate with a NAND Chip
203 * @rb: the Ready/Busy description
204 */
205struct sunxi_nand_chip_sel {
206 u8 cs;
207 struct sunxi_nand_rb rb;
208};
209
210/*
211 * sunxi HW ECC infos: stores information related to HW ECC support
212 *
213 * @mode: the sunxi ECC mode field deduced from ECC requirements
214 * @layout: the OOB layout depending on the ECC requirements and the
215 * selected ECC mode
216 */
217struct sunxi_nand_hw_ecc {
218 int mode;
219 struct nand_ecclayout layout;
220};
221
222/*
223 * NAND chip structure: stores NAND chip device related information
224 *
225 * @node: used to store NAND chips into a list
226 * @nand: base NAND chip structure
227 * @mtd: base MTD structure
228 * @clk_rate: clk_rate required for this NAND chip
Roy Spliet9c618292015-06-26 11:00:10 +0200229 * @timing_cfg TIMING_CFG register value for this NAND chip
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200230 * @selected: current active CS
231 * @nsels: number of CS lines required by the NAND chip
232 * @sels: array of CS lines descriptions
233 */
234struct sunxi_nand_chip {
235 struct list_head node;
236 struct nand_chip nand;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200237 unsigned long clk_rate;
Roy Spliet9c618292015-06-26 11:00:10 +0200238 u32 timing_cfg;
Roy Splietd052e502015-06-26 11:00:11 +0200239 u32 timing_ctl;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200240 int selected;
Boris Brezillone9aa6712015-09-16 09:05:31 +0200241 int addr_cycles;
242 u32 addr[2];
243 int cmd_cycles;
244 u8 cmd[2];
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200245 int nsels;
246 struct sunxi_nand_chip_sel sels[0];
247};
248
249static inline struct sunxi_nand_chip *to_sunxi_nand(struct nand_chip *nand)
250{
251 return container_of(nand, struct sunxi_nand_chip, nand);
252}
253
254/*
255 * NAND Controller structure: stores sunxi NAND controller information
256 *
257 * @controller: base controller structure
258 * @dev: parent device (used to print error messages)
259 * @regs: NAND controller registers
260 * @ahb_clk: NAND Controller AHB clock
261 * @mod_clk: NAND Controller mod clock
262 * @assigned_cs: bitmask describing already assigned CS lines
263 * @clk_rate: NAND controller current clock rate
264 * @chips: a list containing all the NAND chips attached to
265 * this NAND controller
266 * @complete: a completion object used to wait for NAND
267 * controller events
268 */
269struct sunxi_nfc {
270 struct nand_hw_control controller;
271 struct device *dev;
272 void __iomem *regs;
273 struct clk *ahb_clk;
274 struct clk *mod_clk;
275 unsigned long assigned_cs;
276 unsigned long clk_rate;
277 struct list_head chips;
278 struct completion complete;
279};
280
281static inline struct sunxi_nfc *to_sunxi_nfc(struct nand_hw_control *ctrl)
282{
283 return container_of(ctrl, struct sunxi_nfc, controller);
284}
285
286static irqreturn_t sunxi_nfc_interrupt(int irq, void *dev_id)
287{
288 struct sunxi_nfc *nfc = dev_id;
289 u32 st = readl(nfc->regs + NFC_REG_ST);
290 u32 ien = readl(nfc->regs + NFC_REG_INT);
291
292 if (!(ien & st))
293 return IRQ_NONE;
294
295 if ((ien & st) == ien)
296 complete(&nfc->complete);
297
298 writel(st & NFC_INT_MASK, nfc->regs + NFC_REG_ST);
299 writel(~st & ien & NFC_INT_MASK, nfc->regs + NFC_REG_INT);
300
301 return IRQ_HANDLED;
302}
303
Boris Brezillonc0c9dfa2016-03-07 15:34:39 +0100304static int sunxi_nfc_wait_events(struct sunxi_nfc *nfc, u32 events,
305 bool use_polling, unsigned int timeout_ms)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200306{
Boris Brezillonc0c9dfa2016-03-07 15:34:39 +0100307 int ret;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200308
Boris Brezillonc0c9dfa2016-03-07 15:34:39 +0100309 if (events & ~NFC_INT_MASK)
310 return -EINVAL;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200311
312 if (!timeout_ms)
313 timeout_ms = NFC_DEFAULT_TIMEOUT_MS;
314
Boris Brezillonc0c9dfa2016-03-07 15:34:39 +0100315 if (!use_polling) {
316 init_completion(&nfc->complete);
317
318 writel(events, nfc->regs + NFC_REG_INT);
319
320 ret = wait_for_completion_timeout(&nfc->complete,
321 msecs_to_jiffies(timeout_ms));
322
323 writel(0, nfc->regs + NFC_REG_INT);
324 } else {
325 u32 status;
326
327 ret = readl_poll_timeout(nfc->regs + NFC_REG_ST, status,
328 (status & events) == events, 1,
329 timeout_ms * 1000);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200330 }
331
Boris Brezillonc0c9dfa2016-03-07 15:34:39 +0100332 writel(events & NFC_INT_MASK, nfc->regs + NFC_REG_ST);
333
334 if (ret)
335 dev_err(nfc->dev, "wait interrupt timedout\n");
336
337 return ret;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200338}
339
340static int sunxi_nfc_wait_cmd_fifo_empty(struct sunxi_nfc *nfc)
341{
Boris Brezillon166f08c2016-03-07 15:25:17 +0100342 u32 status;
343 int ret;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200344
Boris Brezillon166f08c2016-03-07 15:25:17 +0100345 ret = readl_poll_timeout(nfc->regs + NFC_REG_ST, status,
346 !(status & NFC_CMD_FIFO_STATUS), 1,
347 NFC_DEFAULT_TIMEOUT_MS * 1000);
348 if (ret)
349 dev_err(nfc->dev, "wait for empty cmd FIFO timedout\n");
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200350
Boris Brezillon166f08c2016-03-07 15:25:17 +0100351 return ret;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200352}
353
354static int sunxi_nfc_rst(struct sunxi_nfc *nfc)
355{
Boris Brezillon166f08c2016-03-07 15:25:17 +0100356 u32 ctl;
357 int ret;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200358
359 writel(0, nfc->regs + NFC_REG_ECC_CTL);
360 writel(NFC_RESET, nfc->regs + NFC_REG_CTL);
361
Boris Brezillon166f08c2016-03-07 15:25:17 +0100362 ret = readl_poll_timeout(nfc->regs + NFC_REG_CTL, ctl,
363 !(ctl & NFC_RESET), 1,
364 NFC_DEFAULT_TIMEOUT_MS * 1000);
365 if (ret)
366 dev_err(nfc->dev, "wait for NAND controller reset timedout\n");
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200367
Boris Brezillon166f08c2016-03-07 15:25:17 +0100368 return ret;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200369}
370
371static int sunxi_nfc_dev_ready(struct mtd_info *mtd)
372{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100373 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200374 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
375 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
376 struct sunxi_nand_rb *rb;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200377 int ret;
378
379 if (sunxi_nand->selected < 0)
380 return 0;
381
382 rb = &sunxi_nand->sels[sunxi_nand->selected].rb;
383
384 switch (rb->type) {
385 case RB_NATIVE:
386 ret = !!(readl(nfc->regs + NFC_REG_ST) &
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200387 NFC_RB_STATE(rb->info.nativeid));
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200388 break;
389 case RB_GPIO:
390 ret = gpio_get_value(rb->info.gpio);
391 break;
392 case RB_NONE:
393 default:
394 ret = 0;
395 dev_err(nfc->dev, "cannot check R/B NAND status!\n");
396 break;
397 }
398
399 return ret;
400}
401
402static void sunxi_nfc_select_chip(struct mtd_info *mtd, int chip)
403{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100404 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200405 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
406 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
407 struct sunxi_nand_chip_sel *sel;
408 u32 ctl;
409
410 if (chip > 0 && chip >= sunxi_nand->nsels)
411 return;
412
413 if (chip == sunxi_nand->selected)
414 return;
415
416 ctl = readl(nfc->regs + NFC_REG_CTL) &
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200417 ~(NFC_PAGE_SHIFT_MSK | NFC_CE_SEL_MSK | NFC_RB_SEL_MSK | NFC_EN);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200418
419 if (chip >= 0) {
420 sel = &sunxi_nand->sels[chip];
421
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200422 ctl |= NFC_CE_SEL(sel->cs) | NFC_EN |
Boris Brezillon68ffbf72016-03-04 17:29:20 +0100423 NFC_PAGE_SHIFT(nand->page_shift);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200424 if (sel->rb.type == RB_NONE) {
425 nand->dev_ready = NULL;
426 } else {
427 nand->dev_ready = sunxi_nfc_dev_ready;
428 if (sel->rb.type == RB_NATIVE)
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200429 ctl |= NFC_RB_SEL(sel->rb.info.nativeid);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200430 }
431
432 writel(mtd->writesize, nfc->regs + NFC_REG_SPARE_AREA);
433
434 if (nfc->clk_rate != sunxi_nand->clk_rate) {
435 clk_set_rate(nfc->mod_clk, sunxi_nand->clk_rate);
436 nfc->clk_rate = sunxi_nand->clk_rate;
437 }
438 }
439
Roy Splietd052e502015-06-26 11:00:11 +0200440 writel(sunxi_nand->timing_ctl, nfc->regs + NFC_REG_TIMING_CTL);
Roy Spliet9c618292015-06-26 11:00:10 +0200441 writel(sunxi_nand->timing_cfg, nfc->regs + NFC_REG_TIMING_CFG);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200442 writel(ctl, nfc->regs + NFC_REG_CTL);
443
444 sunxi_nand->selected = chip;
445}
446
447static void sunxi_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
448{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100449 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200450 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
451 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
452 int ret;
453 int cnt;
454 int offs = 0;
455 u32 tmp;
456
457 while (len > offs) {
458 cnt = min(len - offs, NFC_SRAM_SIZE);
459
460 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
461 if (ret)
462 break;
463
464 writel(cnt, nfc->regs + NFC_REG_CNT);
465 tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD;
466 writel(tmp, nfc->regs + NFC_REG_CMD);
467
Boris Brezillonc0c9dfa2016-03-07 15:34:39 +0100468 ret = sunxi_nfc_wait_events(nfc, NFC_CMD_INT_FLAG, true, 0);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200469 if (ret)
470 break;
471
472 if (buf)
473 memcpy_fromio(buf + offs, nfc->regs + NFC_RAM0_BASE,
474 cnt);
475 offs += cnt;
476 }
477}
478
479static void sunxi_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf,
480 int len)
481{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100482 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200483 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
484 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
485 int ret;
486 int cnt;
487 int offs = 0;
488 u32 tmp;
489
490 while (len > offs) {
491 cnt = min(len - offs, NFC_SRAM_SIZE);
492
493 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
494 if (ret)
495 break;
496
497 writel(cnt, nfc->regs + NFC_REG_CNT);
498 memcpy_toio(nfc->regs + NFC_RAM0_BASE, buf + offs, cnt);
499 tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD |
500 NFC_ACCESS_DIR;
501 writel(tmp, nfc->regs + NFC_REG_CMD);
502
Boris Brezillonc0c9dfa2016-03-07 15:34:39 +0100503 ret = sunxi_nfc_wait_events(nfc, NFC_CMD_INT_FLAG, true, 0);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200504 if (ret)
505 break;
506
507 offs += cnt;
508 }
509}
510
511static uint8_t sunxi_nfc_read_byte(struct mtd_info *mtd)
512{
513 uint8_t ret;
514
515 sunxi_nfc_read_buf(mtd, &ret, 1);
516
517 return ret;
518}
519
520static void sunxi_nfc_cmd_ctrl(struct mtd_info *mtd, int dat,
521 unsigned int ctrl)
522{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100523 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200524 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
525 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
526 int ret;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200527
528 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
529 if (ret)
530 return;
531
Boris Brezillone9aa6712015-09-16 09:05:31 +0200532 if (dat == NAND_CMD_NONE && (ctrl & NAND_NCE) &&
533 !(ctrl & (NAND_CLE | NAND_ALE))) {
534 u32 cmd = 0;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200535
Boris Brezillone9aa6712015-09-16 09:05:31 +0200536 if (!sunxi_nand->addr_cycles && !sunxi_nand->cmd_cycles)
537 return;
538
539 if (sunxi_nand->cmd_cycles--)
540 cmd |= NFC_SEND_CMD1 | sunxi_nand->cmd[0];
541
542 if (sunxi_nand->cmd_cycles--) {
543 cmd |= NFC_SEND_CMD2;
544 writel(sunxi_nand->cmd[1],
545 nfc->regs + NFC_REG_RCMD_SET);
546 }
547
548 sunxi_nand->cmd_cycles = 0;
549
550 if (sunxi_nand->addr_cycles) {
551 cmd |= NFC_SEND_ADR |
552 NFC_ADR_NUM(sunxi_nand->addr_cycles);
553 writel(sunxi_nand->addr[0],
554 nfc->regs + NFC_REG_ADDR_LOW);
555 }
556
557 if (sunxi_nand->addr_cycles > 4)
558 writel(sunxi_nand->addr[1],
559 nfc->regs + NFC_REG_ADDR_HIGH);
560
561 writel(cmd, nfc->regs + NFC_REG_CMD);
562 sunxi_nand->addr[0] = 0;
563 sunxi_nand->addr[1] = 0;
564 sunxi_nand->addr_cycles = 0;
Boris Brezillonc0c9dfa2016-03-07 15:34:39 +0100565 sunxi_nfc_wait_events(nfc, NFC_CMD_INT_FLAG, true, 0);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200566 }
567
Boris Brezillone9aa6712015-09-16 09:05:31 +0200568 if (ctrl & NAND_CLE) {
569 sunxi_nand->cmd[sunxi_nand->cmd_cycles++] = dat;
570 } else if (ctrl & NAND_ALE) {
571 sunxi_nand->addr[sunxi_nand->addr_cycles / 4] |=
572 dat << ((sunxi_nand->addr_cycles % 4) * 8);
573 sunxi_nand->addr_cycles++;
574 }
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200575}
576
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100577/* These seed values have been extracted from Allwinner's BSP */
578static const u16 sunxi_nfc_randomizer_page_seeds[] = {
579 0x2b75, 0x0bd0, 0x5ca3, 0x62d1, 0x1c93, 0x07e9, 0x2162, 0x3a72,
580 0x0d67, 0x67f9, 0x1be7, 0x077d, 0x032f, 0x0dac, 0x2716, 0x2436,
581 0x7922, 0x1510, 0x3860, 0x5287, 0x480f, 0x4252, 0x1789, 0x5a2d,
582 0x2a49, 0x5e10, 0x437f, 0x4b4e, 0x2f45, 0x216e, 0x5cb7, 0x7130,
583 0x2a3f, 0x60e4, 0x4dc9, 0x0ef0, 0x0f52, 0x1bb9, 0x6211, 0x7a56,
584 0x226d, 0x4ea7, 0x6f36, 0x3692, 0x38bf, 0x0c62, 0x05eb, 0x4c55,
585 0x60f4, 0x728c, 0x3b6f, 0x2037, 0x7f69, 0x0936, 0x651a, 0x4ceb,
586 0x6218, 0x79f3, 0x383f, 0x18d9, 0x4f05, 0x5c82, 0x2912, 0x6f17,
587 0x6856, 0x5938, 0x1007, 0x61ab, 0x3e7f, 0x57c2, 0x542f, 0x4f62,
588 0x7454, 0x2eac, 0x7739, 0x42d4, 0x2f90, 0x435a, 0x2e52, 0x2064,
589 0x637c, 0x66ad, 0x2c90, 0x0bad, 0x759c, 0x0029, 0x0986, 0x7126,
590 0x1ca7, 0x1605, 0x386a, 0x27f5, 0x1380, 0x6d75, 0x24c3, 0x0f8e,
591 0x2b7a, 0x1418, 0x1fd1, 0x7dc1, 0x2d8e, 0x43af, 0x2267, 0x7da3,
592 0x4e3d, 0x1338, 0x50db, 0x454d, 0x764d, 0x40a3, 0x42e6, 0x262b,
593 0x2d2e, 0x1aea, 0x2e17, 0x173d, 0x3a6e, 0x71bf, 0x25f9, 0x0a5d,
594 0x7c57, 0x0fbe, 0x46ce, 0x4939, 0x6b17, 0x37bb, 0x3e91, 0x76db,
595};
596
597/*
598 * sunxi_nfc_randomizer_ecc512_seeds and sunxi_nfc_randomizer_ecc1024_seeds
599 * have been generated using
600 * sunxi_nfc_randomizer_step(seed, (step_size * 8) + 15), which is what
601 * the randomizer engine does internally before de/scrambling OOB data.
602 *
603 * Those tables are statically defined to avoid calculating randomizer state
604 * at runtime.
605 */
606static const u16 sunxi_nfc_randomizer_ecc512_seeds[] = {
607 0x3346, 0x367f, 0x1f18, 0x769a, 0x4f64, 0x068c, 0x2ef1, 0x6b64,
608 0x28a9, 0x15d7, 0x30f8, 0x3659, 0x53db, 0x7c5f, 0x71d4, 0x4409,
609 0x26eb, 0x03cc, 0x655d, 0x47d4, 0x4daa, 0x0877, 0x712d, 0x3617,
610 0x3264, 0x49aa, 0x7f9e, 0x588e, 0x4fbc, 0x7176, 0x7f91, 0x6c6d,
611 0x4b95, 0x5fb7, 0x3844, 0x4037, 0x0184, 0x081b, 0x0ee8, 0x5b91,
612 0x293d, 0x1f71, 0x0e6f, 0x402b, 0x5122, 0x1e52, 0x22be, 0x3d2d,
613 0x75bc, 0x7c60, 0x6291, 0x1a2f, 0x61d4, 0x74aa, 0x4140, 0x29ab,
614 0x472d, 0x2852, 0x017e, 0x15e8, 0x5ec2, 0x17cf, 0x7d0f, 0x06b8,
615 0x117a, 0x6b94, 0x789b, 0x3126, 0x6ac5, 0x5be7, 0x150f, 0x51f8,
616 0x7889, 0x0aa5, 0x663d, 0x77e8, 0x0b87, 0x3dcb, 0x360d, 0x218b,
617 0x512f, 0x7dc9, 0x6a4d, 0x630a, 0x3547, 0x1dd2, 0x5aea, 0x69a5,
618 0x7bfa, 0x5e4f, 0x1519, 0x6430, 0x3a0e, 0x5eb3, 0x5425, 0x0c7a,
619 0x5540, 0x3670, 0x63c1, 0x31e9, 0x5a39, 0x2de7, 0x5979, 0x2891,
620 0x1562, 0x014b, 0x5b05, 0x2756, 0x5a34, 0x13aa, 0x6cb5, 0x2c36,
621 0x5e72, 0x1306, 0x0861, 0x15ef, 0x1ee8, 0x5a37, 0x7ac4, 0x45dd,
622 0x44c4, 0x7266, 0x2f41, 0x3ccc, 0x045e, 0x7d40, 0x7c66, 0x0fa0,
623};
624
625static const u16 sunxi_nfc_randomizer_ecc1024_seeds[] = {
626 0x2cf5, 0x35f1, 0x63a4, 0x5274, 0x2bd2, 0x778b, 0x7285, 0x32b6,
627 0x6a5c, 0x70d6, 0x757d, 0x6769, 0x5375, 0x1e81, 0x0cf3, 0x3982,
628 0x6787, 0x042a, 0x6c49, 0x1925, 0x56a8, 0x40a9, 0x063e, 0x7bd9,
629 0x4dbf, 0x55ec, 0x672e, 0x7334, 0x5185, 0x4d00, 0x232a, 0x7e07,
630 0x445d, 0x6b92, 0x528f, 0x4255, 0x53ba, 0x7d82, 0x2a2e, 0x3a4e,
631 0x75eb, 0x450c, 0x6844, 0x1b5d, 0x581a, 0x4cc6, 0x0379, 0x37b2,
632 0x419f, 0x0e92, 0x6b27, 0x5624, 0x01e3, 0x07c1, 0x44a5, 0x130c,
633 0x13e8, 0x5910, 0x0876, 0x60c5, 0x54e3, 0x5b7f, 0x2269, 0x509f,
634 0x7665, 0x36fd, 0x3e9a, 0x0579, 0x6295, 0x14ef, 0x0a81, 0x1bcc,
635 0x4b16, 0x64db, 0x0514, 0x4f07, 0x0591, 0x3576, 0x6853, 0x0d9e,
636 0x259f, 0x38b7, 0x64fb, 0x3094, 0x4693, 0x6ddd, 0x29bb, 0x0bc8,
637 0x3f47, 0x490e, 0x0c0e, 0x7933, 0x3c9e, 0x5840, 0x398d, 0x3e68,
638 0x4af1, 0x71f5, 0x57cf, 0x1121, 0x64eb, 0x3579, 0x15ac, 0x584d,
639 0x5f2a, 0x47e2, 0x6528, 0x6eac, 0x196e, 0x6b96, 0x0450, 0x0179,
640 0x609c, 0x06e1, 0x4626, 0x42c7, 0x273e, 0x486f, 0x0705, 0x1601,
641 0x145b, 0x407e, 0x062b, 0x57a5, 0x53f9, 0x5659, 0x4410, 0x3ccd,
642};
643
644static u16 sunxi_nfc_randomizer_step(u16 state, int count)
645{
646 state &= 0x7fff;
647
648 /*
649 * This loop is just a simple implementation of a Fibonacci LFSR using
650 * the x16 + x15 + 1 polynomial.
651 */
652 while (count--)
653 state = ((state >> 1) |
654 (((state ^ (state >> 1)) & 1) << 14)) & 0x7fff;
655
656 return state;
657}
658
659static u16 sunxi_nfc_randomizer_state(struct mtd_info *mtd, int page, bool ecc)
660{
661 const u16 *seeds = sunxi_nfc_randomizer_page_seeds;
Brian Norris46c135c2016-01-22 18:57:13 -0800662 int mod = mtd_div_by_ws(mtd->erasesize, mtd);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100663
664 if (mod > ARRAY_SIZE(sunxi_nfc_randomizer_page_seeds))
665 mod = ARRAY_SIZE(sunxi_nfc_randomizer_page_seeds);
666
667 if (ecc) {
668 if (mtd->ecc_step_size == 512)
669 seeds = sunxi_nfc_randomizer_ecc512_seeds;
670 else
671 seeds = sunxi_nfc_randomizer_ecc1024_seeds;
672 }
673
674 return seeds[page % mod];
675}
676
677static void sunxi_nfc_randomizer_config(struct mtd_info *mtd,
678 int page, bool ecc)
679{
Boris BREZILLONf671a1f2016-03-05 00:21:20 +0100680 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100681 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
682 u32 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL);
683 u16 state;
684
685 if (!(nand->options & NAND_NEED_SCRAMBLING))
686 return;
687
688 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL);
689 state = sunxi_nfc_randomizer_state(mtd, page, ecc);
690 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_RANDOM_SEED_MSK;
691 writel(ecc_ctl | NFC_RANDOM_SEED(state), nfc->regs + NFC_REG_ECC_CTL);
692}
693
694static void sunxi_nfc_randomizer_enable(struct mtd_info *mtd)
695{
Boris BREZILLONf671a1f2016-03-05 00:21:20 +0100696 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100697 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
698
699 if (!(nand->options & NAND_NEED_SCRAMBLING))
700 return;
701
702 writel(readl(nfc->regs + NFC_REG_ECC_CTL) | NFC_RANDOM_EN,
703 nfc->regs + NFC_REG_ECC_CTL);
704}
705
706static void sunxi_nfc_randomizer_disable(struct mtd_info *mtd)
707{
Boris BREZILLONf671a1f2016-03-05 00:21:20 +0100708 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100709 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
710
711 if (!(nand->options & NAND_NEED_SCRAMBLING))
712 return;
713
714 writel(readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_RANDOM_EN,
715 nfc->regs + NFC_REG_ECC_CTL);
716}
717
718static void sunxi_nfc_randomize_bbm(struct mtd_info *mtd, int page, u8 *bbm)
719{
720 u16 state = sunxi_nfc_randomizer_state(mtd, page, true);
721
722 bbm[0] ^= state;
723 bbm[1] ^= sunxi_nfc_randomizer_step(state, 8);
724}
725
726static void sunxi_nfc_randomizer_write_buf(struct mtd_info *mtd,
727 const uint8_t *buf, int len,
728 bool ecc, int page)
729{
730 sunxi_nfc_randomizer_config(mtd, page, ecc);
731 sunxi_nfc_randomizer_enable(mtd);
732 sunxi_nfc_write_buf(mtd, buf, len);
733 sunxi_nfc_randomizer_disable(mtd);
734}
735
736static void sunxi_nfc_randomizer_read_buf(struct mtd_info *mtd, uint8_t *buf,
737 int len, bool ecc, int page)
738{
739 sunxi_nfc_randomizer_config(mtd, page, ecc);
740 sunxi_nfc_randomizer_enable(mtd);
741 sunxi_nfc_read_buf(mtd, buf, len);
742 sunxi_nfc_randomizer_disable(mtd);
743}
744
Boris BREZILLONc9118ec2015-09-30 23:45:23 +0200745static void sunxi_nfc_hw_ecc_enable(struct mtd_info *mtd)
746{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100747 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLONc9118ec2015-09-30 23:45:23 +0200748 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
749 struct sunxi_nand_hw_ecc *data = nand->ecc.priv;
750 u32 ecc_ctl;
751
752 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL);
753 ecc_ctl &= ~(NFC_ECC_MODE_MSK | NFC_ECC_PIPELINE |
754 NFC_ECC_BLOCK_SIZE_MSK);
Boris Brezillon336de7b2016-03-04 17:33:10 +0100755 ecc_ctl |= NFC_ECC_EN | NFC_ECC_MODE(data->mode) | NFC_ECC_EXCEPTION |
756 NFC_ECC_PIPELINE;
Boris BREZILLONc9118ec2015-09-30 23:45:23 +0200757
758 writel(ecc_ctl, nfc->regs + NFC_REG_ECC_CTL);
759}
760
761static void sunxi_nfc_hw_ecc_disable(struct mtd_info *mtd)
762{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100763 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLONc9118ec2015-09-30 23:45:23 +0200764 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
765
766 writel(readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_ECC_EN,
767 nfc->regs + NFC_REG_ECC_CTL);
768}
769
Boris BREZILLONf363e0f2015-09-30 23:45:27 +0200770static inline void sunxi_nfc_user_data_to_buf(u32 user_data, u8 *buf)
771{
772 buf[0] = user_data;
773 buf[1] = user_data >> 8;
774 buf[2] = user_data >> 16;
775 buf[3] = user_data >> 24;
776}
777
Boris Brezilloncc6822f2016-03-04 17:56:47 +0100778static inline u32 sunxi_nfc_buf_to_user_data(const u8 *buf)
779{
780 return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
781}
782
783static void sunxi_nfc_hw_ecc_get_prot_oob_bytes(struct mtd_info *mtd, u8 *oob,
784 int step, bool bbm, int page)
785{
786 struct nand_chip *nand = mtd_to_nand(mtd);
787 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
788
789 sunxi_nfc_user_data_to_buf(readl(nfc->regs + NFC_REG_USER_DATA(step)),
790 oob);
791
792 /* De-randomize the Bad Block Marker. */
793 if (bbm && (nand->options & NAND_NEED_SCRAMBLING))
794 sunxi_nfc_randomize_bbm(mtd, page, oob);
795}
796
797static void sunxi_nfc_hw_ecc_set_prot_oob_bytes(struct mtd_info *mtd,
798 const u8 *oob, int step,
799 bool bbm, int page)
800{
801 struct nand_chip *nand = mtd_to_nand(mtd);
802 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
803 u8 user_data[4];
804
805 /* Randomize the Bad Block Marker. */
806 if (bbm && (nand->options & NAND_NEED_SCRAMBLING)) {
807 memcpy(user_data, oob, sizeof(user_data));
808 sunxi_nfc_randomize_bbm(mtd, page, user_data);
809 oob = user_data;
810 }
811
812 writel(sunxi_nfc_buf_to_user_data(oob),
813 nfc->regs + NFC_REG_USER_DATA(step));
814}
815
816static void sunxi_nfc_hw_ecc_update_stats(struct mtd_info *mtd,
817 unsigned int *max_bitflips, int ret)
818{
819 if (ret < 0) {
820 mtd->ecc_stats.failed++;
821 } else {
822 mtd->ecc_stats.corrected += ret;
823 *max_bitflips = max_t(unsigned int, *max_bitflips, ret);
824 }
825}
826
827static int sunxi_nfc_hw_ecc_correct(struct mtd_info *mtd, u8 *data, u8 *oob,
828 int step, bool *erased)
829{
830 struct nand_chip *nand = mtd_to_nand(mtd);
831 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
832 struct nand_ecc_ctrl *ecc = &nand->ecc;
833 u32 status, tmp;
834
835 *erased = false;
836
837 status = readl(nfc->regs + NFC_REG_ECC_ST);
838
839 if (status & NFC_ECC_ERR(step))
840 return -EBADMSG;
841
842 if (status & NFC_ECC_PAT_FOUND(step)) {
843 u8 pattern;
844
845 if (unlikely(!(readl(nfc->regs + NFC_REG_PAT_ID) & 0x1))) {
846 pattern = 0x0;
847 } else {
848 pattern = 0xff;
849 *erased = true;
850 }
851
852 if (data)
853 memset(data, pattern, ecc->size);
854
855 if (oob)
856 memset(oob, pattern, ecc->bytes + 4);
857
858 return 0;
859 }
860
861 tmp = readl(nfc->regs + NFC_REG_ECC_ERR_CNT(step));
862
863 return NFC_ECC_ERR_CNT(step, tmp);
864}
865
Boris BREZILLON913821b2015-09-30 23:45:24 +0200866static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd,
867 u8 *data, int data_off,
868 u8 *oob, int oob_off,
869 int *cur_off,
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100870 unsigned int *max_bitflips,
871 bool bbm, int page)
Boris BREZILLON913821b2015-09-30 23:45:24 +0200872{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100873 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200874 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
875 struct nand_ecc_ctrl *ecc = &nand->ecc;
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100876 int raw_mode = 0;
Boris Brezilloncc6822f2016-03-04 17:56:47 +0100877 bool erased;
Boris BREZILLON913821b2015-09-30 23:45:24 +0200878 int ret;
879
880 if (*cur_off != data_off)
881 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, data_off, -1);
882
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100883 sunxi_nfc_randomizer_read_buf(mtd, NULL, ecc->size, false, page);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200884
Boris BREZILLON74eb9ff2015-10-20 22:16:00 +0200885 if (data_off + ecc->size != oob_off)
Boris BREZILLON913821b2015-09-30 23:45:24 +0200886 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
887
888 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
889 if (ret)
890 return ret;
891
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100892 sunxi_nfc_randomizer_enable(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200893 writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_ECC_OP,
894 nfc->regs + NFC_REG_CMD);
895
Boris Brezillonc0c9dfa2016-03-07 15:34:39 +0100896 ret = sunxi_nfc_wait_events(nfc, NFC_CMD_INT_FLAG, true, 0);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100897 sunxi_nfc_randomizer_disable(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200898 if (ret)
899 return ret;
900
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100901 *cur_off = oob_off + ecc->bytes + 4;
902
Boris Brezilloncc6822f2016-03-04 17:56:47 +0100903 ret = sunxi_nfc_hw_ecc_correct(mtd, data, oob, 0, &erased);
904 if (erased)
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100905 return 1;
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100906
Boris Brezilloncc6822f2016-03-04 17:56:47 +0100907 if (ret < 0) {
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100908 /*
909 * Re-read the data with the randomizer disabled to identify
910 * bitflips in erased pages.
911 */
912 if (nand->options & NAND_NEED_SCRAMBLING) {
913 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, data_off, -1);
914 nand->read_buf(mtd, data, ecc->size);
Boris Brezilloncc6822f2016-03-04 17:56:47 +0100915 } else {
916 memcpy_fromio(data, nfc->regs + NFC_RAM0_BASE,
917 ecc->size);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100918 }
919
Boris Brezilloncc6822f2016-03-04 17:56:47 +0100920 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
921 nand->read_buf(mtd, oob, ecc->bytes + 4);
922
Boris BREZILLON146b5032015-09-30 23:45:29 +0200923 ret = nand_check_erased_ecc_chunk(data, ecc->size,
924 oob, ecc->bytes + 4,
925 NULL, 0, ecc->strength);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100926 if (ret >= 0)
927 raw_mode = 1;
Boris BREZILLONf363e0f2015-09-30 23:45:27 +0200928 } else {
Boris Brezilloncc6822f2016-03-04 17:56:47 +0100929 memcpy_fromio(data, nfc->regs + NFC_RAM0_BASE, ecc->size);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100930
Boris Brezilloncc6822f2016-03-04 17:56:47 +0100931 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
932 sunxi_nfc_randomizer_read_buf(mtd, oob, ecc->bytes + 4,
933 true, page);
934
935 sunxi_nfc_hw_ecc_get_prot_oob_bytes(mtd, oob, 0,
936 bbm, page);
Boris BREZILLONf363e0f2015-09-30 23:45:27 +0200937 }
Boris BREZILLON913821b2015-09-30 23:45:24 +0200938
Boris Brezilloncc6822f2016-03-04 17:56:47 +0100939 sunxi_nfc_hw_ecc_update_stats(mtd, max_bitflips, ret);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200940
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100941 return raw_mode;
Boris BREZILLON913821b2015-09-30 23:45:24 +0200942}
943
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200944static void sunxi_nfc_hw_ecc_read_extra_oob(struct mtd_info *mtd,
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100945 u8 *oob, int *cur_off,
946 bool randomize, int page)
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200947{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100948 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200949 struct nand_ecc_ctrl *ecc = &nand->ecc;
950 int offset = ((ecc->bytes + 4) * ecc->steps);
951 int len = mtd->oobsize - offset;
952
953 if (len <= 0)
954 return;
955
956 if (*cur_off != offset)
957 nand->cmdfunc(mtd, NAND_CMD_RNDOUT,
958 offset + mtd->writesize, -1);
959
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100960 if (!randomize)
961 sunxi_nfc_read_buf(mtd, oob + offset, len);
962 else
963 sunxi_nfc_randomizer_read_buf(mtd, oob + offset, len,
964 false, page);
Boris BREZILLON35d0e242015-09-30 23:45:26 +0200965
966 *cur_off = mtd->oobsize + mtd->writesize;
967}
968
Boris BREZILLON913821b2015-09-30 23:45:24 +0200969static int sunxi_nfc_hw_ecc_write_chunk(struct mtd_info *mtd,
970 const u8 *data, int data_off,
971 const u8 *oob, int oob_off,
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100972 int *cur_off, bool bbm,
973 int page)
Boris BREZILLON913821b2015-09-30 23:45:24 +0200974{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100975 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200976 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
977 struct nand_ecc_ctrl *ecc = &nand->ecc;
978 int ret;
979
980 if (data_off != *cur_off)
981 nand->cmdfunc(mtd, NAND_CMD_RNDIN, data_off, -1);
982
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100983 sunxi_nfc_randomizer_write_buf(mtd, data, ecc->size, false, page);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200984
Boris BREZILLON74eb9ff2015-10-20 22:16:00 +0200985 if (data_off + ecc->size != oob_off)
Boris BREZILLON913821b2015-09-30 23:45:24 +0200986 nand->cmdfunc(mtd, NAND_CMD_RNDIN, oob_off, -1);
987
988 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
989 if (ret)
990 return ret;
991
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100992 sunxi_nfc_randomizer_enable(mtd);
Boris Brezilloncc6822f2016-03-04 17:56:47 +0100993 sunxi_nfc_hw_ecc_set_prot_oob_bytes(mtd, oob, 0, bbm, page);
994
Boris BREZILLON913821b2015-09-30 23:45:24 +0200995 writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD |
996 NFC_ACCESS_DIR | NFC_ECC_OP,
997 nfc->regs + NFC_REG_CMD);
998
Boris Brezillonc0c9dfa2016-03-07 15:34:39 +0100999 ret = sunxi_nfc_wait_events(nfc, NFC_CMD_INT_FLAG, true, 0);
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001000 sunxi_nfc_randomizer_disable(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +02001001 if (ret)
1002 return ret;
1003
1004 *cur_off = oob_off + ecc->bytes + 4;
1005
1006 return 0;
1007}
1008
Boris BREZILLON35d0e242015-09-30 23:45:26 +02001009static void sunxi_nfc_hw_ecc_write_extra_oob(struct mtd_info *mtd,
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001010 u8 *oob, int *cur_off,
1011 int page)
Boris BREZILLON35d0e242015-09-30 23:45:26 +02001012{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +01001013 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON35d0e242015-09-30 23:45:26 +02001014 struct nand_ecc_ctrl *ecc = &nand->ecc;
1015 int offset = ((ecc->bytes + 4) * ecc->steps);
1016 int len = mtd->oobsize - offset;
1017
1018 if (len <= 0)
1019 return;
1020
1021 if (*cur_off != offset)
1022 nand->cmdfunc(mtd, NAND_CMD_RNDIN,
1023 offset + mtd->writesize, -1);
1024
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001025 sunxi_nfc_randomizer_write_buf(mtd, oob + offset, len, false, page);
Boris BREZILLON35d0e242015-09-30 23:45:26 +02001026
1027 *cur_off = mtd->oobsize + mtd->writesize;
1028}
1029
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001030static int sunxi_nfc_hw_ecc_read_page(struct mtd_info *mtd,
1031 struct nand_chip *chip, uint8_t *buf,
1032 int oob_required, int page)
1033{
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001034 struct nand_ecc_ctrl *ecc = &chip->ecc;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001035 unsigned int max_bitflips = 0;
Boris BREZILLONb4625512015-09-30 23:45:25 +02001036 int ret, i, cur_off = 0;
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001037 bool raw_mode = false;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001038
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001039 sunxi_nfc_hw_ecc_enable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001040
1041 for (i = 0; i < ecc->steps; i++) {
Boris BREZILLONb4625512015-09-30 23:45:25 +02001042 int data_off = i * ecc->size;
1043 int oob_off = i * (ecc->bytes + 4);
1044 u8 *data = buf + data_off;
1045 u8 *oob = chip->oob_poi + oob_off;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001046
Boris BREZILLONb4625512015-09-30 23:45:25 +02001047 ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off, oob,
1048 oob_off + mtd->writesize,
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001049 &cur_off, &max_bitflips,
1050 !i, page);
1051 if (ret < 0)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001052 return ret;
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001053 else if (ret)
1054 raw_mode = true;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001055 }
1056
Boris BREZILLON35d0e242015-09-30 23:45:26 +02001057 if (oob_required)
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001058 sunxi_nfc_hw_ecc_read_extra_oob(mtd, chip->oob_poi, &cur_off,
1059 !raw_mode, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001060
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001061 sunxi_nfc_hw_ecc_disable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001062
1063 return max_bitflips;
1064}
1065
Boris Brezillonfe82cce2015-09-16 09:01:45 +02001066static int sunxi_nfc_hw_ecc_read_subpage(struct mtd_info *mtd,
1067 struct nand_chip *chip,
1068 u32 data_offs, u32 readlen,
1069 u8 *bufpoi, int page)
1070{
1071 struct nand_ecc_ctrl *ecc = &chip->ecc;
1072 int ret, i, cur_off = 0;
1073 unsigned int max_bitflips = 0;
1074
1075 sunxi_nfc_hw_ecc_enable(mtd);
1076
1077 chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
1078 for (i = data_offs / ecc->size;
1079 i < DIV_ROUND_UP(data_offs + readlen, ecc->size); i++) {
1080 int data_off = i * ecc->size;
1081 int oob_off = i * (ecc->bytes + 4);
1082 u8 *data = bufpoi + data_off;
1083 u8 *oob = chip->oob_poi + oob_off;
1084
1085 ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off,
1086 oob,
1087 oob_off + mtd->writesize,
1088 &cur_off, &max_bitflips,
1089 !i, page);
1090 if (ret < 0)
1091 return ret;
1092 }
1093
1094 sunxi_nfc_hw_ecc_disable(mtd);
1095
1096 return max_bitflips;
1097}
1098
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001099static int sunxi_nfc_hw_ecc_write_page(struct mtd_info *mtd,
1100 struct nand_chip *chip,
Boris BREZILLON45aaeff2015-10-13 11:22:18 +02001101 const uint8_t *buf, int oob_required,
1102 int page)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001103{
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001104 struct nand_ecc_ctrl *ecc = &chip->ecc;
Boris BREZILLONb4625512015-09-30 23:45:25 +02001105 int ret, i, cur_off = 0;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001106
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001107 sunxi_nfc_hw_ecc_enable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001108
1109 for (i = 0; i < ecc->steps; i++) {
Boris BREZILLONb4625512015-09-30 23:45:25 +02001110 int data_off = i * ecc->size;
1111 int oob_off = i * (ecc->bytes + 4);
1112 const u8 *data = buf + data_off;
1113 const u8 *oob = chip->oob_poi + oob_off;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001114
Boris BREZILLONb4625512015-09-30 23:45:25 +02001115 ret = sunxi_nfc_hw_ecc_write_chunk(mtd, data, data_off, oob,
1116 oob_off + mtd->writesize,
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001117 &cur_off, !i, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001118 if (ret)
1119 return ret;
1120 }
1121
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001122 if (oob_required || (chip->options & NAND_NEED_SCRAMBLING))
1123 sunxi_nfc_hw_ecc_write_extra_oob(mtd, chip->oob_poi,
1124 &cur_off, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001125
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001126 sunxi_nfc_hw_ecc_disable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001127
1128 return 0;
1129}
1130
1131static int sunxi_nfc_hw_syndrome_ecc_read_page(struct mtd_info *mtd,
1132 struct nand_chip *chip,
1133 uint8_t *buf, int oob_required,
1134 int page)
1135{
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001136 struct nand_ecc_ctrl *ecc = &chip->ecc;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001137 unsigned int max_bitflips = 0;
Boris BREZILLONb4625512015-09-30 23:45:25 +02001138 int ret, i, cur_off = 0;
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001139 bool raw_mode = false;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001140
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001141 sunxi_nfc_hw_ecc_enable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001142
1143 for (i = 0; i < ecc->steps; i++) {
Boris BREZILLONb4625512015-09-30 23:45:25 +02001144 int data_off = i * (ecc->size + ecc->bytes + 4);
1145 int oob_off = data_off + ecc->size;
1146 u8 *data = buf + (i * ecc->size);
1147 u8 *oob = chip->oob_poi + (i * (ecc->bytes + 4));
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001148
Boris BREZILLONb4625512015-09-30 23:45:25 +02001149 ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off, oob,
1150 oob_off, &cur_off,
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001151 &max_bitflips, !i, page);
1152 if (ret < 0)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001153 return ret;
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001154 else if (ret)
1155 raw_mode = true;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001156 }
1157
Boris BREZILLON35d0e242015-09-30 23:45:26 +02001158 if (oob_required)
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001159 sunxi_nfc_hw_ecc_read_extra_oob(mtd, chip->oob_poi, &cur_off,
1160 !raw_mode, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001161
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001162 sunxi_nfc_hw_ecc_disable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001163
1164 return max_bitflips;
1165}
1166
1167static int sunxi_nfc_hw_syndrome_ecc_write_page(struct mtd_info *mtd,
1168 struct nand_chip *chip,
1169 const uint8_t *buf,
Boris BREZILLON45aaeff2015-10-13 11:22:18 +02001170 int oob_required, int page)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001171{
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001172 struct nand_ecc_ctrl *ecc = &chip->ecc;
Boris BREZILLONb4625512015-09-30 23:45:25 +02001173 int ret, i, cur_off = 0;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001174
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001175 sunxi_nfc_hw_ecc_enable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001176
1177 for (i = 0; i < ecc->steps; i++) {
Boris BREZILLONb4625512015-09-30 23:45:25 +02001178 int data_off = i * (ecc->size + ecc->bytes + 4);
1179 int oob_off = data_off + ecc->size;
1180 const u8 *data = buf + (i * ecc->size);
1181 const u8 *oob = chip->oob_poi + (i * (ecc->bytes + 4));
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001182
Boris BREZILLONb4625512015-09-30 23:45:25 +02001183 ret = sunxi_nfc_hw_ecc_write_chunk(mtd, data, data_off,
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001184 oob, oob_off, &cur_off,
1185 false, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001186 if (ret)
1187 return ret;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001188 }
1189
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001190 if (oob_required || (chip->options & NAND_NEED_SCRAMBLING))
1191 sunxi_nfc_hw_ecc_write_extra_oob(mtd, chip->oob_poi,
1192 &cur_off, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001193
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001194 sunxi_nfc_hw_ecc_disable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001195
1196 return 0;
1197}
1198
Boris Brezillon1c1bdd62015-09-02 15:05:52 +02001199static int sunxi_nfc_hw_common_ecc_read_oob(struct mtd_info *mtd,
1200 struct nand_chip *chip,
1201 int page)
1202{
1203 chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
1204
1205 chip->pagebuf = -1;
1206
1207 return chip->ecc.read_page(mtd, chip, chip->buffers->databuf, 1, page);
1208}
1209
1210static int sunxi_nfc_hw_common_ecc_write_oob(struct mtd_info *mtd,
1211 struct nand_chip *chip,
1212 int page)
1213{
1214 int ret, status;
1215
1216 chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0, page);
1217
1218 chip->pagebuf = -1;
1219
1220 memset(chip->buffers->databuf, 0xff, mtd->writesize);
1221 ret = chip->ecc.write_page(mtd, chip, chip->buffers->databuf, 1, page);
1222 if (ret)
1223 return ret;
1224
1225 /* Send command to program the OOB data */
1226 chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
1227
1228 status = chip->waitfunc(mtd, chip);
1229
1230 return status & NAND_STATUS_FAIL ? -EIO : 0;
1231}
1232
Roy Spliet9c618292015-06-26 11:00:10 +02001233static const s32 tWB_lut[] = {6, 12, 16, 20};
1234static const s32 tRHW_lut[] = {4, 8, 12, 20};
1235
1236static int _sunxi_nand_lookup_timing(const s32 *lut, int lut_size, u32 duration,
1237 u32 clk_period)
1238{
1239 u32 clk_cycles = DIV_ROUND_UP(duration, clk_period);
1240 int i;
1241
1242 for (i = 0; i < lut_size; i++) {
1243 if (clk_cycles <= lut[i])
1244 return i;
1245 }
1246
1247 /* Doesn't fit */
1248 return -EINVAL;
1249}
1250
1251#define sunxi_nand_lookup_timing(l, p, c) \
1252 _sunxi_nand_lookup_timing(l, ARRAY_SIZE(l), p, c)
1253
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001254static int sunxi_nand_chip_set_timings(struct sunxi_nand_chip *chip,
1255 const struct nand_sdr_timings *timings)
1256{
Roy Spliet9c618292015-06-26 11:00:10 +02001257 struct sunxi_nfc *nfc = to_sunxi_nfc(chip->nand.controller);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001258 u32 min_clk_period = 0;
Roy Spliet9c618292015-06-26 11:00:10 +02001259 s32 tWB, tADL, tWHR, tRHW, tCAD;
Boris Brezillon2d434572015-12-02 15:57:20 +01001260 long real_clk_rate;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001261
1262 /* T1 <=> tCLS */
1263 if (timings->tCLS_min > min_clk_period)
1264 min_clk_period = timings->tCLS_min;
1265
1266 /* T2 <=> tCLH */
1267 if (timings->tCLH_min > min_clk_period)
1268 min_clk_period = timings->tCLH_min;
1269
1270 /* T3 <=> tCS */
1271 if (timings->tCS_min > min_clk_period)
1272 min_clk_period = timings->tCS_min;
1273
1274 /* T4 <=> tCH */
1275 if (timings->tCH_min > min_clk_period)
1276 min_clk_period = timings->tCH_min;
1277
1278 /* T5 <=> tWP */
1279 if (timings->tWP_min > min_clk_period)
1280 min_clk_period = timings->tWP_min;
1281
1282 /* T6 <=> tWH */
1283 if (timings->tWH_min > min_clk_period)
1284 min_clk_period = timings->tWH_min;
1285
1286 /* T7 <=> tALS */
1287 if (timings->tALS_min > min_clk_period)
1288 min_clk_period = timings->tALS_min;
1289
1290 /* T8 <=> tDS */
1291 if (timings->tDS_min > min_clk_period)
1292 min_clk_period = timings->tDS_min;
1293
1294 /* T9 <=> tDH */
1295 if (timings->tDH_min > min_clk_period)
1296 min_clk_period = timings->tDH_min;
1297
1298 /* T10 <=> tRR */
1299 if (timings->tRR_min > (min_clk_period * 3))
1300 min_clk_period = DIV_ROUND_UP(timings->tRR_min, 3);
1301
1302 /* T11 <=> tALH */
1303 if (timings->tALH_min > min_clk_period)
1304 min_clk_period = timings->tALH_min;
1305
1306 /* T12 <=> tRP */
1307 if (timings->tRP_min > min_clk_period)
1308 min_clk_period = timings->tRP_min;
1309
1310 /* T13 <=> tREH */
1311 if (timings->tREH_min > min_clk_period)
1312 min_clk_period = timings->tREH_min;
1313
1314 /* T14 <=> tRC */
1315 if (timings->tRC_min > (min_clk_period * 2))
1316 min_clk_period = DIV_ROUND_UP(timings->tRC_min, 2);
1317
1318 /* T15 <=> tWC */
1319 if (timings->tWC_min > (min_clk_period * 2))
1320 min_clk_period = DIV_ROUND_UP(timings->tWC_min, 2);
1321
Roy Spliet9c618292015-06-26 11:00:10 +02001322 /* T16 - T19 + tCAD */
Boris Brezillon5abcd952015-11-11 22:30:30 +01001323 if (timings->tWB_max > (min_clk_period * 20))
1324 min_clk_period = DIV_ROUND_UP(timings->tWB_max, 20);
1325
1326 if (timings->tADL_min > (min_clk_period * 32))
1327 min_clk_period = DIV_ROUND_UP(timings->tADL_min, 32);
1328
1329 if (timings->tWHR_min > (min_clk_period * 32))
1330 min_clk_period = DIV_ROUND_UP(timings->tWHR_min, 32);
1331
1332 if (timings->tRHW_min > (min_clk_period * 20))
1333 min_clk_period = DIV_ROUND_UP(timings->tRHW_min, 20);
1334
Roy Spliet9c618292015-06-26 11:00:10 +02001335 tWB = sunxi_nand_lookup_timing(tWB_lut, timings->tWB_max,
1336 min_clk_period);
1337 if (tWB < 0) {
1338 dev_err(nfc->dev, "unsupported tWB\n");
1339 return tWB;
1340 }
1341
1342 tADL = DIV_ROUND_UP(timings->tADL_min, min_clk_period) >> 3;
1343 if (tADL > 3) {
1344 dev_err(nfc->dev, "unsupported tADL\n");
1345 return -EINVAL;
1346 }
1347
1348 tWHR = DIV_ROUND_UP(timings->tWHR_min, min_clk_period) >> 3;
1349 if (tWHR > 3) {
1350 dev_err(nfc->dev, "unsupported tWHR\n");
1351 return -EINVAL;
1352 }
1353
1354 tRHW = sunxi_nand_lookup_timing(tRHW_lut, timings->tRHW_min,
1355 min_clk_period);
1356 if (tRHW < 0) {
1357 dev_err(nfc->dev, "unsupported tRHW\n");
1358 return tRHW;
1359 }
1360
1361 /*
1362 * TODO: according to ONFI specs this value only applies for DDR NAND,
1363 * but Allwinner seems to set this to 0x7. Mimic them for now.
1364 */
1365 tCAD = 0x7;
1366
1367 /* TODO: A83 has some more bits for CDQSS, CS, CLHZ, CCS, WC */
1368 chip->timing_cfg = NFC_TIMING_CFG(tWB, tADL, tWHR, tRHW, tCAD);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001369
1370 /* Convert min_clk_period from picoseconds to nanoseconds */
1371 min_clk_period = DIV_ROUND_UP(min_clk_period, 1000);
1372
1373 /*
Boris Brezillon2f9992e2015-12-02 15:10:40 +01001374 * Unlike what is stated in Allwinner datasheet, the clk_rate should
1375 * be set to (1 / min_clk_period), and not (2 / min_clk_period).
1376 * This new formula was verified with a scope and validated by
1377 * Allwinner engineers.
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001378 */
Boris Brezillon2f9992e2015-12-02 15:10:40 +01001379 chip->clk_rate = NSEC_PER_SEC / min_clk_period;
Boris Brezillon2d434572015-12-02 15:57:20 +01001380 real_clk_rate = clk_round_rate(nfc->mod_clk, chip->clk_rate);
1381
1382 /*
1383 * ONFI specification 3.1, paragraph 4.15.2 dictates that EDO data
1384 * output cycle timings shall be used if the host drives tRC less than
1385 * 30 ns.
1386 */
1387 min_clk_period = NSEC_PER_SEC / real_clk_rate;
1388 chip->timing_ctl = ((min_clk_period * 2) < 30) ?
1389 NFC_TIMING_CTL_EDO : 0;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001390
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001391 return 0;
1392}
1393
1394static int sunxi_nand_chip_init_timings(struct sunxi_nand_chip *chip,
1395 struct device_node *np)
1396{
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001397 struct mtd_info *mtd = nand_to_mtd(&chip->nand);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001398 const struct nand_sdr_timings *timings;
1399 int ret;
1400 int mode;
1401
1402 mode = onfi_get_async_timing_mode(&chip->nand);
1403 if (mode == ONFI_TIMING_MODE_UNKNOWN) {
1404 mode = chip->nand.onfi_timing_mode_default;
1405 } else {
1406 uint8_t feature[ONFI_SUBFEATURE_PARAM_LEN] = {};
Stefan Roese7eadd472015-08-28 14:45:21 +02001407 int i;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001408
1409 mode = fls(mode) - 1;
1410 if (mode < 0)
1411 mode = 0;
1412
1413 feature[0] = mode;
Stefan Roese7eadd472015-08-28 14:45:21 +02001414 for (i = 0; i < chip->nsels; i++) {
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001415 chip->nand.select_chip(mtd, i);
1416 ret = chip->nand.onfi_set_features(mtd, &chip->nand,
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001417 ONFI_FEATURE_ADDR_TIMING_MODE,
1418 feature);
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001419 chip->nand.select_chip(mtd, -1);
Stefan Roese7eadd472015-08-28 14:45:21 +02001420 if (ret)
1421 return ret;
1422 }
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001423 }
1424
1425 timings = onfi_async_timing_mode_to_sdr_timings(mode);
1426 if (IS_ERR(timings))
1427 return PTR_ERR(timings);
1428
1429 return sunxi_nand_chip_set_timings(chip, timings);
1430}
1431
1432static int sunxi_nand_hw_common_ecc_ctrl_init(struct mtd_info *mtd,
1433 struct nand_ecc_ctrl *ecc,
1434 struct device_node *np)
1435{
1436 static const u8 strengths[] = { 16, 24, 28, 32, 40, 48, 56, 60, 64 };
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +01001437 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001438 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
1439 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
1440 struct sunxi_nand_hw_ecc *data;
1441 struct nand_ecclayout *layout;
1442 int nsectors;
1443 int ret;
1444 int i;
1445
1446 data = kzalloc(sizeof(*data), GFP_KERNEL);
1447 if (!data)
1448 return -ENOMEM;
1449
1450 /* Add ECC info retrieval from DT */
1451 for (i = 0; i < ARRAY_SIZE(strengths); i++) {
1452 if (ecc->strength <= strengths[i])
1453 break;
1454 }
1455
1456 if (i >= ARRAY_SIZE(strengths)) {
1457 dev_err(nfc->dev, "unsupported strength\n");
1458 ret = -ENOTSUPP;
1459 goto err;
1460 }
1461
1462 data->mode = i;
1463
1464 /* HW ECC always request ECC bytes for 1024 bytes blocks */
1465 ecc->bytes = DIV_ROUND_UP(ecc->strength * fls(8 * 1024), 8);
1466
1467 /* HW ECC always work with even numbers of ECC bytes */
1468 ecc->bytes = ALIGN(ecc->bytes, 2);
1469
1470 layout = &data->layout;
1471 nsectors = mtd->writesize / ecc->size;
1472
1473 if (mtd->oobsize < ((ecc->bytes + 4) * nsectors)) {
1474 ret = -EINVAL;
1475 goto err;
1476 }
1477
1478 layout->eccbytes = (ecc->bytes * nsectors);
1479
Boris Brezillon1c1bdd62015-09-02 15:05:52 +02001480 ecc->read_oob = sunxi_nfc_hw_common_ecc_read_oob;
1481 ecc->write_oob = sunxi_nfc_hw_common_ecc_write_oob;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001482 ecc->layout = layout;
1483 ecc->priv = data;
1484
1485 return 0;
1486
1487err:
1488 kfree(data);
1489
1490 return ret;
1491}
1492
1493static void sunxi_nand_hw_common_ecc_ctrl_cleanup(struct nand_ecc_ctrl *ecc)
1494{
1495 kfree(ecc->priv);
1496}
1497
1498static int sunxi_nand_hw_ecc_ctrl_init(struct mtd_info *mtd,
1499 struct nand_ecc_ctrl *ecc,
1500 struct device_node *np)
1501{
1502 struct nand_ecclayout *layout;
1503 int nsectors;
1504 int i, j;
1505 int ret;
1506
1507 ret = sunxi_nand_hw_common_ecc_ctrl_init(mtd, ecc, np);
1508 if (ret)
1509 return ret;
1510
1511 ecc->read_page = sunxi_nfc_hw_ecc_read_page;
1512 ecc->write_page = sunxi_nfc_hw_ecc_write_page;
Boris Brezillon1c1bdd62015-09-02 15:05:52 +02001513 ecc->read_oob_raw = nand_read_oob_std;
1514 ecc->write_oob_raw = nand_write_oob_std;
Boris Brezillonfe82cce2015-09-16 09:01:45 +02001515 ecc->read_subpage = sunxi_nfc_hw_ecc_read_subpage;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001516 layout = ecc->layout;
1517 nsectors = mtd->writesize / ecc->size;
1518
1519 for (i = 0; i < nsectors; i++) {
1520 if (i) {
1521 layout->oobfree[i].offset =
1522 layout->oobfree[i - 1].offset +
1523 layout->oobfree[i - 1].length +
1524 ecc->bytes;
1525 layout->oobfree[i].length = 4;
1526 } else {
1527 /*
1528 * The first 2 bytes are used for BB markers, hence we
1529 * only have 2 bytes available in the first user data
1530 * section.
1531 */
1532 layout->oobfree[i].length = 2;
1533 layout->oobfree[i].offset = 2;
1534 }
1535
1536 for (j = 0; j < ecc->bytes; j++)
1537 layout->eccpos[(ecc->bytes * i) + j] =
1538 layout->oobfree[i].offset +
1539 layout->oobfree[i].length + j;
1540 }
1541
1542 if (mtd->oobsize > (ecc->bytes + 4) * nsectors) {
1543 layout->oobfree[nsectors].offset =
1544 layout->oobfree[nsectors - 1].offset +
1545 layout->oobfree[nsectors - 1].length +
1546 ecc->bytes;
1547 layout->oobfree[nsectors].length = mtd->oobsize -
1548 ((ecc->bytes + 4) * nsectors);
1549 }
1550
1551 return 0;
1552}
1553
1554static int sunxi_nand_hw_syndrome_ecc_ctrl_init(struct mtd_info *mtd,
1555 struct nand_ecc_ctrl *ecc,
1556 struct device_node *np)
1557{
1558 struct nand_ecclayout *layout;
1559 int nsectors;
1560 int i;
1561 int ret;
1562
1563 ret = sunxi_nand_hw_common_ecc_ctrl_init(mtd, ecc, np);
1564 if (ret)
1565 return ret;
1566
1567 ecc->prepad = 4;
1568 ecc->read_page = sunxi_nfc_hw_syndrome_ecc_read_page;
1569 ecc->write_page = sunxi_nfc_hw_syndrome_ecc_write_page;
Boris Brezillon1c1bdd62015-09-02 15:05:52 +02001570 ecc->read_oob_raw = nand_read_oob_syndrome;
1571 ecc->write_oob_raw = nand_write_oob_syndrome;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001572
1573 layout = ecc->layout;
1574 nsectors = mtd->writesize / ecc->size;
1575
1576 for (i = 0; i < (ecc->bytes * nsectors); i++)
1577 layout->eccpos[i] = i;
1578
1579 layout->oobfree[0].length = mtd->oobsize - i;
1580 layout->oobfree[0].offset = i;
1581
1582 return 0;
1583}
1584
1585static void sunxi_nand_ecc_cleanup(struct nand_ecc_ctrl *ecc)
1586{
1587 switch (ecc->mode) {
1588 case NAND_ECC_HW:
1589 case NAND_ECC_HW_SYNDROME:
1590 sunxi_nand_hw_common_ecc_ctrl_cleanup(ecc);
1591 break;
1592 case NAND_ECC_NONE:
1593 kfree(ecc->layout);
1594 default:
1595 break;
1596 }
1597}
1598
1599static int sunxi_nand_ecc_init(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc,
1600 struct device_node *np)
1601{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +01001602 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001603 int ret;
1604
Boris BREZILLONa3d22a52015-09-02 10:30:25 +02001605 if (!ecc->size) {
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001606 ecc->size = nand->ecc_step_ds;
1607 ecc->strength = nand->ecc_strength_ds;
1608 }
1609
1610 if (!ecc->size || !ecc->strength)
1611 return -EINVAL;
1612
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001613 switch (ecc->mode) {
1614 case NAND_ECC_SOFT_BCH:
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001615 break;
1616 case NAND_ECC_HW:
1617 ret = sunxi_nand_hw_ecc_ctrl_init(mtd, ecc, np);
1618 if (ret)
1619 return ret;
1620 break;
1621 case NAND_ECC_HW_SYNDROME:
1622 ret = sunxi_nand_hw_syndrome_ecc_ctrl_init(mtd, ecc, np);
1623 if (ret)
1624 return ret;
1625 break;
1626 case NAND_ECC_NONE:
1627 ecc->layout = kzalloc(sizeof(*ecc->layout), GFP_KERNEL);
1628 if (!ecc->layout)
1629 return -ENOMEM;
1630 ecc->layout->oobfree[0].length = mtd->oobsize;
1631 case NAND_ECC_SOFT:
1632 break;
1633 default:
1634 return -EINVAL;
1635 }
1636
1637 return 0;
1638}
1639
1640static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc,
1641 struct device_node *np)
1642{
1643 const struct nand_sdr_timings *timings;
1644 struct sunxi_nand_chip *chip;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001645 struct mtd_info *mtd;
1646 struct nand_chip *nand;
1647 int nsels;
1648 int ret;
1649 int i;
1650 u32 tmp;
1651
1652 if (!of_get_property(np, "reg", &nsels))
1653 return -EINVAL;
1654
1655 nsels /= sizeof(u32);
1656 if (!nsels) {
1657 dev_err(dev, "invalid reg property size\n");
1658 return -EINVAL;
1659 }
1660
1661 chip = devm_kzalloc(dev,
1662 sizeof(*chip) +
1663 (nsels * sizeof(struct sunxi_nand_chip_sel)),
1664 GFP_KERNEL);
1665 if (!chip) {
1666 dev_err(dev, "could not allocate chip\n");
1667 return -ENOMEM;
1668 }
1669
1670 chip->nsels = nsels;
1671 chip->selected = -1;
1672
1673 for (i = 0; i < nsels; i++) {
1674 ret = of_property_read_u32_index(np, "reg", i, &tmp);
1675 if (ret) {
1676 dev_err(dev, "could not retrieve reg property: %d\n",
1677 ret);
1678 return ret;
1679 }
1680
1681 if (tmp > NFC_MAX_CS) {
1682 dev_err(dev,
1683 "invalid reg value: %u (max CS = 7)\n",
1684 tmp);
1685 return -EINVAL;
1686 }
1687
1688 if (test_and_set_bit(tmp, &nfc->assigned_cs)) {
1689 dev_err(dev, "CS %d already assigned\n", tmp);
1690 return -EINVAL;
1691 }
1692
1693 chip->sels[i].cs = tmp;
1694
1695 if (!of_property_read_u32_index(np, "allwinner,rb", i, &tmp) &&
1696 tmp < 2) {
1697 chip->sels[i].rb.type = RB_NATIVE;
1698 chip->sels[i].rb.info.nativeid = tmp;
1699 } else {
1700 ret = of_get_named_gpio(np, "rb-gpios", i);
1701 if (ret >= 0) {
1702 tmp = ret;
1703 chip->sels[i].rb.type = RB_GPIO;
1704 chip->sels[i].rb.info.gpio = tmp;
1705 ret = devm_gpio_request(dev, tmp, "nand-rb");
1706 if (ret)
1707 return ret;
1708
1709 ret = gpio_direction_input(tmp);
1710 if (ret)
1711 return ret;
1712 } else {
1713 chip->sels[i].rb.type = RB_NONE;
1714 }
1715 }
1716 }
1717
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001718 nand = &chip->nand;
1719 /* Default tR value specified in the ONFI spec (chapter 4.15.1) */
1720 nand->chip_delay = 200;
1721 nand->controller = &nfc->controller;
Boris BREZILLONa3d22a52015-09-02 10:30:25 +02001722 /*
1723 * Set the ECC mode to the default value in case nothing is specified
1724 * in the DT.
1725 */
1726 nand->ecc.mode = NAND_ECC_HW;
Brian Norris63752192015-10-30 20:33:23 -07001727 nand_set_flash_node(nand, np);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001728 nand->select_chip = sunxi_nfc_select_chip;
1729 nand->cmd_ctrl = sunxi_nfc_cmd_ctrl;
1730 nand->read_buf = sunxi_nfc_read_buf;
1731 nand->write_buf = sunxi_nfc_write_buf;
1732 nand->read_byte = sunxi_nfc_read_byte;
1733
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001734 mtd = nand_to_mtd(nand);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001735 mtd->dev.parent = dev;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001736
Boris Brezillon9edb4702015-12-02 16:00:57 +01001737 timings = onfi_async_timing_mode_to_sdr_timings(0);
1738 if (IS_ERR(timings)) {
1739 ret = PTR_ERR(timings);
1740 dev_err(dev,
1741 "could not retrieve timings for ONFI mode 0: %d\n",
1742 ret);
1743 return ret;
1744 }
1745
1746 ret = sunxi_nand_chip_set_timings(chip, timings);
1747 if (ret) {
1748 dev_err(dev, "could not configure chip timings: %d\n", ret);
1749 return ret;
1750 }
1751
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001752 ret = nand_scan_ident(mtd, nsels, NULL);
1753 if (ret)
1754 return ret;
1755
Boris BREZILLONa3d22a52015-09-02 10:30:25 +02001756 if (nand->bbt_options & NAND_BBT_USE_FLASH)
1757 nand->bbt_options |= NAND_BBT_NO_OOB;
1758
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001759 if (nand->options & NAND_NEED_SCRAMBLING)
1760 nand->options |= NAND_NO_SUBPAGE_WRITE;
1761
Boris Brezillonfe82cce2015-09-16 09:01:45 +02001762 nand->options |= NAND_SUBPAGE_READ;
1763
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001764 ret = sunxi_nand_chip_init_timings(chip, np);
1765 if (ret) {
1766 dev_err(dev, "could not configure chip timings: %d\n", ret);
1767 return ret;
1768 }
1769
1770 ret = sunxi_nand_ecc_init(mtd, &nand->ecc, np);
1771 if (ret) {
1772 dev_err(dev, "ECC init failed: %d\n", ret);
1773 return ret;
1774 }
1775
1776 ret = nand_scan_tail(mtd);
1777 if (ret) {
1778 dev_err(dev, "nand_scan_tail failed: %d\n", ret);
1779 return ret;
1780 }
1781
Brian Norrisa61ae812015-10-30 20:33:25 -07001782 ret = mtd_device_register(mtd, NULL, 0);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001783 if (ret) {
1784 dev_err(dev, "failed to register mtd device: %d\n", ret);
1785 nand_release(mtd);
1786 return ret;
1787 }
1788
1789 list_add_tail(&chip->node, &nfc->chips);
1790
1791 return 0;
1792}
1793
1794static int sunxi_nand_chips_init(struct device *dev, struct sunxi_nfc *nfc)
1795{
1796 struct device_node *np = dev->of_node;
1797 struct device_node *nand_np;
1798 int nchips = of_get_child_count(np);
1799 int ret;
1800
1801 if (nchips > 8) {
1802 dev_err(dev, "too many NAND chips: %d (max = 8)\n", nchips);
1803 return -EINVAL;
1804 }
1805
1806 for_each_child_of_node(np, nand_np) {
1807 ret = sunxi_nand_chip_init(dev, nfc, nand_np);
Julia Lawalla81c0f02015-11-18 23:04:12 +01001808 if (ret) {
1809 of_node_put(nand_np);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001810 return ret;
Julia Lawalla81c0f02015-11-18 23:04:12 +01001811 }
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001812 }
1813
1814 return 0;
1815}
1816
1817static void sunxi_nand_chips_cleanup(struct sunxi_nfc *nfc)
1818{
1819 struct sunxi_nand_chip *chip;
1820
1821 while (!list_empty(&nfc->chips)) {
1822 chip = list_first_entry(&nfc->chips, struct sunxi_nand_chip,
1823 node);
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001824 nand_release(nand_to_mtd(&chip->nand));
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001825 sunxi_nand_ecc_cleanup(&chip->nand.ecc);
Boris BREZILLON8e375cc2015-09-13 18:14:43 +02001826 list_del(&chip->node);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001827 }
1828}
1829
1830static int sunxi_nfc_probe(struct platform_device *pdev)
1831{
1832 struct device *dev = &pdev->dev;
1833 struct resource *r;
1834 struct sunxi_nfc *nfc;
1835 int irq;
1836 int ret;
1837
1838 nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
1839 if (!nfc)
1840 return -ENOMEM;
1841
1842 nfc->dev = dev;
1843 spin_lock_init(&nfc->controller.lock);
1844 init_waitqueue_head(&nfc->controller.wq);
1845 INIT_LIST_HEAD(&nfc->chips);
1846
1847 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1848 nfc->regs = devm_ioremap_resource(dev, r);
1849 if (IS_ERR(nfc->regs))
1850 return PTR_ERR(nfc->regs);
1851
1852 irq = platform_get_irq(pdev, 0);
1853 if (irq < 0) {
1854 dev_err(dev, "failed to retrieve irq\n");
1855 return irq;
1856 }
1857
1858 nfc->ahb_clk = devm_clk_get(dev, "ahb");
1859 if (IS_ERR(nfc->ahb_clk)) {
1860 dev_err(dev, "failed to retrieve ahb clk\n");
1861 return PTR_ERR(nfc->ahb_clk);
1862 }
1863
1864 ret = clk_prepare_enable(nfc->ahb_clk);
1865 if (ret)
1866 return ret;
1867
1868 nfc->mod_clk = devm_clk_get(dev, "mod");
1869 if (IS_ERR(nfc->mod_clk)) {
1870 dev_err(dev, "failed to retrieve mod clk\n");
1871 ret = PTR_ERR(nfc->mod_clk);
1872 goto out_ahb_clk_unprepare;
1873 }
1874
1875 ret = clk_prepare_enable(nfc->mod_clk);
1876 if (ret)
1877 goto out_ahb_clk_unprepare;
1878
1879 ret = sunxi_nfc_rst(nfc);
1880 if (ret)
1881 goto out_mod_clk_unprepare;
1882
1883 writel(0, nfc->regs + NFC_REG_INT);
1884 ret = devm_request_irq(dev, irq, sunxi_nfc_interrupt,
1885 0, "sunxi-nand", nfc);
1886 if (ret)
1887 goto out_mod_clk_unprepare;
1888
1889 platform_set_drvdata(pdev, nfc);
1890
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001891 ret = sunxi_nand_chips_init(dev, nfc);
1892 if (ret) {
1893 dev_err(dev, "failed to init nand chips\n");
1894 goto out_mod_clk_unprepare;
1895 }
1896
1897 return 0;
1898
1899out_mod_clk_unprepare:
1900 clk_disable_unprepare(nfc->mod_clk);
1901out_ahb_clk_unprepare:
1902 clk_disable_unprepare(nfc->ahb_clk);
1903
1904 return ret;
1905}
1906
1907static int sunxi_nfc_remove(struct platform_device *pdev)
1908{
1909 struct sunxi_nfc *nfc = platform_get_drvdata(pdev);
1910
1911 sunxi_nand_chips_cleanup(nfc);
Boris Brezillondd26a452016-03-04 18:26:40 +01001912 clk_disable_unprepare(nfc->mod_clk);
1913 clk_disable_unprepare(nfc->ahb_clk);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001914
1915 return 0;
1916}
1917
1918static const struct of_device_id sunxi_nfc_ids[] = {
1919 { .compatible = "allwinner,sun4i-a10-nand" },
1920 { /* sentinel */ }
1921};
1922MODULE_DEVICE_TABLE(of, sunxi_nfc_ids);
1923
1924static struct platform_driver sunxi_nfc_driver = {
1925 .driver = {
1926 .name = "sunxi_nand",
1927 .of_match_table = sunxi_nfc_ids,
1928 },
1929 .probe = sunxi_nfc_probe,
1930 .remove = sunxi_nfc_remove,
1931};
1932module_platform_driver(sunxi_nfc_driver);
1933
1934MODULE_LICENSE("GPL v2");
1935MODULE_AUTHOR("Boris BREZILLON");
1936MODULE_DESCRIPTION("Allwinner NAND Flash Controller driver");
1937MODULE_ALIAS("platform:sunxi_nand");