1 From d5814bdb661d3dac61422f8f69e459be884c9a9d Mon Sep 17 00:00:00 2001
2 From: Maarten ter Huurne <maarten@treewalker.org>
3 Date: Tue, 2 Aug 2011 10:49:28 +0200
4 Subject: [PATCH 06/21] MTD: NAND: JZ4740: Multi-bank support with
7 The platform data can now specify which external memory banks to probe
8 for NAND chips, and in which order. Banks that contain a NAND are used
9 and the other banks are freed.
11 Squashed version of development done in jz-2.6.38 branch.
12 Original patch by Lars-Peter Clausen with some bug fixes from me.
13 Thanks to Paul Cercueil for the initial autodetection patch.
15 arch/mips/include/asm/mach-jz4740/jz4740_nand.h | 4 +
16 arch/mips/jz4740/platform.c | 20 ++-
17 drivers/mtd/nand/jz4740_nand.c | 228 +++++++++++++++++++----
18 3 files changed, 215 insertions(+), 37 deletions(-)
20 diff --git a/arch/mips/include/asm/mach-jz4740/jz4740_nand.h b/arch/mips/include/asm/mach-jz4740/jz4740_nand.h
21 index bb5b9a4..986982d 100644
22 --- a/arch/mips/include/asm/mach-jz4740/jz4740_nand.h
23 +++ b/arch/mips/include/asm/mach-jz4740/jz4740_nand.h
25 #include <linux/mtd/nand.h>
26 #include <linux/mtd/partitions.h>
28 +#define JZ_NAND_NUM_BANKS 4
30 struct jz_nand_platform_data {
32 struct mtd_partition *partitions;
33 @@ -27,6 +29,8 @@ struct jz_nand_platform_data {
35 unsigned int busy_gpio;
37 + unsigned char banks[JZ_NAND_NUM_BANKS];
39 void (*ident_callback)(struct platform_device *, struct nand_chip *,
40 struct mtd_partition **, int *num_partitions);
42 diff --git a/arch/mips/jz4740/platform.c b/arch/mips/jz4740/platform.c
43 index 10929e2..e342ed4 100644
44 --- a/arch/mips/jz4740/platform.c
45 +++ b/arch/mips/jz4740/platform.c
46 @@ -157,11 +157,29 @@ static struct resource jz4740_nand_resources[] = {
47 .flags = IORESOURCE_MEM,
53 .end = 0x180C0000 - 1,
54 .flags = IORESOURCE_MEM,
58 + .start = 0x14000000,
59 + .end = 0x140C0000 - 1,
60 + .flags = IORESOURCE_MEM,
64 + .start = 0x0C000000,
65 + .end = 0x0C0C0000 - 1,
66 + .flags = IORESOURCE_MEM,
70 + .start = 0x08000000,
71 + .end = 0x080C0000 - 1,
72 + .flags = IORESOURCE_MEM,
76 struct platform_device jz4740_nand_device = {
77 diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c
78 index e266407..b254b99 100644
79 --- a/drivers/mtd/nand/jz4740_nand.c
80 +++ b/drivers/mtd/nand/jz4740_nand.c
83 #define JZ_NAND_CTRL_ENABLE_CHIP(x) BIT((x) << 1)
84 #define JZ_NAND_CTRL_ASSERT_CHIP(x) BIT(((x) << 1) + 1)
85 +#define JZ_NAND_CTRL_ASSERT_CHIP_MASK 0xaa
87 -#define JZ_NAND_MEM_ADDR_OFFSET 0x10000
88 #define JZ_NAND_MEM_CMD_OFFSET 0x08000
89 +#define JZ_NAND_MEM_ADDR_OFFSET 0x10000
93 @@ -62,8 +63,11 @@ struct jz_nand {
97 - void __iomem *bank_base;
98 - struct resource *bank_mem;
99 + unsigned char banks[JZ_NAND_NUM_BANKS];
100 + void __iomem *bank_base[JZ_NAND_NUM_BANKS];
101 + struct resource *bank_mem[JZ_NAND_NUM_BANKS];
105 struct jz_nand_platform_data *pdata;
107 @@ -74,26 +78,50 @@ static inline struct jz_nand *mtd_to_jz_nand(struct mtd_info *mtd)
108 return container_of(mtd, struct jz_nand, mtd);
111 +static void jz_nand_select_chip(struct mtd_info *mtd, int chipnr)
113 + struct jz_nand *nand = mtd_to_jz_nand(mtd);
114 + struct nand_chip *chip = mtd->priv;
118 + ctrl = readl(nand->base + JZ_REG_NAND_CTRL);
119 + ctrl &= ~JZ_NAND_CTRL_ASSERT_CHIP_MASK;
121 + if (chipnr == -1) {
124 + banknr = nand->banks[chipnr] - 1;
125 + chip->IO_ADDR_R = nand->bank_base[banknr];
126 + chip->IO_ADDR_W = nand->bank_base[banknr];
128 + writel(ctrl, nand->base + JZ_REG_NAND_CTRL);
130 + nand->selected_bank = banknr;
133 static void jz_nand_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl)
135 struct jz_nand *nand = mtd_to_jz_nand(mtd);
136 struct nand_chip *chip = mtd->priv;
138 + void __iomem *bank_base = nand->bank_base[nand->selected_bank];
140 + BUG_ON(nand->selected_bank < 0);
142 if (ctrl & NAND_CTRL_CHANGE) {
143 BUG_ON((ctrl & NAND_ALE) && (ctrl & NAND_CLE));
145 - chip->IO_ADDR_W = nand->bank_base + JZ_NAND_MEM_ADDR_OFFSET;
146 + bank_base += JZ_NAND_MEM_ADDR_OFFSET;
147 else if (ctrl & NAND_CLE)
148 - chip->IO_ADDR_W = nand->bank_base + JZ_NAND_MEM_CMD_OFFSET;
150 - chip->IO_ADDR_W = nand->bank_base;
151 + bank_base += JZ_NAND_MEM_CMD_OFFSET;
152 + chip->IO_ADDR_W = bank_base;
154 reg = readl(nand->base + JZ_REG_NAND_CTRL);
156 - reg |= JZ_NAND_CTRL_ASSERT_CHIP(0);
157 + reg |= JZ_NAND_CTRL_ASSERT_CHIP(nand->selected_bank);
159 - reg &= ~JZ_NAND_CTRL_ASSERT_CHIP(0);
160 + reg &= ~JZ_NAND_CTRL_ASSERT_CHIP(nand->selected_bank);
161 writel(reg, nand->base + JZ_REG_NAND_CTRL);
163 if (dat != NAND_CMD_NONE)
164 @@ -252,7 +280,7 @@ static int jz_nand_correct_ecc_rs(struct mtd_info *mtd, uint8_t *dat,
167 static int jz_nand_ioremap_resource(struct platform_device *pdev,
168 - const char *name, struct resource **res, void __iomem **base)
169 + const char *name, struct resource **res, void *__iomem *base)
173 @@ -288,6 +316,90 @@ err:
177 +static inline void jz_nand_iounmap_resource(struct resource *res, void __iomem *base)
180 + release_mem_region(res->start, resource_size(res));
183 +static int __devinit jz_nand_detect_bank(struct platform_device *pdev, struct jz_nand *nand, unsigned char bank, size_t chipnr, uint8_t *nand_maf_id, uint8_t *nand_dev_id) {
189 + struct mtd_info *mtd = &nand->mtd;
190 + struct nand_chip *chip = &nand->chip;
192 + /* Request GPIO port. */
193 + gpio = JZ_GPIO_MEM_CS0 + bank - 1;
194 + sprintf(gpio_name, "NAND CS%d", bank);
195 + ret = gpio_request(gpio, gpio_name);
197 + dev_warn(&pdev->dev,
198 + "Failed to request %s gpio %d: %d\n",
199 + gpio_name, gpio, ret);
200 + goto notfound_gpio;
203 + /* Request I/O resource. */
204 + sprintf(res_name, "bank%d", bank);
205 + ret = jz_nand_ioremap_resource(pdev, res_name,
206 + &nand->bank_mem[bank - 1],
207 + &nand->bank_base[bank - 1]);
209 + goto notfound_resource;
211 + /* Enable chip in bank. */
212 + jz_gpio_set_function(gpio, JZ_GPIO_FUNC_MEM_CS0);
213 + ctrl = readl(nand->base + JZ_REG_NAND_CTRL);
214 + ctrl |= JZ_NAND_CTRL_ENABLE_CHIP(bank - 1);
215 + writel(ctrl, nand->base + JZ_REG_NAND_CTRL);
218 + /* Detect first chip. */
219 + ret = nand_scan_ident(mtd, 1, NULL);
223 + /* Retrieve the IDs from the first chip. */
224 + chip->select_chip(mtd, 0);
225 + chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
226 + chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
227 + *nand_maf_id = chip->read_byte(mtd);
228 + *nand_dev_id = chip->read_byte(mtd);
230 + /* Detect additional chip. */
231 + chip->select_chip(mtd, chipnr);
232 + chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
233 + chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
234 + if (*nand_maf_id != chip->read_byte(mtd)
235 + || *nand_dev_id != chip->read_byte(mtd)) {
240 + /* Update size of the MTD. */
242 + mtd->size += chip->chipsize;
245 + dev_info(&pdev->dev, "Found chip %i on bank %i\n", chipnr, bank);
249 + dev_info(&pdev->dev, "No chip found on bank %i\n", bank);
250 + ctrl &= ~(JZ_NAND_CTRL_ENABLE_CHIP(bank - 1));
251 + writel(ctrl, nand->base + JZ_REG_NAND_CTRL);
252 + jz_gpio_set_function(gpio, JZ_GPIO_FUNC_NONE);
253 + jz_nand_iounmap_resource(nand->bank_mem[bank - 1],
254 + nand->bank_base[bank - 1]);
261 static int __devinit jz_nand_probe(struct platform_device *pdev)
264 @@ -295,6 +407,8 @@ static int __devinit jz_nand_probe(struct platform_device *pdev)
265 struct nand_chip *chip;
266 struct mtd_info *mtd;
267 struct jz_nand_platform_data *pdata = pdev->dev.platform_data;
268 + size_t chipnr, bank_idx;
269 + uint8_t nand_maf_id = 0, nand_dev_id = 0;
271 nand = kzalloc(sizeof(*nand), GFP_KERNEL);
273 @@ -305,10 +419,6 @@ static int __devinit jz_nand_probe(struct platform_device *pdev)
274 ret = jz_nand_ioremap_resource(pdev, "mmio", &nand->mem, &nand->base);
277 - ret = jz_nand_ioremap_resource(pdev, "bank", &nand->bank_mem,
280 - goto err_iounmap_mmio;
282 if (pdata && gpio_is_valid(pdata->busy_gpio)) {
283 ret = gpio_request(pdata->busy_gpio, "NAND busy pin");
284 @@ -316,7 +426,7 @@ static int __devinit jz_nand_probe(struct platform_device *pdev)
286 "Failed to request busy gpio %d: %d\n",
287 pdata->busy_gpio, ret);
288 - goto err_iounmap_mem;
289 + goto err_iounmap_mmio;
293 @@ -338,22 +448,51 @@ static int __devinit jz_nand_probe(struct platform_device *pdev)
295 chip->chip_delay = 50;
296 chip->cmd_ctrl = jz_nand_cmd_ctrl;
297 + chip->select_chip = jz_nand_select_chip;
299 if (pdata && gpio_is_valid(pdata->busy_gpio))
300 chip->dev_ready = jz_nand_dev_ready;
302 - chip->IO_ADDR_R = nand->bank_base;
303 - chip->IO_ADDR_W = nand->bank_base;
306 platform_set_drvdata(pdev, nand);
308 - writel(JZ_NAND_CTRL_ENABLE_CHIP(0), nand->base + JZ_REG_NAND_CTRL);
310 - ret = nand_scan_ident(mtd, 1, NULL);
312 - dev_err(&pdev->dev, "Failed to scan nand\n");
313 - goto err_gpio_free;
314 + /* We are going to autodetect NAND chips in the banks specified in the
315 + * platform data. Although nand_scan_ident() can detect multiple chips,
316 + * it requires those chips to be numbered consecuitively, which is not
317 + * always the case for external memory banks. And a fixed chip-to-bank
318 + * mapping is not practical either, since for example Dingoo units
319 + * produced at different times have NAND chips in different banks.
322 + for (bank_idx = 0; bank_idx < JZ_NAND_NUM_BANKS; bank_idx++) {
323 + unsigned char bank;
325 + /* If there is no platform data, look for NAND in bank 1,
326 + * which is the most likely bank since it is the only one
327 + * that can be booted from.
329 + bank = pdata ? pdata->banks[bank_idx] : bank_idx ^ 1;
332 + if (bank > JZ_NAND_NUM_BANKS) {
333 + dev_warn(&pdev->dev,
334 + "Skipping non-existing bank: %d\n", bank);
337 + /* The detection routine will directly or indirectly call
338 + * jz_nand_select_chip(), so nand->banks has to contain the
339 + * bank we're checking.
341 + nand->banks[chipnr] = bank;
342 + if (jz_nand_detect_bank(pdev, nand, bank, chipnr,
343 + &nand_maf_id, &nand_dev_id) == 0)
346 + nand->banks[chipnr] = 0;
349 + dev_err(&pdev->dev, "No NAND chips found\n");
350 + goto err_gpio_busy;
353 if (pdata && pdata->ident_callback) {
354 @@ -363,8 +502,8 @@ static int __devinit jz_nand_probe(struct platform_device *pdev)
356 ret = nand_scan_tail(mtd);
358 - dev_err(&pdev->dev, "Failed to scan nand\n");
359 - goto err_gpio_free;
360 + dev_err(&pdev->dev, "Failed to scan NAND\n");
361 + goto err_unclaim_banks;
364 ret = mtd_device_parse_register(mtd, NULL, 0,
365 @@ -381,14 +520,21 @@ static int __devinit jz_nand_probe(struct platform_device *pdev)
369 - nand_release(&nand->mtd);
374 + unsigned char bank = nand->banks[chipnr];
375 + gpio_free(JZ_GPIO_MEM_CS0 + bank - 1);
376 + jz_nand_iounmap_resource(nand->bank_mem[bank - 1],
377 + nand->bank_base[bank - 1]);
379 + writel(0, nand->base + JZ_REG_NAND_CTRL);
381 + if (pdata && gpio_is_valid(pdata->busy_gpio))
382 + gpio_free(pdata->busy_gpio);
383 platform_set_drvdata(pdev, NULL);
384 - gpio_free(pdata->busy_gpio);
386 - iounmap(nand->bank_base);
388 - iounmap(nand->base);
389 + jz_nand_iounmap_resource(nand->mem, nand->base);
393 @@ -397,16 +543,26 @@ err_free:
394 static int __devexit jz_nand_remove(struct platform_device *pdev)
396 struct jz_nand *nand = platform_get_drvdata(pdev);
397 + struct jz_nand_platform_data *pdata = pdev->dev.platform_data;
400 nand_release(&nand->mtd);
402 /* Deassert and disable all chips */
403 writel(0, nand->base + JZ_REG_NAND_CTRL);
405 - iounmap(nand->bank_base);
406 - release_mem_region(nand->bank_mem->start, resource_size(nand->bank_mem));
407 - iounmap(nand->base);
408 - release_mem_region(nand->mem->start, resource_size(nand->mem));
409 + for (i = 0; i < JZ_NAND_NUM_BANKS; ++i) {
410 + unsigned char bank = nand->banks[i];
412 + jz_nand_iounmap_resource(nand->bank_mem[bank - 1],
413 + nand->bank_base[bank - 1]);
414 + gpio_free(JZ_GPIO_MEM_CS0 + bank - 1);
417 + if (pdata && gpio_is_valid(pdata->busy_gpio))
418 + gpio_free(pdata->busy_gpio);
420 + jz_nand_iounmap_resource(nand->mem, nand->base);
422 platform_set_drvdata(pdev, NULL);