hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/mtd/nand/raw/sunxi_nand.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0+
12 /*
23 * Copyright (C) 2013 Boris BREZILLON <b.brezillon.dev@gmail.com>
34 *
....@@ -10,16 +11,6 @@
1011 *
1112 * Copyright (C) 2013 Dmitriy B. <rzk333@gmail.com>
1213 * Copyright (C) 2013 Sergey Lapin <slapin@ossfans.org>
13
- *
14
- * This program is free software; you can redistribute it and/or modify
15
- * it under the terms of the GNU General Public License as published by
16
- * the Free Software Foundation; either version 2 of the License, or
17
- * (at your option) any later version.
18
- *
19
- * This program is distributed in the hope that it will be useful,
20
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
- * GNU General Public License for more details.
2314 */
2415
2516 #include <linux/dma-mapping.h>
....@@ -51,7 +42,8 @@
5142 #define NFC_REG_CMD 0x0024
5243 #define NFC_REG_RCMD_SET 0x0028
5344 #define NFC_REG_WCMD_SET 0x002C
54
-#define NFC_REG_IO_DATA 0x0030
45
+#define NFC_REG_A10_IO_DATA 0x0030
46
+#define NFC_REG_A23_IO_DATA 0x0300
5547 #define NFC_REG_ECC_CTL 0x0034
5648 #define NFC_REG_ECC_ST 0x0038
5749 #define NFC_REG_DEBUG 0x003C
....@@ -59,6 +51,7 @@
5951 #define NFC_REG_USER_DATA(x) (0x0050 + ((x) * 4))
6052 #define NFC_REG_SPARE_AREA 0x00A0
6153 #define NFC_REG_PAT_ID 0x00A4
54
+#define NFC_REG_MDMA_CNT 0x00C4
6255 #define NFC_RAM0_BASE 0x0400
6356 #define NFC_RAM1_BASE 0x0800
6457
....@@ -77,6 +70,7 @@
7770 #define NFC_PAGE_SHIFT(x) (((x) < 10 ? 0 : (x) - 10) << 8)
7871 #define NFC_SAM BIT(12)
7972 #define NFC_RAM_METHOD BIT(14)
73
+#define NFC_DMA_TYPE_NORMAL BIT(15)
8074 #define NFC_DEBUG_CTL BIT(31)
8175
8276 /* define bit use in NFC_ST */
....@@ -163,38 +157,36 @@
163157
164158 #define NFC_MAX_CS 7
165159
166
-/*
167
- * Chip Select structure: stores information related to NAND Chip Select
160
+/**
161
+ * struct sunxi_nand_chip_sel - stores information related to NAND Chip Select
168162 *
169
- * @cs: the NAND CS id used to communicate with a NAND Chip
170
- * @rb: the Ready/Busy pin ID. -1 means no R/B pin connected to the
171
- * NFC
163
+ * @cs: the NAND CS id used to communicate with a NAND Chip
164
+ * @rb: the Ready/Busy pin ID. -1 means no R/B pin connected to the NFC
172165 */
173166 struct sunxi_nand_chip_sel {
174167 u8 cs;
175168 s8 rb;
176169 };
177170
178
-/*
179
- * sunxi HW ECC infos: stores information related to HW ECC support
171
+/**
172
+ * struct sunxi_nand_hw_ecc - stores information related to HW ECC support
180173 *
181
- * @mode: the sunxi ECC mode field deduced from ECC requirements
174
+ * @mode: the sunxi ECC mode field deduced from ECC requirements
182175 */
183176 struct sunxi_nand_hw_ecc {
184177 int mode;
185178 };
186179
187
-/*
188
- * NAND chip structure: stores NAND chip device related information
180
+/**
181
+ * struct sunxi_nand_chip - stores NAND chip device related information
189182 *
190
- * @node: used to store NAND chips into a list
191
- * @nand: base NAND chip structure
192
- * @mtd: base MTD structure
193
- * @clk_rate: clk_rate required for this NAND chip
194
- * @timing_cfg TIMING_CFG register value for this NAND chip
195
- * @selected: current active CS
196
- * @nsels: number of CS lines required by the NAND chip
197
- * @sels: array of CS lines descriptions
183
+ * @node: used to store NAND chips into a list
184
+ * @nand: base NAND chip structure
185
+ * @clk_rate: clk_rate required for this NAND chip
186
+ * @timing_cfg: TIMING_CFG register value for this NAND chip
187
+ * @timing_ctl: TIMING_CTL register value for this NAND chip
188
+ * @nsels: number of CS lines required by the NAND chip
189
+ * @sels: array of CS lines descriptions
198190 */
199191 struct sunxi_nand_chip {
200192 struct list_head node;
....@@ -202,13 +194,8 @@
202194 unsigned long clk_rate;
203195 u32 timing_cfg;
204196 u32 timing_ctl;
205
- int selected;
206
- int addr_cycles;
207
- u32 addr[2];
208
- int cmd_cycles;
209
- u8 cmd[2];
210197 int nsels;
211
- struct sunxi_nand_chip_sel sels[0];
198
+ struct sunxi_nand_chip_sel sels[];
212199 };
213200
214201 static inline struct sunxi_nand_chip *to_sunxi_nand(struct nand_chip *nand)
....@@ -217,19 +204,35 @@
217204 }
218205
219206 /*
220
- * NAND Controller structure: stores sunxi NAND controller information
207
+ * NAND Controller capabilities structure: stores NAND controller capabilities
208
+ * for distinction between compatible strings.
221209 *
222
- * @controller: base controller structure
223
- * @dev: parent device (used to print error messages)
224
- * @regs: NAND controller registers
225
- * @ahb_clk: NAND Controller AHB clock
226
- * @mod_clk: NAND Controller mod clock
227
- * @assigned_cs: bitmask describing already assigned CS lines
228
- * @clk_rate: NAND controller current clock rate
229
- * @chips: a list containing all the NAND chips attached to
230
- * this NAND controller
231
- * @complete: a completion object used to wait for NAND
232
- * controller events
210
+ * @extra_mbus_conf: Contrary to A10, A10s and A13, accessing internal RAM
211
+ * through MBUS on A23/A33 needs extra configuration.
212
+ * @reg_io_data: I/O data register
213
+ * @dma_maxburst: DMA maxburst
214
+ */
215
+struct sunxi_nfc_caps {
216
+ bool extra_mbus_conf;
217
+ unsigned int reg_io_data;
218
+ unsigned int dma_maxburst;
219
+};
220
+
221
+/**
222
+ * struct sunxi_nfc - stores sunxi NAND controller information
223
+ *
224
+ * @controller: base controller structure
225
+ * @dev: parent device (used to print error messages)
226
+ * @regs: NAND controller registers
227
+ * @ahb_clk: NAND controller AHB clock
228
+ * @mod_clk: NAND controller mod clock
229
+ * @reset: NAND controller reset line
230
+ * @assigned_cs: bitmask describing already assigned CS lines
231
+ * @clk_rate: NAND controller current clock rate
232
+ * @chips: a list containing all the NAND chips attached to this NAND
233
+ * controller
234
+ * @complete: a completion object used to wait for NAND controller events
235
+ * @dmac: the DMA channel attached to the NAND controller
233236 */
234237 struct sunxi_nfc {
235238 struct nand_controller controller;
....@@ -243,6 +246,7 @@
243246 struct list_head chips;
244247 struct completion complete;
245248 struct dma_chan *dmac;
249
+ const struct sunxi_nfc_caps *caps;
246250 };
247251
248252 static inline struct sunxi_nfc *to_sunxi_nfc(struct nand_controller *ctrl)
....@@ -339,13 +343,11 @@
339343 return ret;
340344 }
341345
342
-static int sunxi_nfc_dma_op_prepare(struct mtd_info *mtd, const void *buf,
346
+static int sunxi_nfc_dma_op_prepare(struct sunxi_nfc *nfc, const void *buf,
343347 int chunksize, int nchunks,
344348 enum dma_data_direction ddir,
345349 struct scatterlist *sg)
346350 {
347
- struct nand_chip *nand = mtd_to_nand(mtd);
348
- struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
349351 struct dma_async_tx_descriptor *dmad;
350352 enum dma_transfer_direction tdir;
351353 dma_cookie_t dmat;
....@@ -371,6 +373,9 @@
371373 nfc->regs + NFC_REG_CTL);
372374 writel(nchunks, nfc->regs + NFC_REG_SECTOR_NUM);
373375 writel(chunksize, nfc->regs + NFC_REG_CNT);
376
+ if (nfc->caps->extra_mbus_conf)
377
+ writel(chunksize * nchunks, nfc->regs + NFC_REG_MDMA_CNT);
378
+
374379 dmat = dmaengine_submit(dmad);
375380
376381 ret = dma_submit_error(dmat);
....@@ -388,85 +393,48 @@
388393 return ret;
389394 }
390395
391
-static void sunxi_nfc_dma_op_cleanup(struct mtd_info *mtd,
396
+static void sunxi_nfc_dma_op_cleanup(struct sunxi_nfc *nfc,
392397 enum dma_data_direction ddir,
393398 struct scatterlist *sg)
394399 {
395
- struct nand_chip *nand = mtd_to_nand(mtd);
396
- struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
397
-
398400 dma_unmap_sg(nfc->dev, sg, 1, ddir);
399401 writel(readl(nfc->regs + NFC_REG_CTL) & ~NFC_RAM_METHOD,
400402 nfc->regs + NFC_REG_CTL);
401403 }
402404
403
-static int sunxi_nfc_dev_ready(struct mtd_info *mtd)
405
+static void sunxi_nfc_select_chip(struct nand_chip *nand, unsigned int cs)
404406 {
405
- struct nand_chip *nand = mtd_to_nand(mtd);
406
- struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
407
- struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
408
- u32 mask;
409
-
410
- if (sunxi_nand->selected < 0)
411
- return 0;
412
-
413
- if (sunxi_nand->sels[sunxi_nand->selected].rb < 0) {
414
- dev_err(nfc->dev, "cannot check R/B NAND status!\n");
415
- return 0;
416
- }
417
-
418
- mask = NFC_RB_STATE(sunxi_nand->sels[sunxi_nand->selected].rb);
419
-
420
- return !!(readl(nfc->regs + NFC_REG_ST) & mask);
421
-}
422
-
423
-static void sunxi_nfc_select_chip(struct mtd_info *mtd, int chip)
424
-{
425
- struct nand_chip *nand = mtd_to_nand(mtd);
407
+ struct mtd_info *mtd = nand_to_mtd(nand);
426408 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
427409 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
428410 struct sunxi_nand_chip_sel *sel;
429411 u32 ctl;
430412
431
- if (chip > 0 && chip >= sunxi_nand->nsels)
432
- return;
433
-
434
- if (chip == sunxi_nand->selected)
413
+ if (cs > 0 && cs >= sunxi_nand->nsels)
435414 return;
436415
437416 ctl = readl(nfc->regs + NFC_REG_CTL) &
438417 ~(NFC_PAGE_SHIFT_MSK | NFC_CE_SEL_MSK | NFC_RB_SEL_MSK | NFC_EN);
439418
440
- if (chip >= 0) {
441
- sel = &sunxi_nand->sels[chip];
419
+ sel = &sunxi_nand->sels[cs];
420
+ ctl |= NFC_CE_SEL(sel->cs) | NFC_EN | NFC_PAGE_SHIFT(nand->page_shift);
421
+ if (sel->rb >= 0)
422
+ ctl |= NFC_RB_SEL(sel->rb);
442423
443
- ctl |= NFC_CE_SEL(sel->cs) | NFC_EN |
444
- NFC_PAGE_SHIFT(nand->page_shift);
445
- if (sel->rb < 0) {
446
- nand->dev_ready = NULL;
447
- } else {
448
- nand->dev_ready = sunxi_nfc_dev_ready;
449
- ctl |= NFC_RB_SEL(sel->rb);
450
- }
424
+ writel(mtd->writesize, nfc->regs + NFC_REG_SPARE_AREA);
451425
452
- writel(mtd->writesize, nfc->regs + NFC_REG_SPARE_AREA);
453
-
454
- if (nfc->clk_rate != sunxi_nand->clk_rate) {
455
- clk_set_rate(nfc->mod_clk, sunxi_nand->clk_rate);
456
- nfc->clk_rate = sunxi_nand->clk_rate;
457
- }
426
+ if (nfc->clk_rate != sunxi_nand->clk_rate) {
427
+ clk_set_rate(nfc->mod_clk, sunxi_nand->clk_rate);
428
+ nfc->clk_rate = sunxi_nand->clk_rate;
458429 }
459430
460431 writel(sunxi_nand->timing_ctl, nfc->regs + NFC_REG_TIMING_CTL);
461432 writel(sunxi_nand->timing_cfg, nfc->regs + NFC_REG_TIMING_CFG);
462433 writel(ctl, nfc->regs + NFC_REG_CTL);
463
-
464
- sunxi_nand->selected = chip;
465434 }
466435
467
-static void sunxi_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
436
+static void sunxi_nfc_read_buf(struct nand_chip *nand, uint8_t *buf, int len)
468437 {
469
- struct nand_chip *nand = mtd_to_nand(mtd);
470438 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
471439 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
472440 int ret;
....@@ -502,10 +470,9 @@
502470 }
503471 }
504472
505
-static void sunxi_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf,
473
+static void sunxi_nfc_write_buf(struct nand_chip *nand, const uint8_t *buf,
506474 int len)
507475 {
508
- struct nand_chip *nand = mtd_to_nand(mtd);
509476 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
510477 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
511478 int ret;
....@@ -537,72 +504,6 @@
537504 break;
538505
539506 offs += cnt;
540
- }
541
-}
542
-
543
-static uint8_t sunxi_nfc_read_byte(struct mtd_info *mtd)
544
-{
545
- uint8_t ret = 0;
546
-
547
- sunxi_nfc_read_buf(mtd, &ret, 1);
548
-
549
- return ret;
550
-}
551
-
552
-static void sunxi_nfc_cmd_ctrl(struct mtd_info *mtd, int dat,
553
- unsigned int ctrl)
554
-{
555
- struct nand_chip *nand = mtd_to_nand(mtd);
556
- struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
557
- struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
558
- int ret;
559
-
560
- if (dat == NAND_CMD_NONE && (ctrl & NAND_NCE) &&
561
- !(ctrl & (NAND_CLE | NAND_ALE))) {
562
- u32 cmd = 0;
563
-
564
- if (!sunxi_nand->addr_cycles && !sunxi_nand->cmd_cycles)
565
- return;
566
-
567
- if (sunxi_nand->cmd_cycles--)
568
- cmd |= NFC_SEND_CMD1 | sunxi_nand->cmd[0];
569
-
570
- if (sunxi_nand->cmd_cycles--) {
571
- cmd |= NFC_SEND_CMD2;
572
- writel(sunxi_nand->cmd[1],
573
- nfc->regs + NFC_REG_RCMD_SET);
574
- }
575
-
576
- sunxi_nand->cmd_cycles = 0;
577
-
578
- if (sunxi_nand->addr_cycles) {
579
- cmd |= NFC_SEND_ADR |
580
- NFC_ADR_NUM(sunxi_nand->addr_cycles);
581
- writel(sunxi_nand->addr[0],
582
- nfc->regs + NFC_REG_ADDR_LOW);
583
- }
584
-
585
- if (sunxi_nand->addr_cycles > 4)
586
- writel(sunxi_nand->addr[1],
587
- nfc->regs + NFC_REG_ADDR_HIGH);
588
-
589
- ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
590
- if (ret)
591
- return;
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_events(nfc, NFC_CMD_INT_FLAG, true, 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++;
606507 }
607508 }
608509
....@@ -688,8 +589,10 @@
688589 return state;
689590 }
690591
691
-static u16 sunxi_nfc_randomizer_state(struct mtd_info *mtd, int page, bool ecc)
592
+static u16 sunxi_nfc_randomizer_state(struct nand_chip *nand, int page,
593
+ bool ecc)
692594 {
595
+ struct mtd_info *mtd = nand_to_mtd(nand);
693596 const u16 *seeds = sunxi_nfc_randomizer_page_seeds;
694597 int mod = mtd_div_by_ws(mtd->erasesize, mtd);
695598
....@@ -706,10 +609,9 @@
706609 return seeds[page % mod];
707610 }
708611
709
-static void sunxi_nfc_randomizer_config(struct mtd_info *mtd,
710
- int page, bool ecc)
612
+static void sunxi_nfc_randomizer_config(struct nand_chip *nand, int page,
613
+ bool ecc)
711614 {
712
- struct nand_chip *nand = mtd_to_nand(mtd);
713615 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
714616 u32 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL);
715617 u16 state;
....@@ -718,14 +620,13 @@
718620 return;
719621
720622 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL);
721
- state = sunxi_nfc_randomizer_state(mtd, page, ecc);
623
+ state = sunxi_nfc_randomizer_state(nand, page, ecc);
722624 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_RANDOM_SEED_MSK;
723625 writel(ecc_ctl | NFC_RANDOM_SEED(state), nfc->regs + NFC_REG_ECC_CTL);
724626 }
725627
726
-static void sunxi_nfc_randomizer_enable(struct mtd_info *mtd)
628
+static void sunxi_nfc_randomizer_enable(struct nand_chip *nand)
727629 {
728
- struct nand_chip *nand = mtd_to_nand(mtd);
729630 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
730631
731632 if (!(nand->options & NAND_NEED_SCRAMBLING))
....@@ -735,9 +636,8 @@
735636 nfc->regs + NFC_REG_ECC_CTL);
736637 }
737638
738
-static void sunxi_nfc_randomizer_disable(struct mtd_info *mtd)
639
+static void sunxi_nfc_randomizer_disable(struct nand_chip *nand)
739640 {
740
- struct nand_chip *nand = mtd_to_nand(mtd);
741641 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
742642
743643 if (!(nand->options & NAND_NEED_SCRAMBLING))
....@@ -747,36 +647,35 @@
747647 nfc->regs + NFC_REG_ECC_CTL);
748648 }
749649
750
-static void sunxi_nfc_randomize_bbm(struct mtd_info *mtd, int page, u8 *bbm)
650
+static void sunxi_nfc_randomize_bbm(struct nand_chip *nand, int page, u8 *bbm)
751651 {
752
- u16 state = sunxi_nfc_randomizer_state(mtd, page, true);
652
+ u16 state = sunxi_nfc_randomizer_state(nand, page, true);
753653
754654 bbm[0] ^= state;
755655 bbm[1] ^= sunxi_nfc_randomizer_step(state, 8);
756656 }
757657
758
-static void sunxi_nfc_randomizer_write_buf(struct mtd_info *mtd,
658
+static void sunxi_nfc_randomizer_write_buf(struct nand_chip *nand,
759659 const uint8_t *buf, int len,
760660 bool ecc, int page)
761661 {
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);
662
+ sunxi_nfc_randomizer_config(nand, page, ecc);
663
+ sunxi_nfc_randomizer_enable(nand);
664
+ sunxi_nfc_write_buf(nand, buf, len);
665
+ sunxi_nfc_randomizer_disable(nand);
766666 }
767667
768
-static void sunxi_nfc_randomizer_read_buf(struct mtd_info *mtd, uint8_t *buf,
668
+static void sunxi_nfc_randomizer_read_buf(struct nand_chip *nand, uint8_t *buf,
769669 int len, bool ecc, int page)
770670 {
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);
671
+ sunxi_nfc_randomizer_config(nand, page, ecc);
672
+ sunxi_nfc_randomizer_enable(nand);
673
+ sunxi_nfc_read_buf(nand, buf, len);
674
+ sunxi_nfc_randomizer_disable(nand);
775675 }
776676
777
-static void sunxi_nfc_hw_ecc_enable(struct mtd_info *mtd)
677
+static void sunxi_nfc_hw_ecc_enable(struct nand_chip *nand)
778678 {
779
- struct nand_chip *nand = mtd_to_nand(mtd);
780679 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
781680 struct sunxi_nand_hw_ecc *data = nand->ecc.priv;
782681 u32 ecc_ctl;
....@@ -793,9 +692,8 @@
793692 writel(ecc_ctl, nfc->regs + NFC_REG_ECC_CTL);
794693 }
795694
796
-static void sunxi_nfc_hw_ecc_disable(struct mtd_info *mtd)
695
+static void sunxi_nfc_hw_ecc_disable(struct nand_chip *nand)
797696 {
798
- struct nand_chip *nand = mtd_to_nand(mtd);
799697 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
800698
801699 writel(readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_ECC_EN,
....@@ -815,10 +713,9 @@
815713 return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
816714 }
817715
818
-static void sunxi_nfc_hw_ecc_get_prot_oob_bytes(struct mtd_info *mtd, u8 *oob,
716
+static void sunxi_nfc_hw_ecc_get_prot_oob_bytes(struct nand_chip *nand, u8 *oob,
819717 int step, bool bbm, int page)
820718 {
821
- struct nand_chip *nand = mtd_to_nand(mtd);
822719 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
823720
824721 sunxi_nfc_user_data_to_buf(readl(nfc->regs + NFC_REG_USER_DATA(step)),
....@@ -826,21 +723,20 @@
826723
827724 /* De-randomize the Bad Block Marker. */
828725 if (bbm && (nand->options & NAND_NEED_SCRAMBLING))
829
- sunxi_nfc_randomize_bbm(mtd, page, oob);
726
+ sunxi_nfc_randomize_bbm(nand, page, oob);
830727 }
831728
832
-static void sunxi_nfc_hw_ecc_set_prot_oob_bytes(struct mtd_info *mtd,
729
+static void sunxi_nfc_hw_ecc_set_prot_oob_bytes(struct nand_chip *nand,
833730 const u8 *oob, int step,
834731 bool bbm, int page)
835732 {
836
- struct nand_chip *nand = mtd_to_nand(mtd);
837733 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
838734 u8 user_data[4];
839735
840736 /* Randomize the Bad Block Marker. */
841737 if (bbm && (nand->options & NAND_NEED_SCRAMBLING)) {
842738 memcpy(user_data, oob, sizeof(user_data));
843
- sunxi_nfc_randomize_bbm(mtd, page, user_data);
739
+ sunxi_nfc_randomize_bbm(nand, page, user_data);
844740 oob = user_data;
845741 }
846742
....@@ -848,9 +744,11 @@
848744 nfc->regs + NFC_REG_USER_DATA(step));
849745 }
850746
851
-static void sunxi_nfc_hw_ecc_update_stats(struct mtd_info *mtd,
747
+static void sunxi_nfc_hw_ecc_update_stats(struct nand_chip *nand,
852748 unsigned int *max_bitflips, int ret)
853749 {
750
+ struct mtd_info *mtd = nand_to_mtd(nand);
751
+
854752 if (ret < 0) {
855753 mtd->ecc_stats.failed++;
856754 } else {
....@@ -859,10 +757,9 @@
859757 }
860758 }
861759
862
-static int sunxi_nfc_hw_ecc_correct(struct mtd_info *mtd, u8 *data, u8 *oob,
760
+static int sunxi_nfc_hw_ecc_correct(struct nand_chip *nand, u8 *data, u8 *oob,
863761 int step, u32 status, bool *erased)
864762 {
865
- struct nand_chip *nand = mtd_to_nand(mtd);
866763 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
867764 struct nand_ecc_ctrl *ecc = &nand->ecc;
868765 u32 tmp;
....@@ -896,14 +793,13 @@
896793 return NFC_ECC_ERR_CNT(step, tmp);
897794 }
898795
899
-static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd,
796
+static int sunxi_nfc_hw_ecc_read_chunk(struct nand_chip *nand,
900797 u8 *data, int data_off,
901798 u8 *oob, int oob_off,
902799 int *cur_off,
903800 unsigned int *max_bitflips,
904801 bool bbm, bool oob_required, int page)
905802 {
906
- struct nand_chip *nand = mtd_to_nand(mtd);
907803 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
908804 struct nand_ecc_ctrl *ecc = &nand->ecc;
909805 int raw_mode = 0;
....@@ -913,7 +809,7 @@
913809 if (*cur_off != data_off)
914810 nand_change_read_column_op(nand, data_off, NULL, 0, false);
915811
916
- sunxi_nfc_randomizer_read_buf(mtd, NULL, ecc->size, false, page);
812
+ sunxi_nfc_randomizer_read_buf(nand, NULL, ecc->size, false, page);
917813
918814 if (data_off + ecc->size != oob_off)
919815 nand_change_read_column_op(nand, oob_off, NULL, 0, false);
....@@ -922,18 +818,18 @@
922818 if (ret)
923819 return ret;
924820
925
- sunxi_nfc_randomizer_enable(mtd);
821
+ sunxi_nfc_randomizer_enable(nand);
926822 writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_ECC_OP,
927823 nfc->regs + NFC_REG_CMD);
928824
929825 ret = sunxi_nfc_wait_events(nfc, NFC_CMD_INT_FLAG, false, 0);
930
- sunxi_nfc_randomizer_disable(mtd);
826
+ sunxi_nfc_randomizer_disable(nand);
931827 if (ret)
932828 return ret;
933829
934830 *cur_off = oob_off + ecc->bytes + 4;
935831
936
- ret = sunxi_nfc_hw_ecc_correct(mtd, data, oob_required ? oob : NULL, 0,
832
+ ret = sunxi_nfc_hw_ecc_correct(nand, data, oob_required ? oob : NULL, 0,
937833 readl(nfc->regs + NFC_REG_ECC_ST),
938834 &erased);
939835 if (erased)
....@@ -965,24 +861,24 @@
965861 if (oob_required) {
966862 nand_change_read_column_op(nand, oob_off, NULL, 0,
967863 false);
968
- sunxi_nfc_randomizer_read_buf(mtd, oob, ecc->bytes + 4,
864
+ sunxi_nfc_randomizer_read_buf(nand, oob, ecc->bytes + 4,
969865 true, page);
970866
971
- sunxi_nfc_hw_ecc_get_prot_oob_bytes(mtd, oob, 0,
867
+ sunxi_nfc_hw_ecc_get_prot_oob_bytes(nand, oob, 0,
972868 bbm, page);
973869 }
974870 }
975871
976
- sunxi_nfc_hw_ecc_update_stats(mtd, max_bitflips, ret);
872
+ sunxi_nfc_hw_ecc_update_stats(nand, max_bitflips, ret);
977873
978874 return raw_mode;
979875 }
980876
981
-static void sunxi_nfc_hw_ecc_read_extra_oob(struct mtd_info *mtd,
877
+static void sunxi_nfc_hw_ecc_read_extra_oob(struct nand_chip *nand,
982878 u8 *oob, int *cur_off,
983879 bool randomize, int page)
984880 {
985
- struct nand_chip *nand = mtd_to_nand(mtd);
881
+ struct mtd_info *mtd = nand_to_mtd(nand);
986882 struct nand_ecc_ctrl *ecc = &nand->ecc;
987883 int offset = ((ecc->bytes + 4) * ecc->steps);
988884 int len = mtd->oobsize - offset;
....@@ -995,22 +891,22 @@
995891 false);
996892
997893 if (!randomize)
998
- sunxi_nfc_read_buf(mtd, oob + offset, len);
894
+ sunxi_nfc_read_buf(nand, oob + offset, len);
999895 else
1000
- sunxi_nfc_randomizer_read_buf(mtd, oob + offset, len,
896
+ sunxi_nfc_randomizer_read_buf(nand, oob + offset, len,
1001897 false, page);
1002898
1003899 if (cur_off)
1004900 *cur_off = mtd->oobsize + mtd->writesize;
1005901 }
1006902
1007
-static int sunxi_nfc_hw_ecc_read_chunks_dma(struct mtd_info *mtd, uint8_t *buf,
903
+static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, uint8_t *buf,
1008904 int oob_required, int page,
1009905 int nchunks)
1010906 {
1011
- struct nand_chip *nand = mtd_to_nand(mtd);
1012907 bool randomized = nand->options & NAND_NEED_SCRAMBLING;
1013908 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
909
+ struct mtd_info *mtd = nand_to_mtd(nand);
1014910 struct nand_ecc_ctrl *ecc = &nand->ecc;
1015911 unsigned int max_bitflips = 0;
1016912 int ret, i, raw_mode = 0;
....@@ -1021,14 +917,14 @@
1021917 if (ret)
1022918 return ret;
1023919
1024
- ret = sunxi_nfc_dma_op_prepare(mtd, buf, ecc->size, nchunks,
920
+ ret = sunxi_nfc_dma_op_prepare(nfc, buf, ecc->size, nchunks,
1025921 DMA_FROM_DEVICE, &sg);
1026922 if (ret)
1027923 return ret;
1028924
1029
- sunxi_nfc_hw_ecc_enable(mtd);
1030
- sunxi_nfc_randomizer_config(mtd, page, false);
1031
- sunxi_nfc_randomizer_enable(mtd);
925
+ sunxi_nfc_hw_ecc_enable(nand);
926
+ sunxi_nfc_randomizer_config(nand, page, false);
927
+ sunxi_nfc_randomizer_enable(nand);
1032928
1033929 writel((NAND_CMD_RNDOUTSTART << 16) | (NAND_CMD_RNDOUT << 8) |
1034930 NAND_CMD_READSTART, nfc->regs + NFC_REG_RCMD_SET);
....@@ -1042,10 +938,10 @@
1042938 if (ret)
1043939 dmaengine_terminate_all(nfc->dmac);
1044940
1045
- sunxi_nfc_randomizer_disable(mtd);
1046
- sunxi_nfc_hw_ecc_disable(mtd);
941
+ sunxi_nfc_randomizer_disable(nand);
942
+ sunxi_nfc_hw_ecc_disable(nand);
1047943
1048
- sunxi_nfc_dma_op_cleanup(mtd, DMA_FROM_DEVICE, &sg);
944
+ sunxi_nfc_dma_op_cleanup(nfc, DMA_FROM_DEVICE, &sg);
1049945
1050946 if (ret)
1051947 return ret;
....@@ -1059,7 +955,7 @@
1059955 u8 *oob = nand->oob_poi + oob_off;
1060956 bool erased;
1061957
1062
- ret = sunxi_nfc_hw_ecc_correct(mtd, randomized ? data : NULL,
958
+ ret = sunxi_nfc_hw_ecc_correct(nand, randomized ? data : NULL,
1063959 oob_required ? oob : NULL,
1064960 i, status, &erased);
1065961
....@@ -1073,14 +969,14 @@
1073969 mtd->writesize + oob_off,
1074970 oob, ecc->bytes + 4, false);
1075971
1076
- sunxi_nfc_hw_ecc_get_prot_oob_bytes(mtd, oob, i,
972
+ sunxi_nfc_hw_ecc_get_prot_oob_bytes(nand, oob, i,
1077973 !i, page);
1078974 }
1079975
1080976 if (erased)
1081977 raw_mode = 1;
1082978
1083
- sunxi_nfc_hw_ecc_update_stats(mtd, &max_bitflips, ret);
979
+ sunxi_nfc_hw_ecc_update_stats(nand, &max_bitflips, ret);
1084980 }
1085981
1086982 if (status & NFC_ECC_ERR_MSK) {
....@@ -1115,25 +1011,24 @@
11151011 if (ret >= 0)
11161012 raw_mode = 1;
11171013
1118
- sunxi_nfc_hw_ecc_update_stats(mtd, &max_bitflips, ret);
1014
+ sunxi_nfc_hw_ecc_update_stats(nand, &max_bitflips, ret);
11191015 }
11201016 }
11211017
11221018 if (oob_required)
1123
- sunxi_nfc_hw_ecc_read_extra_oob(mtd, nand->oob_poi,
1019
+ sunxi_nfc_hw_ecc_read_extra_oob(nand, nand->oob_poi,
11241020 NULL, !raw_mode,
11251021 page);
11261022
11271023 return max_bitflips;
11281024 }
11291025
1130
-static int sunxi_nfc_hw_ecc_write_chunk(struct mtd_info *mtd,
1026
+static int sunxi_nfc_hw_ecc_write_chunk(struct nand_chip *nand,
11311027 const u8 *data, int data_off,
11321028 const u8 *oob, int oob_off,
11331029 int *cur_off, bool bbm,
11341030 int page)
11351031 {
1136
- struct nand_chip *nand = mtd_to_nand(mtd);
11371032 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
11381033 struct nand_ecc_ctrl *ecc = &nand->ecc;
11391034 int ret;
....@@ -1141,7 +1036,7 @@
11411036 if (data_off != *cur_off)
11421037 nand_change_write_column_op(nand, data_off, NULL, 0, false);
11431038
1144
- sunxi_nfc_randomizer_write_buf(mtd, data, ecc->size, false, page);
1039
+ sunxi_nfc_randomizer_write_buf(nand, data, ecc->size, false, page);
11451040
11461041 if (data_off + ecc->size != oob_off)
11471042 nand_change_write_column_op(nand, oob_off, NULL, 0, false);
....@@ -1150,15 +1045,15 @@
11501045 if (ret)
11511046 return ret;
11521047
1153
- sunxi_nfc_randomizer_enable(mtd);
1154
- sunxi_nfc_hw_ecc_set_prot_oob_bytes(mtd, oob, 0, bbm, page);
1048
+ sunxi_nfc_randomizer_enable(nand);
1049
+ sunxi_nfc_hw_ecc_set_prot_oob_bytes(nand, oob, 0, bbm, page);
11551050
11561051 writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD |
11571052 NFC_ACCESS_DIR | NFC_ECC_OP,
11581053 nfc->regs + NFC_REG_CMD);
11591054
11601055 ret = sunxi_nfc_wait_events(nfc, NFC_CMD_INT_FLAG, false, 0);
1161
- sunxi_nfc_randomizer_disable(mtd);
1056
+ sunxi_nfc_randomizer_disable(nand);
11621057 if (ret)
11631058 return ret;
11641059
....@@ -1167,11 +1062,11 @@
11671062 return 0;
11681063 }
11691064
1170
-static void sunxi_nfc_hw_ecc_write_extra_oob(struct mtd_info *mtd,
1065
+static void sunxi_nfc_hw_ecc_write_extra_oob(struct nand_chip *nand,
11711066 u8 *oob, int *cur_off,
11721067 int page)
11731068 {
1174
- struct nand_chip *nand = mtd_to_nand(mtd);
1069
+ struct mtd_info *mtd = nand_to_mtd(nand);
11751070 struct nand_ecc_ctrl *ecc = &nand->ecc;
11761071 int offset = ((ecc->bytes + 4) * ecc->steps);
11771072 int len = mtd->oobsize - offset;
....@@ -1183,32 +1078,34 @@
11831078 nand_change_write_column_op(nand, offset + mtd->writesize,
11841079 NULL, 0, false);
11851080
1186
- sunxi_nfc_randomizer_write_buf(mtd, oob + offset, len, false, page);
1081
+ sunxi_nfc_randomizer_write_buf(nand, oob + offset, len, false, page);
11871082
11881083 if (cur_off)
11891084 *cur_off = mtd->oobsize + mtd->writesize;
11901085 }
11911086
1192
-static int sunxi_nfc_hw_ecc_read_page(struct mtd_info *mtd,
1193
- struct nand_chip *chip, uint8_t *buf,
1087
+static int sunxi_nfc_hw_ecc_read_page(struct nand_chip *nand, uint8_t *buf,
11941088 int oob_required, int page)
11951089 {
1196
- struct nand_ecc_ctrl *ecc = &chip->ecc;
1090
+ struct mtd_info *mtd = nand_to_mtd(nand);
1091
+ struct nand_ecc_ctrl *ecc = &nand->ecc;
11971092 unsigned int max_bitflips = 0;
11981093 int ret, i, cur_off = 0;
11991094 bool raw_mode = false;
12001095
1201
- nand_read_page_op(chip, page, 0, NULL, 0);
1096
+ sunxi_nfc_select_chip(nand, nand->cur_cs);
12021097
1203
- sunxi_nfc_hw_ecc_enable(mtd);
1098
+ nand_read_page_op(nand, page, 0, NULL, 0);
1099
+
1100
+ sunxi_nfc_hw_ecc_enable(nand);
12041101
12051102 for (i = 0; i < ecc->steps; i++) {
12061103 int data_off = i * ecc->size;
12071104 int oob_off = i * (ecc->bytes + 4);
12081105 u8 *data = buf + data_off;
1209
- u8 *oob = chip->oob_poi + oob_off;
1106
+ u8 *oob = nand->oob_poi + oob_off;
12101107
1211
- ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off, oob,
1108
+ ret = sunxi_nfc_hw_ecc_read_chunk(nand, data, data_off, oob,
12121109 oob_off + mtd->writesize,
12131110 &cur_off, &max_bitflips,
12141111 !i, oob_required, page);
....@@ -1219,52 +1116,55 @@
12191116 }
12201117
12211118 if (oob_required)
1222
- sunxi_nfc_hw_ecc_read_extra_oob(mtd, chip->oob_poi, &cur_off,
1119
+ sunxi_nfc_hw_ecc_read_extra_oob(nand, nand->oob_poi, &cur_off,
12231120 !raw_mode, page);
12241121
1225
- sunxi_nfc_hw_ecc_disable(mtd);
1122
+ sunxi_nfc_hw_ecc_disable(nand);
12261123
12271124 return max_bitflips;
12281125 }
12291126
1230
-static int sunxi_nfc_hw_ecc_read_page_dma(struct mtd_info *mtd,
1231
- struct nand_chip *chip, u8 *buf,
1127
+static int sunxi_nfc_hw_ecc_read_page_dma(struct nand_chip *nand, u8 *buf,
12321128 int oob_required, int page)
12331129 {
12341130 int ret;
12351131
1236
- nand_read_page_op(chip, page, 0, NULL, 0);
1132
+ sunxi_nfc_select_chip(nand, nand->cur_cs);
12371133
1238
- ret = sunxi_nfc_hw_ecc_read_chunks_dma(mtd, buf, oob_required, page,
1239
- chip->ecc.steps);
1134
+ nand_read_page_op(nand, page, 0, NULL, 0);
1135
+
1136
+ ret = sunxi_nfc_hw_ecc_read_chunks_dma(nand, buf, oob_required, page,
1137
+ nand->ecc.steps);
12401138 if (ret >= 0)
12411139 return ret;
12421140
12431141 /* Fallback to PIO mode */
1244
- return sunxi_nfc_hw_ecc_read_page(mtd, chip, buf, oob_required, page);
1142
+ return sunxi_nfc_hw_ecc_read_page(nand, buf, oob_required, page);
12451143 }
12461144
1247
-static int sunxi_nfc_hw_ecc_read_subpage(struct mtd_info *mtd,
1248
- struct nand_chip *chip,
1145
+static int sunxi_nfc_hw_ecc_read_subpage(struct nand_chip *nand,
12491146 u32 data_offs, u32 readlen,
12501147 u8 *bufpoi, int page)
12511148 {
1252
- struct nand_ecc_ctrl *ecc = &chip->ecc;
1149
+ struct mtd_info *mtd = nand_to_mtd(nand);
1150
+ struct nand_ecc_ctrl *ecc = &nand->ecc;
12531151 int ret, i, cur_off = 0;
12541152 unsigned int max_bitflips = 0;
12551153
1256
- nand_read_page_op(chip, page, 0, NULL, 0);
1154
+ sunxi_nfc_select_chip(nand, nand->cur_cs);
12571155
1258
- sunxi_nfc_hw_ecc_enable(mtd);
1156
+ nand_read_page_op(nand, page, 0, NULL, 0);
1157
+
1158
+ sunxi_nfc_hw_ecc_enable(nand);
12591159
12601160 for (i = data_offs / ecc->size;
12611161 i < DIV_ROUND_UP(data_offs + readlen, ecc->size); i++) {
12621162 int data_off = i * ecc->size;
12631163 int oob_off = i * (ecc->bytes + 4);
12641164 u8 *data = bufpoi + data_off;
1265
- u8 *oob = chip->oob_poi + oob_off;
1165
+ u8 *oob = nand->oob_poi + oob_off;
12661166
1267
- ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off,
1167
+ ret = sunxi_nfc_hw_ecc_read_chunk(nand, data, data_off,
12681168 oob,
12691169 oob_off + mtd->writesize,
12701170 &cur_off, &max_bitflips, !i,
....@@ -1273,113 +1173,118 @@
12731173 return ret;
12741174 }
12751175
1276
- sunxi_nfc_hw_ecc_disable(mtd);
1176
+ sunxi_nfc_hw_ecc_disable(nand);
12771177
12781178 return max_bitflips;
12791179 }
12801180
1281
-static int sunxi_nfc_hw_ecc_read_subpage_dma(struct mtd_info *mtd,
1282
- struct nand_chip *chip,
1181
+static int sunxi_nfc_hw_ecc_read_subpage_dma(struct nand_chip *nand,
12831182 u32 data_offs, u32 readlen,
12841183 u8 *buf, int page)
12851184 {
1286
- int nchunks = DIV_ROUND_UP(data_offs + readlen, chip->ecc.size);
1185
+ int nchunks = DIV_ROUND_UP(data_offs + readlen, nand->ecc.size);
12871186 int ret;
12881187
1289
- nand_read_page_op(chip, page, 0, NULL, 0);
1188
+ sunxi_nfc_select_chip(nand, nand->cur_cs);
12901189
1291
- ret = sunxi_nfc_hw_ecc_read_chunks_dma(mtd, buf, false, page, nchunks);
1190
+ nand_read_page_op(nand, page, 0, NULL, 0);
1191
+
1192
+ ret = sunxi_nfc_hw_ecc_read_chunks_dma(nand, buf, false, page, nchunks);
12921193 if (ret >= 0)
12931194 return ret;
12941195
12951196 /* Fallback to PIO mode */
1296
- return sunxi_nfc_hw_ecc_read_subpage(mtd, chip, data_offs, readlen,
1197
+ return sunxi_nfc_hw_ecc_read_subpage(nand, data_offs, readlen,
12971198 buf, page);
12981199 }
12991200
1300
-static int sunxi_nfc_hw_ecc_write_page(struct mtd_info *mtd,
1301
- struct nand_chip *chip,
1201
+static int sunxi_nfc_hw_ecc_write_page(struct nand_chip *nand,
13021202 const uint8_t *buf, int oob_required,
13031203 int page)
13041204 {
1305
- struct nand_ecc_ctrl *ecc = &chip->ecc;
1205
+ struct mtd_info *mtd = nand_to_mtd(nand);
1206
+ struct nand_ecc_ctrl *ecc = &nand->ecc;
13061207 int ret, i, cur_off = 0;
13071208
1308
- nand_prog_page_begin_op(chip, page, 0, NULL, 0);
1209
+ sunxi_nfc_select_chip(nand, nand->cur_cs);
13091210
1310
- sunxi_nfc_hw_ecc_enable(mtd);
1211
+ nand_prog_page_begin_op(nand, page, 0, NULL, 0);
1212
+
1213
+ sunxi_nfc_hw_ecc_enable(nand);
13111214
13121215 for (i = 0; i < ecc->steps; i++) {
13131216 int data_off = i * ecc->size;
13141217 int oob_off = i * (ecc->bytes + 4);
13151218 const u8 *data = buf + data_off;
1316
- const u8 *oob = chip->oob_poi + oob_off;
1219
+ const u8 *oob = nand->oob_poi + oob_off;
13171220
1318
- ret = sunxi_nfc_hw_ecc_write_chunk(mtd, data, data_off, oob,
1221
+ ret = sunxi_nfc_hw_ecc_write_chunk(nand, data, data_off, oob,
13191222 oob_off + mtd->writesize,
13201223 &cur_off, !i, page);
13211224 if (ret)
13221225 return ret;
13231226 }
13241227
1325
- if (oob_required || (chip->options & NAND_NEED_SCRAMBLING))
1326
- sunxi_nfc_hw_ecc_write_extra_oob(mtd, chip->oob_poi,
1228
+ if (oob_required || (nand->options & NAND_NEED_SCRAMBLING))
1229
+ sunxi_nfc_hw_ecc_write_extra_oob(nand, nand->oob_poi,
13271230 &cur_off, page);
13281231
1329
- sunxi_nfc_hw_ecc_disable(mtd);
1232
+ sunxi_nfc_hw_ecc_disable(nand);
13301233
1331
- return nand_prog_page_end_op(chip);
1234
+ return nand_prog_page_end_op(nand);
13321235 }
13331236
1334
-static int sunxi_nfc_hw_ecc_write_subpage(struct mtd_info *mtd,
1335
- struct nand_chip *chip,
1237
+static int sunxi_nfc_hw_ecc_write_subpage(struct nand_chip *nand,
13361238 u32 data_offs, u32 data_len,
13371239 const u8 *buf, int oob_required,
13381240 int page)
13391241 {
1340
- struct nand_ecc_ctrl *ecc = &chip->ecc;
1242
+ struct mtd_info *mtd = nand_to_mtd(nand);
1243
+ struct nand_ecc_ctrl *ecc = &nand->ecc;
13411244 int ret, i, cur_off = 0;
13421245
1343
- nand_prog_page_begin_op(chip, page, 0, NULL, 0);
1246
+ sunxi_nfc_select_chip(nand, nand->cur_cs);
13441247
1345
- sunxi_nfc_hw_ecc_enable(mtd);
1248
+ nand_prog_page_begin_op(nand, page, 0, NULL, 0);
1249
+
1250
+ sunxi_nfc_hw_ecc_enable(nand);
13461251
13471252 for (i = data_offs / ecc->size;
13481253 i < DIV_ROUND_UP(data_offs + data_len, ecc->size); i++) {
13491254 int data_off = i * ecc->size;
13501255 int oob_off = i * (ecc->bytes + 4);
13511256 const u8 *data = buf + data_off;
1352
- const u8 *oob = chip->oob_poi + oob_off;
1257
+ const u8 *oob = nand->oob_poi + oob_off;
13531258
1354
- ret = sunxi_nfc_hw_ecc_write_chunk(mtd, data, data_off, oob,
1259
+ ret = sunxi_nfc_hw_ecc_write_chunk(nand, data, data_off, oob,
13551260 oob_off + mtd->writesize,
13561261 &cur_off, !i, page);
13571262 if (ret)
13581263 return ret;
13591264 }
13601265
1361
- sunxi_nfc_hw_ecc_disable(mtd);
1266
+ sunxi_nfc_hw_ecc_disable(nand);
13621267
1363
- return nand_prog_page_end_op(chip);
1268
+ return nand_prog_page_end_op(nand);
13641269 }
13651270
1366
-static int sunxi_nfc_hw_ecc_write_page_dma(struct mtd_info *mtd,
1367
- struct nand_chip *chip,
1271
+static int sunxi_nfc_hw_ecc_write_page_dma(struct nand_chip *nand,
13681272 const u8 *buf,
13691273 int oob_required,
13701274 int page)
13711275 {
1372
- struct nand_chip *nand = mtd_to_nand(mtd);
13731276 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
13741277 struct nand_ecc_ctrl *ecc = &nand->ecc;
13751278 struct scatterlist sg;
13761279 int ret, i;
13771280
1281
+ sunxi_nfc_select_chip(nand, nand->cur_cs);
1282
+
13781283 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
13791284 if (ret)
13801285 return ret;
13811286
1382
- ret = sunxi_nfc_dma_op_prepare(mtd, buf, ecc->size, ecc->steps,
1287
+ ret = sunxi_nfc_dma_op_prepare(nfc, buf, ecc->size, ecc->steps,
13831288 DMA_TO_DEVICE, &sg);
13841289 if (ret)
13851290 goto pio_fallback;
....@@ -1387,14 +1292,14 @@
13871292 for (i = 0; i < ecc->steps; i++) {
13881293 const u8 *oob = nand->oob_poi + (i * (ecc->bytes + 4));
13891294
1390
- sunxi_nfc_hw_ecc_set_prot_oob_bytes(mtd, oob, i, !i, page);
1295
+ sunxi_nfc_hw_ecc_set_prot_oob_bytes(nand, oob, i, !i, page);
13911296 }
13921297
1393
- nand_prog_page_begin_op(chip, page, 0, NULL, 0);
1298
+ nand_prog_page_begin_op(nand, page, 0, NULL, 0);
13941299
1395
- sunxi_nfc_hw_ecc_enable(mtd);
1396
- sunxi_nfc_randomizer_config(mtd, page, false);
1397
- sunxi_nfc_randomizer_enable(mtd);
1300
+ sunxi_nfc_hw_ecc_enable(nand);
1301
+ sunxi_nfc_randomizer_config(nand, page, false);
1302
+ sunxi_nfc_randomizer_enable(nand);
13981303
13991304 writel((NAND_CMD_RNDIN << 8) | NAND_CMD_PAGEPROG,
14001305 nfc->regs + NFC_REG_WCMD_SET);
....@@ -1409,49 +1314,45 @@
14091314 if (ret)
14101315 dmaengine_terminate_all(nfc->dmac);
14111316
1412
- sunxi_nfc_randomizer_disable(mtd);
1413
- sunxi_nfc_hw_ecc_disable(mtd);
1317
+ sunxi_nfc_randomizer_disable(nand);
1318
+ sunxi_nfc_hw_ecc_disable(nand);
14141319
1415
- sunxi_nfc_dma_op_cleanup(mtd, DMA_TO_DEVICE, &sg);
1320
+ sunxi_nfc_dma_op_cleanup(nfc, DMA_TO_DEVICE, &sg);
14161321
14171322 if (ret)
14181323 return ret;
14191324
1420
- if (oob_required || (chip->options & NAND_NEED_SCRAMBLING))
1325
+ if (oob_required || (nand->options & NAND_NEED_SCRAMBLING))
14211326 /* TODO: use DMA to transfer extra OOB bytes ? */
1422
- sunxi_nfc_hw_ecc_write_extra_oob(mtd, chip->oob_poi,
1327
+ sunxi_nfc_hw_ecc_write_extra_oob(nand, nand->oob_poi,
14231328 NULL, page);
14241329
1425
- return nand_prog_page_end_op(chip);
1330
+ return nand_prog_page_end_op(nand);
14261331
14271332 pio_fallback:
1428
- return sunxi_nfc_hw_ecc_write_page(mtd, chip, buf, oob_required, page);
1333
+ return sunxi_nfc_hw_ecc_write_page(nand, buf, oob_required, page);
14291334 }
14301335
1431
-static int sunxi_nfc_hw_ecc_read_oob(struct mtd_info *mtd,
1432
- struct nand_chip *chip,
1433
- int page)
1336
+static int sunxi_nfc_hw_ecc_read_oob(struct nand_chip *nand, int page)
14341337 {
1435
- chip->pagebuf = -1;
1338
+ u8 *buf = nand_get_data_buf(nand);
14361339
1437
- return chip->ecc.read_page(mtd, chip, chip->data_buf, 1, page);
1340
+ return nand->ecc.read_page(nand, buf, 1, page);
14381341 }
14391342
1440
-static int sunxi_nfc_hw_ecc_write_oob(struct mtd_info *mtd,
1441
- struct nand_chip *chip,
1442
- int page)
1343
+static int sunxi_nfc_hw_ecc_write_oob(struct nand_chip *nand, int page)
14431344 {
1345
+ struct mtd_info *mtd = nand_to_mtd(nand);
1346
+ u8 *buf = nand_get_data_buf(nand);
14441347 int ret;
14451348
1446
- chip->pagebuf = -1;
1447
-
1448
- memset(chip->data_buf, 0xff, mtd->writesize);
1449
- ret = chip->ecc.write_page(mtd, chip, chip->data_buf, 1, page);
1349
+ memset(buf, 0xff, mtd->writesize);
1350
+ ret = nand->ecc.write_page(nand, buf, 1, page);
14501351 if (ret)
14511352 return ret;
14521353
14531354 /* Send command to program the OOB data */
1454
- return nand_prog_page_end_op(chip);
1355
+ return nand_prog_page_end_op(nand);
14551356 }
14561357
14571358 static const s32 tWB_lut[] = {6, 12, 16, 20};
....@@ -1475,12 +1376,11 @@
14751376 #define sunxi_nand_lookup_timing(l, p, c) \
14761377 _sunxi_nand_lookup_timing(l, ARRAY_SIZE(l), p, c)
14771378
1478
-static int sunxi_nfc_setup_data_interface(struct mtd_info *mtd, int csline,
1479
- const struct nand_data_interface *conf)
1379
+static int sunxi_nfc_setup_interface(struct nand_chip *nand, int csline,
1380
+ const struct nand_interface_config *conf)
14801381 {
1481
- struct nand_chip *nand = mtd_to_nand(mtd);
1482
- struct sunxi_nand_chip *chip = to_sunxi_nand(nand);
1483
- struct sunxi_nfc *nfc = to_sunxi_nfc(chip->nand.controller);
1382
+ struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
1383
+ struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
14841384 const struct nand_sdr_timings *timings;
14851385 u32 min_clk_period = 0;
14861386 s32 tWB, tADL, tWHR, tRHW, tCAD;
....@@ -1563,6 +1463,20 @@
15631463 if (timings->tRHW_min > (min_clk_period * 20))
15641464 min_clk_period = DIV_ROUND_UP(timings->tRHW_min, 20);
15651465
1466
+ /*
1467
+ * In non-EDO, tREA should be less than tRP to guarantee that the
1468
+ * controller does not sample the IO lines too early. Unfortunately,
1469
+ * the sunxi NAND controller does not allow us to have different
1470
+ * values for tRP and tREH (tRP = tREH = tRW / 2).
1471
+ *
1472
+ * We have 2 options to overcome this limitation:
1473
+ *
1474
+ * 1/ Extend tRC to fulfil the tREA <= tRC / 2 constraint
1475
+ * 2/ Use EDO mode (only works if timings->tRLOH > 0)
1476
+ */
1477
+ if (timings->tREA_max > min_clk_period && !timings->tRLOH_min)
1478
+ min_clk_period = timings->tREA_max;
1479
+
15661480 tWB = sunxi_nand_lookup_timing(tWB_lut, timings->tWB_max,
15671481 min_clk_period);
15681482 if (tWB < 0) {
....@@ -1599,7 +1513,7 @@
15991513 tCAD = 0x7;
16001514
16011515 /* TODO: A83 has some more bits for CDQSS, CS, CLHZ, CCS, WC */
1602
- chip->timing_cfg = NFC_TIMING_CFG(tWB, tADL, tWHR, tRHW, tCAD);
1516
+ sunxi_nand->timing_cfg = NFC_TIMING_CFG(tWB, tADL, tWHR, tRHW, tCAD);
16031517
16041518 /* Convert min_clk_period from picoseconds to nanoseconds */
16051519 min_clk_period = DIV_ROUND_UP(min_clk_period, 1000);
....@@ -1610,21 +1524,24 @@
16101524 * This new formula was verified with a scope and validated by
16111525 * Allwinner engineers.
16121526 */
1613
- chip->clk_rate = NSEC_PER_SEC / min_clk_period;
1614
- real_clk_rate = clk_round_rate(nfc->mod_clk, chip->clk_rate);
1527
+ sunxi_nand->clk_rate = NSEC_PER_SEC / min_clk_period;
1528
+ real_clk_rate = clk_round_rate(nfc->mod_clk, sunxi_nand->clk_rate);
16151529 if (real_clk_rate <= 0) {
1616
- dev_err(nfc->dev, "Unable to round clk %lu\n", chip->clk_rate);
1530
+ dev_err(nfc->dev, "Unable to round clk %lu\n",
1531
+ sunxi_nand->clk_rate);
16171532 return -EINVAL;
16181533 }
1534
+
1535
+ sunxi_nand->timing_ctl = 0;
16191536
16201537 /*
16211538 * ONFI specification 3.1, paragraph 4.15.2 dictates that EDO data
16221539 * output cycle timings shall be used if the host drives tRC less than
1623
- * 30 ns.
1540
+ * 30 ns. We should also use EDO mode if tREA is bigger than tRP.
16241541 */
16251542 min_clk_period = NSEC_PER_SEC / real_clk_rate;
1626
- chip->timing_ctl = ((min_clk_period * 2) < 30) ?
1627
- NFC_TIMING_CTL_EDO : 0;
1543
+ if (min_clk_period * 2 < 30 || min_clk_period * 1000 < timings->tREA_max)
1544
+ sunxi_nand->timing_ctl = NFC_TIMING_CTL_EDO;
16281545
16291546 return 0;
16301547 }
....@@ -1658,7 +1575,7 @@
16581575 * only have 2 bytes available in the first user data
16591576 * section.
16601577 */
1661
- if (!section && ecc->mode == NAND_ECC_HW) {
1578
+ if (!section && ecc->engine_type == NAND_ECC_ENGINE_TYPE_ON_HOST) {
16621579 oobregion->offset = 2;
16631580 oobregion->length = 2;
16641581
....@@ -1670,7 +1587,7 @@
16701587 if (section < ecc->steps)
16711588 oobregion->length = 4;
16721589 else
1673
- oobregion->offset = mtd->oobsize - oobregion->offset;
1590
+ oobregion->length = mtd->oobsize - oobregion->offset;
16741591
16751592 return 0;
16761593 }
....@@ -1685,20 +1602,20 @@
16851602 kfree(ecc->priv);
16861603 }
16871604
1688
-static int sunxi_nand_hw_ecc_ctrl_init(struct mtd_info *mtd,
1605
+static int sunxi_nand_hw_ecc_ctrl_init(struct nand_chip *nand,
16891606 struct nand_ecc_ctrl *ecc,
16901607 struct device_node *np)
16911608 {
16921609 static const u8 strengths[] = { 16, 24, 28, 32, 40, 48, 56, 60, 64 };
1693
- struct nand_chip *nand = mtd_to_nand(mtd);
1694
- struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
1695
- struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
1610
+ struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
1611
+ struct mtd_info *mtd = nand_to_mtd(nand);
1612
+ struct nand_device *nanddev = mtd_to_nanddev(mtd);
16961613 struct sunxi_nand_hw_ecc *data;
16971614 int nsectors;
16981615 int ret;
16991616 int i;
17001617
1701
- if (ecc->options & NAND_ECC_MAXIMIZE) {
1618
+ if (nanddev->ecc.user_conf.flags & NAND_ECC_MAXIMIZE_STRENGTH) {
17021619 int bytes;
17031620
17041621 ecc->size = 1024;
....@@ -1782,7 +1699,7 @@
17821699 ecc->read_page = sunxi_nfc_hw_ecc_read_page_dma;
17831700 ecc->read_subpage = sunxi_nfc_hw_ecc_read_subpage_dma;
17841701 ecc->write_page = sunxi_nfc_hw_ecc_write_page_dma;
1785
- nand->options |= NAND_USE_BOUNCE_BUFFER;
1702
+ nand->options |= NAND_USES_DMA;
17861703 } else {
17871704 ecc->read_page = sunxi_nfc_hw_ecc_read_page;
17881705 ecc->read_subpage = sunxi_nfc_hw_ecc_read_subpage;
....@@ -1804,11 +1721,11 @@
18041721
18051722 static void sunxi_nand_ecc_cleanup(struct nand_ecc_ctrl *ecc)
18061723 {
1807
- switch (ecc->mode) {
1808
- case NAND_ECC_HW:
1724
+ switch (ecc->engine_type) {
1725
+ case NAND_ECC_ENGINE_TYPE_ON_HOST:
18091726 sunxi_nand_hw_ecc_ctrl_cleanup(ecc);
18101727 break;
1811
- case NAND_ECC_NONE:
1728
+ case NAND_ECC_ENGINE_TYPE_NONE:
18121729 default:
18131730 break;
18141731 }
....@@ -1816,7 +1733,8 @@
18161733
18171734 static int sunxi_nand_attach_chip(struct nand_chip *nand)
18181735 {
1819
- struct mtd_info *mtd = nand_to_mtd(nand);
1736
+ const struct nand_ecc_props *requirements =
1737
+ nanddev_get_ecc_requirements(&nand->base);
18201738 struct nand_ecc_ctrl *ecc = &nand->ecc;
18211739 struct device_node *np = nand_get_flash_node(nand);
18221740 int ret;
....@@ -1830,21 +1748,21 @@
18301748 nand->options |= NAND_SUBPAGE_READ;
18311749
18321750 if (!ecc->size) {
1833
- ecc->size = nand->ecc_step_ds;
1834
- ecc->strength = nand->ecc_strength_ds;
1751
+ ecc->size = requirements->step_size;
1752
+ ecc->strength = requirements->strength;
18351753 }
18361754
18371755 if (!ecc->size || !ecc->strength)
18381756 return -EINVAL;
18391757
1840
- switch (ecc->mode) {
1841
- case NAND_ECC_HW:
1842
- ret = sunxi_nand_hw_ecc_ctrl_init(mtd, ecc, np);
1758
+ switch (ecc->engine_type) {
1759
+ case NAND_ECC_ENGINE_TYPE_ON_HOST:
1760
+ ret = sunxi_nand_hw_ecc_ctrl_init(nand, ecc, np);
18431761 if (ret)
18441762 return ret;
18451763 break;
1846
- case NAND_ECC_NONE:
1847
- case NAND_ECC_SOFT:
1764
+ case NAND_ECC_ENGINE_TYPE_NONE:
1765
+ case NAND_ECC_ENGINE_TYPE_SOFT:
18481766 break;
18491767 default:
18501768 return -EINVAL;
....@@ -1853,14 +1771,166 @@
18531771 return 0;
18541772 }
18551773
1774
+static int sunxi_nfc_exec_subop(struct nand_chip *nand,
1775
+ const struct nand_subop *subop)
1776
+{
1777
+ struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
1778
+ u32 cmd = 0, extcmd = 0, cnt = 0, addrs[2] = { };
1779
+ unsigned int i, j, remaining, start;
1780
+ void *inbuf = NULL;
1781
+ int ret;
1782
+
1783
+ for (i = 0; i < subop->ninstrs; i++) {
1784
+ const struct nand_op_instr *instr = &subop->instrs[i];
1785
+
1786
+ switch (instr->type) {
1787
+ case NAND_OP_CMD_INSTR:
1788
+ if (cmd & NFC_SEND_CMD1) {
1789
+ if (WARN_ON(cmd & NFC_SEND_CMD2))
1790
+ return -EINVAL;
1791
+
1792
+ cmd |= NFC_SEND_CMD2;
1793
+ extcmd |= instr->ctx.cmd.opcode;
1794
+ } else {
1795
+ cmd |= NFC_SEND_CMD1 |
1796
+ NFC_CMD(instr->ctx.cmd.opcode);
1797
+ }
1798
+ break;
1799
+
1800
+ case NAND_OP_ADDR_INSTR:
1801
+ remaining = nand_subop_get_num_addr_cyc(subop, i);
1802
+ start = nand_subop_get_addr_start_off(subop, i);
1803
+ for (j = 0; j < 8 && j + start < remaining; j++) {
1804
+ u32 addr = instr->ctx.addr.addrs[j + start];
1805
+
1806
+ addrs[j / 4] |= addr << (j % 4) * 8;
1807
+ }
1808
+
1809
+ if (j)
1810
+ cmd |= NFC_SEND_ADR | NFC_ADR_NUM(j);
1811
+
1812
+ break;
1813
+
1814
+ case NAND_OP_DATA_IN_INSTR:
1815
+ case NAND_OP_DATA_OUT_INSTR:
1816
+ start = nand_subop_get_data_start_off(subop, i);
1817
+ remaining = nand_subop_get_data_len(subop, i);
1818
+ cnt = min_t(u32, remaining, NFC_SRAM_SIZE);
1819
+ cmd |= NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD;
1820
+
1821
+ if (instr->type == NAND_OP_DATA_OUT_INSTR) {
1822
+ cmd |= NFC_ACCESS_DIR;
1823
+ memcpy_toio(nfc->regs + NFC_RAM0_BASE,
1824
+ instr->ctx.data.buf.out + start,
1825
+ cnt);
1826
+ } else {
1827
+ inbuf = instr->ctx.data.buf.in + start;
1828
+ }
1829
+
1830
+ break;
1831
+
1832
+ case NAND_OP_WAITRDY_INSTR:
1833
+ cmd |= NFC_WAIT_FLAG;
1834
+ break;
1835
+ }
1836
+ }
1837
+
1838
+ ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
1839
+ if (ret)
1840
+ return ret;
1841
+
1842
+ if (cmd & NFC_SEND_ADR) {
1843
+ writel(addrs[0], nfc->regs + NFC_REG_ADDR_LOW);
1844
+ writel(addrs[1], nfc->regs + NFC_REG_ADDR_HIGH);
1845
+ }
1846
+
1847
+ if (cmd & NFC_SEND_CMD2)
1848
+ writel(extcmd,
1849
+ nfc->regs +
1850
+ (cmd & NFC_ACCESS_DIR ?
1851
+ NFC_REG_WCMD_SET : NFC_REG_RCMD_SET));
1852
+
1853
+ if (cmd & NFC_DATA_TRANS)
1854
+ writel(cnt, nfc->regs + NFC_REG_CNT);
1855
+
1856
+ writel(cmd, nfc->regs + NFC_REG_CMD);
1857
+
1858
+ ret = sunxi_nfc_wait_events(nfc, NFC_CMD_INT_FLAG,
1859
+ !(cmd & NFC_WAIT_FLAG) && cnt < 64,
1860
+ 0);
1861
+ if (ret)
1862
+ return ret;
1863
+
1864
+ if (inbuf)
1865
+ memcpy_fromio(inbuf, nfc->regs + NFC_RAM0_BASE, cnt);
1866
+
1867
+ return 0;
1868
+}
1869
+
1870
+static int sunxi_nfc_soft_waitrdy(struct nand_chip *nand,
1871
+ const struct nand_subop *subop)
1872
+{
1873
+ return nand_soft_waitrdy(nand,
1874
+ subop->instrs[0].ctx.waitrdy.timeout_ms);
1875
+}
1876
+
1877
+static const struct nand_op_parser sunxi_nfc_op_parser = NAND_OP_PARSER(
1878
+ NAND_OP_PARSER_PATTERN(sunxi_nfc_exec_subop,
1879
+ NAND_OP_PARSER_PAT_CMD_ELEM(true),
1880
+ NAND_OP_PARSER_PAT_ADDR_ELEM(true, 8),
1881
+ NAND_OP_PARSER_PAT_CMD_ELEM(true),
1882
+ NAND_OP_PARSER_PAT_WAITRDY_ELEM(true),
1883
+ NAND_OP_PARSER_PAT_DATA_IN_ELEM(true, 1024)),
1884
+ NAND_OP_PARSER_PATTERN(sunxi_nfc_exec_subop,
1885
+ NAND_OP_PARSER_PAT_CMD_ELEM(true),
1886
+ NAND_OP_PARSER_PAT_ADDR_ELEM(true, 8),
1887
+ NAND_OP_PARSER_PAT_DATA_OUT_ELEM(true, 1024),
1888
+ NAND_OP_PARSER_PAT_CMD_ELEM(true),
1889
+ NAND_OP_PARSER_PAT_WAITRDY_ELEM(true)),
1890
+);
1891
+
1892
+static const struct nand_op_parser sunxi_nfc_norb_op_parser = NAND_OP_PARSER(
1893
+ NAND_OP_PARSER_PATTERN(sunxi_nfc_exec_subop,
1894
+ NAND_OP_PARSER_PAT_CMD_ELEM(true),
1895
+ NAND_OP_PARSER_PAT_ADDR_ELEM(true, 8),
1896
+ NAND_OP_PARSER_PAT_CMD_ELEM(true),
1897
+ NAND_OP_PARSER_PAT_DATA_IN_ELEM(true, 1024)),
1898
+ NAND_OP_PARSER_PATTERN(sunxi_nfc_exec_subop,
1899
+ NAND_OP_PARSER_PAT_CMD_ELEM(true),
1900
+ NAND_OP_PARSER_PAT_ADDR_ELEM(true, 8),
1901
+ NAND_OP_PARSER_PAT_DATA_OUT_ELEM(true, 1024),
1902
+ NAND_OP_PARSER_PAT_CMD_ELEM(true)),
1903
+ NAND_OP_PARSER_PATTERN(sunxi_nfc_soft_waitrdy,
1904
+ NAND_OP_PARSER_PAT_WAITRDY_ELEM(false)),
1905
+);
1906
+
1907
+static int sunxi_nfc_exec_op(struct nand_chip *nand,
1908
+ const struct nand_operation *op, bool check_only)
1909
+{
1910
+ struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
1911
+ const struct nand_op_parser *parser;
1912
+
1913
+ if (!check_only)
1914
+ sunxi_nfc_select_chip(nand, op->cs);
1915
+
1916
+ if (sunxi_nand->sels[op->cs].rb >= 0)
1917
+ parser = &sunxi_nfc_op_parser;
1918
+ else
1919
+ parser = &sunxi_nfc_norb_op_parser;
1920
+
1921
+ return nand_op_parser_exec_op(nand, parser, op, check_only);
1922
+}
1923
+
18561924 static const struct nand_controller_ops sunxi_nand_controller_ops = {
18571925 .attach_chip = sunxi_nand_attach_chip,
1926
+ .setup_interface = sunxi_nfc_setup_interface,
1927
+ .exec_op = sunxi_nfc_exec_op,
18581928 };
18591929
18601930 static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc,
18611931 struct device_node *np)
18621932 {
1863
- struct sunxi_nand_chip *chip;
1933
+ struct sunxi_nand_chip *sunxi_nand;
18641934 struct mtd_info *mtd;
18651935 struct nand_chip *nand;
18661936 int nsels;
....@@ -1877,17 +1947,14 @@
18771947 return -EINVAL;
18781948 }
18791949
1880
- chip = devm_kzalloc(dev,
1881
- sizeof(*chip) +
1882
- (nsels * sizeof(struct sunxi_nand_chip_sel)),
1883
- GFP_KERNEL);
1884
- if (!chip) {
1950
+ sunxi_nand = devm_kzalloc(dev, struct_size(sunxi_nand, sels, nsels),
1951
+ GFP_KERNEL);
1952
+ if (!sunxi_nand) {
18851953 dev_err(dev, "could not allocate chip\n");
18861954 return -ENOMEM;
18871955 }
18881956
1889
- chip->nsels = nsels;
1890
- chip->selected = -1;
1957
+ sunxi_nand->nsels = nsels;
18911958
18921959 for (i = 0; i < nsels; i++) {
18931960 ret = of_property_read_u32_index(np, "reg", i, &tmp);
....@@ -1909,18 +1976,17 @@
19091976 return -EINVAL;
19101977 }
19111978
1912
- chip->sels[i].cs = tmp;
1979
+ sunxi_nand->sels[i].cs = tmp;
19131980
19141981 if (!of_property_read_u32_index(np, "allwinner,rb", i, &tmp) &&
19151982 tmp < 2)
1916
- chip->sels[i].rb = tmp;
1983
+ sunxi_nand->sels[i].rb = tmp;
19171984 else
1918
- chip->sels[i].rb = -1;
1985
+ sunxi_nand->sels[i].rb = -1;
19191986 }
19201987
1921
- nand = &chip->nand;
1988
+ nand = &sunxi_nand->nand;
19221989 /* Default tR value specified in the ONFI spec (chapter 4.15.1) */
1923
- nand->chip_delay = 200;
19241990 nand->controller = &nfc->controller;
19251991 nand->controller->ops = &sunxi_nand_controller_ops;
19261992
....@@ -1928,14 +1994,8 @@
19281994 * Set the ECC mode to the default value in case nothing is specified
19291995 * in the DT.
19301996 */
1931
- nand->ecc.mode = NAND_ECC_HW;
1997
+ nand->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST;
19321998 nand_set_flash_node(nand, np);
1933
- nand->select_chip = sunxi_nfc_select_chip;
1934
- nand->cmd_ctrl = sunxi_nfc_cmd_ctrl;
1935
- nand->read_buf = sunxi_nfc_read_buf;
1936
- nand->write_buf = sunxi_nfc_write_buf;
1937
- nand->read_byte = sunxi_nfc_read_byte;
1938
- nand->setup_data_interface = sunxi_nfc_setup_data_interface;
19391999
19402000 mtd = nand_to_mtd(nand);
19412001 mtd->dev.parent = dev;
....@@ -1951,7 +2011,7 @@
19512011 return ret;
19522012 }
19532013
1954
- list_add_tail(&chip->node, &nfc->chips);
2014
+ list_add_tail(&sunxi_nand->node, &nfc->chips);
19552015
19562016 return 0;
19572017 }
....@@ -1981,14 +2041,20 @@
19812041
19822042 static void sunxi_nand_chips_cleanup(struct sunxi_nfc *nfc)
19832043 {
1984
- struct sunxi_nand_chip *chip;
2044
+ struct sunxi_nand_chip *sunxi_nand;
2045
+ struct nand_chip *chip;
2046
+ int ret;
19852047
19862048 while (!list_empty(&nfc->chips)) {
1987
- chip = list_first_entry(&nfc->chips, struct sunxi_nand_chip,
1988
- node);
1989
- nand_release(&chip->nand);
1990
- sunxi_nand_ecc_cleanup(&chip->nand.ecc);
1991
- list_del(&chip->node);
2049
+ sunxi_nand = list_first_entry(&nfc->chips,
2050
+ struct sunxi_nand_chip,
2051
+ node);
2052
+ chip = &sunxi_nand->nand;
2053
+ ret = mtd_device_unregister(nand_to_mtd(chip));
2054
+ WARN_ON(ret);
2055
+ nand_cleanup(chip);
2056
+ sunxi_nand_ecc_cleanup(&chip->ecc);
2057
+ list_del(&sunxi_nand->node);
19922058 }
19932059 }
19942060
....@@ -2014,10 +2080,8 @@
20142080 return PTR_ERR(nfc->regs);
20152081
20162082 irq = platform_get_irq(pdev, 0);
2017
- if (irq < 0) {
2018
- dev_err(dev, "failed to retrieve irq\n");
2083
+ if (irq < 0)
20192084 return irq;
2020
- }
20212085
20222086 nfc->ahb_clk = devm_clk_get(dev, "ahb");
20232087 if (IS_ERR(nfc->ahb_clk)) {
....@@ -2052,6 +2116,12 @@
20522116 goto out_mod_clk_unprepare;
20532117 }
20542118
2119
+ nfc->caps = of_device_get_match_data(&pdev->dev);
2120
+ if (!nfc->caps) {
2121
+ ret = -EINVAL;
2122
+ goto out_ahb_reset_reassert;
2123
+ }
2124
+
20552125 ret = sunxi_nfc_rst(nfc);
20562126 if (ret)
20572127 goto out_ahb_reset_reassert;
....@@ -2062,19 +2132,29 @@
20622132 if (ret)
20632133 goto out_ahb_reset_reassert;
20642134
2065
- nfc->dmac = dma_request_slave_channel(dev, "rxtx");
2066
- if (nfc->dmac) {
2135
+ nfc->dmac = dma_request_chan(dev, "rxtx");
2136
+ if (IS_ERR(nfc->dmac)) {
2137
+ ret = PTR_ERR(nfc->dmac);
2138
+ if (ret == -EPROBE_DEFER)
2139
+ goto out_ahb_reset_reassert;
2140
+
2141
+ /* Ignore errors to fall back to PIO mode */
2142
+ dev_warn(dev, "failed to request rxtx DMA channel: %d\n", ret);
2143
+ nfc->dmac = NULL;
2144
+ } else {
20672145 struct dma_slave_config dmac_cfg = { };
20682146
2069
- dmac_cfg.src_addr = r->start + NFC_REG_IO_DATA;
2147
+ dmac_cfg.src_addr = r->start + nfc->caps->reg_io_data;
20702148 dmac_cfg.dst_addr = dmac_cfg.src_addr;
20712149 dmac_cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
20722150 dmac_cfg.dst_addr_width = dmac_cfg.src_addr_width;
2073
- dmac_cfg.src_maxburst = 4;
2074
- dmac_cfg.dst_maxburst = 4;
2151
+ dmac_cfg.src_maxburst = nfc->caps->dma_maxburst;
2152
+ dmac_cfg.dst_maxburst = nfc->caps->dma_maxburst;
20752153 dmaengine_slave_config(nfc->dmac, &dmac_cfg);
2076
- } else {
2077
- dev_warn(dev, "failed to request rxtx DMA channel\n");
2154
+
2155
+ if (nfc->caps->extra_mbus_conf)
2156
+ writel(readl(nfc->regs + NFC_REG_CTL) |
2157
+ NFC_DMA_TYPE_NORMAL, nfc->regs + NFC_REG_CTL);
20782158 }
20792159
20802160 platform_set_drvdata(pdev, nfc);
....@@ -2116,8 +2196,26 @@
21162196 return 0;
21172197 }
21182198
2199
+static const struct sunxi_nfc_caps sunxi_nfc_a10_caps = {
2200
+ .reg_io_data = NFC_REG_A10_IO_DATA,
2201
+ .dma_maxburst = 4,
2202
+};
2203
+
2204
+static const struct sunxi_nfc_caps sunxi_nfc_a23_caps = {
2205
+ .extra_mbus_conf = true,
2206
+ .reg_io_data = NFC_REG_A23_IO_DATA,
2207
+ .dma_maxburst = 8,
2208
+};
2209
+
21192210 static const struct of_device_id sunxi_nfc_ids[] = {
2120
- { .compatible = "allwinner,sun4i-a10-nand" },
2211
+ {
2212
+ .compatible = "allwinner,sun4i-a10-nand",
2213
+ .data = &sunxi_nfc_a10_caps,
2214
+ },
2215
+ {
2216
+ .compatible = "allwinner,sun8i-a23-nand-controller",
2217
+ .data = &sunxi_nfc_a23_caps,
2218
+ },
21212219 { /* sentinel */ }
21222220 };
21232221 MODULE_DEVICE_TABLE(of, sunxi_nfc_ids);
....@@ -2132,7 +2230,7 @@
21322230 };
21332231 module_platform_driver(sunxi_nfc_driver);
21342232
2135
-MODULE_LICENSE("GPL v2");
2233
+MODULE_LICENSE("GPL");
21362234 MODULE_AUTHOR("Boris BREZILLON");
21372235 MODULE_DESCRIPTION("Allwinner NAND Flash Controller driver");
21382236 MODULE_ALIAS("platform:sunxi_nand");