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