blob: ef7f6dfde80b869830d409ee3d290987488c4a99 [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)
Boris Brezillon614049a2016-04-15 15:10:30 +0200156#define NFC_ECC_ERR_MSK GENMASK(15, 0)
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200157#define NFC_ECC_PAT_FOUND(x) BIT(x + 16)
Boris Brezillonf8b04742016-03-04 17:25:08 +0100158#define NFC_ECC_ERR_CNT(b, x) (((x) >> (((b) % 4) * 8)) & 0xff)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200159
160#define NFC_DEFAULT_TIMEOUT_MS 1000
161
162#define NFC_SRAM_SIZE 1024
163
164#define NFC_MAX_CS 7
165
166/*
167 * Ready/Busy detection type: describes the Ready/Busy detection modes
168 *
169 * @RB_NONE: no external detection available, rely on STATUS command
170 * and software timeouts
171 * @RB_NATIVE: use sunxi NAND controller Ready/Busy support. The Ready/Busy
172 * pin of the NAND flash chip must be connected to one of the
173 * native NAND R/B pins (those which can be muxed to the NAND
174 * Controller)
175 * @RB_GPIO: use a simple GPIO to handle Ready/Busy status. The Ready/Busy
176 * pin of the NAND flash chip must be connected to a GPIO capable
177 * pin.
178 */
179enum sunxi_nand_rb_type {
180 RB_NONE,
181 RB_NATIVE,
182 RB_GPIO,
183};
184
185/*
186 * Ready/Busy structure: stores information related to Ready/Busy detection
187 *
188 * @type: the Ready/Busy detection mode
189 * @info: information related to the R/B detection mode. Either a gpio
190 * id or a native R/B id (those supported by the NAND controller).
191 */
192struct sunxi_nand_rb {
193 enum sunxi_nand_rb_type type;
194 union {
195 int gpio;
196 int nativeid;
197 } info;
198};
199
200/*
201 * Chip Select structure: stores information related to NAND Chip Select
202 *
203 * @cs: the NAND CS id used to communicate with a NAND Chip
204 * @rb: the Ready/Busy description
205 */
206struct sunxi_nand_chip_sel {
207 u8 cs;
208 struct sunxi_nand_rb rb;
209};
210
211/*
212 * sunxi HW ECC infos: stores information related to HW ECC support
213 *
214 * @mode: the sunxi ECC mode field deduced from ECC requirements
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200215 */
216struct sunxi_nand_hw_ecc {
217 int mode;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200218};
219
220/*
221 * NAND chip structure: stores NAND chip device related information
222 *
223 * @node: used to store NAND chips into a list
224 * @nand: base NAND chip structure
225 * @mtd: base MTD structure
226 * @clk_rate: clk_rate required for this NAND chip
Roy Spliet9c618292015-06-26 11:00:10 +0200227 * @timing_cfg TIMING_CFG register value for this NAND chip
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200228 * @selected: current active CS
229 * @nsels: number of CS lines required by the NAND chip
230 * @sels: array of CS lines descriptions
231 */
232struct sunxi_nand_chip {
233 struct list_head node;
234 struct nand_chip nand;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200235 unsigned long clk_rate;
Roy Spliet9c618292015-06-26 11:00:10 +0200236 u32 timing_cfg;
Roy Splietd052e502015-06-26 11:00:11 +0200237 u32 timing_ctl;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200238 int selected;
Boris Brezillone9aa6712015-09-16 09:05:31 +0200239 int addr_cycles;
240 u32 addr[2];
241 int cmd_cycles;
242 u8 cmd[2];
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200243 int nsels;
244 struct sunxi_nand_chip_sel sels[0];
245};
246
247static inline struct sunxi_nand_chip *to_sunxi_nand(struct nand_chip *nand)
248{
249 return container_of(nand, struct sunxi_nand_chip, nand);
250}
251
252/*
253 * NAND Controller structure: stores sunxi NAND controller information
254 *
255 * @controller: base controller structure
256 * @dev: parent device (used to print error messages)
257 * @regs: NAND controller registers
258 * @ahb_clk: NAND Controller AHB clock
259 * @mod_clk: NAND Controller mod clock
260 * @assigned_cs: bitmask describing already assigned CS lines
261 * @clk_rate: NAND controller current clock rate
262 * @chips: a list containing all the NAND chips attached to
263 * this NAND controller
264 * @complete: a completion object used to wait for NAND
265 * controller events
266 */
267struct sunxi_nfc {
268 struct nand_hw_control controller;
269 struct device *dev;
270 void __iomem *regs;
271 struct clk *ahb_clk;
272 struct clk *mod_clk;
273 unsigned long assigned_cs;
274 unsigned long clk_rate;
275 struct list_head chips;
276 struct completion complete;
Boris Brezillon614049a2016-04-15 15:10:30 +0200277 struct dma_chan *dmac;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200278};
279
280static inline struct sunxi_nfc *to_sunxi_nfc(struct nand_hw_control *ctrl)
281{
282 return container_of(ctrl, struct sunxi_nfc, controller);
283}
284
285static irqreturn_t sunxi_nfc_interrupt(int irq, void *dev_id)
286{
287 struct sunxi_nfc *nfc = dev_id;
288 u32 st = readl(nfc->regs + NFC_REG_ST);
289 u32 ien = readl(nfc->regs + NFC_REG_INT);
290
291 if (!(ien & st))
292 return IRQ_NONE;
293
294 if ((ien & st) == ien)
295 complete(&nfc->complete);
296
297 writel(st & NFC_INT_MASK, nfc->regs + NFC_REG_ST);
298 writel(~st & ien & NFC_INT_MASK, nfc->regs + NFC_REG_INT);
299
300 return IRQ_HANDLED;
301}
302
Boris Brezillonc0c9dfa2016-03-07 15:34:39 +0100303static int sunxi_nfc_wait_events(struct sunxi_nfc *nfc, u32 events,
304 bool use_polling, unsigned int timeout_ms)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200305{
Boris Brezillonc0c9dfa2016-03-07 15:34:39 +0100306 int ret;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200307
Boris Brezillonc0c9dfa2016-03-07 15:34:39 +0100308 if (events & ~NFC_INT_MASK)
309 return -EINVAL;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200310
311 if (!timeout_ms)
312 timeout_ms = NFC_DEFAULT_TIMEOUT_MS;
313
Boris Brezillonc0c9dfa2016-03-07 15:34:39 +0100314 if (!use_polling) {
315 init_completion(&nfc->complete);
316
317 writel(events, nfc->regs + NFC_REG_INT);
318
319 ret = wait_for_completion_timeout(&nfc->complete,
320 msecs_to_jiffies(timeout_ms));
321
322 writel(0, nfc->regs + NFC_REG_INT);
323 } else {
324 u32 status;
325
326 ret = readl_poll_timeout(nfc->regs + NFC_REG_ST, status,
327 (status & events) == events, 1,
328 timeout_ms * 1000);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200329 }
330
Boris Brezillonc0c9dfa2016-03-07 15:34:39 +0100331 writel(events & NFC_INT_MASK, nfc->regs + NFC_REG_ST);
332
333 if (ret)
334 dev_err(nfc->dev, "wait interrupt timedout\n");
335
336 return ret;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200337}
338
339static int sunxi_nfc_wait_cmd_fifo_empty(struct sunxi_nfc *nfc)
340{
Boris Brezillon166f08c2016-03-07 15:25:17 +0100341 u32 status;
342 int ret;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200343
Boris Brezillon166f08c2016-03-07 15:25:17 +0100344 ret = readl_poll_timeout(nfc->regs + NFC_REG_ST, status,
345 !(status & NFC_CMD_FIFO_STATUS), 1,
346 NFC_DEFAULT_TIMEOUT_MS * 1000);
347 if (ret)
348 dev_err(nfc->dev, "wait for empty cmd FIFO timedout\n");
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200349
Boris Brezillon166f08c2016-03-07 15:25:17 +0100350 return ret;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200351}
352
353static int sunxi_nfc_rst(struct sunxi_nfc *nfc)
354{
Boris Brezillon166f08c2016-03-07 15:25:17 +0100355 u32 ctl;
356 int ret;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200357
358 writel(0, nfc->regs + NFC_REG_ECC_CTL);
359 writel(NFC_RESET, nfc->regs + NFC_REG_CTL);
360
Boris Brezillon166f08c2016-03-07 15:25:17 +0100361 ret = readl_poll_timeout(nfc->regs + NFC_REG_CTL, ctl,
362 !(ctl & NFC_RESET), 1,
363 NFC_DEFAULT_TIMEOUT_MS * 1000);
364 if (ret)
365 dev_err(nfc->dev, "wait for NAND controller reset timedout\n");
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200366
Boris Brezillon166f08c2016-03-07 15:25:17 +0100367 return ret;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200368}
369
Boris Brezillon614049a2016-04-15 15:10:30 +0200370static int sunxi_nfc_dma_op_prepare(struct mtd_info *mtd, const void *buf,
371 int chunksize, int nchunks,
372 enum dma_data_direction ddir,
373 struct scatterlist *sg)
374{
375 struct nand_chip *nand = mtd_to_nand(mtd);
376 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
377 struct dma_async_tx_descriptor *dmad;
378 enum dma_transfer_direction tdir;
379 dma_cookie_t dmat;
380 int ret;
381
382 if (ddir == DMA_FROM_DEVICE)
383 tdir = DMA_DEV_TO_MEM;
384 else
385 tdir = DMA_MEM_TO_DEV;
386
387 sg_init_one(sg, buf, nchunks * chunksize);
388 ret = dma_map_sg(nfc->dev, sg, 1, ddir);
389 if (!ret)
390 return -ENOMEM;
391
392 dmad = dmaengine_prep_slave_sg(nfc->dmac, sg, 1, tdir, DMA_CTRL_ACK);
393 if (IS_ERR(dmad)) {
394 ret = PTR_ERR(dmad);
395 goto err_unmap_buf;
396 }
397
398 writel(readl(nfc->regs + NFC_REG_CTL) | NFC_RAM_METHOD,
399 nfc->regs + NFC_REG_CTL);
400 writel(nchunks, nfc->regs + NFC_REG_SECTOR_NUM);
401 writel(chunksize, nfc->regs + NFC_REG_CNT);
402 dmat = dmaengine_submit(dmad);
403
404 ret = dma_submit_error(dmat);
405 if (ret)
406 goto err_clr_dma_flag;
407
408 return 0;
409
410err_clr_dma_flag:
411 writel(readl(nfc->regs + NFC_REG_CTL) & ~NFC_RAM_METHOD,
412 nfc->regs + NFC_REG_CTL);
413
414err_unmap_buf:
415 dma_unmap_sg(nfc->dev, sg, 1, ddir);
416 return ret;
417}
418
419static void sunxi_nfc_dma_op_cleanup(struct mtd_info *mtd,
420 enum dma_data_direction ddir,
421 struct scatterlist *sg)
422{
423 struct nand_chip *nand = mtd_to_nand(mtd);
424 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
425
426 dma_unmap_sg(nfc->dev, sg, 1, ddir);
427 writel(readl(nfc->regs + NFC_REG_CTL) & ~NFC_RAM_METHOD,
428 nfc->regs + NFC_REG_CTL);
429}
430
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200431static int sunxi_nfc_dev_ready(struct mtd_info *mtd)
432{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100433 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200434 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
435 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
436 struct sunxi_nand_rb *rb;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200437 int ret;
438
439 if (sunxi_nand->selected < 0)
440 return 0;
441
442 rb = &sunxi_nand->sels[sunxi_nand->selected].rb;
443
444 switch (rb->type) {
445 case RB_NATIVE:
446 ret = !!(readl(nfc->regs + NFC_REG_ST) &
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200447 NFC_RB_STATE(rb->info.nativeid));
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200448 break;
449 case RB_GPIO:
450 ret = gpio_get_value(rb->info.gpio);
451 break;
452 case RB_NONE:
453 default:
454 ret = 0;
455 dev_err(nfc->dev, "cannot check R/B NAND status!\n");
456 break;
457 }
458
459 return ret;
460}
461
462static void sunxi_nfc_select_chip(struct mtd_info *mtd, int chip)
463{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100464 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200465 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
466 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
467 struct sunxi_nand_chip_sel *sel;
468 u32 ctl;
469
470 if (chip > 0 && chip >= sunxi_nand->nsels)
471 return;
472
473 if (chip == sunxi_nand->selected)
474 return;
475
476 ctl = readl(nfc->regs + NFC_REG_CTL) &
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200477 ~(NFC_PAGE_SHIFT_MSK | NFC_CE_SEL_MSK | NFC_RB_SEL_MSK | NFC_EN);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200478
479 if (chip >= 0) {
480 sel = &sunxi_nand->sels[chip];
481
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200482 ctl |= NFC_CE_SEL(sel->cs) | NFC_EN |
Boris Brezillon68ffbf72016-03-04 17:29:20 +0100483 NFC_PAGE_SHIFT(nand->page_shift);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200484 if (sel->rb.type == RB_NONE) {
485 nand->dev_ready = NULL;
486 } else {
487 nand->dev_ready = sunxi_nfc_dev_ready;
488 if (sel->rb.type == RB_NATIVE)
Boris BREZILLONb6a02c02015-09-16 09:46:36 +0200489 ctl |= NFC_RB_SEL(sel->rb.info.nativeid);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200490 }
491
492 writel(mtd->writesize, nfc->regs + NFC_REG_SPARE_AREA);
493
494 if (nfc->clk_rate != sunxi_nand->clk_rate) {
495 clk_set_rate(nfc->mod_clk, sunxi_nand->clk_rate);
496 nfc->clk_rate = sunxi_nand->clk_rate;
497 }
498 }
499
Roy Splietd052e502015-06-26 11:00:11 +0200500 writel(sunxi_nand->timing_ctl, nfc->regs + NFC_REG_TIMING_CTL);
Roy Spliet9c618292015-06-26 11:00:10 +0200501 writel(sunxi_nand->timing_cfg, nfc->regs + NFC_REG_TIMING_CFG);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200502 writel(ctl, nfc->regs + NFC_REG_CTL);
503
504 sunxi_nand->selected = chip;
505}
506
507static void sunxi_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
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 int cnt;
514 int offs = 0;
515 u32 tmp;
516
517 while (len > offs) {
518 cnt = min(len - offs, NFC_SRAM_SIZE);
519
520 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
521 if (ret)
522 break;
523
524 writel(cnt, nfc->regs + NFC_REG_CNT);
525 tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD;
526 writel(tmp, nfc->regs + NFC_REG_CMD);
527
Boris Brezillonc0c9dfa2016-03-07 15:34:39 +0100528 ret = sunxi_nfc_wait_events(nfc, NFC_CMD_INT_FLAG, true, 0);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200529 if (ret)
530 break;
531
532 if (buf)
533 memcpy_fromio(buf + offs, nfc->regs + NFC_RAM0_BASE,
534 cnt);
535 offs += cnt;
536 }
537}
538
539static void sunxi_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf,
540 int len)
541{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100542 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200543 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
544 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
545 int ret;
546 int cnt;
547 int offs = 0;
548 u32 tmp;
549
550 while (len > offs) {
551 cnt = min(len - offs, NFC_SRAM_SIZE);
552
553 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
554 if (ret)
555 break;
556
557 writel(cnt, nfc->regs + NFC_REG_CNT);
558 memcpy_toio(nfc->regs + NFC_RAM0_BASE, buf + offs, cnt);
559 tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD |
560 NFC_ACCESS_DIR;
561 writel(tmp, nfc->regs + NFC_REG_CMD);
562
Boris Brezillonc0c9dfa2016-03-07 15:34:39 +0100563 ret = sunxi_nfc_wait_events(nfc, NFC_CMD_INT_FLAG, true, 0);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200564 if (ret)
565 break;
566
567 offs += cnt;
568 }
569}
570
571static uint8_t sunxi_nfc_read_byte(struct mtd_info *mtd)
572{
573 uint8_t ret;
574
575 sunxi_nfc_read_buf(mtd, &ret, 1);
576
577 return ret;
578}
579
580static void sunxi_nfc_cmd_ctrl(struct mtd_info *mtd, int dat,
581 unsigned int ctrl)
582{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100583 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200584 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
585 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
586 int ret;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200587
588 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
589 if (ret)
590 return;
591
Boris Brezillone9aa6712015-09-16 09:05:31 +0200592 if (dat == NAND_CMD_NONE && (ctrl & NAND_NCE) &&
593 !(ctrl & (NAND_CLE | NAND_ALE))) {
594 u32 cmd = 0;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200595
Boris Brezillone9aa6712015-09-16 09:05:31 +0200596 if (!sunxi_nand->addr_cycles && !sunxi_nand->cmd_cycles)
597 return;
598
599 if (sunxi_nand->cmd_cycles--)
600 cmd |= NFC_SEND_CMD1 | sunxi_nand->cmd[0];
601
602 if (sunxi_nand->cmd_cycles--) {
603 cmd |= NFC_SEND_CMD2;
604 writel(sunxi_nand->cmd[1],
605 nfc->regs + NFC_REG_RCMD_SET);
606 }
607
608 sunxi_nand->cmd_cycles = 0;
609
610 if (sunxi_nand->addr_cycles) {
611 cmd |= NFC_SEND_ADR |
612 NFC_ADR_NUM(sunxi_nand->addr_cycles);
613 writel(sunxi_nand->addr[0],
614 nfc->regs + NFC_REG_ADDR_LOW);
615 }
616
617 if (sunxi_nand->addr_cycles > 4)
618 writel(sunxi_nand->addr[1],
619 nfc->regs + NFC_REG_ADDR_HIGH);
620
621 writel(cmd, nfc->regs + NFC_REG_CMD);
622 sunxi_nand->addr[0] = 0;
623 sunxi_nand->addr[1] = 0;
624 sunxi_nand->addr_cycles = 0;
Boris Brezillonc0c9dfa2016-03-07 15:34:39 +0100625 sunxi_nfc_wait_events(nfc, NFC_CMD_INT_FLAG, true, 0);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200626 }
627
Boris Brezillone9aa6712015-09-16 09:05:31 +0200628 if (ctrl & NAND_CLE) {
629 sunxi_nand->cmd[sunxi_nand->cmd_cycles++] = dat;
630 } else if (ctrl & NAND_ALE) {
631 sunxi_nand->addr[sunxi_nand->addr_cycles / 4] |=
632 dat << ((sunxi_nand->addr_cycles % 4) * 8);
633 sunxi_nand->addr_cycles++;
634 }
Boris BREZILLON1fef62c2014-10-21 15:08:41 +0200635}
636
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100637/* These seed values have been extracted from Allwinner's BSP */
638static const u16 sunxi_nfc_randomizer_page_seeds[] = {
639 0x2b75, 0x0bd0, 0x5ca3, 0x62d1, 0x1c93, 0x07e9, 0x2162, 0x3a72,
640 0x0d67, 0x67f9, 0x1be7, 0x077d, 0x032f, 0x0dac, 0x2716, 0x2436,
641 0x7922, 0x1510, 0x3860, 0x5287, 0x480f, 0x4252, 0x1789, 0x5a2d,
642 0x2a49, 0x5e10, 0x437f, 0x4b4e, 0x2f45, 0x216e, 0x5cb7, 0x7130,
643 0x2a3f, 0x60e4, 0x4dc9, 0x0ef0, 0x0f52, 0x1bb9, 0x6211, 0x7a56,
644 0x226d, 0x4ea7, 0x6f36, 0x3692, 0x38bf, 0x0c62, 0x05eb, 0x4c55,
645 0x60f4, 0x728c, 0x3b6f, 0x2037, 0x7f69, 0x0936, 0x651a, 0x4ceb,
646 0x6218, 0x79f3, 0x383f, 0x18d9, 0x4f05, 0x5c82, 0x2912, 0x6f17,
647 0x6856, 0x5938, 0x1007, 0x61ab, 0x3e7f, 0x57c2, 0x542f, 0x4f62,
648 0x7454, 0x2eac, 0x7739, 0x42d4, 0x2f90, 0x435a, 0x2e52, 0x2064,
649 0x637c, 0x66ad, 0x2c90, 0x0bad, 0x759c, 0x0029, 0x0986, 0x7126,
650 0x1ca7, 0x1605, 0x386a, 0x27f5, 0x1380, 0x6d75, 0x24c3, 0x0f8e,
651 0x2b7a, 0x1418, 0x1fd1, 0x7dc1, 0x2d8e, 0x43af, 0x2267, 0x7da3,
652 0x4e3d, 0x1338, 0x50db, 0x454d, 0x764d, 0x40a3, 0x42e6, 0x262b,
653 0x2d2e, 0x1aea, 0x2e17, 0x173d, 0x3a6e, 0x71bf, 0x25f9, 0x0a5d,
654 0x7c57, 0x0fbe, 0x46ce, 0x4939, 0x6b17, 0x37bb, 0x3e91, 0x76db,
655};
656
657/*
658 * sunxi_nfc_randomizer_ecc512_seeds and sunxi_nfc_randomizer_ecc1024_seeds
659 * have been generated using
660 * sunxi_nfc_randomizer_step(seed, (step_size * 8) + 15), which is what
661 * the randomizer engine does internally before de/scrambling OOB data.
662 *
663 * Those tables are statically defined to avoid calculating randomizer state
664 * at runtime.
665 */
666static const u16 sunxi_nfc_randomizer_ecc512_seeds[] = {
667 0x3346, 0x367f, 0x1f18, 0x769a, 0x4f64, 0x068c, 0x2ef1, 0x6b64,
668 0x28a9, 0x15d7, 0x30f8, 0x3659, 0x53db, 0x7c5f, 0x71d4, 0x4409,
669 0x26eb, 0x03cc, 0x655d, 0x47d4, 0x4daa, 0x0877, 0x712d, 0x3617,
670 0x3264, 0x49aa, 0x7f9e, 0x588e, 0x4fbc, 0x7176, 0x7f91, 0x6c6d,
671 0x4b95, 0x5fb7, 0x3844, 0x4037, 0x0184, 0x081b, 0x0ee8, 0x5b91,
672 0x293d, 0x1f71, 0x0e6f, 0x402b, 0x5122, 0x1e52, 0x22be, 0x3d2d,
673 0x75bc, 0x7c60, 0x6291, 0x1a2f, 0x61d4, 0x74aa, 0x4140, 0x29ab,
674 0x472d, 0x2852, 0x017e, 0x15e8, 0x5ec2, 0x17cf, 0x7d0f, 0x06b8,
675 0x117a, 0x6b94, 0x789b, 0x3126, 0x6ac5, 0x5be7, 0x150f, 0x51f8,
676 0x7889, 0x0aa5, 0x663d, 0x77e8, 0x0b87, 0x3dcb, 0x360d, 0x218b,
677 0x512f, 0x7dc9, 0x6a4d, 0x630a, 0x3547, 0x1dd2, 0x5aea, 0x69a5,
678 0x7bfa, 0x5e4f, 0x1519, 0x6430, 0x3a0e, 0x5eb3, 0x5425, 0x0c7a,
679 0x5540, 0x3670, 0x63c1, 0x31e9, 0x5a39, 0x2de7, 0x5979, 0x2891,
680 0x1562, 0x014b, 0x5b05, 0x2756, 0x5a34, 0x13aa, 0x6cb5, 0x2c36,
681 0x5e72, 0x1306, 0x0861, 0x15ef, 0x1ee8, 0x5a37, 0x7ac4, 0x45dd,
682 0x44c4, 0x7266, 0x2f41, 0x3ccc, 0x045e, 0x7d40, 0x7c66, 0x0fa0,
683};
684
685static const u16 sunxi_nfc_randomizer_ecc1024_seeds[] = {
686 0x2cf5, 0x35f1, 0x63a4, 0x5274, 0x2bd2, 0x778b, 0x7285, 0x32b6,
687 0x6a5c, 0x70d6, 0x757d, 0x6769, 0x5375, 0x1e81, 0x0cf3, 0x3982,
688 0x6787, 0x042a, 0x6c49, 0x1925, 0x56a8, 0x40a9, 0x063e, 0x7bd9,
689 0x4dbf, 0x55ec, 0x672e, 0x7334, 0x5185, 0x4d00, 0x232a, 0x7e07,
690 0x445d, 0x6b92, 0x528f, 0x4255, 0x53ba, 0x7d82, 0x2a2e, 0x3a4e,
691 0x75eb, 0x450c, 0x6844, 0x1b5d, 0x581a, 0x4cc6, 0x0379, 0x37b2,
692 0x419f, 0x0e92, 0x6b27, 0x5624, 0x01e3, 0x07c1, 0x44a5, 0x130c,
693 0x13e8, 0x5910, 0x0876, 0x60c5, 0x54e3, 0x5b7f, 0x2269, 0x509f,
694 0x7665, 0x36fd, 0x3e9a, 0x0579, 0x6295, 0x14ef, 0x0a81, 0x1bcc,
695 0x4b16, 0x64db, 0x0514, 0x4f07, 0x0591, 0x3576, 0x6853, 0x0d9e,
696 0x259f, 0x38b7, 0x64fb, 0x3094, 0x4693, 0x6ddd, 0x29bb, 0x0bc8,
697 0x3f47, 0x490e, 0x0c0e, 0x7933, 0x3c9e, 0x5840, 0x398d, 0x3e68,
698 0x4af1, 0x71f5, 0x57cf, 0x1121, 0x64eb, 0x3579, 0x15ac, 0x584d,
699 0x5f2a, 0x47e2, 0x6528, 0x6eac, 0x196e, 0x6b96, 0x0450, 0x0179,
700 0x609c, 0x06e1, 0x4626, 0x42c7, 0x273e, 0x486f, 0x0705, 0x1601,
701 0x145b, 0x407e, 0x062b, 0x57a5, 0x53f9, 0x5659, 0x4410, 0x3ccd,
702};
703
704static u16 sunxi_nfc_randomizer_step(u16 state, int count)
705{
706 state &= 0x7fff;
707
708 /*
709 * This loop is just a simple implementation of a Fibonacci LFSR using
710 * the x16 + x15 + 1 polynomial.
711 */
712 while (count--)
713 state = ((state >> 1) |
714 (((state ^ (state >> 1)) & 1) << 14)) & 0x7fff;
715
716 return state;
717}
718
719static u16 sunxi_nfc_randomizer_state(struct mtd_info *mtd, int page, bool ecc)
720{
721 const u16 *seeds = sunxi_nfc_randomizer_page_seeds;
Brian Norris46c135c2016-01-22 18:57:13 -0800722 int mod = mtd_div_by_ws(mtd->erasesize, mtd);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100723
724 if (mod > ARRAY_SIZE(sunxi_nfc_randomizer_page_seeds))
725 mod = ARRAY_SIZE(sunxi_nfc_randomizer_page_seeds);
726
727 if (ecc) {
728 if (mtd->ecc_step_size == 512)
729 seeds = sunxi_nfc_randomizer_ecc512_seeds;
730 else
731 seeds = sunxi_nfc_randomizer_ecc1024_seeds;
732 }
733
734 return seeds[page % mod];
735}
736
737static void sunxi_nfc_randomizer_config(struct mtd_info *mtd,
738 int page, bool ecc)
739{
Boris BREZILLONf671a1f2016-03-05 00:21:20 +0100740 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100741 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
742 u32 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL);
743 u16 state;
744
745 if (!(nand->options & NAND_NEED_SCRAMBLING))
746 return;
747
748 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL);
749 state = sunxi_nfc_randomizer_state(mtd, page, ecc);
750 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_RANDOM_SEED_MSK;
751 writel(ecc_ctl | NFC_RANDOM_SEED(state), nfc->regs + NFC_REG_ECC_CTL);
752}
753
754static void sunxi_nfc_randomizer_enable(struct mtd_info *mtd)
755{
Boris BREZILLONf671a1f2016-03-05 00:21:20 +0100756 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100757 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
758
759 if (!(nand->options & NAND_NEED_SCRAMBLING))
760 return;
761
762 writel(readl(nfc->regs + NFC_REG_ECC_CTL) | NFC_RANDOM_EN,
763 nfc->regs + NFC_REG_ECC_CTL);
764}
765
766static void sunxi_nfc_randomizer_disable(struct mtd_info *mtd)
767{
Boris BREZILLONf671a1f2016-03-05 00:21:20 +0100768 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100769 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
770
771 if (!(nand->options & NAND_NEED_SCRAMBLING))
772 return;
773
774 writel(readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_RANDOM_EN,
775 nfc->regs + NFC_REG_ECC_CTL);
776}
777
778static void sunxi_nfc_randomize_bbm(struct mtd_info *mtd, int page, u8 *bbm)
779{
780 u16 state = sunxi_nfc_randomizer_state(mtd, page, true);
781
782 bbm[0] ^= state;
783 bbm[1] ^= sunxi_nfc_randomizer_step(state, 8);
784}
785
786static void sunxi_nfc_randomizer_write_buf(struct mtd_info *mtd,
787 const uint8_t *buf, int len,
788 bool ecc, int page)
789{
790 sunxi_nfc_randomizer_config(mtd, page, ecc);
791 sunxi_nfc_randomizer_enable(mtd);
792 sunxi_nfc_write_buf(mtd, buf, len);
793 sunxi_nfc_randomizer_disable(mtd);
794}
795
796static void sunxi_nfc_randomizer_read_buf(struct mtd_info *mtd, uint8_t *buf,
797 int len, bool ecc, int page)
798{
799 sunxi_nfc_randomizer_config(mtd, page, ecc);
800 sunxi_nfc_randomizer_enable(mtd);
801 sunxi_nfc_read_buf(mtd, buf, len);
802 sunxi_nfc_randomizer_disable(mtd);
803}
804
Boris BREZILLONc9118ec2015-09-30 23:45:23 +0200805static void sunxi_nfc_hw_ecc_enable(struct mtd_info *mtd)
806{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100807 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLONc9118ec2015-09-30 23:45:23 +0200808 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
809 struct sunxi_nand_hw_ecc *data = nand->ecc.priv;
810 u32 ecc_ctl;
811
812 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL);
813 ecc_ctl &= ~(NFC_ECC_MODE_MSK | NFC_ECC_PIPELINE |
814 NFC_ECC_BLOCK_SIZE_MSK);
Boris Brezillon336de7b2016-03-04 17:33:10 +0100815 ecc_ctl |= NFC_ECC_EN | NFC_ECC_MODE(data->mode) | NFC_ECC_EXCEPTION |
816 NFC_ECC_PIPELINE;
Boris BREZILLONc9118ec2015-09-30 23:45:23 +0200817
818 writel(ecc_ctl, nfc->regs + NFC_REG_ECC_CTL);
819}
820
821static void sunxi_nfc_hw_ecc_disable(struct mtd_info *mtd)
822{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100823 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLONc9118ec2015-09-30 23:45:23 +0200824 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
825
826 writel(readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_ECC_EN,
827 nfc->regs + NFC_REG_ECC_CTL);
828}
829
Boris BREZILLONf363e0f2015-09-30 23:45:27 +0200830static inline void sunxi_nfc_user_data_to_buf(u32 user_data, u8 *buf)
831{
832 buf[0] = user_data;
833 buf[1] = user_data >> 8;
834 buf[2] = user_data >> 16;
835 buf[3] = user_data >> 24;
836}
837
Boris Brezilloncc6822f2016-03-04 17:56:47 +0100838static inline u32 sunxi_nfc_buf_to_user_data(const u8 *buf)
839{
840 return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
841}
842
843static void sunxi_nfc_hw_ecc_get_prot_oob_bytes(struct mtd_info *mtd, u8 *oob,
844 int step, bool bbm, int page)
845{
846 struct nand_chip *nand = mtd_to_nand(mtd);
847 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
848
849 sunxi_nfc_user_data_to_buf(readl(nfc->regs + NFC_REG_USER_DATA(step)),
850 oob);
851
852 /* De-randomize the Bad Block Marker. */
853 if (bbm && (nand->options & NAND_NEED_SCRAMBLING))
854 sunxi_nfc_randomize_bbm(mtd, page, oob);
855}
856
857static void sunxi_nfc_hw_ecc_set_prot_oob_bytes(struct mtd_info *mtd,
858 const u8 *oob, int step,
859 bool bbm, int page)
860{
861 struct nand_chip *nand = mtd_to_nand(mtd);
862 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
863 u8 user_data[4];
864
865 /* Randomize the Bad Block Marker. */
866 if (bbm && (nand->options & NAND_NEED_SCRAMBLING)) {
867 memcpy(user_data, oob, sizeof(user_data));
868 sunxi_nfc_randomize_bbm(mtd, page, user_data);
869 oob = user_data;
870 }
871
872 writel(sunxi_nfc_buf_to_user_data(oob),
873 nfc->regs + NFC_REG_USER_DATA(step));
874}
875
876static void sunxi_nfc_hw_ecc_update_stats(struct mtd_info *mtd,
877 unsigned int *max_bitflips, int ret)
878{
879 if (ret < 0) {
880 mtd->ecc_stats.failed++;
881 } else {
882 mtd->ecc_stats.corrected += ret;
883 *max_bitflips = max_t(unsigned int, *max_bitflips, ret);
884 }
885}
886
887static int sunxi_nfc_hw_ecc_correct(struct mtd_info *mtd, u8 *data, u8 *oob,
Boris Brezillon614049a2016-04-15 15:10:30 +0200888 int step, u32 status, bool *erased)
Boris Brezilloncc6822f2016-03-04 17:56:47 +0100889{
890 struct nand_chip *nand = mtd_to_nand(mtd);
891 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
892 struct nand_ecc_ctrl *ecc = &nand->ecc;
Boris Brezillon614049a2016-04-15 15:10:30 +0200893 u32 tmp;
Boris Brezilloncc6822f2016-03-04 17:56:47 +0100894
895 *erased = false;
896
Boris Brezilloncc6822f2016-03-04 17:56:47 +0100897 if (status & NFC_ECC_ERR(step))
898 return -EBADMSG;
899
900 if (status & NFC_ECC_PAT_FOUND(step)) {
901 u8 pattern;
902
903 if (unlikely(!(readl(nfc->regs + NFC_REG_PAT_ID) & 0x1))) {
904 pattern = 0x0;
905 } else {
906 pattern = 0xff;
907 *erased = true;
908 }
909
910 if (data)
911 memset(data, pattern, ecc->size);
912
913 if (oob)
914 memset(oob, pattern, ecc->bytes + 4);
915
916 return 0;
917 }
918
919 tmp = readl(nfc->regs + NFC_REG_ECC_ERR_CNT(step));
920
921 return NFC_ECC_ERR_CNT(step, tmp);
922}
923
Boris BREZILLON913821b2015-09-30 23:45:24 +0200924static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd,
925 u8 *data, int data_off,
926 u8 *oob, int oob_off,
927 int *cur_off,
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100928 unsigned int *max_bitflips,
Boris Brezillon828dec12016-03-04 18:09:21 +0100929 bool bbm, bool oob_required, int page)
Boris BREZILLON913821b2015-09-30 23:45:24 +0200930{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100931 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200932 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
933 struct nand_ecc_ctrl *ecc = &nand->ecc;
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100934 int raw_mode = 0;
Boris Brezilloncc6822f2016-03-04 17:56:47 +0100935 bool erased;
Boris BREZILLON913821b2015-09-30 23:45:24 +0200936 int ret;
937
938 if (*cur_off != data_off)
939 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, data_off, -1);
940
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100941 sunxi_nfc_randomizer_read_buf(mtd, NULL, ecc->size, false, page);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200942
Boris BREZILLON74eb9ff2015-10-20 22:16:00 +0200943 if (data_off + ecc->size != oob_off)
Boris BREZILLON913821b2015-09-30 23:45:24 +0200944 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
945
946 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
947 if (ret)
948 return ret;
949
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100950 sunxi_nfc_randomizer_enable(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200951 writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_ECC_OP,
952 nfc->regs + NFC_REG_CMD);
953
Boris Brezillonc0c9dfa2016-03-07 15:34:39 +0100954 ret = sunxi_nfc_wait_events(nfc, NFC_CMD_INT_FLAG, true, 0);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100955 sunxi_nfc_randomizer_disable(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +0200956 if (ret)
957 return ret;
958
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100959 *cur_off = oob_off + ecc->bytes + 4;
960
Boris Brezillon828dec12016-03-04 18:09:21 +0100961 ret = sunxi_nfc_hw_ecc_correct(mtd, data, oob_required ? oob : NULL, 0,
Boris Brezillon614049a2016-04-15 15:10:30 +0200962 readl(nfc->regs + NFC_REG_ECC_ST),
Boris Brezillon828dec12016-03-04 18:09:21 +0100963 &erased);
Boris Brezilloncc6822f2016-03-04 17:56:47 +0100964 if (erased)
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100965 return 1;
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100966
Boris Brezilloncc6822f2016-03-04 17:56:47 +0100967 if (ret < 0) {
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100968 /*
969 * Re-read the data with the randomizer disabled to identify
970 * bitflips in erased pages.
971 */
972 if (nand->options & NAND_NEED_SCRAMBLING) {
973 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, data_off, -1);
974 nand->read_buf(mtd, data, ecc->size);
Boris Brezilloncc6822f2016-03-04 17:56:47 +0100975 } else {
976 memcpy_fromio(data, nfc->regs + NFC_RAM0_BASE,
977 ecc->size);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100978 }
979
Boris Brezilloncc6822f2016-03-04 17:56:47 +0100980 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
981 nand->read_buf(mtd, oob, ecc->bytes + 4);
982
Boris BREZILLON146b5032015-09-30 23:45:29 +0200983 ret = nand_check_erased_ecc_chunk(data, ecc->size,
984 oob, ecc->bytes + 4,
985 NULL, 0, ecc->strength);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100986 if (ret >= 0)
987 raw_mode = 1;
Boris BREZILLONf363e0f2015-09-30 23:45:27 +0200988 } else {
Boris Brezilloncc6822f2016-03-04 17:56:47 +0100989 memcpy_fromio(data, nfc->regs + NFC_RAM0_BASE, ecc->size);
Boris BREZILLON4be4e032015-12-02 12:01:07 +0100990
Boris Brezillon828dec12016-03-04 18:09:21 +0100991 if (oob_required) {
992 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
993 sunxi_nfc_randomizer_read_buf(mtd, oob, ecc->bytes + 4,
994 true, page);
Boris Brezilloncc6822f2016-03-04 17:56:47 +0100995
Boris Brezillon828dec12016-03-04 18:09:21 +0100996 sunxi_nfc_hw_ecc_get_prot_oob_bytes(mtd, oob, 0,
997 bbm, page);
998 }
Boris BREZILLONf363e0f2015-09-30 23:45:27 +0200999 }
Boris BREZILLON913821b2015-09-30 23:45:24 +02001000
Boris Brezilloncc6822f2016-03-04 17:56:47 +01001001 sunxi_nfc_hw_ecc_update_stats(mtd, max_bitflips, ret);
Boris BREZILLON913821b2015-09-30 23:45:24 +02001002
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001003 return raw_mode;
Boris BREZILLON913821b2015-09-30 23:45:24 +02001004}
1005
Boris BREZILLON35d0e242015-09-30 23:45:26 +02001006static void sunxi_nfc_hw_ecc_read_extra_oob(struct mtd_info *mtd,
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001007 u8 *oob, int *cur_off,
1008 bool randomize, int page)
Boris BREZILLON35d0e242015-09-30 23:45:26 +02001009{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +01001010 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON35d0e242015-09-30 23:45:26 +02001011 struct nand_ecc_ctrl *ecc = &nand->ecc;
1012 int offset = ((ecc->bytes + 4) * ecc->steps);
1013 int len = mtd->oobsize - offset;
1014
1015 if (len <= 0)
1016 return;
1017
Boris Brezillonc4f3ef22016-03-04 18:13:10 +01001018 if (!cur_off || *cur_off != offset)
Boris BREZILLON35d0e242015-09-30 23:45:26 +02001019 nand->cmdfunc(mtd, NAND_CMD_RNDOUT,
1020 offset + mtd->writesize, -1);
1021
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001022 if (!randomize)
1023 sunxi_nfc_read_buf(mtd, oob + offset, len);
1024 else
1025 sunxi_nfc_randomizer_read_buf(mtd, oob + offset, len,
1026 false, page);
Boris BREZILLON35d0e242015-09-30 23:45:26 +02001027
Boris Brezillonc4f3ef22016-03-04 18:13:10 +01001028 if (cur_off)
1029 *cur_off = mtd->oobsize + mtd->writesize;
Boris BREZILLON35d0e242015-09-30 23:45:26 +02001030}
1031
Boris Brezillon614049a2016-04-15 15:10:30 +02001032static int sunxi_nfc_hw_ecc_read_chunks_dma(struct mtd_info *mtd, uint8_t *buf,
1033 int oob_required, int page,
1034 int nchunks)
1035{
1036 struct nand_chip *nand = mtd_to_nand(mtd);
1037 bool randomized = nand->options & NAND_NEED_SCRAMBLING;
1038 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
1039 struct nand_ecc_ctrl *ecc = &nand->ecc;
1040 unsigned int max_bitflips = 0;
1041 int ret, i, raw_mode = 0;
1042 struct scatterlist sg;
1043 u32 status;
1044
1045 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
1046 if (ret)
1047 return ret;
1048
1049 ret = sunxi_nfc_dma_op_prepare(mtd, buf, ecc->size, nchunks,
1050 DMA_FROM_DEVICE, &sg);
1051 if (ret)
1052 return ret;
1053
1054 sunxi_nfc_hw_ecc_enable(mtd);
1055 sunxi_nfc_randomizer_config(mtd, page, false);
1056 sunxi_nfc_randomizer_enable(mtd);
1057
1058 writel((NAND_CMD_RNDOUTSTART << 16) | (NAND_CMD_RNDOUT << 8) |
1059 NAND_CMD_READSTART, nfc->regs + NFC_REG_RCMD_SET);
1060
1061 dma_async_issue_pending(nfc->dmac);
1062
1063 writel(NFC_PAGE_OP | NFC_DATA_SWAP_METHOD | NFC_DATA_TRANS,
1064 nfc->regs + NFC_REG_CMD);
1065
1066 ret = sunxi_nfc_wait_events(nfc, NFC_CMD_INT_FLAG, true, 0);
1067 if (ret)
1068 dmaengine_terminate_all(nfc->dmac);
1069
1070 sunxi_nfc_randomizer_disable(mtd);
1071 sunxi_nfc_hw_ecc_disable(mtd);
1072
1073 sunxi_nfc_dma_op_cleanup(mtd, DMA_FROM_DEVICE, &sg);
1074
1075 if (ret)
1076 return ret;
1077
1078 status = readl(nfc->regs + NFC_REG_ECC_ST);
1079
1080 for (i = 0; i < nchunks; i++) {
1081 int data_off = i * ecc->size;
1082 int oob_off = i * (ecc->bytes + 4);
1083 u8 *data = buf + data_off;
1084 u8 *oob = nand->oob_poi + oob_off;
1085 bool erased;
1086
1087 ret = sunxi_nfc_hw_ecc_correct(mtd, randomized ? data : NULL,
1088 oob_required ? oob : NULL,
1089 i, status, &erased);
1090
1091 /* ECC errors are handled in the second loop. */
1092 if (ret < 0)
1093 continue;
1094
1095 if (oob_required && !erased) {
1096 /* TODO: use DMA to retrieve OOB */
1097 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
1098 nand->read_buf(mtd, oob, ecc->bytes + 4);
1099
1100 sunxi_nfc_hw_ecc_get_prot_oob_bytes(mtd, oob, i,
1101 !i, page);
1102 }
1103
1104 if (erased)
1105 raw_mode = 1;
1106
1107 sunxi_nfc_hw_ecc_update_stats(mtd, &max_bitflips, ret);
1108 }
1109
1110 if (status & NFC_ECC_ERR_MSK) {
1111 for (i = 0; i < nchunks; i++) {
1112 int data_off = i * ecc->size;
1113 int oob_off = i * (ecc->bytes + 4);
1114 u8 *data = buf + data_off;
1115 u8 *oob = nand->oob_poi + oob_off;
1116
1117 if (!(status & NFC_ECC_ERR(i)))
1118 continue;
1119
1120 /*
1121 * Re-read the data with the randomizer disabled to
1122 * identify bitflips in erased pages.
1123 */
1124 if (randomized) {
1125 /* TODO: use DMA to read page in raw mode */
1126 nand->cmdfunc(mtd, NAND_CMD_RNDOUT,
1127 data_off, -1);
1128 nand->read_buf(mtd, data, ecc->size);
1129 }
1130
1131 /* TODO: use DMA to retrieve OOB */
1132 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
1133 nand->read_buf(mtd, oob, ecc->bytes + 4);
1134
1135 ret = nand_check_erased_ecc_chunk(data, ecc->size,
1136 oob, ecc->bytes + 4,
1137 NULL, 0,
1138 ecc->strength);
1139 if (ret >= 0)
1140 raw_mode = 1;
1141
1142 sunxi_nfc_hw_ecc_update_stats(mtd, &max_bitflips, ret);
1143 }
1144 }
1145
1146 if (oob_required)
1147 sunxi_nfc_hw_ecc_read_extra_oob(mtd, nand->oob_poi,
1148 NULL, !raw_mode,
1149 page);
1150
1151 return max_bitflips;
1152}
1153
Boris BREZILLON913821b2015-09-30 23:45:24 +02001154static int sunxi_nfc_hw_ecc_write_chunk(struct mtd_info *mtd,
1155 const u8 *data, int data_off,
1156 const u8 *oob, int oob_off,
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001157 int *cur_off, bool bbm,
1158 int page)
Boris BREZILLON913821b2015-09-30 23:45:24 +02001159{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +01001160 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +02001161 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
1162 struct nand_ecc_ctrl *ecc = &nand->ecc;
1163 int ret;
1164
1165 if (data_off != *cur_off)
1166 nand->cmdfunc(mtd, NAND_CMD_RNDIN, data_off, -1);
1167
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001168 sunxi_nfc_randomizer_write_buf(mtd, data, ecc->size, false, page);
Boris BREZILLON913821b2015-09-30 23:45:24 +02001169
Boris BREZILLON74eb9ff2015-10-20 22:16:00 +02001170 if (data_off + ecc->size != oob_off)
Boris BREZILLON913821b2015-09-30 23:45:24 +02001171 nand->cmdfunc(mtd, NAND_CMD_RNDIN, oob_off, -1);
1172
1173 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
1174 if (ret)
1175 return ret;
1176
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001177 sunxi_nfc_randomizer_enable(mtd);
Boris Brezilloncc6822f2016-03-04 17:56:47 +01001178 sunxi_nfc_hw_ecc_set_prot_oob_bytes(mtd, oob, 0, bbm, page);
1179
Boris BREZILLON913821b2015-09-30 23:45:24 +02001180 writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD |
1181 NFC_ACCESS_DIR | NFC_ECC_OP,
1182 nfc->regs + NFC_REG_CMD);
1183
Boris Brezillonc0c9dfa2016-03-07 15:34:39 +01001184 ret = sunxi_nfc_wait_events(nfc, NFC_CMD_INT_FLAG, true, 0);
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001185 sunxi_nfc_randomizer_disable(mtd);
Boris BREZILLON913821b2015-09-30 23:45:24 +02001186 if (ret)
1187 return ret;
1188
1189 *cur_off = oob_off + ecc->bytes + 4;
1190
1191 return 0;
1192}
1193
Boris BREZILLON35d0e242015-09-30 23:45:26 +02001194static void sunxi_nfc_hw_ecc_write_extra_oob(struct mtd_info *mtd,
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001195 u8 *oob, int *cur_off,
1196 int page)
Boris BREZILLON35d0e242015-09-30 23:45:26 +02001197{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +01001198 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON35d0e242015-09-30 23:45:26 +02001199 struct nand_ecc_ctrl *ecc = &nand->ecc;
1200 int offset = ((ecc->bytes + 4) * ecc->steps);
1201 int len = mtd->oobsize - offset;
1202
1203 if (len <= 0)
1204 return;
1205
Boris Brezillonc4f3ef22016-03-04 18:13:10 +01001206 if (!cur_off || *cur_off != offset)
Boris BREZILLON35d0e242015-09-30 23:45:26 +02001207 nand->cmdfunc(mtd, NAND_CMD_RNDIN,
1208 offset + mtd->writesize, -1);
1209
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001210 sunxi_nfc_randomizer_write_buf(mtd, oob + offset, len, false, page);
Boris BREZILLON35d0e242015-09-30 23:45:26 +02001211
Boris Brezillonc4f3ef22016-03-04 18:13:10 +01001212 if (cur_off)
1213 *cur_off = mtd->oobsize + mtd->writesize;
Boris BREZILLON35d0e242015-09-30 23:45:26 +02001214}
1215
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001216static int sunxi_nfc_hw_ecc_read_page(struct mtd_info *mtd,
1217 struct nand_chip *chip, uint8_t *buf,
1218 int oob_required, int page)
1219{
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001220 struct nand_ecc_ctrl *ecc = &chip->ecc;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001221 unsigned int max_bitflips = 0;
Boris BREZILLONb4625512015-09-30 23:45:25 +02001222 int ret, i, cur_off = 0;
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001223 bool raw_mode = false;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001224
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001225 sunxi_nfc_hw_ecc_enable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001226
1227 for (i = 0; i < ecc->steps; i++) {
Boris BREZILLONb4625512015-09-30 23:45:25 +02001228 int data_off = i * ecc->size;
1229 int oob_off = i * (ecc->bytes + 4);
1230 u8 *data = buf + data_off;
1231 u8 *oob = chip->oob_poi + oob_off;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001232
Boris BREZILLONb4625512015-09-30 23:45:25 +02001233 ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off, oob,
1234 oob_off + mtd->writesize,
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001235 &cur_off, &max_bitflips,
Boris Brezillon828dec12016-03-04 18:09:21 +01001236 !i, oob_required, page);
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001237 if (ret < 0)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001238 return ret;
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001239 else if (ret)
1240 raw_mode = true;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001241 }
1242
Boris BREZILLON35d0e242015-09-30 23:45:26 +02001243 if (oob_required)
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001244 sunxi_nfc_hw_ecc_read_extra_oob(mtd, chip->oob_poi, &cur_off,
1245 !raw_mode, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001246
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001247 sunxi_nfc_hw_ecc_disable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001248
1249 return max_bitflips;
1250}
1251
Boris Brezillon614049a2016-04-15 15:10:30 +02001252static int sunxi_nfc_hw_ecc_read_page_dma(struct mtd_info *mtd,
1253 struct nand_chip *chip, u8 *buf,
1254 int oob_required, int page)
1255{
1256 int ret;
1257
1258 ret = sunxi_nfc_hw_ecc_read_chunks_dma(mtd, buf, oob_required, page,
1259 chip->ecc.steps);
1260 if (ret >= 0)
1261 return ret;
1262
1263 /* Fallback to PIO mode */
1264 chip->cmdfunc(mtd, NAND_CMD_RNDOUT, 0, -1);
1265
1266 return sunxi_nfc_hw_ecc_read_page(mtd, chip, buf, oob_required, page);
1267}
1268
Boris Brezillonfe82cce2015-09-16 09:01:45 +02001269static int sunxi_nfc_hw_ecc_read_subpage(struct mtd_info *mtd,
1270 struct nand_chip *chip,
1271 u32 data_offs, u32 readlen,
1272 u8 *bufpoi, int page)
1273{
1274 struct nand_ecc_ctrl *ecc = &chip->ecc;
1275 int ret, i, cur_off = 0;
1276 unsigned int max_bitflips = 0;
1277
1278 sunxi_nfc_hw_ecc_enable(mtd);
1279
1280 chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
1281 for (i = data_offs / ecc->size;
1282 i < DIV_ROUND_UP(data_offs + readlen, ecc->size); i++) {
1283 int data_off = i * ecc->size;
1284 int oob_off = i * (ecc->bytes + 4);
1285 u8 *data = bufpoi + data_off;
1286 u8 *oob = chip->oob_poi + oob_off;
1287
1288 ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off,
1289 oob,
1290 oob_off + mtd->writesize,
Boris Brezillon828dec12016-03-04 18:09:21 +01001291 &cur_off, &max_bitflips, !i,
1292 false, page);
Boris Brezillonfe82cce2015-09-16 09:01:45 +02001293 if (ret < 0)
1294 return ret;
1295 }
1296
1297 sunxi_nfc_hw_ecc_disable(mtd);
1298
1299 return max_bitflips;
1300}
1301
Boris Brezillon614049a2016-04-15 15:10:30 +02001302static int sunxi_nfc_hw_ecc_read_subpage_dma(struct mtd_info *mtd,
1303 struct nand_chip *chip,
1304 u32 data_offs, u32 readlen,
1305 u8 *buf, int page)
1306{
1307 int nchunks = DIV_ROUND_UP(data_offs + readlen, chip->ecc.size);
1308 int ret;
1309
1310 ret = sunxi_nfc_hw_ecc_read_chunks_dma(mtd, buf, false, page, nchunks);
1311 if (ret >= 0)
1312 return ret;
1313
1314 /* Fallback to PIO mode */
1315 chip->cmdfunc(mtd, NAND_CMD_RNDOUT, 0, -1);
1316
1317 return sunxi_nfc_hw_ecc_read_subpage(mtd, chip, data_offs, readlen,
1318 buf, page);
1319}
1320
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001321static int sunxi_nfc_hw_ecc_write_page(struct mtd_info *mtd,
1322 struct nand_chip *chip,
Boris BREZILLON45aaeff2015-10-13 11:22:18 +02001323 const uint8_t *buf, int oob_required,
1324 int page)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001325{
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001326 struct nand_ecc_ctrl *ecc = &chip->ecc;
Boris BREZILLONb4625512015-09-30 23:45:25 +02001327 int ret, i, cur_off = 0;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001328
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001329 sunxi_nfc_hw_ecc_enable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001330
1331 for (i = 0; i < ecc->steps; i++) {
Boris BREZILLONb4625512015-09-30 23:45:25 +02001332 int data_off = i * ecc->size;
1333 int oob_off = i * (ecc->bytes + 4);
1334 const u8 *data = buf + data_off;
1335 const u8 *oob = chip->oob_poi + oob_off;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001336
Boris BREZILLONb4625512015-09-30 23:45:25 +02001337 ret = sunxi_nfc_hw_ecc_write_chunk(mtd, data, data_off, oob,
1338 oob_off + mtd->writesize,
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001339 &cur_off, !i, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001340 if (ret)
1341 return ret;
1342 }
1343
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001344 if (oob_required || (chip->options & NAND_NEED_SCRAMBLING))
1345 sunxi_nfc_hw_ecc_write_extra_oob(mtd, chip->oob_poi,
1346 &cur_off, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001347
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001348 sunxi_nfc_hw_ecc_disable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001349
1350 return 0;
1351}
1352
Boris Brezillon614049a2016-04-15 15:10:30 +02001353static int sunxi_nfc_hw_ecc_write_page_dma(struct mtd_info *mtd,
1354 struct nand_chip *chip,
1355 const u8 *buf,
1356 int oob_required,
1357 int page)
1358{
1359 struct nand_chip *nand = mtd_to_nand(mtd);
1360 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
1361 struct nand_ecc_ctrl *ecc = &nand->ecc;
1362 struct scatterlist sg;
1363 int ret, i;
1364
1365 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
1366 if (ret)
1367 return ret;
1368
1369 ret = sunxi_nfc_dma_op_prepare(mtd, buf, ecc->size, ecc->steps,
1370 DMA_TO_DEVICE, &sg);
1371 if (ret)
1372 goto pio_fallback;
1373
1374 for (i = 0; i < ecc->steps; i++) {
1375 const u8 *oob = nand->oob_poi + (i * (ecc->bytes + 4));
1376
1377 sunxi_nfc_hw_ecc_set_prot_oob_bytes(mtd, oob, i, !i, page);
1378 }
1379
1380 sunxi_nfc_hw_ecc_enable(mtd);
1381 sunxi_nfc_randomizer_config(mtd, page, false);
1382 sunxi_nfc_randomizer_enable(mtd);
1383
1384 writel((NAND_CMD_RNDIN << 8) | NAND_CMD_PAGEPROG,
1385 nfc->regs + NFC_REG_RCMD_SET);
1386
1387 dma_async_issue_pending(nfc->dmac);
1388
1389 writel(NFC_PAGE_OP | NFC_DATA_SWAP_METHOD |
1390 NFC_DATA_TRANS | NFC_ACCESS_DIR,
1391 nfc->regs + NFC_REG_CMD);
1392
1393 ret = sunxi_nfc_wait_events(nfc, NFC_CMD_INT_FLAG, true, 0);
1394 if (ret)
1395 dmaengine_terminate_all(nfc->dmac);
1396
1397 sunxi_nfc_randomizer_disable(mtd);
1398 sunxi_nfc_hw_ecc_disable(mtd);
1399
1400 sunxi_nfc_dma_op_cleanup(mtd, DMA_TO_DEVICE, &sg);
1401
1402 if (ret)
1403 return ret;
1404
1405 if (oob_required || (chip->options & NAND_NEED_SCRAMBLING))
1406 /* TODO: use DMA to transfer extra OOB bytes ? */
1407 sunxi_nfc_hw_ecc_write_extra_oob(mtd, chip->oob_poi,
1408 NULL, page);
1409
1410 return 0;
1411
1412pio_fallback:
1413 return sunxi_nfc_hw_ecc_write_page(mtd, chip, buf, oob_required, page);
1414}
1415
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001416static int sunxi_nfc_hw_syndrome_ecc_read_page(struct mtd_info *mtd,
1417 struct nand_chip *chip,
1418 uint8_t *buf, int oob_required,
1419 int page)
1420{
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001421 struct nand_ecc_ctrl *ecc = &chip->ecc;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001422 unsigned int max_bitflips = 0;
Boris BREZILLONb4625512015-09-30 23:45:25 +02001423 int ret, i, cur_off = 0;
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001424 bool raw_mode = false;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001425
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001426 sunxi_nfc_hw_ecc_enable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001427
1428 for (i = 0; i < ecc->steps; i++) {
Boris BREZILLONb4625512015-09-30 23:45:25 +02001429 int data_off = i * (ecc->size + ecc->bytes + 4);
1430 int oob_off = data_off + ecc->size;
1431 u8 *data = buf + (i * ecc->size);
1432 u8 *oob = chip->oob_poi + (i * (ecc->bytes + 4));
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001433
Boris BREZILLONb4625512015-09-30 23:45:25 +02001434 ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off, oob,
1435 oob_off, &cur_off,
Boris Brezillon828dec12016-03-04 18:09:21 +01001436 &max_bitflips, !i,
1437 oob_required,
1438 page);
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001439 if (ret < 0)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001440 return ret;
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001441 else if (ret)
1442 raw_mode = true;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001443 }
1444
Boris BREZILLON35d0e242015-09-30 23:45:26 +02001445 if (oob_required)
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001446 sunxi_nfc_hw_ecc_read_extra_oob(mtd, chip->oob_poi, &cur_off,
1447 !raw_mode, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001448
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001449 sunxi_nfc_hw_ecc_disable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001450
1451 return max_bitflips;
1452}
1453
1454static int sunxi_nfc_hw_syndrome_ecc_write_page(struct mtd_info *mtd,
1455 struct nand_chip *chip,
1456 const uint8_t *buf,
Boris BREZILLON45aaeff2015-10-13 11:22:18 +02001457 int oob_required, int page)
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001458{
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001459 struct nand_ecc_ctrl *ecc = &chip->ecc;
Boris BREZILLONb4625512015-09-30 23:45:25 +02001460 int ret, i, cur_off = 0;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001461
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001462 sunxi_nfc_hw_ecc_enable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001463
1464 for (i = 0; i < ecc->steps; i++) {
Boris BREZILLONb4625512015-09-30 23:45:25 +02001465 int data_off = i * (ecc->size + ecc->bytes + 4);
1466 int oob_off = data_off + ecc->size;
1467 const u8 *data = buf + (i * ecc->size);
1468 const u8 *oob = chip->oob_poi + (i * (ecc->bytes + 4));
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001469
Boris BREZILLONb4625512015-09-30 23:45:25 +02001470 ret = sunxi_nfc_hw_ecc_write_chunk(mtd, data, data_off,
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001471 oob, oob_off, &cur_off,
1472 false, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001473 if (ret)
1474 return ret;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001475 }
1476
Boris BREZILLON4be4e032015-12-02 12:01:07 +01001477 if (oob_required || (chip->options & NAND_NEED_SCRAMBLING))
1478 sunxi_nfc_hw_ecc_write_extra_oob(mtd, chip->oob_poi,
1479 &cur_off, page);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001480
Boris BREZILLONc9118ec2015-09-30 23:45:23 +02001481 sunxi_nfc_hw_ecc_disable(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001482
1483 return 0;
1484}
1485
Boris Brezillon1c1bdd62015-09-02 15:05:52 +02001486static int sunxi_nfc_hw_common_ecc_read_oob(struct mtd_info *mtd,
1487 struct nand_chip *chip,
1488 int page)
1489{
1490 chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
1491
1492 chip->pagebuf = -1;
1493
1494 return chip->ecc.read_page(mtd, chip, chip->buffers->databuf, 1, page);
1495}
1496
1497static int sunxi_nfc_hw_common_ecc_write_oob(struct mtd_info *mtd,
1498 struct nand_chip *chip,
1499 int page)
1500{
1501 int ret, status;
1502
1503 chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0, page);
1504
1505 chip->pagebuf = -1;
1506
1507 memset(chip->buffers->databuf, 0xff, mtd->writesize);
1508 ret = chip->ecc.write_page(mtd, chip, chip->buffers->databuf, 1, page);
1509 if (ret)
1510 return ret;
1511
1512 /* Send command to program the OOB data */
1513 chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
1514
1515 status = chip->waitfunc(mtd, chip);
1516
1517 return status & NAND_STATUS_FAIL ? -EIO : 0;
1518}
1519
Roy Spliet9c618292015-06-26 11:00:10 +02001520static const s32 tWB_lut[] = {6, 12, 16, 20};
1521static const s32 tRHW_lut[] = {4, 8, 12, 20};
1522
1523static int _sunxi_nand_lookup_timing(const s32 *lut, int lut_size, u32 duration,
1524 u32 clk_period)
1525{
1526 u32 clk_cycles = DIV_ROUND_UP(duration, clk_period);
1527 int i;
1528
1529 for (i = 0; i < lut_size; i++) {
1530 if (clk_cycles <= lut[i])
1531 return i;
1532 }
1533
1534 /* Doesn't fit */
1535 return -EINVAL;
1536}
1537
1538#define sunxi_nand_lookup_timing(l, p, c) \
1539 _sunxi_nand_lookup_timing(l, ARRAY_SIZE(l), p, c)
1540
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001541static int sunxi_nand_chip_set_timings(struct sunxi_nand_chip *chip,
1542 const struct nand_sdr_timings *timings)
1543{
Roy Spliet9c618292015-06-26 11:00:10 +02001544 struct sunxi_nfc *nfc = to_sunxi_nfc(chip->nand.controller);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001545 u32 min_clk_period = 0;
Roy Spliet9c618292015-06-26 11:00:10 +02001546 s32 tWB, tADL, tWHR, tRHW, tCAD;
Boris Brezillon2d434572015-12-02 15:57:20 +01001547 long real_clk_rate;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001548
1549 /* T1 <=> tCLS */
1550 if (timings->tCLS_min > min_clk_period)
1551 min_clk_period = timings->tCLS_min;
1552
1553 /* T2 <=> tCLH */
1554 if (timings->tCLH_min > min_clk_period)
1555 min_clk_period = timings->tCLH_min;
1556
1557 /* T3 <=> tCS */
1558 if (timings->tCS_min > min_clk_period)
1559 min_clk_period = timings->tCS_min;
1560
1561 /* T4 <=> tCH */
1562 if (timings->tCH_min > min_clk_period)
1563 min_clk_period = timings->tCH_min;
1564
1565 /* T5 <=> tWP */
1566 if (timings->tWP_min > min_clk_period)
1567 min_clk_period = timings->tWP_min;
1568
1569 /* T6 <=> tWH */
1570 if (timings->tWH_min > min_clk_period)
1571 min_clk_period = timings->tWH_min;
1572
1573 /* T7 <=> tALS */
1574 if (timings->tALS_min > min_clk_period)
1575 min_clk_period = timings->tALS_min;
1576
1577 /* T8 <=> tDS */
1578 if (timings->tDS_min > min_clk_period)
1579 min_clk_period = timings->tDS_min;
1580
1581 /* T9 <=> tDH */
1582 if (timings->tDH_min > min_clk_period)
1583 min_clk_period = timings->tDH_min;
1584
1585 /* T10 <=> tRR */
1586 if (timings->tRR_min > (min_clk_period * 3))
1587 min_clk_period = DIV_ROUND_UP(timings->tRR_min, 3);
1588
1589 /* T11 <=> tALH */
1590 if (timings->tALH_min > min_clk_period)
1591 min_clk_period = timings->tALH_min;
1592
1593 /* T12 <=> tRP */
1594 if (timings->tRP_min > min_clk_period)
1595 min_clk_period = timings->tRP_min;
1596
1597 /* T13 <=> tREH */
1598 if (timings->tREH_min > min_clk_period)
1599 min_clk_period = timings->tREH_min;
1600
1601 /* T14 <=> tRC */
1602 if (timings->tRC_min > (min_clk_period * 2))
1603 min_clk_period = DIV_ROUND_UP(timings->tRC_min, 2);
1604
1605 /* T15 <=> tWC */
1606 if (timings->tWC_min > (min_clk_period * 2))
1607 min_clk_period = DIV_ROUND_UP(timings->tWC_min, 2);
1608
Roy Spliet9c618292015-06-26 11:00:10 +02001609 /* T16 - T19 + tCAD */
Boris Brezillon5abcd952015-11-11 22:30:30 +01001610 if (timings->tWB_max > (min_clk_period * 20))
1611 min_clk_period = DIV_ROUND_UP(timings->tWB_max, 20);
1612
1613 if (timings->tADL_min > (min_clk_period * 32))
1614 min_clk_period = DIV_ROUND_UP(timings->tADL_min, 32);
1615
1616 if (timings->tWHR_min > (min_clk_period * 32))
1617 min_clk_period = DIV_ROUND_UP(timings->tWHR_min, 32);
1618
1619 if (timings->tRHW_min > (min_clk_period * 20))
1620 min_clk_period = DIV_ROUND_UP(timings->tRHW_min, 20);
1621
Roy Spliet9c618292015-06-26 11:00:10 +02001622 tWB = sunxi_nand_lookup_timing(tWB_lut, timings->tWB_max,
1623 min_clk_period);
1624 if (tWB < 0) {
1625 dev_err(nfc->dev, "unsupported tWB\n");
1626 return tWB;
1627 }
1628
1629 tADL = DIV_ROUND_UP(timings->tADL_min, min_clk_period) >> 3;
1630 if (tADL > 3) {
1631 dev_err(nfc->dev, "unsupported tADL\n");
1632 return -EINVAL;
1633 }
1634
1635 tWHR = DIV_ROUND_UP(timings->tWHR_min, min_clk_period) >> 3;
1636 if (tWHR > 3) {
1637 dev_err(nfc->dev, "unsupported tWHR\n");
1638 return -EINVAL;
1639 }
1640
1641 tRHW = sunxi_nand_lookup_timing(tRHW_lut, timings->tRHW_min,
1642 min_clk_period);
1643 if (tRHW < 0) {
1644 dev_err(nfc->dev, "unsupported tRHW\n");
1645 return tRHW;
1646 }
1647
1648 /*
1649 * TODO: according to ONFI specs this value only applies for DDR NAND,
1650 * but Allwinner seems to set this to 0x7. Mimic them for now.
1651 */
1652 tCAD = 0x7;
1653
1654 /* TODO: A83 has some more bits for CDQSS, CS, CLHZ, CCS, WC */
1655 chip->timing_cfg = NFC_TIMING_CFG(tWB, tADL, tWHR, tRHW, tCAD);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001656
1657 /* Convert min_clk_period from picoseconds to nanoseconds */
1658 min_clk_period = DIV_ROUND_UP(min_clk_period, 1000);
1659
1660 /*
Boris Brezillon2f9992e2015-12-02 15:10:40 +01001661 * Unlike what is stated in Allwinner datasheet, the clk_rate should
1662 * be set to (1 / min_clk_period), and not (2 / min_clk_period).
1663 * This new formula was verified with a scope and validated by
1664 * Allwinner engineers.
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001665 */
Boris Brezillon2f9992e2015-12-02 15:10:40 +01001666 chip->clk_rate = NSEC_PER_SEC / min_clk_period;
Boris Brezillon2d434572015-12-02 15:57:20 +01001667 real_clk_rate = clk_round_rate(nfc->mod_clk, chip->clk_rate);
1668
1669 /*
1670 * ONFI specification 3.1, paragraph 4.15.2 dictates that EDO data
1671 * output cycle timings shall be used if the host drives tRC less than
1672 * 30 ns.
1673 */
1674 min_clk_period = NSEC_PER_SEC / real_clk_rate;
1675 chip->timing_ctl = ((min_clk_period * 2) < 30) ?
1676 NFC_TIMING_CTL_EDO : 0;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001677
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001678 return 0;
1679}
1680
1681static int sunxi_nand_chip_init_timings(struct sunxi_nand_chip *chip,
1682 struct device_node *np)
1683{
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001684 struct mtd_info *mtd = nand_to_mtd(&chip->nand);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001685 const struct nand_sdr_timings *timings;
1686 int ret;
1687 int mode;
1688
1689 mode = onfi_get_async_timing_mode(&chip->nand);
1690 if (mode == ONFI_TIMING_MODE_UNKNOWN) {
1691 mode = chip->nand.onfi_timing_mode_default;
1692 } else {
1693 uint8_t feature[ONFI_SUBFEATURE_PARAM_LEN] = {};
Stefan Roese7eadd472015-08-28 14:45:21 +02001694 int i;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001695
1696 mode = fls(mode) - 1;
1697 if (mode < 0)
1698 mode = 0;
1699
1700 feature[0] = mode;
Stefan Roese7eadd472015-08-28 14:45:21 +02001701 for (i = 0; i < chip->nsels; i++) {
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001702 chip->nand.select_chip(mtd, i);
1703 ret = chip->nand.onfi_set_features(mtd, &chip->nand,
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001704 ONFI_FEATURE_ADDR_TIMING_MODE,
1705 feature);
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01001706 chip->nand.select_chip(mtd, -1);
Stefan Roese7eadd472015-08-28 14:45:21 +02001707 if (ret)
1708 return ret;
1709 }
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001710 }
1711
1712 timings = onfi_async_timing_mode_to_sdr_timings(mode);
1713 if (IS_ERR(timings))
1714 return PTR_ERR(timings);
1715
1716 return sunxi_nand_chip_set_timings(chip, timings);
1717}
1718
Boris Brezillonc66811e2016-02-03 20:05:13 +01001719static int sunxi_nand_ooblayout_ecc(struct mtd_info *mtd, int section,
1720 struct mtd_oob_region *oobregion)
1721{
1722 struct nand_chip *nand = mtd_to_nand(mtd);
1723 struct nand_ecc_ctrl *ecc = &nand->ecc;
1724
1725 if (section >= ecc->steps)
1726 return -ERANGE;
1727
1728 oobregion->offset = section * (ecc->bytes + 4) + 4;
1729 oobregion->length = ecc->bytes;
1730
1731 return 0;
1732}
1733
1734static int sunxi_nand_ooblayout_free(struct mtd_info *mtd, int section,
1735 struct mtd_oob_region *oobregion)
1736{
1737 struct nand_chip *nand = mtd_to_nand(mtd);
1738 struct nand_ecc_ctrl *ecc = &nand->ecc;
1739
1740 if (section > ecc->steps)
1741 return -ERANGE;
1742
1743 /*
1744 * The first 2 bytes are used for BB markers, hence we
1745 * only have 2 bytes available in the first user data
1746 * section.
1747 */
1748 if (!section && ecc->mode == NAND_ECC_HW) {
1749 oobregion->offset = 2;
1750 oobregion->length = 2;
1751
1752 return 0;
1753 }
1754
1755 oobregion->offset = section * (ecc->bytes + 4);
1756
1757 if (section < ecc->steps)
1758 oobregion->length = 4;
1759 else
1760 oobregion->offset = mtd->oobsize - oobregion->offset;
1761
1762 return 0;
1763}
1764
1765static const struct mtd_ooblayout_ops sunxi_nand_ooblayout_ops = {
1766 .ecc = sunxi_nand_ooblayout_ecc,
1767 .free = sunxi_nand_ooblayout_free,
1768};
1769
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001770static int sunxi_nand_hw_common_ecc_ctrl_init(struct mtd_info *mtd,
1771 struct nand_ecc_ctrl *ecc,
1772 struct device_node *np)
1773{
1774 static const u8 strengths[] = { 16, 24, 28, 32, 40, 48, 56, 60, 64 };
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +01001775 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001776 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
1777 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
1778 struct sunxi_nand_hw_ecc *data;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001779 int nsectors;
1780 int ret;
1781 int i;
1782
1783 data = kzalloc(sizeof(*data), GFP_KERNEL);
1784 if (!data)
1785 return -ENOMEM;
1786
1787 /* Add ECC info retrieval from DT */
1788 for (i = 0; i < ARRAY_SIZE(strengths); i++) {
1789 if (ecc->strength <= strengths[i])
1790 break;
1791 }
1792
1793 if (i >= ARRAY_SIZE(strengths)) {
1794 dev_err(nfc->dev, "unsupported strength\n");
1795 ret = -ENOTSUPP;
1796 goto err;
1797 }
1798
1799 data->mode = i;
1800
1801 /* HW ECC always request ECC bytes for 1024 bytes blocks */
1802 ecc->bytes = DIV_ROUND_UP(ecc->strength * fls(8 * 1024), 8);
1803
1804 /* HW ECC always work with even numbers of ECC bytes */
1805 ecc->bytes = ALIGN(ecc->bytes, 2);
1806
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001807 nsectors = mtd->writesize / ecc->size;
1808
1809 if (mtd->oobsize < ((ecc->bytes + 4) * nsectors)) {
1810 ret = -EINVAL;
1811 goto err;
1812 }
1813
Boris Brezillon1c1bdd62015-09-02 15:05:52 +02001814 ecc->read_oob = sunxi_nfc_hw_common_ecc_read_oob;
1815 ecc->write_oob = sunxi_nfc_hw_common_ecc_write_oob;
Boris Brezillonc66811e2016-02-03 20:05:13 +01001816 mtd_set_ooblayout(mtd, &sunxi_nand_ooblayout_ops);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001817 ecc->priv = data;
1818
1819 return 0;
1820
1821err:
1822 kfree(data);
1823
1824 return ret;
1825}
1826
1827static void sunxi_nand_hw_common_ecc_ctrl_cleanup(struct nand_ecc_ctrl *ecc)
1828{
1829 kfree(ecc->priv);
1830}
1831
1832static int sunxi_nand_hw_ecc_ctrl_init(struct mtd_info *mtd,
1833 struct nand_ecc_ctrl *ecc,
1834 struct device_node *np)
1835{
Boris Brezillon614049a2016-04-15 15:10:30 +02001836 struct nand_chip *nand = mtd_to_nand(mtd);
1837 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
1838 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001839 int ret;
1840
1841 ret = sunxi_nand_hw_common_ecc_ctrl_init(mtd, ecc, np);
1842 if (ret)
1843 return ret;
1844
Boris Brezillon614049a2016-04-15 15:10:30 +02001845 if (nfc->dmac) {
1846 ecc->read_page = sunxi_nfc_hw_ecc_read_page_dma;
1847 ecc->read_subpage = sunxi_nfc_hw_ecc_read_subpage_dma;
1848 ecc->write_page = sunxi_nfc_hw_ecc_write_page_dma;
1849 nand->options |= NAND_USE_BOUNCE_BUFFER;
1850 } else {
1851 ecc->read_page = sunxi_nfc_hw_ecc_read_page;
1852 ecc->read_subpage = sunxi_nfc_hw_ecc_read_subpage;
1853 ecc->write_page = sunxi_nfc_hw_ecc_write_page;
1854 }
1855
1856 /* TODO: support DMA for raw accesses */
Boris Brezillon1c1bdd62015-09-02 15:05:52 +02001857 ecc->read_oob_raw = nand_read_oob_std;
1858 ecc->write_oob_raw = nand_write_oob_std;
Boris Brezillonfe82cce2015-09-16 09:01:45 +02001859 ecc->read_subpage = sunxi_nfc_hw_ecc_read_subpage;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001860
1861 return 0;
1862}
1863
1864static int sunxi_nand_hw_syndrome_ecc_ctrl_init(struct mtd_info *mtd,
1865 struct nand_ecc_ctrl *ecc,
1866 struct device_node *np)
1867{
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001868 int ret;
1869
1870 ret = sunxi_nand_hw_common_ecc_ctrl_init(mtd, ecc, np);
1871 if (ret)
1872 return ret;
1873
1874 ecc->prepad = 4;
1875 ecc->read_page = sunxi_nfc_hw_syndrome_ecc_read_page;
1876 ecc->write_page = sunxi_nfc_hw_syndrome_ecc_write_page;
Boris Brezillon1c1bdd62015-09-02 15:05:52 +02001877 ecc->read_oob_raw = nand_read_oob_syndrome;
1878 ecc->write_oob_raw = nand_write_oob_syndrome;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001879
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001880 return 0;
1881}
1882
1883static void sunxi_nand_ecc_cleanup(struct nand_ecc_ctrl *ecc)
1884{
1885 switch (ecc->mode) {
1886 case NAND_ECC_HW:
1887 case NAND_ECC_HW_SYNDROME:
1888 sunxi_nand_hw_common_ecc_ctrl_cleanup(ecc);
1889 break;
1890 case NAND_ECC_NONE:
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001891 default:
1892 break;
1893 }
1894}
1895
1896static int sunxi_nand_ecc_init(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc,
1897 struct device_node *np)
1898{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +01001899 struct nand_chip *nand = mtd_to_nand(mtd);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001900 int ret;
1901
Boris BREZILLONa3d22a52015-09-02 10:30:25 +02001902 if (!ecc->size) {
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001903 ecc->size = nand->ecc_step_ds;
1904 ecc->strength = nand->ecc_strength_ds;
1905 }
1906
1907 if (!ecc->size || !ecc->strength)
1908 return -EINVAL;
1909
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001910 switch (ecc->mode) {
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001911 case NAND_ECC_HW:
1912 ret = sunxi_nand_hw_ecc_ctrl_init(mtd, ecc, np);
1913 if (ret)
1914 return ret;
1915 break;
1916 case NAND_ECC_HW_SYNDROME:
1917 ret = sunxi_nand_hw_syndrome_ecc_ctrl_init(mtd, ecc, np);
1918 if (ret)
1919 return ret;
1920 break;
1921 case NAND_ECC_NONE:
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001922 case NAND_ECC_SOFT:
1923 break;
1924 default:
1925 return -EINVAL;
1926 }
1927
1928 return 0;
1929}
1930
1931static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc,
1932 struct device_node *np)
1933{
1934 const struct nand_sdr_timings *timings;
1935 struct sunxi_nand_chip *chip;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02001936 struct mtd_info *mtd;
1937 struct nand_chip *nand;
1938 int nsels;
1939 int ret;
1940 int i;
1941 u32 tmp;
1942
1943 if (!of_get_property(np, "reg", &nsels))
1944 return -EINVAL;
1945
1946 nsels /= sizeof(u32);
1947 if (!nsels) {
1948 dev_err(dev, "invalid reg property size\n");
1949 return -EINVAL;
1950 }
1951
1952 chip = devm_kzalloc(dev,
1953 sizeof(*chip) +
1954 (nsels * sizeof(struct sunxi_nand_chip_sel)),
1955 GFP_KERNEL);
1956 if (!chip) {
1957 dev_err(dev, "could not allocate chip\n");
1958 return -ENOMEM;
1959 }
1960
1961 chip->nsels = nsels;
1962 chip->selected = -1;
1963
1964 for (i = 0; i < nsels; i++) {
1965 ret = of_property_read_u32_index(np, "reg", i, &tmp);
1966 if (ret) {
1967 dev_err(dev, "could not retrieve reg property: %d\n",
1968 ret);
1969 return ret;
1970 }
1971
1972 if (tmp > NFC_MAX_CS) {
1973 dev_err(dev,
1974 "invalid reg value: %u (max CS = 7)\n",
1975 tmp);
1976 return -EINVAL;
1977 }
1978
1979 if (test_and_set_bit(tmp, &nfc->assigned_cs)) {
1980 dev_err(dev, "CS %d already assigned\n", tmp);
1981 return -EINVAL;
1982 }
1983
1984 chip->sels[i].cs = tmp;
1985
1986 if (!of_property_read_u32_index(np, "allwinner,rb", i, &tmp) &&
1987 tmp < 2) {
1988 chip->sels[i].rb.type = RB_NATIVE;
1989 chip->sels[i].rb.info.nativeid = tmp;
1990 } else {
1991 ret = of_get_named_gpio(np, "rb-gpios", i);
1992 if (ret >= 0) {
1993 tmp = ret;
1994 chip->sels[i].rb.type = RB_GPIO;
1995 chip->sels[i].rb.info.gpio = tmp;
1996 ret = devm_gpio_request(dev, tmp, "nand-rb");
1997 if (ret)
1998 return ret;
1999
2000 ret = gpio_direction_input(tmp);
2001 if (ret)
2002 return ret;
2003 } else {
2004 chip->sels[i].rb.type = RB_NONE;
2005 }
2006 }
2007 }
2008
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02002009 nand = &chip->nand;
2010 /* Default tR value specified in the ONFI spec (chapter 4.15.1) */
2011 nand->chip_delay = 200;
2012 nand->controller = &nfc->controller;
Boris BREZILLONa3d22a52015-09-02 10:30:25 +02002013 /*
2014 * Set the ECC mode to the default value in case nothing is specified
2015 * in the DT.
2016 */
2017 nand->ecc.mode = NAND_ECC_HW;
Brian Norris63752192015-10-30 20:33:23 -07002018 nand_set_flash_node(nand, np);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02002019 nand->select_chip = sunxi_nfc_select_chip;
2020 nand->cmd_ctrl = sunxi_nfc_cmd_ctrl;
2021 nand->read_buf = sunxi_nfc_read_buf;
2022 nand->write_buf = sunxi_nfc_write_buf;
2023 nand->read_byte = sunxi_nfc_read_byte;
2024
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01002025 mtd = nand_to_mtd(nand);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02002026 mtd->dev.parent = dev;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02002027
Boris Brezillon9edb4702015-12-02 16:00:57 +01002028 timings = onfi_async_timing_mode_to_sdr_timings(0);
2029 if (IS_ERR(timings)) {
2030 ret = PTR_ERR(timings);
2031 dev_err(dev,
2032 "could not retrieve timings for ONFI mode 0: %d\n",
2033 ret);
2034 return ret;
2035 }
2036
2037 ret = sunxi_nand_chip_set_timings(chip, timings);
2038 if (ret) {
2039 dev_err(dev, "could not configure chip timings: %d\n", ret);
2040 return ret;
2041 }
2042
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02002043 ret = nand_scan_ident(mtd, nsels, NULL);
2044 if (ret)
2045 return ret;
2046
Boris BREZILLONa3d22a52015-09-02 10:30:25 +02002047 if (nand->bbt_options & NAND_BBT_USE_FLASH)
2048 nand->bbt_options |= NAND_BBT_NO_OOB;
2049
Boris BREZILLON4be4e032015-12-02 12:01:07 +01002050 if (nand->options & NAND_NEED_SCRAMBLING)
2051 nand->options |= NAND_NO_SUBPAGE_WRITE;
2052
Boris Brezillonfe82cce2015-09-16 09:01:45 +02002053 nand->options |= NAND_SUBPAGE_READ;
2054
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02002055 ret = sunxi_nand_chip_init_timings(chip, np);
2056 if (ret) {
2057 dev_err(dev, "could not configure chip timings: %d\n", ret);
2058 return ret;
2059 }
2060
2061 ret = sunxi_nand_ecc_init(mtd, &nand->ecc, np);
2062 if (ret) {
2063 dev_err(dev, "ECC init failed: %d\n", ret);
2064 return ret;
2065 }
2066
2067 ret = nand_scan_tail(mtd);
2068 if (ret) {
2069 dev_err(dev, "nand_scan_tail failed: %d\n", ret);
2070 return ret;
2071 }
2072
Brian Norrisa61ae812015-10-30 20:33:25 -07002073 ret = mtd_device_register(mtd, NULL, 0);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02002074 if (ret) {
2075 dev_err(dev, "failed to register mtd device: %d\n", ret);
2076 nand_release(mtd);
2077 return ret;
2078 }
2079
2080 list_add_tail(&chip->node, &nfc->chips);
2081
2082 return 0;
2083}
2084
2085static int sunxi_nand_chips_init(struct device *dev, struct sunxi_nfc *nfc)
2086{
2087 struct device_node *np = dev->of_node;
2088 struct device_node *nand_np;
2089 int nchips = of_get_child_count(np);
2090 int ret;
2091
2092 if (nchips > 8) {
2093 dev_err(dev, "too many NAND chips: %d (max = 8)\n", nchips);
2094 return -EINVAL;
2095 }
2096
2097 for_each_child_of_node(np, nand_np) {
2098 ret = sunxi_nand_chip_init(dev, nfc, nand_np);
Julia Lawalla81c0f02015-11-18 23:04:12 +01002099 if (ret) {
2100 of_node_put(nand_np);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02002101 return ret;
Julia Lawalla81c0f02015-11-18 23:04:12 +01002102 }
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02002103 }
2104
2105 return 0;
2106}
2107
2108static void sunxi_nand_chips_cleanup(struct sunxi_nfc *nfc)
2109{
2110 struct sunxi_nand_chip *chip;
2111
2112 while (!list_empty(&nfc->chips)) {
2113 chip = list_first_entry(&nfc->chips, struct sunxi_nand_chip,
2114 node);
Boris BREZILLON32e9f2d2015-12-10 09:00:26 +01002115 nand_release(nand_to_mtd(&chip->nand));
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02002116 sunxi_nand_ecc_cleanup(&chip->nand.ecc);
Boris BREZILLON8e375cc2015-09-13 18:14:43 +02002117 list_del(&chip->node);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02002118 }
2119}
2120
2121static int sunxi_nfc_probe(struct platform_device *pdev)
2122{
2123 struct device *dev = &pdev->dev;
2124 struct resource *r;
2125 struct sunxi_nfc *nfc;
2126 int irq;
2127 int ret;
2128
2129 nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
2130 if (!nfc)
2131 return -ENOMEM;
2132
2133 nfc->dev = dev;
2134 spin_lock_init(&nfc->controller.lock);
2135 init_waitqueue_head(&nfc->controller.wq);
2136 INIT_LIST_HEAD(&nfc->chips);
2137
2138 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2139 nfc->regs = devm_ioremap_resource(dev, r);
2140 if (IS_ERR(nfc->regs))
2141 return PTR_ERR(nfc->regs);
2142
2143 irq = platform_get_irq(pdev, 0);
2144 if (irq < 0) {
2145 dev_err(dev, "failed to retrieve irq\n");
2146 return irq;
2147 }
2148
2149 nfc->ahb_clk = devm_clk_get(dev, "ahb");
2150 if (IS_ERR(nfc->ahb_clk)) {
2151 dev_err(dev, "failed to retrieve ahb clk\n");
2152 return PTR_ERR(nfc->ahb_clk);
2153 }
2154
2155 ret = clk_prepare_enable(nfc->ahb_clk);
2156 if (ret)
2157 return ret;
2158
2159 nfc->mod_clk = devm_clk_get(dev, "mod");
2160 if (IS_ERR(nfc->mod_clk)) {
2161 dev_err(dev, "failed to retrieve mod clk\n");
2162 ret = PTR_ERR(nfc->mod_clk);
2163 goto out_ahb_clk_unprepare;
2164 }
2165
2166 ret = clk_prepare_enable(nfc->mod_clk);
2167 if (ret)
2168 goto out_ahb_clk_unprepare;
2169
2170 ret = sunxi_nfc_rst(nfc);
2171 if (ret)
2172 goto out_mod_clk_unprepare;
2173
2174 writel(0, nfc->regs + NFC_REG_INT);
2175 ret = devm_request_irq(dev, irq, sunxi_nfc_interrupt,
2176 0, "sunxi-nand", nfc);
2177 if (ret)
2178 goto out_mod_clk_unprepare;
2179
Boris Brezillon614049a2016-04-15 15:10:30 +02002180 nfc->dmac = dma_request_slave_channel(dev, "rxtx");
2181 if (nfc->dmac) {
2182 struct dma_slave_config dmac_cfg = { };
2183
2184 dmac_cfg.src_addr = r->start + NFC_REG_IO_DATA;
2185 dmac_cfg.dst_addr = dmac_cfg.src_addr;
2186 dmac_cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
2187 dmac_cfg.dst_addr_width = dmac_cfg.src_addr_width;
2188 dmac_cfg.src_maxburst = 4;
2189 dmac_cfg.dst_maxburst = 4;
2190 dmaengine_slave_config(nfc->dmac, &dmac_cfg);
2191 } else {
2192 dev_warn(dev, "failed to request rxtx DMA channel\n");
2193 }
2194
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02002195 platform_set_drvdata(pdev, nfc);
2196
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02002197 ret = sunxi_nand_chips_init(dev, nfc);
2198 if (ret) {
2199 dev_err(dev, "failed to init nand chips\n");
Boris Brezillon614049a2016-04-15 15:10:30 +02002200 goto out_release_dmac;
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02002201 }
2202
2203 return 0;
2204
Boris Brezillon614049a2016-04-15 15:10:30 +02002205out_release_dmac:
2206 if (nfc->dmac)
2207 dma_release_channel(nfc->dmac);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02002208out_mod_clk_unprepare:
2209 clk_disable_unprepare(nfc->mod_clk);
2210out_ahb_clk_unprepare:
2211 clk_disable_unprepare(nfc->ahb_clk);
2212
2213 return ret;
2214}
2215
2216static int sunxi_nfc_remove(struct platform_device *pdev)
2217{
2218 struct sunxi_nfc *nfc = platform_get_drvdata(pdev);
2219
2220 sunxi_nand_chips_cleanup(nfc);
Boris Brezillon614049a2016-04-15 15:10:30 +02002221 if (nfc->dmac)
2222 dma_release_channel(nfc->dmac);
Boris Brezillondd26a452016-03-04 18:26:40 +01002223 clk_disable_unprepare(nfc->mod_clk);
2224 clk_disable_unprepare(nfc->ahb_clk);
Boris BREZILLON1fef62c2014-10-21 15:08:41 +02002225
2226 return 0;
2227}
2228
2229static const struct of_device_id sunxi_nfc_ids[] = {
2230 { .compatible = "allwinner,sun4i-a10-nand" },
2231 { /* sentinel */ }
2232};
2233MODULE_DEVICE_TABLE(of, sunxi_nfc_ids);
2234
2235static struct platform_driver sunxi_nfc_driver = {
2236 .driver = {
2237 .name = "sunxi_nand",
2238 .of_match_table = sunxi_nfc_ids,
2239 },
2240 .probe = sunxi_nfc_probe,
2241 .remove = sunxi_nfc_remove,
2242};
2243module_platform_driver(sunxi_nfc_driver);
2244
2245MODULE_LICENSE("GPL v2");
2246MODULE_AUTHOR("Boris BREZILLON");
2247MODULE_DESCRIPTION("Allwinner NAND Flash Controller driver");
2248MODULE_ALIAS("platform:sunxi_nand");