blob: ce3449c50e12f3dcaef581e0b6c4d265620f7360 [file] [log] [blame]
eric miaofe69af02008-02-14 15:48:23 +08001/*
2 * drivers/mtd/nand/pxa3xx_nand.c
3 *
4 * Copyright © 2005 Intel Corporation
5 * Copyright © 2006 Marvell International Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
Ezequiel Garciade484a32013-11-07 12:17:10 -030010 *
11 * See Documentation/mtd/nand/pxa3xx-nand.txt for more details.
eric miaofe69af02008-02-14 15:48:23 +080012 */
13
Haojian Zhuanga88bdbb2009-09-11 19:33:58 +080014#include <linux/kernel.h>
eric miaofe69af02008-02-14 15:48:23 +080015#include <linux/module.h>
16#include <linux/interrupt.h>
17#include <linux/platform_device.h>
18#include <linux/dma-mapping.h>
19#include <linux/delay.h>
20#include <linux/clk.h>
21#include <linux/mtd/mtd.h>
22#include <linux/mtd/nand.h>
23#include <linux/mtd/partitions.h>
David Woodhousea1c06ee2008-04-22 20:39:43 +010024#include <linux/io.h>
25#include <linux/irq.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090026#include <linux/slab.h>
Daniel Mack1e7ba632012-07-22 19:51:02 +020027#include <linux/of.h>
28#include <linux/of_device.h>
Ezequiel Garcia776f2652013-11-14 18:25:28 -030029#include <linux/of_mtd.h>
eric miaofe69af02008-02-14 15:48:23 +080030
Ezequiel Garciaf4db2e32013-08-12 14:14:56 -030031#if defined(CONFIG_ARCH_PXA) || defined(CONFIG_ARCH_MMP)
32#define ARCH_HAS_DMA
33#endif
34
35#ifdef ARCH_HAS_DMA
Eric Miaoafb5b5c2008-12-01 11:43:08 +080036#include <mach/dma.h>
Ezequiel Garciaf4db2e32013-08-12 14:14:56 -030037#endif
38
Arnd Bergmann293b2da2012-08-24 15:16:48 +020039#include <linux/platform_data/mtd-nand-pxa3xx.h>
eric miaofe69af02008-02-14 15:48:23 +080040
Ezequiel Garcia55d9fd62013-11-14 18:25:26 -030041#define NAND_DEV_READY_TIMEOUT 50
eric miaofe69af02008-02-14 15:48:23 +080042#define CHIP_DELAY_TIMEOUT (2 * HZ/10)
Lei Wenf8155a42011-02-28 10:32:11 +080043#define NAND_STOP_DELAY (2 * HZ/50)
Lei Wen4eb2da82011-02-28 10:32:13 +080044#define PAGE_CHUNK_SIZE (2048)
eric miaofe69af02008-02-14 15:48:23 +080045
Ezequiel Garcia62e8b852013-10-04 15:30:38 -030046/*
47 * Define a buffer size for the initial command that detects the flash device:
48 * STATUS, READID and PARAM. The largest of these is the PARAM command,
49 * needing 256 bytes.
50 */
51#define INIT_BUFFER_SIZE 256
52
eric miaofe69af02008-02-14 15:48:23 +080053/* registers and bit definitions */
54#define NDCR (0x00) /* Control register */
55#define NDTR0CS0 (0x04) /* Timing Parameter 0 for CS0 */
56#define NDTR1CS0 (0x0C) /* Timing Parameter 1 for CS0 */
57#define NDSR (0x14) /* Status Register */
58#define NDPCR (0x18) /* Page Count Register */
59#define NDBDR0 (0x1C) /* Bad Block Register 0 */
60#define NDBDR1 (0x20) /* Bad Block Register 1 */
Ezequiel Garcia43bcfd22013-11-14 18:25:29 -030061#define NDECCCTRL (0x28) /* ECC control */
eric miaofe69af02008-02-14 15:48:23 +080062#define NDDB (0x40) /* Data Buffer */
63#define NDCB0 (0x48) /* Command Buffer0 */
64#define NDCB1 (0x4C) /* Command Buffer1 */
65#define NDCB2 (0x50) /* Command Buffer2 */
66
67#define NDCR_SPARE_EN (0x1 << 31)
68#define NDCR_ECC_EN (0x1 << 30)
69#define NDCR_DMA_EN (0x1 << 29)
70#define NDCR_ND_RUN (0x1 << 28)
71#define NDCR_DWIDTH_C (0x1 << 27)
72#define NDCR_DWIDTH_M (0x1 << 26)
73#define NDCR_PAGE_SZ (0x1 << 24)
74#define NDCR_NCSX (0x1 << 23)
75#define NDCR_ND_MODE (0x3 << 21)
76#define NDCR_NAND_MODE (0x0)
77#define NDCR_CLR_PG_CNT (0x1 << 20)
Lei Wenf8155a42011-02-28 10:32:11 +080078#define NDCR_STOP_ON_UNCOR (0x1 << 19)
eric miaofe69af02008-02-14 15:48:23 +080079#define NDCR_RD_ID_CNT_MASK (0x7 << 16)
80#define NDCR_RD_ID_CNT(x) (((x) << 16) & NDCR_RD_ID_CNT_MASK)
81
82#define NDCR_RA_START (0x1 << 15)
83#define NDCR_PG_PER_BLK (0x1 << 14)
84#define NDCR_ND_ARB_EN (0x1 << 12)
Lei Wenf8155a42011-02-28 10:32:11 +080085#define NDCR_INT_MASK (0xFFF)
eric miaofe69af02008-02-14 15:48:23 +080086
87#define NDSR_MASK (0xfff)
Lei Wenf8155a42011-02-28 10:32:11 +080088#define NDSR_RDY (0x1 << 12)
89#define NDSR_FLASH_RDY (0x1 << 11)
eric miaofe69af02008-02-14 15:48:23 +080090#define NDSR_CS0_PAGED (0x1 << 10)
91#define NDSR_CS1_PAGED (0x1 << 9)
92#define NDSR_CS0_CMDD (0x1 << 8)
93#define NDSR_CS1_CMDD (0x1 << 7)
94#define NDSR_CS0_BBD (0x1 << 6)
95#define NDSR_CS1_BBD (0x1 << 5)
96#define NDSR_DBERR (0x1 << 4)
97#define NDSR_SBERR (0x1 << 3)
98#define NDSR_WRDREQ (0x1 << 2)
99#define NDSR_RDDREQ (0x1 << 1)
100#define NDSR_WRCMDREQ (0x1)
101
Ezequiel Garcia41a63432013-08-12 14:14:51 -0300102#define NDCB0_LEN_OVRD (0x1 << 28)
Lei Wen4eb2da82011-02-28 10:32:13 +0800103#define NDCB0_ST_ROW_EN (0x1 << 26)
eric miaofe69af02008-02-14 15:48:23 +0800104#define NDCB0_AUTO_RS (0x1 << 25)
105#define NDCB0_CSEL (0x1 << 24)
Ezequiel Garcia70ed8522013-11-14 18:25:37 -0300106#define NDCB0_EXT_CMD_TYPE_MASK (0x7 << 29)
107#define NDCB0_EXT_CMD_TYPE(x) (((x) << 29) & NDCB0_EXT_CMD_TYPE_MASK)
eric miaofe69af02008-02-14 15:48:23 +0800108#define NDCB0_CMD_TYPE_MASK (0x7 << 21)
109#define NDCB0_CMD_TYPE(x) (((x) << 21) & NDCB0_CMD_TYPE_MASK)
110#define NDCB0_NC (0x1 << 20)
111#define NDCB0_DBC (0x1 << 19)
112#define NDCB0_ADDR_CYC_MASK (0x7 << 16)
113#define NDCB0_ADDR_CYC(x) (((x) << 16) & NDCB0_ADDR_CYC_MASK)
114#define NDCB0_CMD2_MASK (0xff << 8)
115#define NDCB0_CMD1_MASK (0xff)
116#define NDCB0_ADDR_CYC_SHIFT (16)
117
Ezequiel Garcia70ed8522013-11-14 18:25:37 -0300118#define EXT_CMD_TYPE_DISPATCH 6 /* Command dispatch */
119#define EXT_CMD_TYPE_NAKED_RW 5 /* Naked read or Naked write */
120#define EXT_CMD_TYPE_READ 4 /* Read */
121#define EXT_CMD_TYPE_DISP_WR 4 /* Command dispatch with write */
122#define EXT_CMD_TYPE_FINAL 3 /* Final command */
123#define EXT_CMD_TYPE_LAST_RW 1 /* Last naked read/write */
124#define EXT_CMD_TYPE_MONO 0 /* Monolithic read/write */
125
eric miaofe69af02008-02-14 15:48:23 +0800126/* macros for registers read/write */
127#define nand_writel(info, off, val) \
128 __raw_writel((val), (info)->mmio_base + (off))
129
130#define nand_readl(info, off) \
131 __raw_readl((info)->mmio_base + (off))
132
133/* error code and state */
134enum {
135 ERR_NONE = 0,
136 ERR_DMABUSERR = -1,
137 ERR_SENDCMD = -2,
138 ERR_DBERR = -3,
139 ERR_BBERR = -4,
Yeasah Pell223cf6c2009-07-01 18:11:35 +0300140 ERR_SBERR = -5,
eric miaofe69af02008-02-14 15:48:23 +0800141};
142
143enum {
Lei Wenf8155a42011-02-28 10:32:11 +0800144 STATE_IDLE = 0,
Lei Wend4568822011-07-14 20:44:32 -0700145 STATE_PREPARED,
eric miaofe69af02008-02-14 15:48:23 +0800146 STATE_CMD_HANDLE,
147 STATE_DMA_READING,
148 STATE_DMA_WRITING,
149 STATE_DMA_DONE,
150 STATE_PIO_READING,
151 STATE_PIO_WRITING,
Lei Wenf8155a42011-02-28 10:32:11 +0800152 STATE_CMD_DONE,
153 STATE_READY,
eric miaofe69af02008-02-14 15:48:23 +0800154};
155
Ezequiel Garciac0f3b862013-08-10 16:34:52 -0300156enum pxa3xx_nand_variant {
157 PXA3XX_NAND_VARIANT_PXA,
158 PXA3XX_NAND_VARIANT_ARMADA370,
159};
160
Lei Wend4568822011-07-14 20:44:32 -0700161struct pxa3xx_nand_host {
162 struct nand_chip chip;
Lei Wend4568822011-07-14 20:44:32 -0700163 struct mtd_info *mtd;
164 void *info_data;
eric miaofe69af02008-02-14 15:48:23 +0800165
Lei Wend4568822011-07-14 20:44:32 -0700166 /* page size of attached chip */
Lei Wend4568822011-07-14 20:44:32 -0700167 int use_ecc;
Lei Wenf3c8cfc2011-07-14 20:44:33 -0700168 int cs;
Lei Wend4568822011-07-14 20:44:32 -0700169
170 /* calculated from pxa3xx_nand_flash data */
171 unsigned int col_addr_cycles;
172 unsigned int row_addr_cycles;
173 size_t read_id_bytes;
174
Lei Wend4568822011-07-14 20:44:32 -0700175};
176
177struct pxa3xx_nand_info {
Lei Wen401e67e2011-02-28 10:32:14 +0800178 struct nand_hw_control controller;
eric miaofe69af02008-02-14 15:48:23 +0800179 struct platform_device *pdev;
eric miaofe69af02008-02-14 15:48:23 +0800180
181 struct clk *clk;
182 void __iomem *mmio_base;
Haojian Zhuang8638fac2009-09-10 14:11:44 +0800183 unsigned long mmio_phys;
Ezequiel Garcia55d9fd62013-11-14 18:25:26 -0300184 struct completion cmd_complete, dev_ready;
eric miaofe69af02008-02-14 15:48:23 +0800185
186 unsigned int buf_start;
187 unsigned int buf_count;
Ezequiel Garcia62e8b852013-10-04 15:30:38 -0300188 unsigned int buf_size;
Ezequiel Garciafa543be2013-11-14 18:25:36 -0300189 unsigned int data_buff_pos;
190 unsigned int oob_buff_pos;
eric miaofe69af02008-02-14 15:48:23 +0800191
192 /* DMA information */
193 int drcmr_dat;
194 int drcmr_cmd;
195
196 unsigned char *data_buff;
Lei Wen18c81b12010-08-17 17:25:57 +0800197 unsigned char *oob_buff;
eric miaofe69af02008-02-14 15:48:23 +0800198 dma_addr_t data_buff_phys;
eric miaofe69af02008-02-14 15:48:23 +0800199 int data_dma_ch;
200 struct pxa_dma_desc *data_desc;
201 dma_addr_t data_desc_addr;
202
Lei Wenf3c8cfc2011-07-14 20:44:33 -0700203 struct pxa3xx_nand_host *host[NUM_CHIP_SELECT];
eric miaofe69af02008-02-14 15:48:23 +0800204 unsigned int state;
205
Ezequiel Garciac0f3b862013-08-10 16:34:52 -0300206 /*
207 * This driver supports NFCv1 (as found in PXA SoC)
208 * and NFCv2 (as found in Armada 370/XP SoC).
209 */
210 enum pxa3xx_nand_variant variant;
211
Lei Wenf3c8cfc2011-07-14 20:44:33 -0700212 int cs;
eric miaofe69af02008-02-14 15:48:23 +0800213 int use_ecc; /* use HW ECC ? */
Ezequiel Garcia43bcfd22013-11-14 18:25:29 -0300214 int ecc_bch; /* using BCH ECC? */
eric miaofe69af02008-02-14 15:48:23 +0800215 int use_dma; /* use DMA ? */
Ezequiel Garcia5bb653e2013-08-12 14:14:49 -0300216 int use_spare; /* use spare ? */
Ezequiel Garcia55d9fd62013-11-14 18:25:26 -0300217 int need_wait;
eric miaofe69af02008-02-14 15:48:23 +0800218
Ezequiel Garcia2128b082013-11-07 12:17:16 -0300219 unsigned int data_size; /* data to be read from FIFO */
Ezequiel Garcia70ed8522013-11-14 18:25:37 -0300220 unsigned int chunk_size; /* split commands chunk size */
Lei Wend4568822011-07-14 20:44:32 -0700221 unsigned int oob_size;
Ezequiel Garcia43bcfd22013-11-14 18:25:29 -0300222 unsigned int spare_size;
223 unsigned int ecc_size;
eric miaofe69af02008-02-14 15:48:23 +0800224 int retcode;
eric miaofe69af02008-02-14 15:48:23 +0800225
Ezequiel Garcia48cf7ef2013-08-12 14:14:55 -0300226 /* cached register value */
227 uint32_t reg_ndcr;
228 uint32_t ndtr0cs0;
229 uint32_t ndtr1cs0;
230
eric miaofe69af02008-02-14 15:48:23 +0800231 /* generated NDCBx register values */
232 uint32_t ndcb0;
233 uint32_t ndcb1;
234 uint32_t ndcb2;
Ezequiel Garcia3a1a3442013-08-12 14:14:50 -0300235 uint32_t ndcb3;
eric miaofe69af02008-02-14 15:48:23 +0800236};
237
Rusty Russell90ab5ee2012-01-13 09:32:20 +1030238static bool use_dma = 1;
eric miaofe69af02008-02-14 15:48:23 +0800239module_param(use_dma, bool, 0444);
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300240MODULE_PARM_DESC(use_dma, "enable DMA for data transferring to/from NAND HW");
eric miaofe69af02008-02-14 15:48:23 +0800241
Lei Wenc1f82472010-08-17 13:50:23 +0800242static struct pxa3xx_nand_timing timing[] = {
Lei Wen227a8862010-08-18 18:00:03 +0800243 { 40, 80, 60, 100, 80, 100, 90000, 400, 40, },
244 { 10, 0, 20, 40, 30, 40, 11123, 110, 10, },
245 { 10, 25, 15, 25, 15, 30, 25000, 60, 10, },
246 { 10, 35, 15, 25, 15, 25, 25000, 60, 10, },
eric miaofe69af02008-02-14 15:48:23 +0800247};
248
Lei Wenc1f82472010-08-17 13:50:23 +0800249static struct pxa3xx_nand_flash builtin_flash_types[] = {
Lei Wen4332c112011-03-03 11:27:01 +0800250{ "DEFAULT FLASH", 0, 0, 2048, 8, 8, 0, &timing[0] },
251{ "64MiB 16-bit", 0x46ec, 32, 512, 16, 16, 4096, &timing[1] },
252{ "256MiB 8-bit", 0xdaec, 64, 2048, 8, 8, 2048, &timing[1] },
253{ "4GiB 8-bit", 0xd7ec, 128, 4096, 8, 8, 8192, &timing[1] },
254{ "128MiB 8-bit", 0xa12c, 64, 2048, 8, 8, 1024, &timing[2] },
255{ "128MiB 16-bit", 0xb12c, 64, 2048, 16, 16, 1024, &timing[2] },
256{ "512MiB 8-bit", 0xdc2c, 64, 2048, 8, 8, 4096, &timing[2] },
257{ "512MiB 16-bit", 0xcc2c, 64, 2048, 16, 16, 4096, &timing[2] },
258{ "256MiB 16-bit", 0xba20, 64, 2048, 16, 16, 2048, &timing[3] },
eric miaofe69af02008-02-14 15:48:23 +0800259};
260
Ezequiel Garcia776f2652013-11-14 18:25:28 -0300261static u8 bbt_pattern[] = {'M', 'V', 'B', 'b', 't', '0' };
262static u8 bbt_mirror_pattern[] = {'1', 't', 'b', 'B', 'V', 'M' };
263
264static struct nand_bbt_descr bbt_main_descr = {
265 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
266 | NAND_BBT_2BIT | NAND_BBT_VERSION,
267 .offs = 8,
268 .len = 6,
269 .veroffs = 14,
270 .maxblocks = 8, /* Last 8 blocks in each chip */
271 .pattern = bbt_pattern
272};
273
274static struct nand_bbt_descr bbt_mirror_descr = {
275 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
276 | NAND_BBT_2BIT | NAND_BBT_VERSION,
277 .offs = 8,
278 .len = 6,
279 .veroffs = 14,
280 .maxblocks = 8, /* Last 8 blocks in each chip */
281 .pattern = bbt_mirror_pattern
282};
283
Ezequiel Garcia70ed8522013-11-14 18:25:37 -0300284static struct nand_ecclayout ecc_layout_4KB_bch4bit = {
285 .eccbytes = 64,
286 .eccpos = {
287 32, 33, 34, 35, 36, 37, 38, 39,
288 40, 41, 42, 43, 44, 45, 46, 47,
289 48, 49, 50, 51, 52, 53, 54, 55,
290 56, 57, 58, 59, 60, 61, 62, 63,
291 96, 97, 98, 99, 100, 101, 102, 103,
292 104, 105, 106, 107, 108, 109, 110, 111,
293 112, 113, 114, 115, 116, 117, 118, 119,
294 120, 121, 122, 123, 124, 125, 126, 127},
295 /* Bootrom looks in bytes 0 & 5 for bad blocks */
296 .oobfree = { {6, 26}, { 64, 32} }
297};
298
299static struct nand_ecclayout ecc_layout_4KB_bch8bit = {
300 .eccbytes = 128,
301 .eccpos = {
302 32, 33, 34, 35, 36, 37, 38, 39,
303 40, 41, 42, 43, 44, 45, 46, 47,
304 48, 49, 50, 51, 52, 53, 54, 55,
305 56, 57, 58, 59, 60, 61, 62, 63},
306 .oobfree = { }
307};
308
Lei Wen227a8862010-08-18 18:00:03 +0800309/* Define a default flash type setting serve as flash detecting only */
310#define DEFAULT_FLASH_TYPE (&builtin_flash_types[0])
311
eric miaofe69af02008-02-14 15:48:23 +0800312#define NDTR0_tCH(c) (min((c), 7) << 19)
313#define NDTR0_tCS(c) (min((c), 7) << 16)
314#define NDTR0_tWH(c) (min((c), 7) << 11)
315#define NDTR0_tWP(c) (min((c), 7) << 8)
316#define NDTR0_tRH(c) (min((c), 7) << 3)
317#define NDTR0_tRP(c) (min((c), 7) << 0)
318
319#define NDTR1_tR(c) (min((c), 65535) << 16)
320#define NDTR1_tWHR(c) (min((c), 15) << 4)
321#define NDTR1_tAR(c) (min((c), 15) << 0)
322
323/* convert nano-seconds to nand flash controller clock cycles */
Axel Lin93b352f2010-08-16 16:09:09 +0800324#define ns2cycle(ns, clk) (int)((ns) * (clk / 1000000) / 1000)
eric miaofe69af02008-02-14 15:48:23 +0800325
Ezequiel Garciac7e9c7e2013-11-07 12:17:14 -0300326static struct of_device_id pxa3xx_nand_dt_ids[] = {
327 {
328 .compatible = "marvell,pxa3xx-nand",
329 .data = (void *)PXA3XX_NAND_VARIANT_PXA,
330 },
331 {}
332};
333MODULE_DEVICE_TABLE(of, pxa3xx_nand_dt_ids);
334
335static enum pxa3xx_nand_variant
336pxa3xx_nand_get_variant(struct platform_device *pdev)
337{
338 const struct of_device_id *of_id =
339 of_match_device(pxa3xx_nand_dt_ids, &pdev->dev);
340 if (!of_id)
341 return PXA3XX_NAND_VARIANT_PXA;
342 return (enum pxa3xx_nand_variant)of_id->data;
343}
344
Lei Wend4568822011-07-14 20:44:32 -0700345static void pxa3xx_nand_set_timing(struct pxa3xx_nand_host *host,
Enrico Scholz7dad4822008-08-29 12:59:50 +0200346 const struct pxa3xx_nand_timing *t)
eric miaofe69af02008-02-14 15:48:23 +0800347{
Lei Wend4568822011-07-14 20:44:32 -0700348 struct pxa3xx_nand_info *info = host->info_data;
eric miaofe69af02008-02-14 15:48:23 +0800349 unsigned long nand_clk = clk_get_rate(info->clk);
350 uint32_t ndtr0, ndtr1;
351
352 ndtr0 = NDTR0_tCH(ns2cycle(t->tCH, nand_clk)) |
353 NDTR0_tCS(ns2cycle(t->tCS, nand_clk)) |
354 NDTR0_tWH(ns2cycle(t->tWH, nand_clk)) |
355 NDTR0_tWP(ns2cycle(t->tWP, nand_clk)) |
356 NDTR0_tRH(ns2cycle(t->tRH, nand_clk)) |
357 NDTR0_tRP(ns2cycle(t->tRP, nand_clk));
358
359 ndtr1 = NDTR1_tR(ns2cycle(t->tR, nand_clk)) |
360 NDTR1_tWHR(ns2cycle(t->tWHR, nand_clk)) |
361 NDTR1_tAR(ns2cycle(t->tAR, nand_clk));
362
Ezequiel Garcia48cf7ef2013-08-12 14:14:55 -0300363 info->ndtr0cs0 = ndtr0;
364 info->ndtr1cs0 = ndtr1;
eric miaofe69af02008-02-14 15:48:23 +0800365 nand_writel(info, NDTR0CS0, ndtr0);
366 nand_writel(info, NDTR1CS0, ndtr1);
367}
368
Ezequiel Garcia6a3e4862013-11-07 12:17:18 -0300369/*
370 * Set the data and OOB size, depending on the selected
371 * spare and ECC configuration.
372 * Only applicable to READ0, READOOB and PAGEPROG commands.
373 */
Ezequiel Garciafa543be2013-11-14 18:25:36 -0300374static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info,
375 struct mtd_info *mtd)
eric miaofe69af02008-02-14 15:48:23 +0800376{
Ezequiel Garcia48cf7ef2013-08-12 14:14:55 -0300377 int oob_enable = info->reg_ndcr & NDCR_SPARE_EN;
Lei Wen9d8b1042010-08-17 14:09:30 +0800378
Ezequiel Garciafa543be2013-11-14 18:25:36 -0300379 info->data_size = mtd->writesize;
Ezequiel Garcia43bcfd22013-11-14 18:25:29 -0300380 if (!oob_enable)
Lei Wen9d8b1042010-08-17 14:09:30 +0800381 return;
Lei Wen9d8b1042010-08-17 14:09:30 +0800382
Ezequiel Garcia43bcfd22013-11-14 18:25:29 -0300383 info->oob_size = info->spare_size;
384 if (!info->use_ecc)
385 info->oob_size += info->ecc_size;
Lei Wen18c81b12010-08-17 17:25:57 +0800386}
387
Lei Wenf8155a42011-02-28 10:32:11 +0800388/**
389 * NOTE: it is a must to set ND_RUN firstly, then write
390 * command buffer, otherwise, it does not work.
391 * We enable all the interrupt at the same time, and
392 * let pxa3xx_nand_irq to handle all logic.
393 */
394static void pxa3xx_nand_start(struct pxa3xx_nand_info *info)
395{
396 uint32_t ndcr;
397
Ezequiel Garcia48cf7ef2013-08-12 14:14:55 -0300398 ndcr = info->reg_ndcr;
Ezequiel Garciacd9d1182013-08-12 14:14:48 -0300399
Ezequiel Garcia43bcfd22013-11-14 18:25:29 -0300400 if (info->use_ecc) {
Ezequiel Garciacd9d1182013-08-12 14:14:48 -0300401 ndcr |= NDCR_ECC_EN;
Ezequiel Garcia43bcfd22013-11-14 18:25:29 -0300402 if (info->ecc_bch)
403 nand_writel(info, NDECCCTRL, 0x1);
404 } else {
Ezequiel Garciacd9d1182013-08-12 14:14:48 -0300405 ndcr &= ~NDCR_ECC_EN;
Ezequiel Garcia43bcfd22013-11-14 18:25:29 -0300406 if (info->ecc_bch)
407 nand_writel(info, NDECCCTRL, 0x0);
408 }
Ezequiel Garciacd9d1182013-08-12 14:14:48 -0300409
410 if (info->use_dma)
411 ndcr |= NDCR_DMA_EN;
412 else
413 ndcr &= ~NDCR_DMA_EN;
414
Ezequiel Garcia5bb653e2013-08-12 14:14:49 -0300415 if (info->use_spare)
416 ndcr |= NDCR_SPARE_EN;
417 else
418 ndcr &= ~NDCR_SPARE_EN;
419
Lei Wenf8155a42011-02-28 10:32:11 +0800420 ndcr |= NDCR_ND_RUN;
421
422 /* clear status bits and run */
423 nand_writel(info, NDCR, 0);
424 nand_writel(info, NDSR, NDSR_MASK);
425 nand_writel(info, NDCR, ndcr);
426}
427
428static void pxa3xx_nand_stop(struct pxa3xx_nand_info *info)
429{
430 uint32_t ndcr;
431 int timeout = NAND_STOP_DELAY;
432
433 /* wait RUN bit in NDCR become 0 */
434 ndcr = nand_readl(info, NDCR);
435 while ((ndcr & NDCR_ND_RUN) && (timeout-- > 0)) {
436 ndcr = nand_readl(info, NDCR);
437 udelay(1);
438 }
439
440 if (timeout <= 0) {
441 ndcr &= ~NDCR_ND_RUN;
442 nand_writel(info, NDCR, ndcr);
443 }
444 /* clear status bits */
445 nand_writel(info, NDSR, NDSR_MASK);
446}
447
Ezequiel Garcia57ff88f2013-08-12 14:14:57 -0300448static void __maybe_unused
449enable_int(struct pxa3xx_nand_info *info, uint32_t int_mask)
eric miaofe69af02008-02-14 15:48:23 +0800450{
451 uint32_t ndcr;
452
453 ndcr = nand_readl(info, NDCR);
454 nand_writel(info, NDCR, ndcr & ~int_mask);
455}
456
457static void disable_int(struct pxa3xx_nand_info *info, uint32_t int_mask)
458{
459 uint32_t ndcr;
460
461 ndcr = nand_readl(info, NDCR);
462 nand_writel(info, NDCR, ndcr | int_mask);
463}
464
Lei Wenf8155a42011-02-28 10:32:11 +0800465static void handle_data_pio(struct pxa3xx_nand_info *info)
eric miaofe69af02008-02-14 15:48:23 +0800466{
Ezequiel Garcia70ed8522013-11-14 18:25:37 -0300467 unsigned int do_bytes = min(info->data_size, info->chunk_size);
Ezequiel Garciafa543be2013-11-14 18:25:36 -0300468
eric miaofe69af02008-02-14 15:48:23 +0800469 switch (info->state) {
470 case STATE_PIO_WRITING:
Ezequiel Garciafa543be2013-11-14 18:25:36 -0300471 __raw_writesl(info->mmio_base + NDDB,
472 info->data_buff + info->data_buff_pos,
473 DIV_ROUND_UP(do_bytes, 4));
474
Lei Wen9d8b1042010-08-17 14:09:30 +0800475 if (info->oob_size > 0)
Ezequiel Garciafa543be2013-11-14 18:25:36 -0300476 __raw_writesl(info->mmio_base + NDDB,
477 info->oob_buff + info->oob_buff_pos,
478 DIV_ROUND_UP(info->oob_size, 4));
eric miaofe69af02008-02-14 15:48:23 +0800479 break;
480 case STATE_PIO_READING:
Ezequiel Garciafa543be2013-11-14 18:25:36 -0300481 __raw_readsl(info->mmio_base + NDDB,
482 info->data_buff + info->data_buff_pos,
483 DIV_ROUND_UP(do_bytes, 4));
484
Lei Wen9d8b1042010-08-17 14:09:30 +0800485 if (info->oob_size > 0)
Ezequiel Garciafa543be2013-11-14 18:25:36 -0300486 __raw_readsl(info->mmio_base + NDDB,
487 info->oob_buff + info->oob_buff_pos,
488 DIV_ROUND_UP(info->oob_size, 4));
eric miaofe69af02008-02-14 15:48:23 +0800489 break;
490 default:
Lei Wenda675b42011-07-14 20:44:31 -0700491 dev_err(&info->pdev->dev, "%s: invalid state %d\n", __func__,
eric miaofe69af02008-02-14 15:48:23 +0800492 info->state);
Lei Wenf8155a42011-02-28 10:32:11 +0800493 BUG();
eric miaofe69af02008-02-14 15:48:23 +0800494 }
Ezequiel Garciafa543be2013-11-14 18:25:36 -0300495
496 /* Update buffer pointers for multi-page read/write */
497 info->data_buff_pos += do_bytes;
498 info->oob_buff_pos += info->oob_size;
499 info->data_size -= do_bytes;
eric miaofe69af02008-02-14 15:48:23 +0800500}
501
Ezequiel Garciaf4db2e32013-08-12 14:14:56 -0300502#ifdef ARCH_HAS_DMA
Lei Wenf8155a42011-02-28 10:32:11 +0800503static void start_data_dma(struct pxa3xx_nand_info *info)
eric miaofe69af02008-02-14 15:48:23 +0800504{
505 struct pxa_dma_desc *desc = info->data_desc;
Lei Wen9d8b1042010-08-17 14:09:30 +0800506 int dma_len = ALIGN(info->data_size + info->oob_size, 32);
eric miaofe69af02008-02-14 15:48:23 +0800507
508 desc->ddadr = DDADR_STOP;
509 desc->dcmd = DCMD_ENDIRQEN | DCMD_WIDTH4 | DCMD_BURST32 | dma_len;
510
Lei Wenf8155a42011-02-28 10:32:11 +0800511 switch (info->state) {
512 case STATE_DMA_WRITING:
eric miaofe69af02008-02-14 15:48:23 +0800513 desc->dsadr = info->data_buff_phys;
Haojian Zhuang8638fac2009-09-10 14:11:44 +0800514 desc->dtadr = info->mmio_phys + NDDB;
eric miaofe69af02008-02-14 15:48:23 +0800515 desc->dcmd |= DCMD_INCSRCADDR | DCMD_FLOWTRG;
Lei Wenf8155a42011-02-28 10:32:11 +0800516 break;
517 case STATE_DMA_READING:
eric miaofe69af02008-02-14 15:48:23 +0800518 desc->dtadr = info->data_buff_phys;
Haojian Zhuang8638fac2009-09-10 14:11:44 +0800519 desc->dsadr = info->mmio_phys + NDDB;
eric miaofe69af02008-02-14 15:48:23 +0800520 desc->dcmd |= DCMD_INCTRGADDR | DCMD_FLOWSRC;
Lei Wenf8155a42011-02-28 10:32:11 +0800521 break;
522 default:
Lei Wenda675b42011-07-14 20:44:31 -0700523 dev_err(&info->pdev->dev, "%s: invalid state %d\n", __func__,
Lei Wenf8155a42011-02-28 10:32:11 +0800524 info->state);
525 BUG();
eric miaofe69af02008-02-14 15:48:23 +0800526 }
527
528 DRCMR(info->drcmr_dat) = DRCMR_MAPVLD | info->data_dma_ch;
529 DDADR(info->data_dma_ch) = info->data_desc_addr;
530 DCSR(info->data_dma_ch) |= DCSR_RUN;
531}
532
533static void pxa3xx_nand_data_dma_irq(int channel, void *data)
534{
535 struct pxa3xx_nand_info *info = data;
536 uint32_t dcsr;
537
538 dcsr = DCSR(channel);
539 DCSR(channel) = dcsr;
540
541 if (dcsr & DCSR_BUSERR) {
542 info->retcode = ERR_DMABUSERR;
eric miaofe69af02008-02-14 15:48:23 +0800543 }
544
Lei Wenf8155a42011-02-28 10:32:11 +0800545 info->state = STATE_DMA_DONE;
546 enable_int(info, NDCR_INT_MASK);
547 nand_writel(info, NDSR, NDSR_WRDREQ | NDSR_RDDREQ);
eric miaofe69af02008-02-14 15:48:23 +0800548}
Ezequiel Garciaf4db2e32013-08-12 14:14:56 -0300549#else
550static void start_data_dma(struct pxa3xx_nand_info *info)
551{}
552#endif
eric miaofe69af02008-02-14 15:48:23 +0800553
554static irqreturn_t pxa3xx_nand_irq(int irq, void *devid)
555{
556 struct pxa3xx_nand_info *info = devid;
Ezequiel Garcia55d9fd62013-11-14 18:25:26 -0300557 unsigned int status, is_completed = 0, is_ready = 0;
Lei Wenf3c8cfc2011-07-14 20:44:33 -0700558 unsigned int ready, cmd_done;
559
560 if (info->cs == 0) {
561 ready = NDSR_FLASH_RDY;
562 cmd_done = NDSR_CS0_CMDD;
563 } else {
564 ready = NDSR_RDY;
565 cmd_done = NDSR_CS1_CMDD;
566 }
eric miaofe69af02008-02-14 15:48:23 +0800567
568 status = nand_readl(info, NDSR);
569
Lei Wenf8155a42011-02-28 10:32:11 +0800570 if (status & NDSR_DBERR)
571 info->retcode = ERR_DBERR;
572 if (status & NDSR_SBERR)
573 info->retcode = ERR_SBERR;
574 if (status & (NDSR_RDDREQ | NDSR_WRDREQ)) {
575 /* whether use dma to transfer data */
eric miaofe69af02008-02-14 15:48:23 +0800576 if (info->use_dma) {
Lei Wenf8155a42011-02-28 10:32:11 +0800577 disable_int(info, NDCR_INT_MASK);
578 info->state = (status & NDSR_RDDREQ) ?
579 STATE_DMA_READING : STATE_DMA_WRITING;
580 start_data_dma(info);
581 goto NORMAL_IRQ_EXIT;
eric miaofe69af02008-02-14 15:48:23 +0800582 } else {
Lei Wenf8155a42011-02-28 10:32:11 +0800583 info->state = (status & NDSR_RDDREQ) ?
584 STATE_PIO_READING : STATE_PIO_WRITING;
585 handle_data_pio(info);
eric miaofe69af02008-02-14 15:48:23 +0800586 }
Lei Wenf8155a42011-02-28 10:32:11 +0800587 }
Lei Wenf3c8cfc2011-07-14 20:44:33 -0700588 if (status & cmd_done) {
Lei Wenf8155a42011-02-28 10:32:11 +0800589 info->state = STATE_CMD_DONE;
590 is_completed = 1;
591 }
Lei Wenf3c8cfc2011-07-14 20:44:33 -0700592 if (status & ready) {
eric miaofe69af02008-02-14 15:48:23 +0800593 info->state = STATE_READY;
Ezequiel Garcia55d9fd62013-11-14 18:25:26 -0300594 is_ready = 1;
Lei Wen401e67e2011-02-28 10:32:14 +0800595 }
Lei Wenf8155a42011-02-28 10:32:11 +0800596
597 if (status & NDSR_WRCMDREQ) {
598 nand_writel(info, NDSR, NDSR_WRCMDREQ);
599 status &= ~NDSR_WRCMDREQ;
600 info->state = STATE_CMD_HANDLE;
Ezequiel Garcia3a1a3442013-08-12 14:14:50 -0300601
602 /*
603 * Command buffer registers NDCB{0-2} (and optionally NDCB3)
604 * must be loaded by writing directly either 12 or 16
605 * bytes directly to NDCB0, four bytes at a time.
606 *
607 * Direct write access to NDCB1, NDCB2 and NDCB3 is ignored
608 * but each NDCBx register can be read.
609 */
Lei Wenf8155a42011-02-28 10:32:11 +0800610 nand_writel(info, NDCB0, info->ndcb0);
611 nand_writel(info, NDCB0, info->ndcb1);
612 nand_writel(info, NDCB0, info->ndcb2);
Ezequiel Garcia3a1a3442013-08-12 14:14:50 -0300613
614 /* NDCB3 register is available in NFCv2 (Armada 370/XP SoC) */
615 if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370)
616 nand_writel(info, NDCB0, info->ndcb3);
eric miaofe69af02008-02-14 15:48:23 +0800617 }
Lei Wenf8155a42011-02-28 10:32:11 +0800618
619 /* clear NDSR to let the controller exit the IRQ */
eric miaofe69af02008-02-14 15:48:23 +0800620 nand_writel(info, NDSR, status);
Lei Wenf8155a42011-02-28 10:32:11 +0800621 if (is_completed)
622 complete(&info->cmd_complete);
Ezequiel Garcia55d9fd62013-11-14 18:25:26 -0300623 if (is_ready)
624 complete(&info->dev_ready);
Lei Wenf8155a42011-02-28 10:32:11 +0800625NORMAL_IRQ_EXIT:
eric miaofe69af02008-02-14 15:48:23 +0800626 return IRQ_HANDLED;
627}
628
eric miaofe69af02008-02-14 15:48:23 +0800629static inline int is_buf_blank(uint8_t *buf, size_t len)
630{
631 for (; len > 0; len--)
632 if (*buf++ != 0xff)
633 return 0;
634 return 1;
635}
636
Ezequiel Garcia86beeba2013-11-14 18:25:31 -0300637static void set_command_address(struct pxa3xx_nand_info *info,
638 unsigned int page_size, uint16_t column, int page_addr)
639{
640 /* small page addr setting */
641 if (page_size < PAGE_CHUNK_SIZE) {
642 info->ndcb1 = ((page_addr & 0xFFFFFF) << 8)
643 | (column & 0xFF);
644
645 info->ndcb2 = 0;
646 } else {
647 info->ndcb1 = ((page_addr & 0xFFFF) << 16)
648 | (column & 0xFFFF);
649
650 if (page_addr & 0xFF0000)
651 info->ndcb2 = (page_addr & 0xFF0000) >> 16;
652 else
653 info->ndcb2 = 0;
654 }
655}
656
Ezequiel Garciac39ff032013-11-14 18:25:33 -0300657static void prepare_start_command(struct pxa3xx_nand_info *info, int command)
Lei Wen4eb2da82011-02-28 10:32:13 +0800658{
Ezequiel Garcia39f83d12013-11-14 18:25:34 -0300659 struct pxa3xx_nand_host *host = info->host[info->cs];
660 struct mtd_info *mtd = host->mtd;
661
Lei Wen4eb2da82011-02-28 10:32:13 +0800662 /* reset data and oob column point to handle data */
Lei Wen401e67e2011-02-28 10:32:14 +0800663 info->buf_start = 0;
664 info->buf_count = 0;
Lei Wen4eb2da82011-02-28 10:32:13 +0800665 info->oob_size = 0;
Ezequiel Garciafa543be2013-11-14 18:25:36 -0300666 info->data_buff_pos = 0;
667 info->oob_buff_pos = 0;
Lei Wen4eb2da82011-02-28 10:32:13 +0800668 info->use_ecc = 0;
Ezequiel Garcia5bb653e2013-08-12 14:14:49 -0300669 info->use_spare = 1;
Lei Wen4eb2da82011-02-28 10:32:13 +0800670 info->retcode = ERR_NONE;
Ezequiel Garciaf0e6a32e2013-11-14 18:25:30 -0300671 info->ndcb3 = 0;
Lei Wen4eb2da82011-02-28 10:32:13 +0800672
673 switch (command) {
674 case NAND_CMD_READ0:
675 case NAND_CMD_PAGEPROG:
676 info->use_ecc = 1;
677 case NAND_CMD_READOOB:
Ezequiel Garciafa543be2013-11-14 18:25:36 -0300678 pxa3xx_set_datasize(info, mtd);
Lei Wen4eb2da82011-02-28 10:32:13 +0800679 break;
Ezequiel Garcia41a63432013-08-12 14:14:51 -0300680 case NAND_CMD_PARAM:
681 info->use_spare = 0;
682 break;
Lei Wen4eb2da82011-02-28 10:32:13 +0800683 default:
684 info->ndcb1 = 0;
685 info->ndcb2 = 0;
686 break;
687 }
Ezequiel Garcia39f83d12013-11-14 18:25:34 -0300688
689 /*
690 * If we are about to issue a read command, or about to set
691 * the write address, then clean the data buffer.
692 */
693 if (command == NAND_CMD_READ0 ||
694 command == NAND_CMD_READOOB ||
695 command == NAND_CMD_SEQIN) {
696
697 info->buf_count = mtd->writesize + mtd->oobsize;
698 memset(info->data_buff, 0xFF, info->buf_count);
699 }
700
Ezequiel Garciac39ff032013-11-14 18:25:33 -0300701}
702
703static int prepare_set_command(struct pxa3xx_nand_info *info, int command,
Ezequiel Garcia70ed8522013-11-14 18:25:37 -0300704 int ext_cmd_type, uint16_t column, int page_addr)
Ezequiel Garciac39ff032013-11-14 18:25:33 -0300705{
706 int addr_cycle, exec_cmd;
707 struct pxa3xx_nand_host *host;
708 struct mtd_info *mtd;
709
710 host = info->host[info->cs];
711 mtd = host->mtd;
712 addr_cycle = 0;
713 exec_cmd = 1;
714
715 if (info->cs != 0)
716 info->ndcb0 = NDCB0_CSEL;
717 else
718 info->ndcb0 = 0;
719
720 if (command == NAND_CMD_SEQIN)
721 exec_cmd = 0;
Lei Wen4eb2da82011-02-28 10:32:13 +0800722
Lei Wend4568822011-07-14 20:44:32 -0700723 addr_cycle = NDCB0_ADDR_CYC(host->row_addr_cycles
724 + host->col_addr_cycles);
Lei Wen4eb2da82011-02-28 10:32:13 +0800725
726 switch (command) {
727 case NAND_CMD_READOOB:
728 case NAND_CMD_READ0:
Ezequiel Garciaec821352013-08-12 14:14:54 -0300729 info->buf_start = column;
730 info->ndcb0 |= NDCB0_CMD_TYPE(0)
731 | addr_cycle
732 | NAND_CMD_READ0;
Lei Wen4eb2da82011-02-28 10:32:13 +0800733
Ezequiel Garciaec821352013-08-12 14:14:54 -0300734 if (command == NAND_CMD_READOOB)
735 info->buf_start += mtd->writesize;
736
Ezequiel Garcia70ed8522013-11-14 18:25:37 -0300737 /*
738 * Multiple page read needs an 'extended command type' field,
739 * which is either naked-read or last-read according to the
740 * state.
741 */
742 if (mtd->writesize == PAGE_CHUNK_SIZE) {
Ezequiel Garciaec821352013-08-12 14:14:54 -0300743 info->ndcb0 |= NDCB0_DBC | (NAND_CMD_READSTART << 8);
Ezequiel Garcia70ed8522013-11-14 18:25:37 -0300744 } else if (mtd->writesize > PAGE_CHUNK_SIZE) {
745 info->ndcb0 |= NDCB0_DBC | (NAND_CMD_READSTART << 8)
746 | NDCB0_LEN_OVRD
747 | NDCB0_EXT_CMD_TYPE(ext_cmd_type);
748 info->ndcb3 = info->chunk_size +
749 info->oob_size;
750 }
Lei Wen4eb2da82011-02-28 10:32:13 +0800751
Ezequiel Garcia01d99472013-11-14 18:25:32 -0300752 set_command_address(info, mtd->writesize, column, page_addr);
Ezequiel Garcia01d99472013-11-14 18:25:32 -0300753 break;
754
Lei Wen4eb2da82011-02-28 10:32:13 +0800755 case NAND_CMD_SEQIN:
Lei Wen4eb2da82011-02-28 10:32:13 +0800756
Ezequiel Garciae7f9a6a2013-11-14 18:25:35 -0300757 info->buf_start = column;
758 set_command_address(info, mtd->writesize, 0, page_addr);
Ezequiel Garcia535cb572013-11-14 18:25:38 -0300759
760 /*
761 * Multiple page programming needs to execute the initial
762 * SEQIN command that sets the page address.
763 */
764 if (mtd->writesize > PAGE_CHUNK_SIZE) {
765 info->ndcb0 |= NDCB0_CMD_TYPE(0x1)
766 | NDCB0_EXT_CMD_TYPE(ext_cmd_type)
767 | addr_cycle
768 | command;
769 /* No data transfer in this case */
770 info->data_size = 0;
771 exec_cmd = 1;
772 }
Lei Wen4eb2da82011-02-28 10:32:13 +0800773 break;
774
775 case NAND_CMD_PAGEPROG:
776 if (is_buf_blank(info->data_buff,
777 (mtd->writesize + mtd->oobsize))) {
778 exec_cmd = 0;
779 break;
780 }
781
Ezequiel Garcia535cb572013-11-14 18:25:38 -0300782 /* Second command setting for large pages */
783 if (mtd->writesize > PAGE_CHUNK_SIZE) {
784 /*
785 * Multiple page write uses the 'extended command'
786 * field. This can be used to issue a command dispatch
787 * or a naked-write depending on the current stage.
788 */
789 info->ndcb0 |= NDCB0_CMD_TYPE(0x1)
790 | NDCB0_LEN_OVRD
791 | NDCB0_EXT_CMD_TYPE(ext_cmd_type);
792 info->ndcb3 = info->chunk_size +
793 info->oob_size;
794
795 /*
796 * This is the command dispatch that completes a chunked
797 * page program operation.
798 */
799 if (info->data_size == 0) {
800 info->ndcb0 = NDCB0_CMD_TYPE(0x1)
801 | NDCB0_EXT_CMD_TYPE(ext_cmd_type)
802 | command;
803 info->ndcb1 = 0;
804 info->ndcb2 = 0;
805 info->ndcb3 = 0;
806 }
807 } else {
808 info->ndcb0 |= NDCB0_CMD_TYPE(0x1)
809 | NDCB0_AUTO_RS
810 | NDCB0_ST_ROW_EN
811 | NDCB0_DBC
812 | (NAND_CMD_PAGEPROG << 8)
813 | NAND_CMD_SEQIN
814 | addr_cycle;
815 }
Lei Wen4eb2da82011-02-28 10:32:13 +0800816 break;
817
Ezequiel Garciace0268f2013-05-14 08:15:25 -0300818 case NAND_CMD_PARAM:
Ezequiel Garciace0268f2013-05-14 08:15:25 -0300819 info->buf_count = 256;
820 info->ndcb0 |= NDCB0_CMD_TYPE(0)
821 | NDCB0_ADDR_CYC(1)
Ezequiel Garcia41a63432013-08-12 14:14:51 -0300822 | NDCB0_LEN_OVRD
Ezequiel Garciaec821352013-08-12 14:14:54 -0300823 | command;
Ezequiel Garciace0268f2013-05-14 08:15:25 -0300824 info->ndcb1 = (column & 0xFF);
Ezequiel Garcia41a63432013-08-12 14:14:51 -0300825 info->ndcb3 = 256;
Ezequiel Garciace0268f2013-05-14 08:15:25 -0300826 info->data_size = 256;
827 break;
828
Lei Wen4eb2da82011-02-28 10:32:13 +0800829 case NAND_CMD_READID:
Lei Wend4568822011-07-14 20:44:32 -0700830 info->buf_count = host->read_id_bytes;
Lei Wen4eb2da82011-02-28 10:32:13 +0800831 info->ndcb0 |= NDCB0_CMD_TYPE(3)
832 | NDCB0_ADDR_CYC(1)
Ezequiel Garciaec821352013-08-12 14:14:54 -0300833 | command;
Ezequiel Garciad14231f2013-05-14 08:15:24 -0300834 info->ndcb1 = (column & 0xFF);
Lei Wen4eb2da82011-02-28 10:32:13 +0800835
836 info->data_size = 8;
837 break;
838 case NAND_CMD_STATUS:
Lei Wen4eb2da82011-02-28 10:32:13 +0800839 info->buf_count = 1;
840 info->ndcb0 |= NDCB0_CMD_TYPE(4)
841 | NDCB0_ADDR_CYC(1)
Ezequiel Garciaec821352013-08-12 14:14:54 -0300842 | command;
Lei Wen4eb2da82011-02-28 10:32:13 +0800843
844 info->data_size = 8;
845 break;
846
847 case NAND_CMD_ERASE1:
Lei Wen4eb2da82011-02-28 10:32:13 +0800848 info->ndcb0 |= NDCB0_CMD_TYPE(2)
849 | NDCB0_AUTO_RS
850 | NDCB0_ADDR_CYC(3)
851 | NDCB0_DBC
Ezequiel Garciaec821352013-08-12 14:14:54 -0300852 | (NAND_CMD_ERASE2 << 8)
853 | NAND_CMD_ERASE1;
Lei Wen4eb2da82011-02-28 10:32:13 +0800854 info->ndcb1 = page_addr;
855 info->ndcb2 = 0;
856
857 break;
858 case NAND_CMD_RESET:
Lei Wen4eb2da82011-02-28 10:32:13 +0800859 info->ndcb0 |= NDCB0_CMD_TYPE(5)
Ezequiel Garciaec821352013-08-12 14:14:54 -0300860 | command;
Lei Wen4eb2da82011-02-28 10:32:13 +0800861
862 break;
863
864 case NAND_CMD_ERASE2:
865 exec_cmd = 0;
866 break;
867
868 default:
869 exec_cmd = 0;
Lei Wenda675b42011-07-14 20:44:31 -0700870 dev_err(&info->pdev->dev, "non-supported command %x\n",
871 command);
Lei Wen4eb2da82011-02-28 10:32:13 +0800872 break;
873 }
874
875 return exec_cmd;
876}
877
eric miaofe69af02008-02-14 15:48:23 +0800878static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
David Woodhousea1c06ee2008-04-22 20:39:43 +0100879 int column, int page_addr)
eric miaofe69af02008-02-14 15:48:23 +0800880{
Lei Wend4568822011-07-14 20:44:32 -0700881 struct pxa3xx_nand_host *host = mtd->priv;
882 struct pxa3xx_nand_info *info = host->info_data;
Lei Wen4eb2da82011-02-28 10:32:13 +0800883 int ret, exec_cmd;
eric miaofe69af02008-02-14 15:48:23 +0800884
Lei Wen4eb2da82011-02-28 10:32:13 +0800885 /*
886 * if this is a x16 device ,then convert the input
887 * "byte" address into a "word" address appropriate
888 * for indexing a word-oriented device
889 */
Ezequiel Garcia48cf7ef2013-08-12 14:14:55 -0300890 if (info->reg_ndcr & NDCR_DWIDTH_M)
Lei Wen4eb2da82011-02-28 10:32:13 +0800891 column /= 2;
eric miaofe69af02008-02-14 15:48:23 +0800892
Lei Wenf3c8cfc2011-07-14 20:44:33 -0700893 /*
894 * There may be different NAND chip hooked to
895 * different chip select, so check whether
896 * chip select has been changed, if yes, reset the timing
897 */
898 if (info->cs != host->cs) {
899 info->cs = host->cs;
Ezequiel Garcia48cf7ef2013-08-12 14:14:55 -0300900 nand_writel(info, NDTR0CS0, info->ndtr0cs0);
901 nand_writel(info, NDTR1CS0, info->ndtr1cs0);
Lei Wenf3c8cfc2011-07-14 20:44:33 -0700902 }
903
Ezequiel Garciac39ff032013-11-14 18:25:33 -0300904 prepare_start_command(info, command);
905
Lei Wend4568822011-07-14 20:44:32 -0700906 info->state = STATE_PREPARED;
Ezequiel Garcia70ed8522013-11-14 18:25:37 -0300907 exec_cmd = prepare_set_command(info, command, 0, column, page_addr);
908
Lei Wenf8155a42011-02-28 10:32:11 +0800909 if (exec_cmd) {
910 init_completion(&info->cmd_complete);
Ezequiel Garcia55d9fd62013-11-14 18:25:26 -0300911 init_completion(&info->dev_ready);
912 info->need_wait = 1;
Lei Wenf8155a42011-02-28 10:32:11 +0800913 pxa3xx_nand_start(info);
914
915 ret = wait_for_completion_timeout(&info->cmd_complete,
916 CHIP_DELAY_TIMEOUT);
917 if (!ret) {
Lei Wenda675b42011-07-14 20:44:31 -0700918 dev_err(&info->pdev->dev, "Wait time out!!!\n");
Lei Wenf8155a42011-02-28 10:32:11 +0800919 /* Stop State Machine for next command cycle */
920 pxa3xx_nand_stop(info);
921 }
eric miaofe69af02008-02-14 15:48:23 +0800922 }
Lei Wend4568822011-07-14 20:44:32 -0700923 info->state = STATE_IDLE;
eric miaofe69af02008-02-14 15:48:23 +0800924}
925
Ezequiel Garcia70ed8522013-11-14 18:25:37 -0300926static void armada370_nand_cmdfunc(struct mtd_info *mtd,
927 const unsigned command,
928 int column, int page_addr)
929{
930 struct pxa3xx_nand_host *host = mtd->priv;
931 struct pxa3xx_nand_info *info = host->info_data;
932 int ret, exec_cmd, ext_cmd_type;
933
934 /*
935 * if this is a x16 device then convert the input
936 * "byte" address into a "word" address appropriate
937 * for indexing a word-oriented device
938 */
939 if (info->reg_ndcr & NDCR_DWIDTH_M)
940 column /= 2;
941
942 /*
943 * There may be different NAND chip hooked to
944 * different chip select, so check whether
945 * chip select has been changed, if yes, reset the timing
946 */
947 if (info->cs != host->cs) {
948 info->cs = host->cs;
949 nand_writel(info, NDTR0CS0, info->ndtr0cs0);
950 nand_writel(info, NDTR1CS0, info->ndtr1cs0);
951 }
952
953 /* Select the extended command for the first command */
954 switch (command) {
955 case NAND_CMD_READ0:
956 case NAND_CMD_READOOB:
957 ext_cmd_type = EXT_CMD_TYPE_MONO;
958 break;
Ezequiel Garcia535cb572013-11-14 18:25:38 -0300959 case NAND_CMD_SEQIN:
960 ext_cmd_type = EXT_CMD_TYPE_DISPATCH;
961 break;
962 case NAND_CMD_PAGEPROG:
963 ext_cmd_type = EXT_CMD_TYPE_NAKED_RW;
964 break;
Ezequiel Garcia70ed8522013-11-14 18:25:37 -0300965 default:
966 ext_cmd_type = 0;
Ezequiel Garcia535cb572013-11-14 18:25:38 -0300967 break;
Ezequiel Garcia70ed8522013-11-14 18:25:37 -0300968 }
969
970 prepare_start_command(info, command);
971
972 /*
973 * Prepare the "is ready" completion before starting a command
974 * transaction sequence. If the command is not executed the
975 * completion will be completed, see below.
976 *
977 * We can do that inside the loop because the command variable
978 * is invariant and thus so is the exec_cmd.
979 */
980 info->need_wait = 1;
981 init_completion(&info->dev_ready);
982 do {
983 info->state = STATE_PREPARED;
984 exec_cmd = prepare_set_command(info, command, ext_cmd_type,
985 column, page_addr);
986 if (!exec_cmd) {
987 info->need_wait = 0;
988 complete(&info->dev_ready);
989 break;
990 }
991
992 init_completion(&info->cmd_complete);
993 pxa3xx_nand_start(info);
994
995 ret = wait_for_completion_timeout(&info->cmd_complete,
996 CHIP_DELAY_TIMEOUT);
997 if (!ret) {
998 dev_err(&info->pdev->dev, "Wait time out!!!\n");
999 /* Stop State Machine for next command cycle */
1000 pxa3xx_nand_stop(info);
1001 break;
1002 }
1003
1004 /* Check if the sequence is complete */
Ezequiel Garcia535cb572013-11-14 18:25:38 -03001005 if (info->data_size == 0 && command != NAND_CMD_PAGEPROG)
1006 break;
1007
1008 /*
1009 * After a splitted program command sequence has issued
1010 * the command dispatch, the command sequence is complete.
1011 */
1012 if (info->data_size == 0 &&
1013 command == NAND_CMD_PAGEPROG &&
1014 ext_cmd_type == EXT_CMD_TYPE_DISPATCH)
Ezequiel Garcia70ed8522013-11-14 18:25:37 -03001015 break;
1016
1017 if (command == NAND_CMD_READ0 || command == NAND_CMD_READOOB) {
1018 /* Last read: issue a 'last naked read' */
1019 if (info->data_size == info->chunk_size)
1020 ext_cmd_type = EXT_CMD_TYPE_LAST_RW;
1021 else
1022 ext_cmd_type = EXT_CMD_TYPE_NAKED_RW;
Ezequiel Garcia535cb572013-11-14 18:25:38 -03001023
1024 /*
1025 * If a splitted program command has no more data to transfer,
1026 * the command dispatch must be issued to complete.
1027 */
1028 } else if (command == NAND_CMD_PAGEPROG &&
1029 info->data_size == 0) {
1030 ext_cmd_type = EXT_CMD_TYPE_DISPATCH;
Ezequiel Garcia70ed8522013-11-14 18:25:37 -03001031 }
1032 } while (1);
1033
1034 info->state = STATE_IDLE;
1035}
1036
Josh Wufdbad98d2012-06-25 18:07:45 +08001037static int pxa3xx_nand_write_page_hwecc(struct mtd_info *mtd,
Brian Norris1fbb9382012-05-02 10:14:55 -07001038 struct nand_chip *chip, const uint8_t *buf, int oob_required)
Lei Wenf8155a42011-02-28 10:32:11 +08001039{
1040 chip->write_buf(mtd, buf, mtd->writesize);
1041 chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
Josh Wufdbad98d2012-06-25 18:07:45 +08001042
1043 return 0;
Lei Wenf8155a42011-02-28 10:32:11 +08001044}
1045
1046static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd,
Brian Norris1fbb9382012-05-02 10:14:55 -07001047 struct nand_chip *chip, uint8_t *buf, int oob_required,
1048 int page)
Lei Wenf8155a42011-02-28 10:32:11 +08001049{
Lei Wend4568822011-07-14 20:44:32 -07001050 struct pxa3xx_nand_host *host = mtd->priv;
1051 struct pxa3xx_nand_info *info = host->info_data;
Ezequiel Garcia4e86fd22013-11-07 12:17:13 -03001052 int max_bitflips = 0;
Lei Wenf8155a42011-02-28 10:32:11 +08001053
1054 chip->read_buf(mtd, buf, mtd->writesize);
1055 chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
1056
1057 if (info->retcode == ERR_SBERR) {
1058 switch (info->use_ecc) {
1059 case 1:
Ezequiel Garcia4e86fd22013-11-07 12:17:13 -03001060 max_bitflips = 1;
Lei Wenf8155a42011-02-28 10:32:11 +08001061 mtd->ecc_stats.corrected++;
1062 break;
1063 case 0:
1064 default:
1065 break;
1066 }
1067 } else if (info->retcode == ERR_DBERR) {
1068 /*
1069 * for blank page (all 0xff), HW will calculate its ECC as
1070 * 0, which is different from the ECC information within
1071 * OOB, ignore such double bit errors
1072 */
1073 if (is_buf_blank(buf, mtd->writesize))
Daniel Mack543e32d2011-06-07 03:01:07 -07001074 info->retcode = ERR_NONE;
1075 else
Lei Wenf8155a42011-02-28 10:32:11 +08001076 mtd->ecc_stats.failed++;
1077 }
1078
Ezequiel Garcia4e86fd22013-11-07 12:17:13 -03001079 return max_bitflips;
Lei Wenf8155a42011-02-28 10:32:11 +08001080}
1081
eric miaofe69af02008-02-14 15:48:23 +08001082static uint8_t pxa3xx_nand_read_byte(struct mtd_info *mtd)
1083{
Lei Wend4568822011-07-14 20:44:32 -07001084 struct pxa3xx_nand_host *host = mtd->priv;
1085 struct pxa3xx_nand_info *info = host->info_data;
eric miaofe69af02008-02-14 15:48:23 +08001086 char retval = 0xFF;
1087
1088 if (info->buf_start < info->buf_count)
1089 /* Has just send a new command? */
1090 retval = info->data_buff[info->buf_start++];
1091
1092 return retval;
1093}
1094
1095static u16 pxa3xx_nand_read_word(struct mtd_info *mtd)
1096{
Lei Wend4568822011-07-14 20:44:32 -07001097 struct pxa3xx_nand_host *host = mtd->priv;
1098 struct pxa3xx_nand_info *info = host->info_data;
eric miaofe69af02008-02-14 15:48:23 +08001099 u16 retval = 0xFFFF;
1100
1101 if (!(info->buf_start & 0x01) && info->buf_start < info->buf_count) {
1102 retval = *((u16 *)(info->data_buff+info->buf_start));
1103 info->buf_start += 2;
1104 }
1105 return retval;
1106}
1107
1108static void pxa3xx_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
1109{
Lei Wend4568822011-07-14 20:44:32 -07001110 struct pxa3xx_nand_host *host = mtd->priv;
1111 struct pxa3xx_nand_info *info = host->info_data;
eric miaofe69af02008-02-14 15:48:23 +08001112 int real_len = min_t(size_t, len, info->buf_count - info->buf_start);
1113
1114 memcpy(buf, info->data_buff + info->buf_start, real_len);
1115 info->buf_start += real_len;
1116}
1117
1118static void pxa3xx_nand_write_buf(struct mtd_info *mtd,
1119 const uint8_t *buf, int len)
1120{
Lei Wend4568822011-07-14 20:44:32 -07001121 struct pxa3xx_nand_host *host = mtd->priv;
1122 struct pxa3xx_nand_info *info = host->info_data;
eric miaofe69af02008-02-14 15:48:23 +08001123 int real_len = min_t(size_t, len, info->buf_count - info->buf_start);
1124
1125 memcpy(info->data_buff + info->buf_start, buf, real_len);
1126 info->buf_start += real_len;
1127}
1128
eric miaofe69af02008-02-14 15:48:23 +08001129static void pxa3xx_nand_select_chip(struct mtd_info *mtd, int chip)
1130{
1131 return;
1132}
1133
1134static int pxa3xx_nand_waitfunc(struct mtd_info *mtd, struct nand_chip *this)
1135{
Lei Wend4568822011-07-14 20:44:32 -07001136 struct pxa3xx_nand_host *host = mtd->priv;
1137 struct pxa3xx_nand_info *info = host->info_data;
Ezequiel Garcia55d9fd62013-11-14 18:25:26 -03001138 int ret;
1139
1140 if (info->need_wait) {
1141 ret = wait_for_completion_timeout(&info->dev_ready,
1142 CHIP_DELAY_TIMEOUT);
1143 info->need_wait = 0;
1144 if (!ret) {
1145 dev_err(&info->pdev->dev, "Ready time out!!!\n");
1146 return NAND_STATUS_FAIL;
1147 }
1148 }
eric miaofe69af02008-02-14 15:48:23 +08001149
1150 /* pxa3xx_nand_send_command has waited for command complete */
1151 if (this->state == FL_WRITING || this->state == FL_ERASING) {
1152 if (info->retcode == ERR_NONE)
1153 return 0;
Ezequiel Garcia55d9fd62013-11-14 18:25:26 -03001154 else
1155 return NAND_STATUS_FAIL;
eric miaofe69af02008-02-14 15:48:23 +08001156 }
1157
Ezequiel Garcia55d9fd62013-11-14 18:25:26 -03001158 return NAND_STATUS_READY;
eric miaofe69af02008-02-14 15:48:23 +08001159}
1160
eric miaofe69af02008-02-14 15:48:23 +08001161static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info,
Enrico Scholzc8c17c82008-08-29 12:59:51 +02001162 const struct pxa3xx_nand_flash *f)
eric miaofe69af02008-02-14 15:48:23 +08001163{
1164 struct platform_device *pdev = info->pdev;
Jingoo Han453810b2013-07-30 17:18:33 +09001165 struct pxa3xx_nand_platform_data *pdata = dev_get_platdata(&pdev->dev);
Lei Wenf3c8cfc2011-07-14 20:44:33 -07001166 struct pxa3xx_nand_host *host = info->host[info->cs];
Lei Wenf8155a42011-02-28 10:32:11 +08001167 uint32_t ndcr = 0x0; /* enable all interrupts */
eric miaofe69af02008-02-14 15:48:23 +08001168
Lei Wenda675b42011-07-14 20:44:31 -07001169 if (f->page_size != 2048 && f->page_size != 512) {
1170 dev_err(&pdev->dev, "Current only support 2048 and 512 size\n");
eric miaofe69af02008-02-14 15:48:23 +08001171 return -EINVAL;
Lei Wenda675b42011-07-14 20:44:31 -07001172 }
eric miaofe69af02008-02-14 15:48:23 +08001173
Lei Wenda675b42011-07-14 20:44:31 -07001174 if (f->flash_width != 16 && f->flash_width != 8) {
1175 dev_err(&pdev->dev, "Only support 8bit and 16 bit!\n");
eric miaofe69af02008-02-14 15:48:23 +08001176 return -EINVAL;
Lei Wenda675b42011-07-14 20:44:31 -07001177 }
eric miaofe69af02008-02-14 15:48:23 +08001178
1179 /* calculate flash information */
Lei Wend4568822011-07-14 20:44:32 -07001180 host->read_id_bytes = (f->page_size == 2048) ? 4 : 2;
eric miaofe69af02008-02-14 15:48:23 +08001181
1182 /* calculate addressing information */
Lei Wend4568822011-07-14 20:44:32 -07001183 host->col_addr_cycles = (f->page_size == 2048) ? 2 : 1;
eric miaofe69af02008-02-14 15:48:23 +08001184
1185 if (f->num_blocks * f->page_per_block > 65536)
Lei Wend4568822011-07-14 20:44:32 -07001186 host->row_addr_cycles = 3;
eric miaofe69af02008-02-14 15:48:23 +08001187 else
Lei Wend4568822011-07-14 20:44:32 -07001188 host->row_addr_cycles = 2;
eric miaofe69af02008-02-14 15:48:23 +08001189
1190 ndcr |= (pdata->enable_arbiter) ? NDCR_ND_ARB_EN : 0;
Lei Wend4568822011-07-14 20:44:32 -07001191 ndcr |= (host->col_addr_cycles == 2) ? NDCR_RA_START : 0;
eric miaofe69af02008-02-14 15:48:23 +08001192 ndcr |= (f->page_per_block == 64) ? NDCR_PG_PER_BLK : 0;
1193 ndcr |= (f->page_size == 2048) ? NDCR_PAGE_SZ : 0;
1194 ndcr |= (f->flash_width == 16) ? NDCR_DWIDTH_M : 0;
1195 ndcr |= (f->dfc_width == 16) ? NDCR_DWIDTH_C : 0;
1196
Lei Wend4568822011-07-14 20:44:32 -07001197 ndcr |= NDCR_RD_ID_CNT(host->read_id_bytes);
eric miaofe69af02008-02-14 15:48:23 +08001198 ndcr |= NDCR_SPARE_EN; /* enable spare by default */
1199
Ezequiel Garcia48cf7ef2013-08-12 14:14:55 -03001200 info->reg_ndcr = ndcr;
eric miaofe69af02008-02-14 15:48:23 +08001201
Lei Wend4568822011-07-14 20:44:32 -07001202 pxa3xx_nand_set_timing(host, f->timing);
eric miaofe69af02008-02-14 15:48:23 +08001203 return 0;
1204}
1205
Mike Rapoportf2710492009-02-17 13:54:47 +02001206static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info)
1207{
Lei Wenf3c8cfc2011-07-14 20:44:33 -07001208 /*
1209 * We set 0 by hard coding here, for we don't support keep_config
1210 * when there is more than one chip attached to the controller
1211 */
1212 struct pxa3xx_nand_host *host = info->host[0];
Mike Rapoportf2710492009-02-17 13:54:47 +02001213 uint32_t ndcr = nand_readl(info, NDCR);
Mike Rapoportf2710492009-02-17 13:54:47 +02001214
Lei Wend4568822011-07-14 20:44:32 -07001215 if (ndcr & NDCR_PAGE_SZ) {
Ezequiel Garcia2128b082013-11-07 12:17:16 -03001216 /* Controller's FIFO size */
Ezequiel Garcia70ed8522013-11-14 18:25:37 -03001217 info->chunk_size = 2048;
Lei Wend4568822011-07-14 20:44:32 -07001218 host->read_id_bytes = 4;
1219 } else {
Ezequiel Garcia70ed8522013-11-14 18:25:37 -03001220 info->chunk_size = 512;
Lei Wend4568822011-07-14 20:44:32 -07001221 host->read_id_bytes = 2;
1222 }
1223
Ezequiel Garcia70ed8522013-11-14 18:25:37 -03001224 /* Set an initial chunk size */
Ezequiel Garcia48cf7ef2013-08-12 14:14:55 -03001225 info->reg_ndcr = ndcr & ~NDCR_INT_MASK;
1226 info->ndtr0cs0 = nand_readl(info, NDTR0CS0);
1227 info->ndtr1cs0 = nand_readl(info, NDTR1CS0);
Mike Rapoportf2710492009-02-17 13:54:47 +02001228 return 0;
1229}
1230
Ezequiel Garciaf4db2e32013-08-12 14:14:56 -03001231#ifdef ARCH_HAS_DMA
eric miaofe69af02008-02-14 15:48:23 +08001232static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info)
1233{
1234 struct platform_device *pdev = info->pdev;
Ezequiel Garcia62e8b852013-10-04 15:30:38 -03001235 int data_desc_offset = info->buf_size - sizeof(struct pxa_dma_desc);
eric miaofe69af02008-02-14 15:48:23 +08001236
1237 if (use_dma == 0) {
Ezequiel Garcia62e8b852013-10-04 15:30:38 -03001238 info->data_buff = kmalloc(info->buf_size, GFP_KERNEL);
eric miaofe69af02008-02-14 15:48:23 +08001239 if (info->data_buff == NULL)
1240 return -ENOMEM;
1241 return 0;
1242 }
1243
Ezequiel Garcia62e8b852013-10-04 15:30:38 -03001244 info->data_buff = dma_alloc_coherent(&pdev->dev, info->buf_size,
eric miaofe69af02008-02-14 15:48:23 +08001245 &info->data_buff_phys, GFP_KERNEL);
1246 if (info->data_buff == NULL) {
1247 dev_err(&pdev->dev, "failed to allocate dma buffer\n");
1248 return -ENOMEM;
1249 }
1250
eric miaofe69af02008-02-14 15:48:23 +08001251 info->data_desc = (void *)info->data_buff + data_desc_offset;
1252 info->data_desc_addr = info->data_buff_phys + data_desc_offset;
1253
1254 info->data_dma_ch = pxa_request_dma("nand-data", DMA_PRIO_LOW,
1255 pxa3xx_nand_data_dma_irq, info);
1256 if (info->data_dma_ch < 0) {
1257 dev_err(&pdev->dev, "failed to request data dma\n");
Ezequiel Garcia62e8b852013-10-04 15:30:38 -03001258 dma_free_coherent(&pdev->dev, info->buf_size,
eric miaofe69af02008-02-14 15:48:23 +08001259 info->data_buff, info->data_buff_phys);
1260 return info->data_dma_ch;
1261 }
1262
Ezequiel Garcia95b26562013-10-04 15:30:37 -03001263 /*
1264 * Now that DMA buffers are allocated we turn on
1265 * DMA proper for I/O operations.
1266 */
1267 info->use_dma = 1;
eric miaofe69af02008-02-14 15:48:23 +08001268 return 0;
1269}
1270
Ezequiel Garcia498b6142013-04-17 13:38:14 -03001271static void pxa3xx_nand_free_buff(struct pxa3xx_nand_info *info)
1272{
1273 struct platform_device *pdev = info->pdev;
Ezequiel Garcia15b540c2013-12-10 09:57:15 -03001274 if (info->use_dma) {
Ezequiel Garcia498b6142013-04-17 13:38:14 -03001275 pxa_free_dma(info->data_dma_ch);
Ezequiel Garcia62e8b852013-10-04 15:30:38 -03001276 dma_free_coherent(&pdev->dev, info->buf_size,
Ezequiel Garcia498b6142013-04-17 13:38:14 -03001277 info->data_buff, info->data_buff_phys);
1278 } else {
1279 kfree(info->data_buff);
1280 }
1281}
Ezequiel Garciaf4db2e32013-08-12 14:14:56 -03001282#else
1283static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info)
1284{
Ezequiel Garcia62e8b852013-10-04 15:30:38 -03001285 info->data_buff = kmalloc(info->buf_size, GFP_KERNEL);
Ezequiel Garciaf4db2e32013-08-12 14:14:56 -03001286 if (info->data_buff == NULL)
1287 return -ENOMEM;
1288 return 0;
1289}
1290
1291static void pxa3xx_nand_free_buff(struct pxa3xx_nand_info *info)
1292{
1293 kfree(info->data_buff);
1294}
1295#endif
Ezequiel Garcia498b6142013-04-17 13:38:14 -03001296
Lei Wen401e67e2011-02-28 10:32:14 +08001297static int pxa3xx_nand_sensing(struct pxa3xx_nand_info *info)
eric miaofe69af02008-02-14 15:48:23 +08001298{
Lei Wenf3c8cfc2011-07-14 20:44:33 -07001299 struct mtd_info *mtd;
Ezequiel Garcia2d79ab12013-11-07 12:17:15 -03001300 struct nand_chip *chip;
Lei Wend4568822011-07-14 20:44:32 -07001301 int ret;
Ezequiel Garcia2d79ab12013-11-07 12:17:15 -03001302
Lei Wenf3c8cfc2011-07-14 20:44:33 -07001303 mtd = info->host[info->cs]->mtd;
Ezequiel Garcia2d79ab12013-11-07 12:17:15 -03001304 chip = mtd->priv;
1305
Lei Wen401e67e2011-02-28 10:32:14 +08001306 /* use the common timing to make a try */
Lei Wend4568822011-07-14 20:44:32 -07001307 ret = pxa3xx_nand_config_flash(info, &builtin_flash_types[0]);
1308 if (ret)
1309 return ret;
1310
Ezequiel Garcia2d79ab12013-11-07 12:17:15 -03001311 chip->cmdfunc(mtd, NAND_CMD_RESET, 0, 0);
Ezequiel Garcia56704d82013-11-14 18:25:27 -03001312 ret = chip->waitfunc(mtd, chip);
1313 if (ret & NAND_STATUS_FAIL)
1314 return -ENODEV;
Lei Wend4568822011-07-14 20:44:32 -07001315
Ezequiel Garcia56704d82013-11-14 18:25:27 -03001316 return 0;
Lei Wen401e67e2011-02-28 10:32:14 +08001317}
eric miaofe69af02008-02-14 15:48:23 +08001318
Ezequiel Garcia43bcfd22013-11-14 18:25:29 -03001319static int pxa_ecc_init(struct pxa3xx_nand_info *info,
1320 struct nand_ecc_ctrl *ecc,
1321 int strength, int page_size)
1322{
1323 /*
1324 * We don't use strength here as the PXA variant
1325 * is used with non-ONFI compliant devices.
1326 */
1327 if (page_size == 2048) {
Ezequiel Garcia70ed8522013-11-14 18:25:37 -03001328 info->chunk_size = 2048;
Ezequiel Garcia43bcfd22013-11-14 18:25:29 -03001329 info->spare_size = 40;
1330 info->ecc_size = 24;
1331 ecc->mode = NAND_ECC_HW;
1332 ecc->size = 512;
1333 ecc->strength = 1;
1334 return 1;
1335
1336 } else if (page_size == 512) {
Ezequiel Garcia70ed8522013-11-14 18:25:37 -03001337 info->chunk_size = 512;
Ezequiel Garcia43bcfd22013-11-14 18:25:29 -03001338 info->spare_size = 8;
1339 info->ecc_size = 8;
1340 ecc->mode = NAND_ECC_HW;
1341 ecc->size = 512;
1342 ecc->strength = 1;
1343 return 1;
1344 }
1345 return 0;
1346}
1347
1348static int armada370_ecc_init(struct pxa3xx_nand_info *info,
1349 struct nand_ecc_ctrl *ecc,
1350 int strength, int page_size)
1351{
Ezequiel Garcia70ed8522013-11-14 18:25:37 -03001352 if (strength == 4 && page_size == 4096) {
1353 info->ecc_bch = 1;
1354 info->chunk_size = 2048;
1355 info->spare_size = 32;
1356 info->ecc_size = 32;
1357 ecc->mode = NAND_ECC_HW;
1358 ecc->size = info->chunk_size;
1359 ecc->layout = &ecc_layout_4KB_bch4bit;
1360 ecc->strength = 16;
1361 return 1;
1362
1363 } else if (strength == 8 && page_size == 4096) {
1364 info->ecc_bch = 1;
1365 info->chunk_size = 1024;
1366 info->spare_size = 0;
1367 info->ecc_size = 32;
1368 ecc->mode = NAND_ECC_HW;
1369 ecc->size = info->chunk_size;
1370 ecc->layout = &ecc_layout_4KB_bch8bit;
1371 ecc->strength = 16;
1372 return 1;
1373 }
Ezequiel Garcia43bcfd22013-11-14 18:25:29 -03001374 return 0;
1375}
1376
Lei Wen401e67e2011-02-28 10:32:14 +08001377static int pxa3xx_nand_scan(struct mtd_info *mtd)
1378{
Lei Wend4568822011-07-14 20:44:32 -07001379 struct pxa3xx_nand_host *host = mtd->priv;
1380 struct pxa3xx_nand_info *info = host->info_data;
Lei Wen401e67e2011-02-28 10:32:14 +08001381 struct platform_device *pdev = info->pdev;
Jingoo Han453810b2013-07-30 17:18:33 +09001382 struct pxa3xx_nand_platform_data *pdata = dev_get_platdata(&pdev->dev);
Lei Wen0fab0282011-06-07 03:01:06 -07001383 struct nand_flash_dev pxa3xx_flash_ids[2], *def = NULL;
Lei Wen401e67e2011-02-28 10:32:14 +08001384 const struct pxa3xx_nand_flash *f = NULL;
1385 struct nand_chip *chip = mtd->priv;
1386 uint32_t id = -1;
Lei Wen4332c112011-03-03 11:27:01 +08001387 uint64_t chipsize;
Lei Wen401e67e2011-02-28 10:32:14 +08001388 int i, ret, num;
1389
1390 if (pdata->keep_config && !pxa3xx_nand_detect_config(info))
Lei Wen4332c112011-03-03 11:27:01 +08001391 goto KEEP_CONFIG;
Lei Wen401e67e2011-02-28 10:32:14 +08001392
1393 ret = pxa3xx_nand_sensing(info);
Lei Wend4568822011-07-14 20:44:32 -07001394 if (ret) {
Lei Wenf3c8cfc2011-07-14 20:44:33 -07001395 dev_info(&info->pdev->dev, "There is no chip on cs %d!\n",
1396 info->cs);
Lei Wen401e67e2011-02-28 10:32:14 +08001397
Lei Wend4568822011-07-14 20:44:32 -07001398 return ret;
Lei Wen401e67e2011-02-28 10:32:14 +08001399 }
1400
1401 chip->cmdfunc(mtd, NAND_CMD_READID, 0, 0);
1402 id = *((uint16_t *)(info->data_buff));
1403 if (id != 0)
Lei Wenda675b42011-07-14 20:44:31 -07001404 dev_info(&info->pdev->dev, "Detect a flash id %x\n", id);
Lei Wen401e67e2011-02-28 10:32:14 +08001405 else {
Lei Wenda675b42011-07-14 20:44:31 -07001406 dev_warn(&info->pdev->dev,
1407 "Read out ID 0, potential timing set wrong!!\n");
Lei Wen401e67e2011-02-28 10:32:14 +08001408
1409 return -EINVAL;
1410 }
1411
1412 num = ARRAY_SIZE(builtin_flash_types) + pdata->num_flash - 1;
1413 for (i = 0; i < num; i++) {
1414 if (i < pdata->num_flash)
1415 f = pdata->flash + i;
1416 else
1417 f = &builtin_flash_types[i - pdata->num_flash + 1];
1418
1419 /* find the chip in default list */
Lei Wen4332c112011-03-03 11:27:01 +08001420 if (f->chip_id == id)
Lei Wen401e67e2011-02-28 10:32:14 +08001421 break;
Lei Wen401e67e2011-02-28 10:32:14 +08001422 }
1423
Lei Wen4332c112011-03-03 11:27:01 +08001424 if (i >= (ARRAY_SIZE(builtin_flash_types) + pdata->num_flash - 1)) {
Lei Wenda675b42011-07-14 20:44:31 -07001425 dev_err(&info->pdev->dev, "ERROR!! flash not defined!!!\n");
Lei Wen401e67e2011-02-28 10:32:14 +08001426
1427 return -EINVAL;
1428 }
1429
Lei Wend4568822011-07-14 20:44:32 -07001430 ret = pxa3xx_nand_config_flash(info, f);
1431 if (ret) {
1432 dev_err(&info->pdev->dev, "ERROR! Configure failed\n");
1433 return ret;
1434 }
1435
Lei Wen4332c112011-03-03 11:27:01 +08001436 pxa3xx_flash_ids[0].name = f->name;
Artem Bityutskiy68aa352de2013-03-04 16:05:00 +02001437 pxa3xx_flash_ids[0].dev_id = (f->chip_id >> 8) & 0xffff;
Lei Wen4332c112011-03-03 11:27:01 +08001438 pxa3xx_flash_ids[0].pagesize = f->page_size;
1439 chipsize = (uint64_t)f->num_blocks * f->page_per_block * f->page_size;
1440 pxa3xx_flash_ids[0].chipsize = chipsize >> 20;
1441 pxa3xx_flash_ids[0].erasesize = f->page_size * f->page_per_block;
1442 if (f->flash_width == 16)
1443 pxa3xx_flash_ids[0].options = NAND_BUSWIDTH_16;
Lei Wen0fab0282011-06-07 03:01:06 -07001444 pxa3xx_flash_ids[1].name = NULL;
1445 def = pxa3xx_flash_ids;
Lei Wen4332c112011-03-03 11:27:01 +08001446KEEP_CONFIG:
Ezequiel Garcia48cf7ef2013-08-12 14:14:55 -03001447 if (info->reg_ndcr & NDCR_DWIDTH_M)
Lei Wend4568822011-07-14 20:44:32 -07001448 chip->options |= NAND_BUSWIDTH_16;
1449
Ezequiel Garcia43bcfd22013-11-14 18:25:29 -03001450 /* Device detection must be done with ECC disabled */
1451 if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370)
1452 nand_writel(info, NDECCCTRL, 0x0);
1453
Lei Wen0fab0282011-06-07 03:01:06 -07001454 if (nand_scan_ident(mtd, 1, def))
Lei Wen4332c112011-03-03 11:27:01 +08001455 return -ENODEV;
Ezequiel Garcia776f2652013-11-14 18:25:28 -03001456
1457 if (pdata->flash_bbt) {
1458 /*
1459 * We'll use a bad block table stored in-flash and don't
1460 * allow writing the bad block marker to the flash.
1461 */
1462 chip->bbt_options |= NAND_BBT_USE_FLASH |
1463 NAND_BBT_NO_OOB_BBM;
1464 chip->bbt_td = &bbt_main_descr;
1465 chip->bbt_md = &bbt_mirror_descr;
1466 }
1467
Ezequiel Garcia43bcfd22013-11-14 18:25:29 -03001468 if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370)
1469 ret = armada370_ecc_init(info, &chip->ecc,
1470 chip->ecc_strength_ds,
1471 mtd->writesize);
1472 else
1473 ret = pxa_ecc_init(info, &chip->ecc,
1474 chip->ecc_strength_ds,
1475 mtd->writesize);
1476 if (!ret) {
1477 dev_err(&info->pdev->dev,
1478 "ECC strength %d at page size %d is not supported\n",
1479 chip->ecc_strength_ds, mtd->writesize);
1480 return -ENODEV;
1481 }
1482
Lei Wen4332c112011-03-03 11:27:01 +08001483 /* calculate addressing information */
Lei Wend4568822011-07-14 20:44:32 -07001484 if (mtd->writesize >= 2048)
1485 host->col_addr_cycles = 2;
1486 else
1487 host->col_addr_cycles = 1;
1488
Ezequiel Garcia62e8b852013-10-04 15:30:38 -03001489 /* release the initial buffer */
1490 kfree(info->data_buff);
1491
1492 /* allocate the real data + oob buffer */
1493 info->buf_size = mtd->writesize + mtd->oobsize;
1494 ret = pxa3xx_nand_init_buff(info);
1495 if (ret)
1496 return ret;
Lei Wen4332c112011-03-03 11:27:01 +08001497 info->oob_buff = info->data_buff + mtd->writesize;
Ezequiel Garcia62e8b852013-10-04 15:30:38 -03001498
Lei Wen4332c112011-03-03 11:27:01 +08001499 if ((mtd->size >> chip->page_shift) > 65536)
Lei Wend4568822011-07-14 20:44:32 -07001500 host->row_addr_cycles = 3;
Lei Wen4332c112011-03-03 11:27:01 +08001501 else
Lei Wend4568822011-07-14 20:44:32 -07001502 host->row_addr_cycles = 2;
Lei Wen401e67e2011-02-28 10:32:14 +08001503 return nand_scan_tail(mtd);
eric miaofe69af02008-02-14 15:48:23 +08001504}
1505
Lei Wend4568822011-07-14 20:44:32 -07001506static int alloc_nand_resource(struct platform_device *pdev)
eric miaofe69af02008-02-14 15:48:23 +08001507{
Lei Wenf3c8cfc2011-07-14 20:44:33 -07001508 struct pxa3xx_nand_platform_data *pdata;
eric miaofe69af02008-02-14 15:48:23 +08001509 struct pxa3xx_nand_info *info;
Lei Wend4568822011-07-14 20:44:32 -07001510 struct pxa3xx_nand_host *host;
Haojian Zhuang6e308f82012-08-20 13:40:31 +08001511 struct nand_chip *chip = NULL;
eric miaofe69af02008-02-14 15:48:23 +08001512 struct mtd_info *mtd;
1513 struct resource *r;
Lei Wenf3c8cfc2011-07-14 20:44:33 -07001514 int ret, irq, cs;
eric miaofe69af02008-02-14 15:48:23 +08001515
Jingoo Han453810b2013-07-30 17:18:33 +09001516 pdata = dev_get_platdata(&pdev->dev);
Ezequiel Garcia4c073cd2013-04-17 13:38:09 -03001517 info = devm_kzalloc(&pdev->dev, sizeof(*info) + (sizeof(*mtd) +
1518 sizeof(*host)) * pdata->num_cs, GFP_KERNEL);
1519 if (!info)
Lei Wend4568822011-07-14 20:44:32 -07001520 return -ENOMEM;
eric miaofe69af02008-02-14 15:48:23 +08001521
eric miaofe69af02008-02-14 15:48:23 +08001522 info->pdev = pdev;
Ezequiel Garciac7e9c7e2013-11-07 12:17:14 -03001523 info->variant = pxa3xx_nand_get_variant(pdev);
Lei Wenf3c8cfc2011-07-14 20:44:33 -07001524 for (cs = 0; cs < pdata->num_cs; cs++) {
1525 mtd = (struct mtd_info *)((unsigned int)&info[1] +
1526 (sizeof(*mtd) + sizeof(*host)) * cs);
1527 chip = (struct nand_chip *)(&mtd[1]);
1528 host = (struct pxa3xx_nand_host *)chip;
1529 info->host[cs] = host;
1530 host->mtd = mtd;
1531 host->cs = cs;
1532 host->info_data = info;
1533 mtd->priv = host;
1534 mtd->owner = THIS_MODULE;
eric miaofe69af02008-02-14 15:48:23 +08001535
Lei Wenf3c8cfc2011-07-14 20:44:33 -07001536 chip->ecc.read_page = pxa3xx_nand_read_page_hwecc;
1537 chip->ecc.write_page = pxa3xx_nand_write_page_hwecc;
1538 chip->controller = &info->controller;
1539 chip->waitfunc = pxa3xx_nand_waitfunc;
1540 chip->select_chip = pxa3xx_nand_select_chip;
Lei Wenf3c8cfc2011-07-14 20:44:33 -07001541 chip->read_word = pxa3xx_nand_read_word;
1542 chip->read_byte = pxa3xx_nand_read_byte;
1543 chip->read_buf = pxa3xx_nand_read_buf;
1544 chip->write_buf = pxa3xx_nand_write_buf;
Ezequiel Garcia664c7f52013-11-07 12:17:12 -03001545 chip->options |= NAND_NO_SUBPAGE_WRITE;
Ezequiel Garcia70ed8522013-11-14 18:25:37 -03001546
1547 if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370)
1548 chip->cmdfunc = armada370_nand_cmdfunc;
1549 else
1550 chip->cmdfunc = pxa3xx_nand_cmdfunc;
Lei Wenf3c8cfc2011-07-14 20:44:33 -07001551 }
Lei Wen401e67e2011-02-28 10:32:14 +08001552
1553 spin_lock_init(&chip->controller->lock);
1554 init_waitqueue_head(&chip->controller->wq);
Ezequiel Garcia9ca79442013-04-17 13:38:11 -03001555 info->clk = devm_clk_get(&pdev->dev, NULL);
eric miaofe69af02008-02-14 15:48:23 +08001556 if (IS_ERR(info->clk)) {
1557 dev_err(&pdev->dev, "failed to get nand clock\n");
Ezequiel Garcia4c073cd2013-04-17 13:38:09 -03001558 return PTR_ERR(info->clk);
eric miaofe69af02008-02-14 15:48:23 +08001559 }
Ezequiel Garcia1f8eaff2013-04-17 13:38:13 -03001560 ret = clk_prepare_enable(info->clk);
1561 if (ret < 0)
1562 return ret;
eric miaofe69af02008-02-14 15:48:23 +08001563
Ezequiel Garcia6b45c1e2013-08-12 14:14:58 -03001564 if (use_dma) {
1565 /*
1566 * This is a dirty hack to make this driver work from
1567 * devicetree bindings. It can be removed once we have
1568 * a prober DMA controller framework for DT.
1569 */
1570 if (pdev->dev.of_node &&
1571 of_machine_is_compatible("marvell,pxa3xx")) {
1572 info->drcmr_dat = 97;
1573 info->drcmr_cmd = 99;
1574 } else {
1575 r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
1576 if (r == NULL) {
1577 dev_err(&pdev->dev,
1578 "no resource defined for data DMA\n");
1579 ret = -ENXIO;
1580 goto fail_disable_clk;
1581 }
1582 info->drcmr_dat = r->start;
eric miaofe69af02008-02-14 15:48:23 +08001583
Ezequiel Garcia6b45c1e2013-08-12 14:14:58 -03001584 r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
1585 if (r == NULL) {
1586 dev_err(&pdev->dev,
1587 "no resource defined for cmd DMA\n");
1588 ret = -ENXIO;
1589 goto fail_disable_clk;
1590 }
1591 info->drcmr_cmd = r->start;
Daniel Mack1e7ba632012-07-22 19:51:02 +02001592 }
eric miaofe69af02008-02-14 15:48:23 +08001593 }
eric miaofe69af02008-02-14 15:48:23 +08001594
1595 irq = platform_get_irq(pdev, 0);
1596 if (irq < 0) {
1597 dev_err(&pdev->dev, "no IRQ resource defined\n");
1598 ret = -ENXIO;
Ezequiel Garcia9ca79442013-04-17 13:38:11 -03001599 goto fail_disable_clk;
eric miaofe69af02008-02-14 15:48:23 +08001600 }
1601
1602 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
Ezequiel Garcia0ddd8462013-04-17 13:38:10 -03001603 info->mmio_base = devm_ioremap_resource(&pdev->dev, r);
1604 if (IS_ERR(info->mmio_base)) {
1605 ret = PTR_ERR(info->mmio_base);
Ezequiel Garcia9ca79442013-04-17 13:38:11 -03001606 goto fail_disable_clk;
eric miaofe69af02008-02-14 15:48:23 +08001607 }
Haojian Zhuang8638fac2009-09-10 14:11:44 +08001608 info->mmio_phys = r->start;
eric miaofe69af02008-02-14 15:48:23 +08001609
Ezequiel Garcia62e8b852013-10-04 15:30:38 -03001610 /* Allocate a buffer to allow flash detection */
1611 info->buf_size = INIT_BUFFER_SIZE;
1612 info->data_buff = kmalloc(info->buf_size, GFP_KERNEL);
1613 if (info->data_buff == NULL) {
1614 ret = -ENOMEM;
Ezequiel Garcia9ca79442013-04-17 13:38:11 -03001615 goto fail_disable_clk;
Ezequiel Garcia62e8b852013-10-04 15:30:38 -03001616 }
eric miaofe69af02008-02-14 15:48:23 +08001617
Haojian Zhuang346e1252009-09-10 14:27:23 +08001618 /* initialize all interrupts to be disabled */
1619 disable_int(info, NDSR_MASK);
1620
Michael Opdenackerb1eb2342013-10-13 08:21:32 +02001621 ret = request_irq(irq, pxa3xx_nand_irq, 0, pdev->name, info);
eric miaofe69af02008-02-14 15:48:23 +08001622 if (ret < 0) {
1623 dev_err(&pdev->dev, "failed to request IRQ\n");
1624 goto fail_free_buf;
1625 }
1626
Lei Wene353a202011-03-03 11:08:30 +08001627 platform_set_drvdata(pdev, info);
eric miaofe69af02008-02-14 15:48:23 +08001628
Lei Wend4568822011-07-14 20:44:32 -07001629 return 0;
eric miaofe69af02008-02-14 15:48:23 +08001630
eric miaofe69af02008-02-14 15:48:23 +08001631fail_free_buf:
Lei Wen401e67e2011-02-28 10:32:14 +08001632 free_irq(irq, info);
Ezequiel Garcia62e8b852013-10-04 15:30:38 -03001633 kfree(info->data_buff);
Ezequiel Garcia9ca79442013-04-17 13:38:11 -03001634fail_disable_clk:
Ezequiel Garciafb320612013-04-17 13:38:12 -03001635 clk_disable_unprepare(info->clk);
Lei Wend4568822011-07-14 20:44:32 -07001636 return ret;
eric miaofe69af02008-02-14 15:48:23 +08001637}
1638
1639static int pxa3xx_nand_remove(struct platform_device *pdev)
1640{
Lei Wene353a202011-03-03 11:08:30 +08001641 struct pxa3xx_nand_info *info = platform_get_drvdata(pdev);
Lei Wenf3c8cfc2011-07-14 20:44:33 -07001642 struct pxa3xx_nand_platform_data *pdata;
Lei Wenf3c8cfc2011-07-14 20:44:33 -07001643 int irq, cs;
eric miaofe69af02008-02-14 15:48:23 +08001644
Lei Wend4568822011-07-14 20:44:32 -07001645 if (!info)
1646 return 0;
1647
Jingoo Han453810b2013-07-30 17:18:33 +09001648 pdata = dev_get_platdata(&pdev->dev);
eric miaofe69af02008-02-14 15:48:23 +08001649
Haojian Zhuangdbf59862009-09-10 14:22:55 +08001650 irq = platform_get_irq(pdev, 0);
1651 if (irq >= 0)
1652 free_irq(irq, info);
Ezequiel Garcia498b6142013-04-17 13:38:14 -03001653 pxa3xx_nand_free_buff(info);
Mike Rapoport82a72d12009-02-17 13:54:46 +02001654
Ezequiel Garciafb320612013-04-17 13:38:12 -03001655 clk_disable_unprepare(info->clk);
Mike Rapoport82a72d12009-02-17 13:54:46 +02001656
Lei Wenf3c8cfc2011-07-14 20:44:33 -07001657 for (cs = 0; cs < pdata->num_cs; cs++)
1658 nand_release(info->host[cs]->mtd);
eric miaofe69af02008-02-14 15:48:23 +08001659 return 0;
1660}
1661
Daniel Mack1e7ba632012-07-22 19:51:02 +02001662static int pxa3xx_nand_probe_dt(struct platform_device *pdev)
1663{
1664 struct pxa3xx_nand_platform_data *pdata;
1665 struct device_node *np = pdev->dev.of_node;
1666 const struct of_device_id *of_id =
1667 of_match_device(pxa3xx_nand_dt_ids, &pdev->dev);
1668
1669 if (!of_id)
1670 return 0;
1671
1672 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
1673 if (!pdata)
1674 return -ENOMEM;
1675
1676 if (of_get_property(np, "marvell,nand-enable-arbiter", NULL))
1677 pdata->enable_arbiter = 1;
1678 if (of_get_property(np, "marvell,nand-keep-config", NULL))
1679 pdata->keep_config = 1;
1680 of_property_read_u32(np, "num-cs", &pdata->num_cs);
Ezequiel Garcia776f2652013-11-14 18:25:28 -03001681 pdata->flash_bbt = of_get_nand_on_flash_bbt(np);
Daniel Mack1e7ba632012-07-22 19:51:02 +02001682
1683 pdev->dev.platform_data = pdata;
1684
1685 return 0;
1686}
Daniel Mack1e7ba632012-07-22 19:51:02 +02001687
Lei Wene353a202011-03-03 11:08:30 +08001688static int pxa3xx_nand_probe(struct platform_device *pdev)
1689{
1690 struct pxa3xx_nand_platform_data *pdata;
Daniel Mack1e7ba632012-07-22 19:51:02 +02001691 struct mtd_part_parser_data ppdata = {};
Lei Wene353a202011-03-03 11:08:30 +08001692 struct pxa3xx_nand_info *info;
Lei Wenf3c8cfc2011-07-14 20:44:33 -07001693 int ret, cs, probe_success;
Lei Wene353a202011-03-03 11:08:30 +08001694
Ezequiel Garciaf4db2e32013-08-12 14:14:56 -03001695#ifndef ARCH_HAS_DMA
1696 if (use_dma) {
1697 use_dma = 0;
1698 dev_warn(&pdev->dev,
1699 "This platform can't do DMA on this device\n");
1700 }
1701#endif
Daniel Mack1e7ba632012-07-22 19:51:02 +02001702 ret = pxa3xx_nand_probe_dt(pdev);
1703 if (ret)
1704 return ret;
1705
Jingoo Han453810b2013-07-30 17:18:33 +09001706 pdata = dev_get_platdata(&pdev->dev);
Lei Wene353a202011-03-03 11:08:30 +08001707 if (!pdata) {
1708 dev_err(&pdev->dev, "no platform data defined\n");
1709 return -ENODEV;
1710 }
1711
Lei Wend4568822011-07-14 20:44:32 -07001712 ret = alloc_nand_resource(pdev);
1713 if (ret) {
1714 dev_err(&pdev->dev, "alloc nand resource failed\n");
1715 return ret;
1716 }
Lei Wene353a202011-03-03 11:08:30 +08001717
Lei Wend4568822011-07-14 20:44:32 -07001718 info = platform_get_drvdata(pdev);
Lei Wenf3c8cfc2011-07-14 20:44:33 -07001719 probe_success = 0;
1720 for (cs = 0; cs < pdata->num_cs; cs++) {
Ezequiel Garciab7655bc2013-08-12 14:14:52 -03001721 struct mtd_info *mtd = info->host[cs]->mtd;
Ezequiel Garciaf4555782013-08-12 14:14:53 -03001722
Ezequiel Garcia18a84e92013-10-19 18:19:25 -03001723 /*
1724 * The mtd name matches the one used in 'mtdparts' kernel
1725 * parameter. This name cannot be changed or otherwise
1726 * user's mtd partitions configuration would get broken.
1727 */
1728 mtd->name = "pxa3xx_nand-0";
Lei Wenf3c8cfc2011-07-14 20:44:33 -07001729 info->cs = cs;
Ezequiel Garciab7655bc2013-08-12 14:14:52 -03001730 ret = pxa3xx_nand_scan(mtd);
Lei Wenf3c8cfc2011-07-14 20:44:33 -07001731 if (ret) {
1732 dev_warn(&pdev->dev, "failed to scan nand at cs %d\n",
1733 cs);
1734 continue;
1735 }
1736
Daniel Mack1e7ba632012-07-22 19:51:02 +02001737 ppdata.of_node = pdev->dev.of_node;
Ezequiel Garciab7655bc2013-08-12 14:14:52 -03001738 ret = mtd_device_parse_register(mtd, NULL,
Daniel Mack1e7ba632012-07-22 19:51:02 +02001739 &ppdata, pdata->parts[cs],
Artem Bityutskiy42d7fbe2012-03-09 19:24:26 +02001740 pdata->nr_parts[cs]);
Lei Wenf3c8cfc2011-07-14 20:44:33 -07001741 if (!ret)
1742 probe_success = 1;
1743 }
1744
1745 if (!probe_success) {
Lei Wene353a202011-03-03 11:08:30 +08001746 pxa3xx_nand_remove(pdev);
1747 return -ENODEV;
1748 }
1749
Lei Wenf3c8cfc2011-07-14 20:44:33 -07001750 return 0;
Lei Wene353a202011-03-03 11:08:30 +08001751}
1752
eric miaofe69af02008-02-14 15:48:23 +08001753#ifdef CONFIG_PM
1754static int pxa3xx_nand_suspend(struct platform_device *pdev, pm_message_t state)
1755{
Lei Wene353a202011-03-03 11:08:30 +08001756 struct pxa3xx_nand_info *info = platform_get_drvdata(pdev);
Lei Wenf3c8cfc2011-07-14 20:44:33 -07001757 struct pxa3xx_nand_platform_data *pdata;
1758 struct mtd_info *mtd;
1759 int cs;
eric miaofe69af02008-02-14 15:48:23 +08001760
Jingoo Han453810b2013-07-30 17:18:33 +09001761 pdata = dev_get_platdata(&pdev->dev);
Lei Wenf8155a42011-02-28 10:32:11 +08001762 if (info->state) {
eric miaofe69af02008-02-14 15:48:23 +08001763 dev_err(&pdev->dev, "driver busy, state = %d\n", info->state);
1764 return -EAGAIN;
1765 }
1766
Lei Wenf3c8cfc2011-07-14 20:44:33 -07001767 for (cs = 0; cs < pdata->num_cs; cs++) {
1768 mtd = info->host[cs]->mtd;
Artem Bityutskiy3fe4bae2011-12-23 19:25:16 +02001769 mtd_suspend(mtd);
Lei Wenf3c8cfc2011-07-14 20:44:33 -07001770 }
1771
eric miaofe69af02008-02-14 15:48:23 +08001772 return 0;
1773}
1774
1775static int pxa3xx_nand_resume(struct platform_device *pdev)
1776{
Lei Wene353a202011-03-03 11:08:30 +08001777 struct pxa3xx_nand_info *info = platform_get_drvdata(pdev);
Lei Wenf3c8cfc2011-07-14 20:44:33 -07001778 struct pxa3xx_nand_platform_data *pdata;
1779 struct mtd_info *mtd;
1780 int cs;
Lei Wen051fc412011-07-14 20:44:30 -07001781
Jingoo Han453810b2013-07-30 17:18:33 +09001782 pdata = dev_get_platdata(&pdev->dev);
Lei Wen051fc412011-07-14 20:44:30 -07001783 /* We don't want to handle interrupt without calling mtd routine */
1784 disable_int(info, NDCR_INT_MASK);
eric miaofe69af02008-02-14 15:48:23 +08001785
Lei Wenf3c8cfc2011-07-14 20:44:33 -07001786 /*
1787 * Directly set the chip select to a invalid value,
1788 * then the driver would reset the timing according
1789 * to current chip select at the beginning of cmdfunc
1790 */
1791 info->cs = 0xff;
eric miaofe69af02008-02-14 15:48:23 +08001792
Lei Wen051fc412011-07-14 20:44:30 -07001793 /*
1794 * As the spec says, the NDSR would be updated to 0x1800 when
1795 * doing the nand_clk disable/enable.
1796 * To prevent it damaging state machine of the driver, clear
1797 * all status before resume
1798 */
1799 nand_writel(info, NDSR, NDSR_MASK);
Lei Wenf3c8cfc2011-07-14 20:44:33 -07001800 for (cs = 0; cs < pdata->num_cs; cs++) {
1801 mtd = info->host[cs]->mtd;
Artem Bityutskiyead995f2011-12-23 19:31:25 +02001802 mtd_resume(mtd);
Lei Wenf3c8cfc2011-07-14 20:44:33 -07001803 }
1804
Lei Wen18c81b12010-08-17 17:25:57 +08001805 return 0;
eric miaofe69af02008-02-14 15:48:23 +08001806}
1807#else
1808#define pxa3xx_nand_suspend NULL
1809#define pxa3xx_nand_resume NULL
1810#endif
1811
1812static struct platform_driver pxa3xx_nand_driver = {
1813 .driver = {
1814 .name = "pxa3xx-nand",
Sachin Kamat5576bc72013-09-30 15:10:24 +05301815 .of_match_table = pxa3xx_nand_dt_ids,
eric miaofe69af02008-02-14 15:48:23 +08001816 },
1817 .probe = pxa3xx_nand_probe,
1818 .remove = pxa3xx_nand_remove,
1819 .suspend = pxa3xx_nand_suspend,
1820 .resume = pxa3xx_nand_resume,
1821};
1822
Axel Linf99640d2011-11-27 20:45:03 +08001823module_platform_driver(pxa3xx_nand_driver);
eric miaofe69af02008-02-14 15:48:23 +08001824
1825MODULE_LICENSE("GPL");
1826MODULE_DESCRIPTION("PXA3xx NAND controller driver");