aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorMaarten ter Huurne <maarten@treewalker.org>2012-03-29 13:17:01 -0400
committerRalf Baechle <ralf@linux-mips.org>2012-07-23 08:56:20 -0400
commit1471d41a5bdfdf83ed1e5c2148a9763e64b1f53b (patch)
treee3e9ffb84311be6af7ba2dccaad0d0f287a8cb32 /drivers/mtd
parent28a33cbc24e4256c143dce96c7d93bf423229f92 (diff)
MTD: NAND: JZ4740: Multi-bank support with autodetection
The platform data can now specify which external memory banks to probe for NAND chips, and in which order. Banks that contain a NAND are used and the other banks are freed. Squashed version of development done in jz-2.6.38 branch. Original patch by Lars-Peter Clausen with some bug fixes from me. Thanks to Paul Cercueil for the initial autodetection patch. Signed-off-by: Maarten ter Huurne <maarten@treewalker.org> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/3560/ Acked-By: David Woodhouse <David.Woodhouse@intel.com> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/nand/jz4740_nand.c228
1 files changed, 192 insertions, 36 deletions
diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c
index a6fa884ae49b..100b6775e175 100644
--- a/drivers/mtd/nand/jz4740_nand.c
+++ b/drivers/mtd/nand/jz4740_nand.c
@@ -52,9 +52,10 @@
52 52
53#define JZ_NAND_CTRL_ENABLE_CHIP(x) BIT((x) << 1) 53#define JZ_NAND_CTRL_ENABLE_CHIP(x) BIT((x) << 1)
54#define JZ_NAND_CTRL_ASSERT_CHIP(x) BIT(((x) << 1) + 1) 54#define JZ_NAND_CTRL_ASSERT_CHIP(x) BIT(((x) << 1) + 1)
55#define JZ_NAND_CTRL_ASSERT_CHIP_MASK 0xaa
55 56
56#define JZ_NAND_MEM_ADDR_OFFSET 0x10000
57#define JZ_NAND_MEM_CMD_OFFSET 0x08000 57#define JZ_NAND_MEM_CMD_OFFSET 0x08000
58#define JZ_NAND_MEM_ADDR_OFFSET 0x10000
58 59
59struct jz_nand { 60struct jz_nand {
60 struct mtd_info mtd; 61 struct mtd_info mtd;
@@ -62,8 +63,11 @@ struct jz_nand {
62 void __iomem *base; 63 void __iomem *base;
63 struct resource *mem; 64 struct resource *mem;
64 65
65 void __iomem *bank_base; 66 unsigned char banks[JZ_NAND_NUM_BANKS];
66 struct resource *bank_mem; 67 void __iomem *bank_base[JZ_NAND_NUM_BANKS];
68 struct resource *bank_mem[JZ_NAND_NUM_BANKS];
69
70 int selected_bank;
67 71
68 struct jz_nand_platform_data *pdata; 72 struct jz_nand_platform_data *pdata;
69 bool is_reading; 73 bool is_reading;
@@ -74,26 +78,50 @@ static inline struct jz_nand *mtd_to_jz_nand(struct mtd_info *mtd)
74 return container_of(mtd, struct jz_nand, mtd); 78 return container_of(mtd, struct jz_nand, mtd);
75} 79}
76 80
81static void jz_nand_select_chip(struct mtd_info *mtd, int chipnr)
82{
83 struct jz_nand *nand = mtd_to_jz_nand(mtd);
84 struct nand_chip *chip = mtd->priv;
85 uint32_t ctrl;
86 int banknr;
87
88 ctrl = readl(nand->base + JZ_REG_NAND_CTRL);
89 ctrl &= ~JZ_NAND_CTRL_ASSERT_CHIP_MASK;
90
91 if (chipnr == -1) {
92 banknr = -1;
93 } else {
94 banknr = nand->banks[chipnr] - 1;
95 chip->IO_ADDR_R = nand->bank_base[banknr];
96 chip->IO_ADDR_W = nand->bank_base[banknr];
97 }
98 writel(ctrl, nand->base + JZ_REG_NAND_CTRL);
99
100 nand->selected_bank = banknr;
101}
102
77static void jz_nand_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl) 103static void jz_nand_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl)
78{ 104{
79 struct jz_nand *nand = mtd_to_jz_nand(mtd); 105 struct jz_nand *nand = mtd_to_jz_nand(mtd);
80 struct nand_chip *chip = mtd->priv; 106 struct nand_chip *chip = mtd->priv;
81 uint32_t reg; 107 uint32_t reg;
108 void __iomem *bank_base = nand->bank_base[nand->selected_bank];
109
110 BUG_ON(nand->selected_bank < 0);
82 111
83 if (ctrl & NAND_CTRL_CHANGE) { 112 if (ctrl & NAND_CTRL_CHANGE) {
84 BUG_ON((ctrl & NAND_ALE) && (ctrl & NAND_CLE)); 113 BUG_ON((ctrl & NAND_ALE) && (ctrl & NAND_CLE));
85 if (ctrl & NAND_ALE) 114 if (ctrl & NAND_ALE)
86 chip->IO_ADDR_W = nand->bank_base + JZ_NAND_MEM_ADDR_OFFSET; 115 bank_base += JZ_NAND_MEM_ADDR_OFFSET;
87 else if (ctrl & NAND_CLE) 116 else if (ctrl & NAND_CLE)
88 chip->IO_ADDR_W = nand->bank_base + JZ_NAND_MEM_CMD_OFFSET; 117 bank_base += JZ_NAND_MEM_CMD_OFFSET;
89 else 118 chip->IO_ADDR_W = bank_base;
90 chip->IO_ADDR_W = nand->bank_base;
91 119
92 reg = readl(nand->base + JZ_REG_NAND_CTRL); 120 reg = readl(nand->base + JZ_REG_NAND_CTRL);
93 if (ctrl & NAND_NCE) 121 if (ctrl & NAND_NCE)
94 reg |= JZ_NAND_CTRL_ASSERT_CHIP(0); 122 reg |= JZ_NAND_CTRL_ASSERT_CHIP(nand->selected_bank);
95 else 123 else
96 reg &= ~JZ_NAND_CTRL_ASSERT_CHIP(0); 124 reg &= ~JZ_NAND_CTRL_ASSERT_CHIP(nand->selected_bank);
97 writel(reg, nand->base + JZ_REG_NAND_CTRL); 125 writel(reg, nand->base + JZ_REG_NAND_CTRL);
98 } 126 }
99 if (dat != NAND_CMD_NONE) 127 if (dat != NAND_CMD_NONE)
@@ -252,7 +280,7 @@ static int jz_nand_correct_ecc_rs(struct mtd_info *mtd, uint8_t *dat,
252} 280}
253 281
254static int jz_nand_ioremap_resource(struct platform_device *pdev, 282static int jz_nand_ioremap_resource(struct platform_device *pdev,
255 const char *name, struct resource **res, void __iomem **base) 283 const char *name, struct resource **res, void *__iomem *base)
256{ 284{
257 int ret; 285 int ret;
258 286
@@ -288,6 +316,90 @@ err:
288 return ret; 316 return ret;
289} 317}
290 318
319static inline void jz_nand_iounmap_resource(struct resource *res, void __iomem *base)
320{
321 iounmap(base);
322 release_mem_region(res->start, resource_size(res));
323}
324
325static 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) {
326 int ret;
327 int gpio;
328 char gpio_name[9];
329 char res_name[6];
330 uint32_t ctrl;
331 struct mtd_info *mtd = &nand->mtd;
332 struct nand_chip *chip = &nand->chip;
333
334 /* Request GPIO port. */
335 gpio = JZ_GPIO_MEM_CS0 + bank - 1;
336 sprintf(gpio_name, "NAND CS%d", bank);
337 ret = gpio_request(gpio, gpio_name);
338 if (ret) {
339 dev_warn(&pdev->dev,
340 "Failed to request %s gpio %d: %d\n",
341 gpio_name, gpio, ret);
342 goto notfound_gpio;
343 }
344
345 /* Request I/O resource. */
346 sprintf(res_name, "bank%d", bank);
347 ret = jz_nand_ioremap_resource(pdev, res_name,
348 &nand->bank_mem[bank - 1],
349 &nand->bank_base[bank - 1]);
350 if (ret)
351 goto notfound_resource;
352
353 /* Enable chip in bank. */
354 jz_gpio_set_function(gpio, JZ_GPIO_FUNC_MEM_CS0);
355 ctrl = readl(nand->base + JZ_REG_NAND_CTRL);
356 ctrl |= JZ_NAND_CTRL_ENABLE_CHIP(bank - 1);
357 writel(ctrl, nand->base + JZ_REG_NAND_CTRL);
358
359 if (chipnr == 0) {
360 /* Detect first chip. */
361 ret = nand_scan_ident(mtd, 1, NULL);
362 if (ret)
363 goto notfound_id;
364
365 /* Retrieve the IDs from the first chip. */
366 chip->select_chip(mtd, 0);
367 chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
368 chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
369 *nand_maf_id = chip->read_byte(mtd);
370 *nand_dev_id = chip->read_byte(mtd);
371 } else {
372 /* Detect additional chip. */
373 chip->select_chip(mtd, chipnr);
374 chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
375 chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
376 if (*nand_maf_id != chip->read_byte(mtd)
377 || *nand_dev_id != chip->read_byte(mtd)) {
378 ret = -ENODEV;
379 goto notfound_id;
380 }
381
382 /* Update size of the MTD. */
383 chip->numchips++;
384 mtd->size += chip->chipsize;
385 }
386
387 dev_info(&pdev->dev, "Found chip %i on bank %i\n", chipnr, bank);
388 return 0;
389
390notfound_id:
391 dev_info(&pdev->dev, "No chip found on bank %i\n", bank);
392 ctrl &= ~(JZ_NAND_CTRL_ENABLE_CHIP(bank - 1));
393 writel(ctrl, nand->base + JZ_REG_NAND_CTRL);
394 jz_gpio_set_function(gpio, JZ_GPIO_FUNC_NONE);
395 jz_nand_iounmap_resource(nand->bank_mem[bank - 1],
396 nand->bank_base[bank - 1]);
397notfound_resource:
398 gpio_free(gpio);
399notfound_gpio:
400 return ret;
401}
402
291static int __devinit jz_nand_probe(struct platform_device *pdev) 403static int __devinit jz_nand_probe(struct platform_device *pdev)
292{ 404{
293 int ret; 405 int ret;
@@ -295,6 +407,8 @@ static int __devinit jz_nand_probe(struct platform_device *pdev)
295 struct nand_chip *chip; 407 struct nand_chip *chip;
296 struct mtd_info *mtd; 408 struct mtd_info *mtd;
297 struct jz_nand_platform_data *pdata = pdev->dev.platform_data; 409 struct jz_nand_platform_data *pdata = pdev->dev.platform_data;
410 size_t chipnr, bank_idx;
411 uint8_t nand_maf_id = 0, nand_dev_id = 0;
298 412
299 nand = kzalloc(sizeof(*nand), GFP_KERNEL); 413 nand = kzalloc(sizeof(*nand), GFP_KERNEL);
300 if (!nand) { 414 if (!nand) {
@@ -305,10 +419,6 @@ static int __devinit jz_nand_probe(struct platform_device *pdev)
305 ret = jz_nand_ioremap_resource(pdev, "mmio", &nand->mem, &nand->base); 419 ret = jz_nand_ioremap_resource(pdev, "mmio", &nand->mem, &nand->base);
306 if (ret) 420 if (ret)
307 goto err_free; 421 goto err_free;
308 ret = jz_nand_ioremap_resource(pdev, "bank", &nand->bank_mem,
309 &nand->bank_base);
310 if (ret)
311 goto err_iounmap_mmio;
312 422
313 if (pdata && gpio_is_valid(pdata->busy_gpio)) { 423 if (pdata && gpio_is_valid(pdata->busy_gpio)) {
314 ret = gpio_request(pdata->busy_gpio, "NAND busy pin"); 424 ret = gpio_request(pdata->busy_gpio, "NAND busy pin");
@@ -316,7 +426,7 @@ static int __devinit jz_nand_probe(struct platform_device *pdev)
316 dev_err(&pdev->dev, 426 dev_err(&pdev->dev,
317 "Failed to request busy gpio %d: %d\n", 427 "Failed to request busy gpio %d: %d\n",
318 pdata->busy_gpio, ret); 428 pdata->busy_gpio, ret);
319 goto err_iounmap_mem; 429 goto err_iounmap_mmio;
320 } 430 }
321 } 431 }
322 432
@@ -339,22 +449,51 @@ static int __devinit jz_nand_probe(struct platform_device *pdev)
339 449
340 chip->chip_delay = 50; 450 chip->chip_delay = 50;
341 chip->cmd_ctrl = jz_nand_cmd_ctrl; 451 chip->cmd_ctrl = jz_nand_cmd_ctrl;
452 chip->select_chip = jz_nand_select_chip;
342 453
343 if (pdata && gpio_is_valid(pdata->busy_gpio)) 454 if (pdata && gpio_is_valid(pdata->busy_gpio))
344 chip->dev_ready = jz_nand_dev_ready; 455 chip->dev_ready = jz_nand_dev_ready;
345 456
346 chip->IO_ADDR_R = nand->bank_base;
347 chip->IO_ADDR_W = nand->bank_base;
348
349 nand->pdata = pdata; 457 nand->pdata = pdata;
350 platform_set_drvdata(pdev, nand); 458 platform_set_drvdata(pdev, nand);
351 459
352 writel(JZ_NAND_CTRL_ENABLE_CHIP(0), nand->base + JZ_REG_NAND_CTRL); 460 /* We are going to autodetect NAND chips in the banks specified in the
353 461 * platform data. Although nand_scan_ident() can detect multiple chips,
354 ret = nand_scan_ident(mtd, 1, NULL); 462 * it requires those chips to be numbered consecuitively, which is not
355 if (ret) { 463 * always the case for external memory banks. And a fixed chip-to-bank
356 dev_err(&pdev->dev, "Failed to scan nand\n"); 464 * mapping is not practical either, since for example Dingoo units
357 goto err_gpio_free; 465 * produced at different times have NAND chips in different banks.
466 */
467 chipnr = 0;
468 for (bank_idx = 0; bank_idx < JZ_NAND_NUM_BANKS; bank_idx++) {
469 unsigned char bank;
470
471 /* If there is no platform data, look for NAND in bank 1,
472 * which is the most likely bank since it is the only one
473 * that can be booted from.
474 */
475 bank = pdata ? pdata->banks[bank_idx] : bank_idx ^ 1;
476 if (bank == 0)
477 break;
478 if (bank > JZ_NAND_NUM_BANKS) {
479 dev_warn(&pdev->dev,
480 "Skipping non-existing bank: %d\n", bank);
481 continue;
482 }
483 /* The detection routine will directly or indirectly call
484 * jz_nand_select_chip(), so nand->banks has to contain the
485 * bank we're checking.
486 */
487 nand->banks[chipnr] = bank;
488 if (jz_nand_detect_bank(pdev, nand, bank, chipnr,
489 &nand_maf_id, &nand_dev_id) == 0)
490 chipnr++;
491 else
492 nand->banks[chipnr] = 0;
493 }
494 if (chipnr == 0) {
495 dev_err(&pdev->dev, "No NAND chips found\n");
496 goto err_gpio_busy;
358 } 497 }
359 498
360 if (pdata && pdata->ident_callback) { 499 if (pdata && pdata->ident_callback) {
@@ -364,8 +503,8 @@ static int __devinit jz_nand_probe(struct platform_device *pdev)
364 503
365 ret = nand_scan_tail(mtd); 504 ret = nand_scan_tail(mtd);
366 if (ret) { 505 if (ret) {
367 dev_err(&pdev->dev, "Failed to scan nand\n"); 506 dev_err(&pdev->dev, "Failed to scan NAND\n");
368 goto err_gpio_free; 507 goto err_unclaim_banks;
369 } 508 }
370 509
371 ret = mtd_device_parse_register(mtd, NULL, NULL, 510 ret = mtd_device_parse_register(mtd, NULL, NULL,
@@ -382,14 +521,21 @@ static int __devinit jz_nand_probe(struct platform_device *pdev)
382 return 0; 521 return 0;
383 522
384err_nand_release: 523err_nand_release:
385 nand_release(&nand->mtd); 524 nand_release(mtd);
386err_gpio_free: 525err_unclaim_banks:
526 while (chipnr--) {
527 unsigned char bank = nand->banks[chipnr];
528 gpio_free(JZ_GPIO_MEM_CS0 + bank - 1);
529 jz_nand_iounmap_resource(nand->bank_mem[bank - 1],
530 nand->bank_base[bank - 1]);
531 }
532 writel(0, nand->base + JZ_REG_NAND_CTRL);
533err_gpio_busy:
534 if (pdata && gpio_is_valid(pdata->busy_gpio))
535 gpio_free(pdata->busy_gpio);
387 platform_set_drvdata(pdev, NULL); 536 platform_set_drvdata(pdev, NULL);
388 gpio_free(pdata->busy_gpio);
389err_iounmap_mem:
390 iounmap(nand->bank_base);
391err_iounmap_mmio: 537err_iounmap_mmio:
392 iounmap(nand->base); 538 jz_nand_iounmap_resource(nand->mem, nand->base);
393err_free: 539err_free:
394 kfree(nand); 540 kfree(nand);
395 return ret; 541 return ret;
@@ -398,16 +544,26 @@ err_free:
398static int __devexit jz_nand_remove(struct platform_device *pdev) 544static int __devexit jz_nand_remove(struct platform_device *pdev)
399{ 545{
400 struct jz_nand *nand = platform_get_drvdata(pdev); 546 struct jz_nand *nand = platform_get_drvdata(pdev);
547 struct jz_nand_platform_data *pdata = pdev->dev.platform_data;
548 size_t i;
401 549
402 nand_release(&nand->mtd); 550 nand_release(&nand->mtd);
403 551
404 /* Deassert and disable all chips */ 552 /* Deassert and disable all chips */
405 writel(0, nand->base + JZ_REG_NAND_CTRL); 553 writel(0, nand->base + JZ_REG_NAND_CTRL);
406 554
407 iounmap(nand->bank_base); 555 for (i = 0; i < JZ_NAND_NUM_BANKS; ++i) {
408 release_mem_region(nand->bank_mem->start, resource_size(nand->bank_mem)); 556 unsigned char bank = nand->banks[i];
409 iounmap(nand->base); 557 if (bank != 0) {
410 release_mem_region(nand->mem->start, resource_size(nand->mem)); 558 jz_nand_iounmap_resource(nand->bank_mem[bank - 1],
559 nand->bank_base[bank - 1]);
560 gpio_free(JZ_GPIO_MEM_CS0 + bank - 1);
561 }
562 }
563 if (pdata && gpio_is_valid(pdata->busy_gpio))
564 gpio_free(pdata->busy_gpio);
565
566 jz_nand_iounmap_resource(nand->mem, nand->base);
411 567
412 platform_set_drvdata(pdev, NULL); 568 platform_set_drvdata(pdev, NULL);
413 kfree(nand); 569 kfree(nand);