blob: 34197bb09a19551655160112f3215e0c9da691ac [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Boris Brezillon57f20382016-06-15 21:09:23 +02002/*
3 * Copyright (C) 2013 Boris BREZILLON <b.brezillon.dev@gmail.com>
4 * Copyright (C) 2015 Roy Spliet <r.spliet@ultimaker.com>
5 *
6 * Derived from:
7 * https://github.com/yuq/sunxi-nfc-mtd
8 * Copyright (C) 2013 Qiang Yu <yuq825@gmail.com>
9 *
10 * https://github.com/hno/Allwinner-Info
11 * Copyright (C) 2013 Henrik Nordström <Henrik Nordström>
12 *
13 * Copyright (C) 2013 Dmitriy B. <rzk333@gmail.com>
14 * Copyright (C) 2013 Sergey Lapin <slapin@ossfans.org>
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
Boris Brezillon57f20382016-06-15 21:09:23 +020025 */
26
Samuel Holland890f7de2023-01-22 16:06:35 -060027#include <clk.h>
Samuel Holland1edb8782023-01-22 16:06:34 -060028#include <dm.h>
Simon Glass9bc15642020-02-03 07:36:16 -070029#include <malloc.h>
Boris Brezillon57f20382016-06-15 21:09:23 +020030#include <memalign.h>
31#include <nand.h>
Samuel Holland890f7de2023-01-22 16:06:35 -060032#include <reset.h>
Simon Glass9bc15642020-02-03 07:36:16 -070033#include <dm/device_compat.h>
Simon Glassd66c5f72020-02-03 07:36:15 -070034#include <dm/devres.h>
Simon Glass4dcacfc2020-05-10 11:40:13 -060035#include <linux/bitops.h>
Simon Glassdbd79542020-05-10 11:40:11 -060036#include <linux/delay.h>
Simon Glassd66c5f72020-02-03 07:36:15 -070037#include <linux/err.h>
Simon Glassbdd5f812023-09-14 18:21:46 -060038#include <linux/printk.h>
Boris Brezillon57f20382016-06-15 21:09:23 +020039
40#include <linux/kernel.h>
41#include <linux/mtd/mtd.h>
Masahiro Yamada2b7a8732017-11-30 13:45:24 +090042#include <linux/mtd/rawnand.h>
Boris Brezillon57f20382016-06-15 21:09:23 +020043#include <linux/mtd/partitions.h>
44#include <linux/io.h>
45
46#include <asm/gpio.h>
47#include <asm/arch/clock.h>
48
Boris Brezillon57f20382016-06-15 21:09:23 +020049#define NFC_REG_CTL 0x0000
50#define NFC_REG_ST 0x0004
51#define NFC_REG_INT 0x0008
52#define NFC_REG_TIMING_CTL 0x000C
53#define NFC_REG_TIMING_CFG 0x0010
54#define NFC_REG_ADDR_LOW 0x0014
55#define NFC_REG_ADDR_HIGH 0x0018
56#define NFC_REG_SECTOR_NUM 0x001C
57#define NFC_REG_CNT 0x0020
58#define NFC_REG_CMD 0x0024
59#define NFC_REG_RCMD_SET 0x0028
60#define NFC_REG_WCMD_SET 0x002C
61#define NFC_REG_IO_DATA 0x0030
62#define NFC_REG_ECC_CTL 0x0034
63#define NFC_REG_ECC_ST 0x0038
64#define NFC_REG_DEBUG 0x003C
65#define NFC_REG_ECC_ERR_CNT(x) ((0x0040 + (x)) & ~0x3)
66#define NFC_REG_USER_DATA(x) (0x0050 + ((x) * 4))
67#define NFC_REG_SPARE_AREA 0x00A0
68#define NFC_REG_PAT_ID 0x00A4
69#define NFC_RAM0_BASE 0x0400
70#define NFC_RAM1_BASE 0x0800
71
72/* define bit use in NFC_CTL */
73#define NFC_EN BIT(0)
74#define NFC_RESET BIT(1)
75#define NFC_BUS_WIDTH_MSK BIT(2)
76#define NFC_BUS_WIDTH_8 (0 << 2)
77#define NFC_BUS_WIDTH_16 (1 << 2)
78#define NFC_RB_SEL_MSK BIT(3)
79#define NFC_RB_SEL(x) ((x) << 3)
80#define NFC_CE_SEL_MSK (0x7 << 24)
81#define NFC_CE_SEL(x) ((x) << 24)
82#define NFC_CE_CTL BIT(6)
83#define NFC_PAGE_SHIFT_MSK (0xf << 8)
84#define NFC_PAGE_SHIFT(x) (((x) < 10 ? 0 : (x) - 10) << 8)
85#define NFC_SAM BIT(12)
86#define NFC_RAM_METHOD BIT(14)
87#define NFC_DEBUG_CTL BIT(31)
88
89/* define bit use in NFC_ST */
90#define NFC_RB_B2R BIT(0)
91#define NFC_CMD_INT_FLAG BIT(1)
92#define NFC_DMA_INT_FLAG BIT(2)
93#define NFC_CMD_FIFO_STATUS BIT(3)
94#define NFC_STA BIT(4)
95#define NFC_NATCH_INT_FLAG BIT(5)
96#define NFC_RB_STATE(x) BIT(x + 8)
97
98/* define bit use in NFC_INT */
99#define NFC_B2R_INT_ENABLE BIT(0)
100#define NFC_CMD_INT_ENABLE BIT(1)
101#define NFC_DMA_INT_ENABLE BIT(2)
102#define NFC_INT_MASK (NFC_B2R_INT_ENABLE | \
103 NFC_CMD_INT_ENABLE | \
104 NFC_DMA_INT_ENABLE)
105
106/* define bit use in NFC_TIMING_CTL */
107#define NFC_TIMING_CTL_EDO BIT(8)
108
109/* define NFC_TIMING_CFG register layout */
110#define NFC_TIMING_CFG(tWB, tADL, tWHR, tRHW, tCAD) \
111 (((tWB) & 0x3) | (((tADL) & 0x3) << 2) | \
112 (((tWHR) & 0x3) << 4) | (((tRHW) & 0x3) << 6) | \
113 (((tCAD) & 0x7) << 8))
114
115/* define bit use in NFC_CMD */
116#define NFC_CMD_LOW_BYTE_MSK 0xff
117#define NFC_CMD_HIGH_BYTE_MSK (0xff << 8)
118#define NFC_CMD(x) (x)
119#define NFC_ADR_NUM_MSK (0x7 << 16)
120#define NFC_ADR_NUM(x) (((x) - 1) << 16)
121#define NFC_SEND_ADR BIT(19)
122#define NFC_ACCESS_DIR BIT(20)
123#define NFC_DATA_TRANS BIT(21)
124#define NFC_SEND_CMD1 BIT(22)
125#define NFC_WAIT_FLAG BIT(23)
126#define NFC_SEND_CMD2 BIT(24)
127#define NFC_SEQ BIT(25)
128#define NFC_DATA_SWAP_METHOD BIT(26)
129#define NFC_ROW_AUTO_INC BIT(27)
130#define NFC_SEND_CMD3 BIT(28)
131#define NFC_SEND_CMD4 BIT(29)
132#define NFC_CMD_TYPE_MSK (0x3 << 30)
133#define NFC_NORMAL_OP (0 << 30)
134#define NFC_ECC_OP (1 << 30)
135#define NFC_PAGE_OP (2 << 30)
136
137/* define bit use in NFC_RCMD_SET */
138#define NFC_READ_CMD_MSK 0xff
139#define NFC_RND_READ_CMD0_MSK (0xff << 8)
140#define NFC_RND_READ_CMD1_MSK (0xff << 16)
141
142/* define bit use in NFC_WCMD_SET */
143#define NFC_PROGRAM_CMD_MSK 0xff
144#define NFC_RND_WRITE_CMD_MSK (0xff << 8)
145#define NFC_READ_CMD0_MSK (0xff << 16)
146#define NFC_READ_CMD1_MSK (0xff << 24)
147
148/* define bit use in NFC_ECC_CTL */
149#define NFC_ECC_EN BIT(0)
150#define NFC_ECC_PIPELINE BIT(3)
151#define NFC_ECC_EXCEPTION BIT(4)
152#define NFC_ECC_BLOCK_SIZE_MSK BIT(5)
153#define NFC_ECC_BLOCK_512 (1 << 5)
154#define NFC_RANDOM_EN BIT(9)
155#define NFC_RANDOM_DIRECTION BIT(10)
156#define NFC_ECC_MODE_MSK (0xf << 12)
157#define NFC_ECC_MODE(x) ((x) << 12)
158#define NFC_RANDOM_SEED_MSK (0x7fff << 16)
159#define NFC_RANDOM_SEED(x) ((x) << 16)
160
161/* define bit use in NFC_ECC_ST */
162#define NFC_ECC_ERR(x) BIT(x)
163#define NFC_ECC_PAT_FOUND(x) BIT(x + 16)
164#define NFC_ECC_ERR_CNT(b, x) (((x) >> ((b) * 8)) & 0xff)
165
166#define NFC_DEFAULT_TIMEOUT_MS 1000
167
168#define NFC_SRAM_SIZE 1024
169
170#define NFC_MAX_CS 7
171
172/*
173 * Ready/Busy detection type: describes the Ready/Busy detection modes
174 *
175 * @RB_NONE: no external detection available, rely on STATUS command
176 * and software timeouts
177 * @RB_NATIVE: use sunxi NAND controller Ready/Busy support. The Ready/Busy
178 * pin of the NAND flash chip must be connected to one of the
179 * native NAND R/B pins (those which can be muxed to the NAND
180 * Controller)
181 * @RB_GPIO: use a simple GPIO to handle Ready/Busy status. The Ready/Busy
182 * pin of the NAND flash chip must be connected to a GPIO capable
183 * pin.
184 */
185enum sunxi_nand_rb_type {
186 RB_NONE,
187 RB_NATIVE,
188 RB_GPIO,
189};
190
191/*
192 * Ready/Busy structure: stores information related to Ready/Busy detection
193 *
194 * @type: the Ready/Busy detection mode
195 * @info: information related to the R/B detection mode. Either a gpio
196 * id or a native R/B id (those supported by the NAND controller).
197 */
198struct sunxi_nand_rb {
199 enum sunxi_nand_rb_type type;
200 union {
201 struct gpio_desc gpio;
202 int nativeid;
203 } info;
204};
205
206/*
207 * Chip Select structure: stores information related to NAND Chip Select
208 *
209 * @cs: the NAND CS id used to communicate with a NAND Chip
210 * @rb: the Ready/Busy description
211 */
212struct sunxi_nand_chip_sel {
213 u8 cs;
214 struct sunxi_nand_rb rb;
215};
216
217/*
218 * sunxi HW ECC infos: stores information related to HW ECC support
219 *
220 * @mode: the sunxi ECC mode field deduced from ECC requirements
221 * @layout: the OOB layout depending on the ECC requirements and the
222 * selected ECC mode
223 */
224struct sunxi_nand_hw_ecc {
225 int mode;
226 struct nand_ecclayout layout;
227};
228
229/*
230 * NAND chip structure: stores NAND chip device related information
231 *
232 * @node: used to store NAND chips into a list
233 * @nand: base NAND chip structure
234 * @mtd: base MTD structure
235 * @clk_rate: clk_rate required for this NAND chip
236 * @timing_cfg TIMING_CFG register value for this NAND chip
237 * @selected: current active CS
238 * @nsels: number of CS lines required by the NAND chip
239 * @sels: array of CS lines descriptions
240 */
241struct sunxi_nand_chip {
242 struct list_head node;
243 struct nand_chip nand;
244 unsigned long clk_rate;
245 u32 timing_cfg;
246 u32 timing_ctl;
247 int selected;
248 int addr_cycles;
249 u32 addr[2];
250 int cmd_cycles;
251 u8 cmd[2];
252 int nsels;
253 struct sunxi_nand_chip_sel sels[0];
254};
255
256static inline struct sunxi_nand_chip *to_sunxi_nand(struct nand_chip *nand)
257{
258 return container_of(nand, struct sunxi_nand_chip, nand);
259}
260
261/*
262 * NAND Controller structure: stores sunxi NAND controller information
263 *
264 * @controller: base controller structure
Samuel Holland890f7de2023-01-22 16:06:35 -0600265 * @dev: DM device (used to print error messages)
Boris Brezillon57f20382016-06-15 21:09:23 +0200266 * @regs: NAND controller registers
267 * @ahb_clk: NAND Controller AHB clock
268 * @mod_clk: NAND Controller mod clock
269 * @assigned_cs: bitmask describing already assigned CS lines
270 * @clk_rate: NAND controller current clock rate
271 * @chips: a list containing all the NAND chips attached to
272 * this NAND controller
273 * @complete: a completion object used to wait for NAND
274 * controller events
275 */
276struct sunxi_nfc {
277 struct nand_hw_control controller;
Samuel Holland890f7de2023-01-22 16:06:35 -0600278 struct udevice *dev;
Boris Brezillon57f20382016-06-15 21:09:23 +0200279 void __iomem *regs;
280 struct clk *ahb_clk;
281 struct clk *mod_clk;
282 unsigned long assigned_cs;
283 unsigned long clk_rate;
284 struct list_head chips;
285};
286
287static inline struct sunxi_nfc *to_sunxi_nfc(struct nand_hw_control *ctrl)
288{
289 return container_of(ctrl, struct sunxi_nfc, controller);
290}
291
292static void sunxi_nfc_set_clk_rate(unsigned long hz)
293{
294 struct sunxi_ccm_reg *const ccm =
295 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
296 int div_m, div_n;
297
298 div_m = (clock_get_pll6() + hz - 1) / hz;
299 for (div_n = 0; div_n < 3 && div_m > 16; div_n++) {
300 if (div_m % 2)
301 div_m++;
302 div_m >>= 1;
303 }
304 if (div_m > 16)
305 div_m = 16;
306
307 /* config mod clock */
308 writel(CCM_NAND_CTRL_ENABLE | CCM_NAND_CTRL_PLL6 |
309 CCM_NAND_CTRL_N(div_n) | CCM_NAND_CTRL_M(div_m),
310 &ccm->nand0_clk_cfg);
311
312 /* gate on nand clock */
313 setbits_le32(&ccm->ahb_gate0, (1 << AHB_GATE_OFFSET_NAND0));
314#ifdef CONFIG_MACH_SUN9I
315 setbits_le32(&ccm->ahb_gate1, (1 << AHB_GATE_OFFSET_DMA));
316#else
317 setbits_le32(&ccm->ahb_gate0, (1 << AHB_GATE_OFFSET_DMA));
318#endif
319}
320
321static int sunxi_nfc_wait_int(struct sunxi_nfc *nfc, u32 flags,
322 unsigned int timeout_ms)
323{
324 unsigned int timeout_ticks;
325 u32 time_start, status;
326 int ret = -ETIMEDOUT;
327
328 if (!timeout_ms)
329 timeout_ms = NFC_DEFAULT_TIMEOUT_MS;
330
331 timeout_ticks = (timeout_ms * CONFIG_SYS_HZ) / 1000;
332
333 time_start = get_timer(0);
334
335 do {
336 status = readl(nfc->regs + NFC_REG_ST);
337 if ((status & flags) == flags) {
338 ret = 0;
339 break;
340 }
341
342 udelay(1);
343 } while (get_timer(time_start) < timeout_ticks);
344
345 writel(status & flags, nfc->regs + NFC_REG_ST);
346
347 return ret;
348}
349
350static int sunxi_nfc_wait_cmd_fifo_empty(struct sunxi_nfc *nfc)
351{
352 unsigned long timeout = (CONFIG_SYS_HZ *
353 NFC_DEFAULT_TIMEOUT_MS) / 1000;
354 u32 time_start;
355
356 time_start = get_timer(0);
357 do {
358 if (!(readl(nfc->regs + NFC_REG_ST) & NFC_CMD_FIFO_STATUS))
359 return 0;
360 } while (get_timer(time_start) < timeout);
361
362 dev_err(nfc->dev, "wait for empty cmd FIFO timedout\n");
363 return -ETIMEDOUT;
364}
365
366static int sunxi_nfc_rst(struct sunxi_nfc *nfc)
367{
368 unsigned long timeout = (CONFIG_SYS_HZ *
369 NFC_DEFAULT_TIMEOUT_MS) / 1000;
370 u32 time_start;
371
372 writel(0, nfc->regs + NFC_REG_ECC_CTL);
373 writel(NFC_RESET, nfc->regs + NFC_REG_CTL);
374
375 time_start = get_timer(0);
376 do {
377 if (!(readl(nfc->regs + NFC_REG_CTL) & NFC_RESET))
378 return 0;
379 } while (get_timer(time_start) < timeout);
380
381 dev_err(nfc->dev, "wait for NAND controller reset timedout\n");
382 return -ETIMEDOUT;
383}
384
385static int sunxi_nfc_dev_ready(struct mtd_info *mtd)
386{
387 struct nand_chip *nand = mtd_to_nand(mtd);
388 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
389 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
390 struct sunxi_nand_rb *rb;
391 unsigned long timeo = (sunxi_nand->nand.state == FL_ERASING ? 400 : 20);
392 int ret;
393
394 if (sunxi_nand->selected < 0)
395 return 0;
396
397 rb = &sunxi_nand->sels[sunxi_nand->selected].rb;
398
399 switch (rb->type) {
400 case RB_NATIVE:
401 ret = !!(readl(nfc->regs + NFC_REG_ST) &
402 NFC_RB_STATE(rb->info.nativeid));
403 if (ret)
404 break;
405
406 sunxi_nfc_wait_int(nfc, NFC_RB_B2R, timeo);
407 ret = !!(readl(nfc->regs + NFC_REG_ST) &
408 NFC_RB_STATE(rb->info.nativeid));
409 break;
410 case RB_GPIO:
411 ret = dm_gpio_get_value(&rb->info.gpio);
412 break;
413 case RB_NONE:
414 default:
415 ret = 0;
416 dev_err(nfc->dev, "cannot check R/B NAND status!\n");
417 break;
418 }
419
420 return ret;
421}
422
423static void sunxi_nfc_select_chip(struct mtd_info *mtd, int chip)
424{
425 struct nand_chip *nand = mtd_to_nand(mtd);
426 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
427 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
428 struct sunxi_nand_chip_sel *sel;
429 u32 ctl;
430
431 if (chip > 0 && chip >= sunxi_nand->nsels)
432 return;
433
434 if (chip == sunxi_nand->selected)
435 return;
436
437 ctl = readl(nfc->regs + NFC_REG_CTL) &
438 ~(NFC_PAGE_SHIFT_MSK | NFC_CE_SEL_MSK | NFC_RB_SEL_MSK | NFC_EN);
439
440 if (chip >= 0) {
441 sel = &sunxi_nand->sels[chip];
442
443 ctl |= NFC_CE_SEL(sel->cs) | NFC_EN |
444 NFC_PAGE_SHIFT(nand->page_shift - 10);
445 if (sel->rb.type == RB_NONE) {
446 nand->dev_ready = NULL;
447 } else {
448 nand->dev_ready = sunxi_nfc_dev_ready;
449 if (sel->rb.type == RB_NATIVE)
450 ctl |= NFC_RB_SEL(sel->rb.info.nativeid);
451 }
452
453 writel(mtd->writesize, nfc->regs + NFC_REG_SPARE_AREA);
454
455 if (nfc->clk_rate != sunxi_nand->clk_rate) {
456 sunxi_nfc_set_clk_rate(sunxi_nand->clk_rate);
457 nfc->clk_rate = sunxi_nand->clk_rate;
458 }
459 }
460
461 writel(sunxi_nand->timing_ctl, nfc->regs + NFC_REG_TIMING_CTL);
462 writel(sunxi_nand->timing_cfg, nfc->regs + NFC_REG_TIMING_CFG);
463 writel(ctl, nfc->regs + NFC_REG_CTL);
464
465 sunxi_nand->selected = chip;
466}
467
468static void sunxi_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
469{
470 struct nand_chip *nand = mtd_to_nand(mtd);
471 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
472 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
473 int ret;
474 int cnt;
475 int offs = 0;
476 u32 tmp;
477
478 while (len > offs) {
479 cnt = min(len - offs, NFC_SRAM_SIZE);
480
481 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
482 if (ret)
483 break;
484
485 writel(cnt, nfc->regs + NFC_REG_CNT);
486 tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD;
487 writel(tmp, nfc->regs + NFC_REG_CMD);
488
489 ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
490 if (ret)
491 break;
492
493 if (buf)
494 memcpy_fromio(buf + offs, nfc->regs + NFC_RAM0_BASE,
495 cnt);
496 offs += cnt;
497 }
498}
499
500static void sunxi_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf,
501 int len)
502{
503 struct nand_chip *nand = mtd_to_nand(mtd);
504 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
505 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
506 int ret;
507 int cnt;
508 int offs = 0;
509 u32 tmp;
510
511 while (len > offs) {
512 cnt = min(len - offs, NFC_SRAM_SIZE);
513
514 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
515 if (ret)
516 break;
517
518 writel(cnt, nfc->regs + NFC_REG_CNT);
519 memcpy_toio(nfc->regs + NFC_RAM0_BASE, buf + offs, cnt);
520 tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD |
521 NFC_ACCESS_DIR;
522 writel(tmp, nfc->regs + NFC_REG_CMD);
523
524 ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
525 if (ret)
526 break;
527
528 offs += cnt;
529 }
530}
531
532static uint8_t sunxi_nfc_read_byte(struct mtd_info *mtd)
533{
534 uint8_t ret;
535
536 sunxi_nfc_read_buf(mtd, &ret, 1);
537
538 return ret;
539}
540
541static void sunxi_nfc_cmd_ctrl(struct mtd_info *mtd, int dat,
542 unsigned int ctrl)
543{
544 struct nand_chip *nand = mtd_to_nand(mtd);
545 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
546 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
547 int ret;
548 u32 tmp;
549
550 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
551 if (ret)
552 return;
553
554 if (ctrl & NAND_CTRL_CHANGE) {
555 tmp = readl(nfc->regs + NFC_REG_CTL);
556 if (ctrl & NAND_NCE)
557 tmp |= NFC_CE_CTL;
558 else
559 tmp &= ~NFC_CE_CTL;
560 writel(tmp, nfc->regs + NFC_REG_CTL);
561 }
562
563 if (dat == NAND_CMD_NONE && (ctrl & NAND_NCE) &&
564 !(ctrl & (NAND_CLE | NAND_ALE))) {
565 u32 cmd = 0;
566
567 if (!sunxi_nand->addr_cycles && !sunxi_nand->cmd_cycles)
568 return;
569
570 if (sunxi_nand->cmd_cycles--)
571 cmd |= NFC_SEND_CMD1 | sunxi_nand->cmd[0];
572
573 if (sunxi_nand->cmd_cycles--) {
574 cmd |= NFC_SEND_CMD2;
575 writel(sunxi_nand->cmd[1],
576 nfc->regs + NFC_REG_RCMD_SET);
577 }
578
579 sunxi_nand->cmd_cycles = 0;
580
581 if (sunxi_nand->addr_cycles) {
582 cmd |= NFC_SEND_ADR |
583 NFC_ADR_NUM(sunxi_nand->addr_cycles);
584 writel(sunxi_nand->addr[0],
585 nfc->regs + NFC_REG_ADDR_LOW);
586 }
587
588 if (sunxi_nand->addr_cycles > 4)
589 writel(sunxi_nand->addr[1],
590 nfc->regs + NFC_REG_ADDR_HIGH);
591
592 writel(cmd, nfc->regs + NFC_REG_CMD);
593 sunxi_nand->addr[0] = 0;
594 sunxi_nand->addr[1] = 0;
595 sunxi_nand->addr_cycles = 0;
596 sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
597 }
598
599 if (ctrl & NAND_CLE) {
600 sunxi_nand->cmd[sunxi_nand->cmd_cycles++] = dat;
601 } else if (ctrl & NAND_ALE) {
602 sunxi_nand->addr[sunxi_nand->addr_cycles / 4] |=
603 dat << ((sunxi_nand->addr_cycles % 4) * 8);
604 sunxi_nand->addr_cycles++;
605 }
606}
607
608/* These seed values have been extracted from Allwinner's BSP */
609static const u16 sunxi_nfc_randomizer_page_seeds[] = {
610 0x2b75, 0x0bd0, 0x5ca3, 0x62d1, 0x1c93, 0x07e9, 0x2162, 0x3a72,
611 0x0d67, 0x67f9, 0x1be7, 0x077d, 0x032f, 0x0dac, 0x2716, 0x2436,
612 0x7922, 0x1510, 0x3860, 0x5287, 0x480f, 0x4252, 0x1789, 0x5a2d,
613 0x2a49, 0x5e10, 0x437f, 0x4b4e, 0x2f45, 0x216e, 0x5cb7, 0x7130,
614 0x2a3f, 0x60e4, 0x4dc9, 0x0ef0, 0x0f52, 0x1bb9, 0x6211, 0x7a56,
615 0x226d, 0x4ea7, 0x6f36, 0x3692, 0x38bf, 0x0c62, 0x05eb, 0x4c55,
616 0x60f4, 0x728c, 0x3b6f, 0x2037, 0x7f69, 0x0936, 0x651a, 0x4ceb,
617 0x6218, 0x79f3, 0x383f, 0x18d9, 0x4f05, 0x5c82, 0x2912, 0x6f17,
618 0x6856, 0x5938, 0x1007, 0x61ab, 0x3e7f, 0x57c2, 0x542f, 0x4f62,
619 0x7454, 0x2eac, 0x7739, 0x42d4, 0x2f90, 0x435a, 0x2e52, 0x2064,
620 0x637c, 0x66ad, 0x2c90, 0x0bad, 0x759c, 0x0029, 0x0986, 0x7126,
621 0x1ca7, 0x1605, 0x386a, 0x27f5, 0x1380, 0x6d75, 0x24c3, 0x0f8e,
622 0x2b7a, 0x1418, 0x1fd1, 0x7dc1, 0x2d8e, 0x43af, 0x2267, 0x7da3,
623 0x4e3d, 0x1338, 0x50db, 0x454d, 0x764d, 0x40a3, 0x42e6, 0x262b,
624 0x2d2e, 0x1aea, 0x2e17, 0x173d, 0x3a6e, 0x71bf, 0x25f9, 0x0a5d,
625 0x7c57, 0x0fbe, 0x46ce, 0x4939, 0x6b17, 0x37bb, 0x3e91, 0x76db,
626};
627
628/*
629 * sunxi_nfc_randomizer_ecc512_seeds and sunxi_nfc_randomizer_ecc1024_seeds
630 * have been generated using
631 * sunxi_nfc_randomizer_step(seed, (step_size * 8) + 15), which is what
632 * the randomizer engine does internally before de/scrambling OOB data.
633 *
634 * Those tables are statically defined to avoid calculating randomizer state
635 * at runtime.
636 */
637static const u16 sunxi_nfc_randomizer_ecc512_seeds[] = {
638 0x3346, 0x367f, 0x1f18, 0x769a, 0x4f64, 0x068c, 0x2ef1, 0x6b64,
639 0x28a9, 0x15d7, 0x30f8, 0x3659, 0x53db, 0x7c5f, 0x71d4, 0x4409,
640 0x26eb, 0x03cc, 0x655d, 0x47d4, 0x4daa, 0x0877, 0x712d, 0x3617,
641 0x3264, 0x49aa, 0x7f9e, 0x588e, 0x4fbc, 0x7176, 0x7f91, 0x6c6d,
642 0x4b95, 0x5fb7, 0x3844, 0x4037, 0x0184, 0x081b, 0x0ee8, 0x5b91,
643 0x293d, 0x1f71, 0x0e6f, 0x402b, 0x5122, 0x1e52, 0x22be, 0x3d2d,
644 0x75bc, 0x7c60, 0x6291, 0x1a2f, 0x61d4, 0x74aa, 0x4140, 0x29ab,
645 0x472d, 0x2852, 0x017e, 0x15e8, 0x5ec2, 0x17cf, 0x7d0f, 0x06b8,
646 0x117a, 0x6b94, 0x789b, 0x3126, 0x6ac5, 0x5be7, 0x150f, 0x51f8,
647 0x7889, 0x0aa5, 0x663d, 0x77e8, 0x0b87, 0x3dcb, 0x360d, 0x218b,
648 0x512f, 0x7dc9, 0x6a4d, 0x630a, 0x3547, 0x1dd2, 0x5aea, 0x69a5,
649 0x7bfa, 0x5e4f, 0x1519, 0x6430, 0x3a0e, 0x5eb3, 0x5425, 0x0c7a,
650 0x5540, 0x3670, 0x63c1, 0x31e9, 0x5a39, 0x2de7, 0x5979, 0x2891,
651 0x1562, 0x014b, 0x5b05, 0x2756, 0x5a34, 0x13aa, 0x6cb5, 0x2c36,
652 0x5e72, 0x1306, 0x0861, 0x15ef, 0x1ee8, 0x5a37, 0x7ac4, 0x45dd,
653 0x44c4, 0x7266, 0x2f41, 0x3ccc, 0x045e, 0x7d40, 0x7c66, 0x0fa0,
654};
655
656static const u16 sunxi_nfc_randomizer_ecc1024_seeds[] = {
657 0x2cf5, 0x35f1, 0x63a4, 0x5274, 0x2bd2, 0x778b, 0x7285, 0x32b6,
658 0x6a5c, 0x70d6, 0x757d, 0x6769, 0x5375, 0x1e81, 0x0cf3, 0x3982,
659 0x6787, 0x042a, 0x6c49, 0x1925, 0x56a8, 0x40a9, 0x063e, 0x7bd9,
660 0x4dbf, 0x55ec, 0x672e, 0x7334, 0x5185, 0x4d00, 0x232a, 0x7e07,
661 0x445d, 0x6b92, 0x528f, 0x4255, 0x53ba, 0x7d82, 0x2a2e, 0x3a4e,
662 0x75eb, 0x450c, 0x6844, 0x1b5d, 0x581a, 0x4cc6, 0x0379, 0x37b2,
663 0x419f, 0x0e92, 0x6b27, 0x5624, 0x01e3, 0x07c1, 0x44a5, 0x130c,
664 0x13e8, 0x5910, 0x0876, 0x60c5, 0x54e3, 0x5b7f, 0x2269, 0x509f,
665 0x7665, 0x36fd, 0x3e9a, 0x0579, 0x6295, 0x14ef, 0x0a81, 0x1bcc,
666 0x4b16, 0x64db, 0x0514, 0x4f07, 0x0591, 0x3576, 0x6853, 0x0d9e,
667 0x259f, 0x38b7, 0x64fb, 0x3094, 0x4693, 0x6ddd, 0x29bb, 0x0bc8,
668 0x3f47, 0x490e, 0x0c0e, 0x7933, 0x3c9e, 0x5840, 0x398d, 0x3e68,
669 0x4af1, 0x71f5, 0x57cf, 0x1121, 0x64eb, 0x3579, 0x15ac, 0x584d,
670 0x5f2a, 0x47e2, 0x6528, 0x6eac, 0x196e, 0x6b96, 0x0450, 0x0179,
671 0x609c, 0x06e1, 0x4626, 0x42c7, 0x273e, 0x486f, 0x0705, 0x1601,
672 0x145b, 0x407e, 0x062b, 0x57a5, 0x53f9, 0x5659, 0x4410, 0x3ccd,
673};
674
675static u16 sunxi_nfc_randomizer_step(u16 state, int count)
676{
677 state &= 0x7fff;
678
679 /*
680 * This loop is just a simple implementation of a Fibonacci LFSR using
681 * the x16 + x15 + 1 polynomial.
682 */
683 while (count--)
684 state = ((state >> 1) |
685 (((state ^ (state >> 1)) & 1) << 14)) & 0x7fff;
686
687 return state;
688}
689
690static u16 sunxi_nfc_randomizer_state(struct mtd_info *mtd, int page, bool ecc)
691{
692 const u16 *seeds = sunxi_nfc_randomizer_page_seeds;
693 int mod = mtd->erasesize / mtd->writesize;
694
695 if (mod > ARRAY_SIZE(sunxi_nfc_randomizer_page_seeds))
696 mod = ARRAY_SIZE(sunxi_nfc_randomizer_page_seeds);
697
698 if (ecc) {
699 if (mtd->ecc_step_size == 512)
700 seeds = sunxi_nfc_randomizer_ecc512_seeds;
701 else
702 seeds = sunxi_nfc_randomizer_ecc1024_seeds;
703 }
704
705 return seeds[page % mod];
706}
707
708static void sunxi_nfc_randomizer_config(struct mtd_info *mtd,
709 int page, bool ecc)
710{
711 struct nand_chip *nand = mtd_to_nand(mtd);
712 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
713 u32 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL);
714 u16 state;
715
716 if (!(nand->options & NAND_NEED_SCRAMBLING))
717 return;
718
719 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL);
720 state = sunxi_nfc_randomizer_state(mtd, page, ecc);
721 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_RANDOM_SEED_MSK;
722 writel(ecc_ctl | NFC_RANDOM_SEED(state), nfc->regs + NFC_REG_ECC_CTL);
723}
724
725static void sunxi_nfc_randomizer_enable(struct mtd_info *mtd)
726{
727 struct nand_chip *nand = mtd_to_nand(mtd);
728 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
729
730 if (!(nand->options & NAND_NEED_SCRAMBLING))
731 return;
732
733 writel(readl(nfc->regs + NFC_REG_ECC_CTL) | NFC_RANDOM_EN,
734 nfc->regs + NFC_REG_ECC_CTL);
735}
736
737static void sunxi_nfc_randomizer_disable(struct mtd_info *mtd)
738{
739 struct nand_chip *nand = mtd_to_nand(mtd);
740 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
741
742 if (!(nand->options & NAND_NEED_SCRAMBLING))
743 return;
744
745 writel(readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_RANDOM_EN,
746 nfc->regs + NFC_REG_ECC_CTL);
747}
748
749static void sunxi_nfc_randomize_bbm(struct mtd_info *mtd, int page, u8 *bbm)
750{
751 u16 state = sunxi_nfc_randomizer_state(mtd, page, true);
752
753 bbm[0] ^= state;
754 bbm[1] ^= sunxi_nfc_randomizer_step(state, 8);
755}
756
757static void sunxi_nfc_randomizer_write_buf(struct mtd_info *mtd,
758 const uint8_t *buf, int len,
759 bool ecc, int page)
760{
761 sunxi_nfc_randomizer_config(mtd, page, ecc);
762 sunxi_nfc_randomizer_enable(mtd);
763 sunxi_nfc_write_buf(mtd, buf, len);
764 sunxi_nfc_randomizer_disable(mtd);
765}
766
767static void sunxi_nfc_randomizer_read_buf(struct mtd_info *mtd, uint8_t *buf,
768 int len, bool ecc, int page)
769{
770 sunxi_nfc_randomizer_config(mtd, page, ecc);
771 sunxi_nfc_randomizer_enable(mtd);
772 sunxi_nfc_read_buf(mtd, buf, len);
773 sunxi_nfc_randomizer_disable(mtd);
774}
775
776static void sunxi_nfc_hw_ecc_enable(struct mtd_info *mtd)
777{
778 struct nand_chip *nand = mtd_to_nand(mtd);
779 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
780 struct sunxi_nand_hw_ecc *data = nand->ecc.priv;
781 u32 ecc_ctl;
782
783 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL);
784 ecc_ctl &= ~(NFC_ECC_MODE_MSK | NFC_ECC_PIPELINE |
785 NFC_ECC_BLOCK_SIZE_MSK);
786 ecc_ctl |= NFC_ECC_EN | NFC_ECC_MODE(data->mode) | NFC_ECC_EXCEPTION;
787
788 if (nand->ecc.size == 512)
789 ecc_ctl |= NFC_ECC_BLOCK_512;
790
791 writel(ecc_ctl, nfc->regs + NFC_REG_ECC_CTL);
792}
793
794static void sunxi_nfc_hw_ecc_disable(struct mtd_info *mtd)
795{
796 struct nand_chip *nand = mtd_to_nand(mtd);
797 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
798
799 writel(readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_ECC_EN,
800 nfc->regs + NFC_REG_ECC_CTL);
801}
802
803static inline void sunxi_nfc_user_data_to_buf(u32 user_data, u8 *buf)
804{
805 buf[0] = user_data;
806 buf[1] = user_data >> 8;
807 buf[2] = user_data >> 16;
808 buf[3] = user_data >> 24;
809}
810
811static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd,
812 u8 *data, int data_off,
813 u8 *oob, int oob_off,
814 int *cur_off,
815 unsigned int *max_bitflips,
816 bool bbm, int page)
817{
818 struct nand_chip *nand = mtd_to_nand(mtd);
819 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
820 struct nand_ecc_ctrl *ecc = &nand->ecc;
821 int raw_mode = 0;
822 u32 status;
823 int ret;
824
825 if (*cur_off != data_off)
826 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, data_off, -1);
827
828 sunxi_nfc_randomizer_read_buf(mtd, NULL, ecc->size, false, page);
829
830 if (data_off + ecc->size != oob_off)
831 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
832
833 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
834 if (ret)
835 return ret;
836
837 sunxi_nfc_randomizer_enable(mtd);
838 writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_ECC_OP,
839 nfc->regs + NFC_REG_CMD);
840
841 ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
842 sunxi_nfc_randomizer_disable(mtd);
843 if (ret)
844 return ret;
845
846 *cur_off = oob_off + ecc->bytes + 4;
847
848 status = readl(nfc->regs + NFC_REG_ECC_ST);
849 if (status & NFC_ECC_PAT_FOUND(0)) {
850 u8 pattern = 0xff;
851
852 if (unlikely(!(readl(nfc->regs + NFC_REG_PAT_ID) & 0x1)))
853 pattern = 0x0;
854
855 memset(data, pattern, ecc->size);
856 memset(oob, pattern, ecc->bytes + 4);
857
858 return 1;
859 }
860
861 ret = NFC_ECC_ERR_CNT(0, readl(nfc->regs + NFC_REG_ECC_ERR_CNT(0)));
862
863 memcpy_fromio(data, nfc->regs + NFC_RAM0_BASE, ecc->size);
864
865 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
866 sunxi_nfc_randomizer_read_buf(mtd, oob, ecc->bytes + 4, true, page);
867
868 if (status & NFC_ECC_ERR(0)) {
869 /*
870 * Re-read the data with the randomizer disabled to identify
871 * bitflips in erased pages.
872 */
873 if (nand->options & NAND_NEED_SCRAMBLING) {
874 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, data_off, -1);
875 nand->read_buf(mtd, data, ecc->size);
876 nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
877 nand->read_buf(mtd, oob, ecc->bytes + 4);
878 }
879
880 ret = nand_check_erased_ecc_chunk(data, ecc->size,
881 oob, ecc->bytes + 4,
882 NULL, 0, ecc->strength);
883 if (ret >= 0)
884 raw_mode = 1;
885 } else {
886 /*
887 * The engine protects 4 bytes of OOB data per chunk.
888 * Retrieve the corrected OOB bytes.
889 */
890 sunxi_nfc_user_data_to_buf(readl(nfc->regs +
891 NFC_REG_USER_DATA(0)),
892 oob);
893
894 /* De-randomize the Bad Block Marker. */
895 if (bbm && nand->options & NAND_NEED_SCRAMBLING)
896 sunxi_nfc_randomize_bbm(mtd, page, oob);
897 }
898
899 if (ret < 0) {
900 mtd->ecc_stats.failed++;
901 } else {
902 mtd->ecc_stats.corrected += ret;
903 *max_bitflips = max_t(unsigned int, *max_bitflips, ret);
904 }
905
906 return raw_mode;
907}
908
909static void sunxi_nfc_hw_ecc_read_extra_oob(struct mtd_info *mtd,
910 u8 *oob, int *cur_off,
911 bool randomize, int page)
912{
913 struct nand_chip *nand = mtd_to_nand(mtd);
914 struct nand_ecc_ctrl *ecc = &nand->ecc;
915 int offset = ((ecc->bytes + 4) * ecc->steps);
916 int len = mtd->oobsize - offset;
917
918 if (len <= 0)
919 return;
920
921 if (*cur_off != offset)
922 nand->cmdfunc(mtd, NAND_CMD_RNDOUT,
923 offset + mtd->writesize, -1);
924
925 if (!randomize)
926 sunxi_nfc_read_buf(mtd, oob + offset, len);
927 else
928 sunxi_nfc_randomizer_read_buf(mtd, oob + offset, len,
929 false, page);
930
931 *cur_off = mtd->oobsize + mtd->writesize;
932}
933
934static inline u32 sunxi_nfc_buf_to_user_data(const u8 *buf)
935{
936 return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
937}
938
939static int sunxi_nfc_hw_ecc_write_chunk(struct mtd_info *mtd,
940 const u8 *data, int data_off,
941 const u8 *oob, int oob_off,
942 int *cur_off, bool bbm,
943 int page)
944{
945 struct nand_chip *nand = mtd_to_nand(mtd);
946 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
947 struct nand_ecc_ctrl *ecc = &nand->ecc;
948 int ret;
949
950 if (data_off != *cur_off)
951 nand->cmdfunc(mtd, NAND_CMD_RNDIN, data_off, -1);
952
953 sunxi_nfc_randomizer_write_buf(mtd, data, ecc->size, false, page);
954
955 /* Fill OOB data in */
956 if ((nand->options & NAND_NEED_SCRAMBLING) && bbm) {
957 u8 user_data[4];
958
959 memcpy(user_data, oob, 4);
960 sunxi_nfc_randomize_bbm(mtd, page, user_data);
961 writel(sunxi_nfc_buf_to_user_data(user_data),
962 nfc->regs + NFC_REG_USER_DATA(0));
963 } else {
964 writel(sunxi_nfc_buf_to_user_data(oob),
965 nfc->regs + NFC_REG_USER_DATA(0));
966 }
967
968 if (data_off + ecc->size != oob_off)
969 nand->cmdfunc(mtd, NAND_CMD_RNDIN, oob_off, -1);
970
971 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
972 if (ret)
973 return ret;
974
975 sunxi_nfc_randomizer_enable(mtd);
976 writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD |
977 NFC_ACCESS_DIR | NFC_ECC_OP,
978 nfc->regs + NFC_REG_CMD);
979
980 ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
981 sunxi_nfc_randomizer_disable(mtd);
982 if (ret)
983 return ret;
984
985 *cur_off = oob_off + ecc->bytes + 4;
986
987 return 0;
988}
989
990static void sunxi_nfc_hw_ecc_write_extra_oob(struct mtd_info *mtd,
991 u8 *oob, int *cur_off,
992 int page)
993{
994 struct nand_chip *nand = mtd_to_nand(mtd);
995 struct nand_ecc_ctrl *ecc = &nand->ecc;
996 int offset = ((ecc->bytes + 4) * ecc->steps);
997 int len = mtd->oobsize - offset;
998
999 if (len <= 0)
1000 return;
1001
1002 if (*cur_off != offset)
1003 nand->cmdfunc(mtd, NAND_CMD_RNDIN,
1004 offset + mtd->writesize, -1);
1005
1006 sunxi_nfc_randomizer_write_buf(mtd, oob + offset, len, false, page);
1007
1008 *cur_off = mtd->oobsize + mtd->writesize;
1009}
1010
1011static int sunxi_nfc_hw_ecc_read_page(struct mtd_info *mtd,
1012 struct nand_chip *chip, uint8_t *buf,
1013 int oob_required, int page)
1014{
1015 struct nand_ecc_ctrl *ecc = &chip->ecc;
1016 unsigned int max_bitflips = 0;
1017 int ret, i, cur_off = 0;
1018 bool raw_mode = false;
1019
1020 sunxi_nfc_hw_ecc_enable(mtd);
1021
1022 for (i = 0; i < ecc->steps; i++) {
1023 int data_off = i * ecc->size;
1024 int oob_off = i * (ecc->bytes + 4);
1025 u8 *data = buf + data_off;
1026 u8 *oob = chip->oob_poi + oob_off;
1027
1028 ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off, oob,
1029 oob_off + mtd->writesize,
1030 &cur_off, &max_bitflips,
1031 !i, page);
1032 if (ret < 0)
1033 return ret;
1034 else if (ret)
1035 raw_mode = true;
1036 }
1037
1038 if (oob_required)
1039 sunxi_nfc_hw_ecc_read_extra_oob(mtd, chip->oob_poi, &cur_off,
1040 !raw_mode, page);
1041
1042 sunxi_nfc_hw_ecc_disable(mtd);
1043
1044 return max_bitflips;
1045}
1046
1047static int sunxi_nfc_hw_ecc_read_subpage(struct mtd_info *mtd,
1048 struct nand_chip *chip,
1049 uint32_t data_offs, uint32_t readlen,
1050 uint8_t *bufpoi, int page)
1051{
1052 struct nand_ecc_ctrl *ecc = &chip->ecc;
1053 int ret, i, cur_off = 0;
1054 unsigned int max_bitflips = 0;
1055
1056 sunxi_nfc_hw_ecc_enable(mtd);
1057
1058 chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
1059 for (i = data_offs / ecc->size;
1060 i < DIV_ROUND_UP(data_offs + readlen, ecc->size); i++) {
1061 int data_off = i * ecc->size;
1062 int oob_off = i * (ecc->bytes + 4);
1063 u8 *data = bufpoi + data_off;
1064 u8 *oob = chip->oob_poi + oob_off;
1065
1066 ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off,
1067 oob, oob_off + mtd->writesize,
1068 &cur_off, &max_bitflips, !i, page);
1069 if (ret < 0)
1070 return ret;
1071 }
1072
1073 sunxi_nfc_hw_ecc_disable(mtd);
1074
1075 return max_bitflips;
1076}
1077
1078static int sunxi_nfc_hw_ecc_write_page(struct mtd_info *mtd,
1079 struct nand_chip *chip,
1080 const uint8_t *buf, int oob_required,
1081 int page)
1082{
1083 struct nand_ecc_ctrl *ecc = &chip->ecc;
1084 int ret, i, cur_off = 0;
1085
1086 sunxi_nfc_hw_ecc_enable(mtd);
1087
1088 for (i = 0; i < ecc->steps; i++) {
1089 int data_off = i * ecc->size;
1090 int oob_off = i * (ecc->bytes + 4);
1091 const u8 *data = buf + data_off;
1092 const u8 *oob = chip->oob_poi + oob_off;
1093
1094 ret = sunxi_nfc_hw_ecc_write_chunk(mtd, data, data_off, oob,
1095 oob_off + mtd->writesize,
1096 &cur_off, !i, page);
1097 if (ret)
1098 return ret;
1099 }
1100
1101 if (oob_required || (chip->options & NAND_NEED_SCRAMBLING))
1102 sunxi_nfc_hw_ecc_write_extra_oob(mtd, chip->oob_poi,
1103 &cur_off, page);
1104
1105 sunxi_nfc_hw_ecc_disable(mtd);
1106
1107 return 0;
1108}
1109
1110static int sunxi_nfc_hw_ecc_write_subpage(struct mtd_info *mtd,
1111 struct nand_chip *chip,
1112 u32 data_offs, u32 data_len,
1113 const u8 *buf, int oob_required,
1114 int page)
1115{
1116 struct nand_ecc_ctrl *ecc = &chip->ecc;
1117 int ret, i, cur_off = 0;
1118
1119 sunxi_nfc_hw_ecc_enable(mtd);
1120
1121 for (i = data_offs / ecc->size;
1122 i < DIV_ROUND_UP(data_offs + data_len, ecc->size); i++) {
1123 int data_off = i * ecc->size;
1124 int oob_off = i * (ecc->bytes + 4);
1125 const u8 *data = buf + data_off;
1126 const u8 *oob = chip->oob_poi + oob_off;
1127
1128 ret = sunxi_nfc_hw_ecc_write_chunk(mtd, data, data_off, oob,
1129 oob_off + mtd->writesize,
1130 &cur_off, !i, page);
1131 if (ret)
1132 return ret;
1133 }
1134
1135 sunxi_nfc_hw_ecc_disable(mtd);
1136
1137 return 0;
1138}
1139
1140static int sunxi_nfc_hw_syndrome_ecc_read_page(struct mtd_info *mtd,
1141 struct nand_chip *chip,
1142 uint8_t *buf, int oob_required,
1143 int page)
1144{
1145 struct nand_ecc_ctrl *ecc = &chip->ecc;
1146 unsigned int max_bitflips = 0;
1147 int ret, i, cur_off = 0;
1148 bool raw_mode = false;
1149
1150 sunxi_nfc_hw_ecc_enable(mtd);
1151
1152 for (i = 0; i < ecc->steps; i++) {
1153 int data_off = i * (ecc->size + ecc->bytes + 4);
1154 int oob_off = data_off + ecc->size;
1155 u8 *data = buf + (i * ecc->size);
1156 u8 *oob = chip->oob_poi + (i * (ecc->bytes + 4));
1157
1158 ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off, oob,
1159 oob_off, &cur_off,
1160 &max_bitflips, !i, page);
1161 if (ret < 0)
1162 return ret;
1163 else if (ret)
1164 raw_mode = true;
1165 }
1166
1167 if (oob_required)
1168 sunxi_nfc_hw_ecc_read_extra_oob(mtd, chip->oob_poi, &cur_off,
1169 !raw_mode, page);
1170
1171 sunxi_nfc_hw_ecc_disable(mtd);
1172
1173 return max_bitflips;
1174}
1175
1176static int sunxi_nfc_hw_syndrome_ecc_write_page(struct mtd_info *mtd,
1177 struct nand_chip *chip,
1178 const uint8_t *buf,
1179 int oob_required, int page)
1180{
1181 struct nand_ecc_ctrl *ecc = &chip->ecc;
1182 int ret, i, cur_off = 0;
1183
1184 sunxi_nfc_hw_ecc_enable(mtd);
1185
1186 for (i = 0; i < ecc->steps; i++) {
1187 int data_off = i * (ecc->size + ecc->bytes + 4);
1188 int oob_off = data_off + ecc->size;
1189 const u8 *data = buf + (i * ecc->size);
1190 const u8 *oob = chip->oob_poi + (i * (ecc->bytes + 4));
1191
1192 ret = sunxi_nfc_hw_ecc_write_chunk(mtd, data, data_off,
1193 oob, oob_off, &cur_off,
1194 false, page);
1195 if (ret)
1196 return ret;
1197 }
1198
1199 if (oob_required || (chip->options & NAND_NEED_SCRAMBLING))
1200 sunxi_nfc_hw_ecc_write_extra_oob(mtd, chip->oob_poi,
1201 &cur_off, page);
1202
1203 sunxi_nfc_hw_ecc_disable(mtd);
1204
1205 return 0;
1206}
1207
1208static const s32 tWB_lut[] = {6, 12, 16, 20};
1209static const s32 tRHW_lut[] = {4, 8, 12, 20};
1210
1211static int _sunxi_nand_lookup_timing(const s32 *lut, int lut_size, u32 duration,
1212 u32 clk_period)
1213{
1214 u32 clk_cycles = DIV_ROUND_UP(duration, clk_period);
1215 int i;
1216
1217 for (i = 0; i < lut_size; i++) {
1218 if (clk_cycles <= lut[i])
1219 return i;
1220 }
1221
1222 /* Doesn't fit */
1223 return -EINVAL;
1224}
1225
1226#define sunxi_nand_lookup_timing(l, p, c) \
1227 _sunxi_nand_lookup_timing(l, ARRAY_SIZE(l), p, c)
1228
Sean Anderson6ae28142020-09-15 10:44:41 -04001229static int sunxi_nand_chip_set_timings(struct sunxi_nfc *nfc,
1230 struct sunxi_nand_chip *chip,
Boris Brezillon57f20382016-06-15 21:09:23 +02001231 const struct nand_sdr_timings *timings)
1232{
1233 u32 min_clk_period = 0;
1234 s32 tWB, tADL, tWHR, tRHW, tCAD;
1235
1236 /* T1 <=> tCLS */
1237 if (timings->tCLS_min > min_clk_period)
1238 min_clk_period = timings->tCLS_min;
1239
1240 /* T2 <=> tCLH */
1241 if (timings->tCLH_min > min_clk_period)
1242 min_clk_period = timings->tCLH_min;
1243
1244 /* T3 <=> tCS */
1245 if (timings->tCS_min > min_clk_period)
1246 min_clk_period = timings->tCS_min;
1247
1248 /* T4 <=> tCH */
1249 if (timings->tCH_min > min_clk_period)
1250 min_clk_period = timings->tCH_min;
1251
1252 /* T5 <=> tWP */
1253 if (timings->tWP_min > min_clk_period)
1254 min_clk_period = timings->tWP_min;
1255
1256 /* T6 <=> tWH */
1257 if (timings->tWH_min > min_clk_period)
1258 min_clk_period = timings->tWH_min;
1259
1260 /* T7 <=> tALS */
1261 if (timings->tALS_min > min_clk_period)
1262 min_clk_period = timings->tALS_min;
1263
1264 /* T8 <=> tDS */
1265 if (timings->tDS_min > min_clk_period)
1266 min_clk_period = timings->tDS_min;
1267
1268 /* T9 <=> tDH */
1269 if (timings->tDH_min > min_clk_period)
1270 min_clk_period = timings->tDH_min;
1271
1272 /* T10 <=> tRR */
1273 if (timings->tRR_min > (min_clk_period * 3))
1274 min_clk_period = DIV_ROUND_UP(timings->tRR_min, 3);
1275
1276 /* T11 <=> tALH */
1277 if (timings->tALH_min > min_clk_period)
1278 min_clk_period = timings->tALH_min;
1279
1280 /* T12 <=> tRP */
1281 if (timings->tRP_min > min_clk_period)
1282 min_clk_period = timings->tRP_min;
1283
1284 /* T13 <=> tREH */
1285 if (timings->tREH_min > min_clk_period)
1286 min_clk_period = timings->tREH_min;
1287
1288 /* T14 <=> tRC */
1289 if (timings->tRC_min > (min_clk_period * 2))
1290 min_clk_period = DIV_ROUND_UP(timings->tRC_min, 2);
1291
1292 /* T15 <=> tWC */
1293 if (timings->tWC_min > (min_clk_period * 2))
1294 min_clk_period = DIV_ROUND_UP(timings->tWC_min, 2);
1295
1296 /* T16 - T19 + tCAD */
1297 tWB = sunxi_nand_lookup_timing(tWB_lut, timings->tWB_max,
1298 min_clk_period);
1299 if (tWB < 0) {
1300 dev_err(nfc->dev, "unsupported tWB\n");
1301 return tWB;
1302 }
1303
1304 tADL = DIV_ROUND_UP(timings->tADL_min, min_clk_period) >> 3;
1305 if (tADL > 3) {
1306 dev_err(nfc->dev, "unsupported tADL\n");
1307 return -EINVAL;
1308 }
1309
1310 tWHR = DIV_ROUND_UP(timings->tWHR_min, min_clk_period) >> 3;
1311 if (tWHR > 3) {
1312 dev_err(nfc->dev, "unsupported tWHR\n");
1313 return -EINVAL;
1314 }
1315
1316 tRHW = sunxi_nand_lookup_timing(tRHW_lut, timings->tRHW_min,
1317 min_clk_period);
1318 if (tRHW < 0) {
1319 dev_err(nfc->dev, "unsupported tRHW\n");
1320 return tRHW;
1321 }
1322
1323 /*
1324 * TODO: according to ONFI specs this value only applies for DDR NAND,
1325 * but Allwinner seems to set this to 0x7. Mimic them for now.
1326 */
1327 tCAD = 0x7;
1328
1329 /* TODO: A83 has some more bits for CDQSS, CS, CLHZ, CCS, WC */
1330 chip->timing_cfg = NFC_TIMING_CFG(tWB, tADL, tWHR, tRHW, tCAD);
1331
1332 /*
1333 * ONFI specification 3.1, paragraph 4.15.2 dictates that EDO data
1334 * output cycle timings shall be used if the host drives tRC less than
1335 * 30 ns.
1336 */
1337 chip->timing_ctl = (timings->tRC_min < 30000) ? NFC_TIMING_CTL_EDO : 0;
1338
1339 /* Convert min_clk_period from picoseconds to nanoseconds */
1340 min_clk_period = DIV_ROUND_UP(min_clk_period, 1000);
1341
1342 /*
1343 * Convert min_clk_period into a clk frequency, then get the
1344 * appropriate rate for the NAND controller IP given this formula
1345 * (specified in the datasheet):
1346 * nand clk_rate = min_clk_rate
1347 */
1348 chip->clk_rate = 1000000000L / min_clk_period;
1349
1350 return 0;
1351}
1352
Sean Anderson6ae28142020-09-15 10:44:41 -04001353static int sunxi_nand_chip_init_timings(struct sunxi_nfc *nfc,
1354 struct sunxi_nand_chip *chip)
Boris Brezillon57f20382016-06-15 21:09:23 +02001355{
1356 struct mtd_info *mtd = nand_to_mtd(&chip->nand);
1357 const struct nand_sdr_timings *timings;
1358 int ret;
1359 int mode;
1360
1361 mode = onfi_get_async_timing_mode(&chip->nand);
1362 if (mode == ONFI_TIMING_MODE_UNKNOWN) {
1363 mode = chip->nand.onfi_timing_mode_default;
1364 } else {
1365 uint8_t feature[ONFI_SUBFEATURE_PARAM_LEN] = {};
1366 int i;
1367
1368 mode = fls(mode) - 1;
1369 if (mode < 0)
1370 mode = 0;
1371
1372 feature[0] = mode;
1373 for (i = 0; i < chip->nsels; i++) {
1374 chip->nand.select_chip(mtd, i);
1375 ret = chip->nand.onfi_set_features(mtd,
1376 &chip->nand,
1377 ONFI_FEATURE_ADDR_TIMING_MODE,
1378 feature);
1379 chip->nand.select_chip(mtd, -1);
Mylène Josserand042b3f52018-07-13 18:10:24 +02001380 if (ret && ret != -ENOTSUPP)
Boris Brezillon57f20382016-06-15 21:09:23 +02001381 return ret;
1382 }
1383 }
1384
1385 timings = onfi_async_timing_mode_to_sdr_timings(mode);
1386 if (IS_ERR(timings))
1387 return PTR_ERR(timings);
1388
Sean Anderson6ae28142020-09-15 10:44:41 -04001389 return sunxi_nand_chip_set_timings(nfc, chip, timings);
Boris Brezillon57f20382016-06-15 21:09:23 +02001390}
1391
1392static int sunxi_nand_hw_common_ecc_ctrl_init(struct mtd_info *mtd,
1393 struct nand_ecc_ctrl *ecc)
1394{
1395 static const u8 strengths[] = { 16, 24, 28, 32, 40, 48, 56, 60, 64 };
1396 struct sunxi_nand_hw_ecc *data;
1397 struct nand_ecclayout *layout;
1398 int nsectors;
1399 int ret;
1400 int i;
1401
1402 data = kzalloc(sizeof(*data), GFP_KERNEL);
1403 if (!data)
1404 return -ENOMEM;
1405
1406 if (ecc->size != 512 && ecc->size != 1024)
1407 return -EINVAL;
1408
1409 /* Prefer 1k ECC chunk over 512 ones */
1410 if (ecc->size == 512 && mtd->writesize > 512) {
1411 ecc->size = 1024;
1412 ecc->strength *= 2;
1413 }
1414
1415 /* Add ECC info retrieval from DT */
1416 for (i = 0; i < ARRAY_SIZE(strengths); i++) {
Miquel Raynal3cb5a812018-02-28 20:51:44 +01001417 if (ecc->strength <= strengths[i]) {
1418 /*
1419 * Update ecc->strength value with the actual strength
1420 * that will be used by the ECC engine.
1421 */
1422 ecc->strength = strengths[i];
Boris Brezillon57f20382016-06-15 21:09:23 +02001423 break;
Miquel Raynal3cb5a812018-02-28 20:51:44 +01001424 }
Boris Brezillon57f20382016-06-15 21:09:23 +02001425 }
1426
1427 if (i >= ARRAY_SIZE(strengths)) {
Sean Anderson6ae28142020-09-15 10:44:41 -04001428 dev_err(mtd->dev, "unsupported strength\n");
Boris Brezillon57f20382016-06-15 21:09:23 +02001429 ret = -ENOTSUPP;
1430 goto err;
1431 }
1432
1433 data->mode = i;
1434
1435 /* HW ECC always request ECC bytes for 1024 bytes blocks */
1436 ecc->bytes = DIV_ROUND_UP(ecc->strength * fls(8 * 1024), 8);
1437
1438 /* HW ECC always work with even numbers of ECC bytes */
1439 ecc->bytes = ALIGN(ecc->bytes, 2);
1440
1441 layout = &data->layout;
1442 nsectors = mtd->writesize / ecc->size;
1443
1444 if (mtd->oobsize < ((ecc->bytes + 4) * nsectors)) {
1445 ret = -EINVAL;
1446 goto err;
1447 }
1448
1449 layout->eccbytes = (ecc->bytes * nsectors);
1450
1451 ecc->layout = layout;
1452 ecc->priv = data;
1453
1454 return 0;
1455
1456err:
1457 kfree(data);
1458
1459 return ret;
1460}
1461
1462#ifndef __UBOOT__
1463static void sunxi_nand_hw_common_ecc_ctrl_cleanup(struct nand_ecc_ctrl *ecc)
1464{
1465 kfree(ecc->priv);
1466}
1467#endif /* __UBOOT__ */
1468
1469static int sunxi_nand_hw_ecc_ctrl_init(struct mtd_info *mtd,
1470 struct nand_ecc_ctrl *ecc)
1471{
1472 struct nand_ecclayout *layout;
1473 int nsectors;
1474 int i, j;
1475 int ret;
1476
1477 ret = sunxi_nand_hw_common_ecc_ctrl_init(mtd, ecc);
1478 if (ret)
1479 return ret;
1480
1481 ecc->read_page = sunxi_nfc_hw_ecc_read_page;
1482 ecc->write_page = sunxi_nfc_hw_ecc_write_page;
1483 ecc->read_subpage = sunxi_nfc_hw_ecc_read_subpage;
1484 ecc->write_subpage = sunxi_nfc_hw_ecc_write_subpage;
1485 layout = ecc->layout;
1486 nsectors = mtd->writesize / ecc->size;
1487
1488 for (i = 0; i < nsectors; i++) {
1489 if (i) {
1490 layout->oobfree[i].offset =
1491 layout->oobfree[i - 1].offset +
1492 layout->oobfree[i - 1].length +
1493 ecc->bytes;
1494 layout->oobfree[i].length = 4;
1495 } else {
1496 /*
1497 * The first 2 bytes are used for BB markers, hence we
1498 * only have 2 bytes available in the first user data
1499 * section.
1500 */
1501 layout->oobfree[i].length = 2;
1502 layout->oobfree[i].offset = 2;
1503 }
1504
1505 for (j = 0; j < ecc->bytes; j++)
1506 layout->eccpos[(ecc->bytes * i) + j] =
1507 layout->oobfree[i].offset +
1508 layout->oobfree[i].length + j;
1509 }
1510
1511 if (mtd->oobsize > (ecc->bytes + 4) * nsectors) {
1512 layout->oobfree[nsectors].offset =
1513 layout->oobfree[nsectors - 1].offset +
1514 layout->oobfree[nsectors - 1].length +
1515 ecc->bytes;
1516 layout->oobfree[nsectors].length = mtd->oobsize -
1517 ((ecc->bytes + 4) * nsectors);
1518 }
1519
1520 return 0;
1521}
1522
1523static int sunxi_nand_hw_syndrome_ecc_ctrl_init(struct mtd_info *mtd,
1524 struct nand_ecc_ctrl *ecc)
1525{
1526 struct nand_ecclayout *layout;
1527 int nsectors;
1528 int i;
1529 int ret;
1530
1531 ret = sunxi_nand_hw_common_ecc_ctrl_init(mtd, ecc);
1532 if (ret)
1533 return ret;
1534
1535 ecc->prepad = 4;
1536 ecc->read_page = sunxi_nfc_hw_syndrome_ecc_read_page;
1537 ecc->write_page = sunxi_nfc_hw_syndrome_ecc_write_page;
1538
1539 layout = ecc->layout;
1540 nsectors = mtd->writesize / ecc->size;
1541
1542 for (i = 0; i < (ecc->bytes * nsectors); i++)
1543 layout->eccpos[i] = i;
1544
1545 layout->oobfree[0].length = mtd->oobsize - i;
1546 layout->oobfree[0].offset = i;
1547
1548 return 0;
1549}
1550
1551#ifndef __UBOOT__
1552static void sunxi_nand_ecc_cleanup(struct nand_ecc_ctrl *ecc)
1553{
1554 switch (ecc->mode) {
1555 case NAND_ECC_HW:
1556 case NAND_ECC_HW_SYNDROME:
1557 sunxi_nand_hw_common_ecc_ctrl_cleanup(ecc);
1558 break;
1559 case NAND_ECC_NONE:
1560 kfree(ecc->layout);
1561 default:
1562 break;
1563 }
1564}
1565#endif /* __UBOOT__ */
1566
1567static int sunxi_nand_ecc_init(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc)
1568{
1569 struct nand_chip *nand = mtd_to_nand(mtd);
1570 int ret;
1571
1572 if (!ecc->size) {
1573 ecc->size = nand->ecc_step_ds;
1574 ecc->strength = nand->ecc_strength_ds;
1575 }
1576
1577 if (!ecc->size || !ecc->strength)
1578 return -EINVAL;
1579
1580 switch (ecc->mode) {
1581 case NAND_ECC_SOFT_BCH:
1582 break;
1583 case NAND_ECC_HW:
1584 ret = sunxi_nand_hw_ecc_ctrl_init(mtd, ecc);
1585 if (ret)
1586 return ret;
1587 break;
1588 case NAND_ECC_HW_SYNDROME:
1589 ret = sunxi_nand_hw_syndrome_ecc_ctrl_init(mtd, ecc);
1590 if (ret)
1591 return ret;
1592 break;
1593 case NAND_ECC_NONE:
1594 ecc->layout = kzalloc(sizeof(*ecc->layout), GFP_KERNEL);
1595 if (!ecc->layout)
1596 return -ENOMEM;
1597 ecc->layout->oobfree[0].length = mtd->oobsize;
1598 case NAND_ECC_SOFT:
1599 break;
1600 default:
1601 return -EINVAL;
1602 }
1603
1604 return 0;
1605}
1606
Samuel Holland62a160f2023-01-22 16:06:36 -06001607static int sunxi_nand_chip_init(struct udevice *dev, struct sunxi_nfc *nfc,
1608 ofnode np, int devnum)
Boris Brezillon57f20382016-06-15 21:09:23 +02001609{
1610 const struct nand_sdr_timings *timings;
Boris Brezillon57f20382016-06-15 21:09:23 +02001611 struct sunxi_nand_chip *chip;
1612 struct mtd_info *mtd;
1613 struct nand_chip *nand;
1614 int nsels;
1615 int ret;
1616 int i;
Samuel Holland1edb8782023-01-22 16:06:34 -06001617 u32 tmp;
Boris Brezillon57f20382016-06-15 21:09:23 +02001618
Samuel Holland1edb8782023-01-22 16:06:34 -06001619 if (!ofnode_get_property(np, "reg", &nsels))
Boris Brezillon57f20382016-06-15 21:09:23 +02001620 return -EINVAL;
1621
1622 nsels /= sizeof(u32);
1623 if (!nsels || nsels > 8) {
Samuel Holland62a160f2023-01-22 16:06:36 -06001624 dev_err(dev, "invalid reg property size\n");
Boris Brezillon57f20382016-06-15 21:09:23 +02001625 return -EINVAL;
1626 }
1627
1628 chip = kzalloc(sizeof(*chip) +
1629 (nsels * sizeof(struct sunxi_nand_chip_sel)),
1630 GFP_KERNEL);
1631 if (!chip) {
Samuel Holland62a160f2023-01-22 16:06:36 -06001632 dev_err(dev, "could not allocate chip\n");
Boris Brezillon57f20382016-06-15 21:09:23 +02001633 return -ENOMEM;
1634 }
1635
1636 chip->nsels = nsels;
1637 chip->selected = -1;
1638
1639 for (i = 0; i < nsels; i++) {
Samuel Holland1edb8782023-01-22 16:06:34 -06001640 ret = ofnode_read_u32_index(np, "reg", i, &tmp);
1641 if (ret) {
Samuel Holland62a160f2023-01-22 16:06:36 -06001642 dev_err(dev, "could not retrieve reg property: %d\n",
Samuel Holland1edb8782023-01-22 16:06:34 -06001643 ret);
1644 return ret;
1645 }
Boris Brezillon57f20382016-06-15 21:09:23 +02001646
1647 if (tmp > NFC_MAX_CS) {
Samuel Holland62a160f2023-01-22 16:06:36 -06001648 dev_err(dev,
Sean Anderson6ae28142020-09-15 10:44:41 -04001649 "invalid reg value: %u (max CS = 7)\n", tmp);
Boris Brezillon57f20382016-06-15 21:09:23 +02001650 return -EINVAL;
1651 }
1652
1653 if (test_and_set_bit(tmp, &nfc->assigned_cs)) {
Samuel Holland62a160f2023-01-22 16:06:36 -06001654 dev_err(dev, "CS %d already assigned\n", tmp);
Boris Brezillon57f20382016-06-15 21:09:23 +02001655 return -EINVAL;
1656 }
1657
1658 chip->sels[i].cs = tmp;
1659
Samuel Holland1edb8782023-01-22 16:06:34 -06001660 if (!ofnode_read_u32_index(np, "allwinner,rb", i, &tmp) &&
1661 tmp < 2) {
Boris Brezillon57f20382016-06-15 21:09:23 +02001662 chip->sels[i].rb.type = RB_NATIVE;
1663 chip->sels[i].rb.info.nativeid = tmp;
1664 } else {
Samuel Holland62a160f2023-01-22 16:06:36 -06001665 ret = gpio_request_by_name(dev, "rb-gpios", i,
1666 &chip->sels[i].rb.info.gpio,
1667 GPIOD_IS_IN);
Boris Brezillon57f20382016-06-15 21:09:23 +02001668 if (ret)
1669 chip->sels[i].rb.type = RB_GPIO;
1670 else
1671 chip->sels[i].rb.type = RB_NONE;
1672 }
1673 }
1674
1675 timings = onfi_async_timing_mode_to_sdr_timings(0);
1676 if (IS_ERR(timings)) {
1677 ret = PTR_ERR(timings);
Samuel Holland62a160f2023-01-22 16:06:36 -06001678 dev_err(dev,
Boris Brezillon57f20382016-06-15 21:09:23 +02001679 "could not retrieve timings for ONFI mode 0: %d\n",
1680 ret);
1681 return ret;
1682 }
1683
Sean Anderson6ae28142020-09-15 10:44:41 -04001684 ret = sunxi_nand_chip_set_timings(nfc, chip, timings);
Boris Brezillon57f20382016-06-15 21:09:23 +02001685 if (ret) {
Samuel Holland62a160f2023-01-22 16:06:36 -06001686 dev_err(dev, "could not configure chip timings: %d\n", ret);
Boris Brezillon57f20382016-06-15 21:09:23 +02001687 return ret;
1688 }
1689
1690 nand = &chip->nand;
1691 /* Default tR value specified in the ONFI spec (chapter 4.15.1) */
1692 nand->chip_delay = 200;
1693 nand->controller = &nfc->controller;
1694 /*
1695 * Set the ECC mode to the default value in case nothing is specified
1696 * in the DT.
1697 */
1698 nand->ecc.mode = NAND_ECC_HW;
Samuel Holland1edb8782023-01-22 16:06:34 -06001699 nand->flash_node = np;
Boris Brezillon57f20382016-06-15 21:09:23 +02001700 nand->select_chip = sunxi_nfc_select_chip;
1701 nand->cmd_ctrl = sunxi_nfc_cmd_ctrl;
1702 nand->read_buf = sunxi_nfc_read_buf;
1703 nand->write_buf = sunxi_nfc_write_buf;
1704 nand->read_byte = sunxi_nfc_read_byte;
1705
1706 mtd = nand_to_mtd(nand);
1707 ret = nand_scan_ident(mtd, nsels, NULL);
1708 if (ret)
1709 return ret;
1710
1711 if (nand->bbt_options & NAND_BBT_USE_FLASH)
1712 nand->bbt_options |= NAND_BBT_NO_OOB;
1713
1714 if (nand->options & NAND_NEED_SCRAMBLING)
1715 nand->options |= NAND_NO_SUBPAGE_WRITE;
1716
1717 nand->options |= NAND_SUBPAGE_READ;
1718
Sean Anderson6ae28142020-09-15 10:44:41 -04001719 ret = sunxi_nand_chip_init_timings(nfc, chip);
Boris Brezillon57f20382016-06-15 21:09:23 +02001720 if (ret) {
Samuel Holland62a160f2023-01-22 16:06:36 -06001721 dev_err(dev, "could not configure chip timings: %d\n", ret);
Boris Brezillon57f20382016-06-15 21:09:23 +02001722 return ret;
1723 }
1724
1725 ret = sunxi_nand_ecc_init(mtd, &nand->ecc);
1726 if (ret) {
Samuel Holland62a160f2023-01-22 16:06:36 -06001727 dev_err(dev, "ECC init failed: %d\n", ret);
Boris Brezillon57f20382016-06-15 21:09:23 +02001728 return ret;
1729 }
1730
1731 ret = nand_scan_tail(mtd);
1732 if (ret) {
Samuel Holland62a160f2023-01-22 16:06:36 -06001733 dev_err(dev, "nand_scan_tail failed: %d\n", ret);
Boris Brezillon57f20382016-06-15 21:09:23 +02001734 return ret;
1735 }
1736
1737 ret = nand_register(devnum, mtd);
1738 if (ret) {
Samuel Holland62a160f2023-01-22 16:06:36 -06001739 dev_err(dev, "failed to register mtd device: %d\n", ret);
Boris Brezillon57f20382016-06-15 21:09:23 +02001740 return ret;
1741 }
1742
1743 list_add_tail(&chip->node, &nfc->chips);
1744
1745 return 0;
1746}
1747
Samuel Holland62a160f2023-01-22 16:06:36 -06001748static int sunxi_nand_chips_init(struct udevice *dev, struct sunxi_nfc *nfc)
Boris Brezillon57f20382016-06-15 21:09:23 +02001749{
Samuel Holland1edb8782023-01-22 16:06:34 -06001750 ofnode nand_np;
Boris Brezillon57f20382016-06-15 21:09:23 +02001751 int ret, i = 0;
1752
Samuel Holland62a160f2023-01-22 16:06:36 -06001753 dev_for_each_subnode(nand_np, dev) {
1754 ret = sunxi_nand_chip_init(dev, nfc, nand_np, i++);
Boris Brezillon57f20382016-06-15 21:09:23 +02001755 if (ret)
1756 return ret;
1757 }
1758
1759 return 0;
1760}
1761
1762#ifndef __UBOOT__
1763static void sunxi_nand_chips_cleanup(struct sunxi_nfc *nfc)
1764{
1765 struct sunxi_nand_chip *chip;
1766
1767 while (!list_empty(&nfc->chips)) {
1768 chip = list_first_entry(&nfc->chips, struct sunxi_nand_chip,
1769 node);
1770 nand_release(&chip->mtd);
1771 sunxi_nand_ecc_cleanup(&chip->nand.ecc);
1772 list_del(&chip->node);
1773 kfree(chip);
1774 }
1775}
1776#endif /* __UBOOT__ */
1777
Samuel Holland890f7de2023-01-22 16:06:35 -06001778static int sunxi_nand_probe(struct udevice *dev)
Boris Brezillon57f20382016-06-15 21:09:23 +02001779{
Samuel Holland890f7de2023-01-22 16:06:35 -06001780 struct sunxi_nfc *nfc = dev_get_priv(dev);
1781 struct reset_ctl_bulk rst_bulk;
1782 struct clk_bulk clk_bulk;
Boris Brezillon57f20382016-06-15 21:09:23 +02001783 int ret;
1784
Samuel Holland890f7de2023-01-22 16:06:35 -06001785 nfc->dev = dev;
Boris Brezillon57f20382016-06-15 21:09:23 +02001786 spin_lock_init(&nfc->controller.lock);
1787 init_waitqueue_head(&nfc->controller.wq);
1788 INIT_LIST_HEAD(&nfc->chips);
1789
Samuel Holland890f7de2023-01-22 16:06:35 -06001790 nfc->regs = dev_read_addr_ptr(dev);
1791 if (!nfc->regs)
1792 return -EINVAL;
Boris Brezillon57f20382016-06-15 21:09:23 +02001793
Samuel Holland890f7de2023-01-22 16:06:35 -06001794 ret = reset_get_bulk(dev, &rst_bulk);
1795 if (!ret)
1796 reset_deassert_bulk(&rst_bulk);
Boris Brezillon57f20382016-06-15 21:09:23 +02001797
Samuel Holland890f7de2023-01-22 16:06:35 -06001798 ret = clk_get_bulk(dev, &clk_bulk);
1799 if (!ret)
1800 clk_enable_bulk(&clk_bulk);
Boris Brezillon57f20382016-06-15 21:09:23 +02001801
1802 ret = sunxi_nfc_rst(nfc);
1803 if (ret)
Samuel Holland890f7de2023-01-22 16:06:35 -06001804 return ret;
Boris Brezillon57f20382016-06-15 21:09:23 +02001805
Samuel Holland62a160f2023-01-22 16:06:36 -06001806 ret = sunxi_nand_chips_init(dev, nfc);
Boris Brezillon57f20382016-06-15 21:09:23 +02001807 if (ret) {
Samuel Holland890f7de2023-01-22 16:06:35 -06001808 dev_err(dev, "failed to init nand chips\n");
1809 return ret;
Boris Brezillon57f20382016-06-15 21:09:23 +02001810 }
1811
Samuel Holland890f7de2023-01-22 16:06:35 -06001812 return 0;
1813}
Boris Brezillon57f20382016-06-15 21:09:23 +02001814
Samuel Holland890f7de2023-01-22 16:06:35 -06001815static const struct udevice_id sunxi_nand_ids[] = {
1816 {
1817 .compatible = "allwinner,sun4i-a10-nand",
1818 },
1819 { }
1820};
1821
1822U_BOOT_DRIVER(sunxi_nand) = {
1823 .name = "sunxi_nand",
1824 .id = UCLASS_MTD,
1825 .of_match = sunxi_nand_ids,
1826 .probe = sunxi_nand_probe,
1827 .priv_auto = sizeof(struct sunxi_nfc),
1828};
1829
1830void board_nand_init(void)
1831{
1832 struct udevice *dev;
1833 int ret;
1834
1835 ret = uclass_get_device_by_driver(UCLASS_MTD,
1836 DM_DRIVER_GET(sunxi_nand), &dev);
1837 if (ret && ret != -ENODEV)
1838 pr_err("Failed to initialize sunxi NAND controller: %d\n", ret);
Boris Brezillon57f20382016-06-15 21:09:23 +02001839}
1840
1841MODULE_LICENSE("GPL v2");
1842MODULE_AUTHOR("Boris BREZILLON");
1843MODULE_DESCRIPTION("Allwinner NAND Flash Controller driver");