lantiq: add v3.9 support
[openwrt.git] / target / linux / lantiq / patches-3.9 / 0013-MTD-lantiq-Add-NAND-support-on-Lantiq-Falcon-SoC.patch
1 From 6bfb122580ccf67b82abf6c5fe2ae1e770812f0d Mon Sep 17 00:00:00 2001
2 From: John Crispin <blogic@openwrt.org>
3 Date: Wed, 30 Jan 2013 21:12:47 +0100
4 Subject: [PATCH 13/22] MTD: lantiq: Add NAND support on Lantiq Falcon SoC.
5
6 The driver uses plat_nand. As the platform_device is loaded from DT, we need
7 to lookup the node and attach our falcon specific "struct platform_nand_data"
8 to it.
9
10 Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
11 Signed-off-by: John Crispin <blogic@openwrt.org>
12 ---
13  drivers/mtd/nand/Kconfig       |    8 ++++
14  drivers/mtd/nand/Makefile      |    1 +
15  drivers/mtd/nand/falcon_nand.c |   83 ++++++++++++++++++++++++++++++++++++++++
16  3 files changed, 92 insertions(+)
17  create mode 100644 drivers/mtd/nand/falcon_nand.c
18
19 diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
20 index 81bf5e5..2738097 100644
21 --- a/drivers/mtd/nand/Kconfig
22 +++ b/drivers/mtd/nand/Kconfig
23 @@ -574,4 +574,12 @@ config MTD_NAND_XWAY
24           Enables support for NAND Flash chips on Lantiq XWAY SoCs. NAND is attached
25           to the External Bus Unit (EBU).
26  
27 +config MTD_NAND_FALCON
28 +       tristate "Support for NAND on Lantiq FALC-ON SoC"
29 +       depends on LANTIQ && SOC_FALCON
30 +       select MTD_NAND_PLATFORM
31 +       help
32 +         Enables support for NAND Flash chips on Lantiq FALC-ON SoCs. NAND is
33 +         attached to the External Bus Unit (EBU).
34 +
35  endif # MTD_NAND
36 diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
37 index d76d912..1a61bf0 100644
38 --- a/drivers/mtd/nand/Makefile
39 +++ b/drivers/mtd/nand/Makefile
40 @@ -53,5 +53,6 @@ obj-$(CONFIG_MTD_NAND_JZ4740)         += jz4740_nand.o
41  obj-$(CONFIG_MTD_NAND_GPMI_NAND)       += gpmi-nand/
42  obj-$(CONFIG_MTD_NAND_XWAY)            += xway_nand.o
43  obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH)   += bcm47xxnflash/
44 +obj-$(CONFIG_MTD_NAND_FALCON)          += falcon_nand.o
45  
46  nand-objs := nand_base.o nand_bbt.o
47 diff --git a/drivers/mtd/nand/falcon_nand.c b/drivers/mtd/nand/falcon_nand.c
48 new file mode 100644
49 index 0000000..13458d3
50 --- /dev/null
51 +++ b/drivers/mtd/nand/falcon_nand.c
52 @@ -0,0 +1,83 @@
53 +/*
54 + * This program is free software; you can redistribute it and/or modify it
55 + * under the terms of the GNU General Public License version 2 as published
56 + * by the Free Software Foundation.
57 + *
58 + * Copyright (C) 2011 Thomas Langer <thomas.langer@lantiq.com>
59 + * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
60 + */
61 +
62 +#include <linux/mtd/nand.h>
63 +#include <linux/of_platform.h>
64 +
65 +#include <lantiq_soc.h>
66 +
67 +/* address lines used for NAND control signals */
68 +#define NAND_ADDR_ALE          0x10000
69 +#define NAND_ADDR_CLE          0x20000
70 +
71 +/* Ready/Busy Status */
72 +#define MODCON_STS             0x0002
73 +
74 +/* Ready/Busy Status Edge */
75 +#define MODCON_STSEDGE         0x0004
76 +#define LTQ_EBU_MODCON         0x000C
77 +
78 +static const char const *part_probes[] = { "cmdlinepart", "ofpart", NULL };
79 +
80 +static int falcon_nand_ready(struct mtd_info *mtd)
81 +{
82 +       u32 modcon = ltq_ebu_r32(LTQ_EBU_MODCON);
83 +
84 +       return (((modcon & (MODCON_STS | MODCON_STSEDGE)) ==
85 +                                               (MODCON_STS | MODCON_STSEDGE)));
86 +}
87 +
88 +static void falcon_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
89 +{
90 +       struct nand_chip *this = mtd->priv;
91 +       unsigned long nandaddr = (unsigned long) this->IO_ADDR_W;
92 +
93 +       if (ctrl & NAND_CTRL_CHANGE) {
94 +               nandaddr &= ~(NAND_ADDR_ALE | NAND_ADDR_CLE);
95 +
96 +               if (ctrl & NAND_CLE)
97 +                       nandaddr |= NAND_ADDR_CLE;
98 +               if (ctrl & NAND_ALE)
99 +                       nandaddr |= NAND_ADDR_ALE;
100 +
101 +               this->IO_ADDR_W = (void __iomem *) nandaddr;
102 +       }
103 +
104 +       if (cmd != NAND_CMD_NONE)
105 +               writeb(cmd, this->IO_ADDR_W);
106 +}
107 +
108 +static struct platform_nand_data falcon_nand_data = {
109 +       .chip = {
110 +               .nr_chips               = 1,
111 +               .chip_delay             = 25,
112 +               .part_probe_types       = part_probes,
113 +       },
114 +       .ctrl = {
115 +               .cmd_ctrl               = falcon_hwcontrol,
116 +               .dev_ready              = falcon_nand_ready,
117 +       }
118 +};
119 +
120 +int __init falcon_register_nand(void)
121 +{
122 +       struct device_node *node;
123 +       struct platform_device *pdev;
124 +
125 +       node = of_find_compatible_node(NULL, NULL, "lantiq,nand-falcon");
126 +       if (!node)
127 +               return -1;
128 +       pdev = of_find_device_by_node(node);
129 +       if (pdev)
130 +               pdev->dev.platform_data = &falcon_nand_data;
131 +       of_node_put(node);
132 +       return 0;
133 +}
134 +
135 +arch_initcall(falcon_register_nand);
136 -- 
137 1.7.10.4
138