aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeiko Schocher <hs@denx.de>2012-07-30 03:22:24 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2012-09-29 09:59:04 -0400
commitcdeadd712f52b16a9285386d61ee26fd14eb4085 (patch)
treeb02e5aa17567fdac6bdc22033c7c9fd8a5aaeb98
parenta445f784ae5558a3da680aa6b39ed53c95a551c1 (diff)
mtd: nand: davinci: add OF support for davinci nand controller
add OF support for the davinci nand controller. Signed-off-by: Heiko Schocher <hs@denx.de> Acked-by: Sekhar Nori <nsekhar@ti.com> Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
-rw-r--r--Documentation/devicetree/bindings/arm/davinci/nand.txt51
-rw-r--r--drivers/mtd/nand/davinci_nand.c72
2 files changed, 122 insertions, 1 deletions
diff --git a/Documentation/devicetree/bindings/arm/davinci/nand.txt b/Documentation/devicetree/bindings/arm/davinci/nand.txt
new file mode 100644
index 00000000000..e37241f1fdd
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/davinci/nand.txt
@@ -0,0 +1,51 @@
1* Texas Instruments Davinci NAND
2
3This file provides information, what the device node for the
4davinci nand interface contain.
5
6Required properties:
7- compatible: "ti,davinci-nand";
8- reg : contain 2 offset/length values:
9 - offset and length for the access window
10 - offset and length for accessing the aemif control registers
11- ti,davinci-chipselect: Indicates on the davinci_nand driver which
12 chipselect is used for accessing the nand.
13
14Recommended properties :
15- ti,davinci-mask-ale: mask for ale
16- ti,davinci-mask-cle: mask for cle
17- ti,davinci-mask-chipsel: mask for chipselect
18- ti,davinci-ecc-mode: ECC mode valid values for davinci driver:
19 - "none"
20 - "soft"
21 - "hw"
22- ti,davinci-ecc-bits: used ECC bits, currently supported 1 or 4.
23- ti,davinci-nand-buswidth: buswidth 8 or 16
24- ti,davinci-nand-use-bbt: use flash based bad block table support.
25
26Example (enbw_cmc board):
27aemif@60000000 {
28 compatible = "ti,davinci-aemif";
29 #address-cells = <2>;
30 #size-cells = <1>;
31 reg = <0x68000000 0x80000>;
32 ranges = <2 0 0x60000000 0x02000000
33 3 0 0x62000000 0x02000000
34 4 0 0x64000000 0x02000000
35 5 0 0x66000000 0x02000000
36 6 0 0x68000000 0x02000000>;
37 nand@3,0 {
38 compatible = "ti,davinci-nand";
39 reg = <3 0x0 0x807ff
40 6 0x0 0x8000>;
41 #address-cells = <1>;
42 #size-cells = <1>;
43 ti,davinci-chipselect = <1>;
44 ti,davinci-mask-ale = <0>;
45 ti,davinci-mask-cle = <0>;
46 ti,davinci-mask-chipsel = <0>;
47 ti,davinci-ecc-mode = "hw";
48 ti,davinci-ecc-bits = <4>;
49 ti,davinci-nand-use-bbt;
50 };
51};
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c
index d94b03c207a..f386b3c5503 100644
--- a/drivers/mtd/nand/davinci_nand.c
+++ b/drivers/mtd/nand/davinci_nand.c
@@ -33,6 +33,7 @@
33#include <linux/mtd/nand.h> 33#include <linux/mtd/nand.h>
34#include <linux/mtd/partitions.h> 34#include <linux/mtd/partitions.h>
35#include <linux/slab.h> 35#include <linux/slab.h>
36#include <linux/of_device.h>
36 37
37#include <mach/nand.h> 38#include <mach/nand.h>
38#include <mach/aemif.h> 39#include <mach/aemif.h>
@@ -518,9 +519,75 @@ static struct nand_ecclayout hwecc4_2048 __initconst = {
518 }, 519 },
519}; 520};
520 521
522#if defined(CONFIG_OF)
523static const struct of_device_id davinci_nand_of_match[] = {
524 {.compatible = "ti,davinci-nand", },
525 {},
526}
527MODULE_DEVICE_TABLE(of, davinci_nand_of_match);
528
529static struct davinci_nand_pdata
530 *nand_davinci_get_pdata(struct platform_device *pdev)
531{
532 if (!pdev->dev.platform_data && pdev->dev.of_node) {
533 struct davinci_nand_pdata *pdata;
534 const char *mode;
535 u32 prop;
536 int len;
537
538 pdata = devm_kzalloc(&pdev->dev,
539 sizeof(struct davinci_nand_pdata),
540 GFP_KERNEL);
541 pdev->dev.platform_data = pdata;
542 if (!pdata)
543 return NULL;
544 if (!of_property_read_u32(pdev->dev.of_node,
545 "ti,davinci-chipselect", &prop))
546 pdev->id = prop;
547 if (!of_property_read_u32(pdev->dev.of_node,
548 "ti,davinci-mask-ale", &prop))
549 pdata->mask_ale = prop;
550 if (!of_property_read_u32(pdev->dev.of_node,
551 "ti,davinci-mask-cle", &prop))
552 pdata->mask_cle = prop;
553 if (!of_property_read_u32(pdev->dev.of_node,
554 "ti,davinci-mask-chipsel", &prop))
555 pdata->mask_chipsel = prop;
556 if (!of_property_read_string(pdev->dev.of_node,
557 "ti,davinci-ecc-mode", &mode)) {
558 if (!strncmp("none", mode, 4))
559 pdata->ecc_mode = NAND_ECC_NONE;
560 if (!strncmp("soft", mode, 4))
561 pdata->ecc_mode = NAND_ECC_SOFT;
562 if (!strncmp("hw", mode, 2))
563 pdata->ecc_mode = NAND_ECC_HW;
564 }
565 if (!of_property_read_u32(pdev->dev.of_node,
566 "ti,davinci-ecc-bits", &prop))
567 pdata->ecc_bits = prop;
568 if (!of_property_read_u32(pdev->dev.of_node,
569 "ti,davinci-nand-buswidth", &prop))
570 if (prop == 16)
571 pdata->options |= NAND_BUSWIDTH_16;
572 if (of_find_property(pdev->dev.of_node,
573 "ti,davinci-nand-use-bbt", &len))
574 pdata->bbt_options = NAND_BBT_USE_FLASH;
575 }
576
577 return pdev->dev.platform_data;
578}
579#else
580#define davinci_nand_of_match NULL
581static struct davinci_nand_pdata
582 *nand_davinci_get_pdata(struct platform_device *pdev)
583{
584 return pdev->dev.platform_data;
585}
586#endif
587
521static int __init nand_davinci_probe(struct platform_device *pdev) 588static int __init nand_davinci_probe(struct platform_device *pdev)
522{ 589{
523 struct davinci_nand_pdata *pdata = pdev->dev.platform_data; 590 struct davinci_nand_pdata *pdata;
524 struct davinci_nand_info *info; 591 struct davinci_nand_info *info;
525 struct resource *res1; 592 struct resource *res1;
526 struct resource *res2; 593 struct resource *res2;
@@ -530,6 +597,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
530 uint32_t val; 597 uint32_t val;
531 nand_ecc_modes_t ecc_mode; 598 nand_ecc_modes_t ecc_mode;
532 599
600 pdata = nand_davinci_get_pdata(pdev);
533 /* insist on board-specific configuration */ 601 /* insist on board-specific configuration */
534 if (!pdata) 602 if (!pdata)
535 return -ENODEV; 603 return -ENODEV;
@@ -816,6 +884,8 @@ static struct platform_driver nand_davinci_driver = {
816 .remove = __exit_p(nand_davinci_remove), 884 .remove = __exit_p(nand_davinci_remove),
817 .driver = { 885 .driver = {
818 .name = "davinci_nand", 886 .name = "davinci_nand",
887 .owner = THIS_MODULE,
888 .of_match_table = davinci_nand_of_match,
819 }, 889 },
820}; 890};
821MODULE_ALIAS("platform:davinci_nand"); 891MODULE_ALIAS("platform:davinci_nand");