lantiq: Fix flash for targets with NO_XIP
[openwrt/svn-archive/archive.git] / target / linux / lantiq / patches-3.14 / 0019-MTD-lantiq-Add-NAND-support-on-Lantiq-Falcon-SoC.patch
1 From c21eed4418956ecc95966a2e174d47f58397071a 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 19/36] 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 --- a/drivers/mtd/nand/Kconfig
20 +++ b/drivers/mtd/nand/Kconfig
21 @@ -510,4 +510,12 @@ config MTD_NAND_XWAY
22 Enables support for NAND Flash chips on Lantiq XWAY SoCs. NAND is attached
23 to the External Bus Unit (EBU).
24
25 +config MTD_NAND_FALCON
26 + tristate "Support for NAND on Lantiq FALC-ON SoC"
27 + depends on LANTIQ && SOC_FALCON
28 + select MTD_NAND_PLATFORM
29 + help
30 + Enables support for NAND Flash chips on Lantiq FALC-ON SoCs. NAND is
31 + attached to the External Bus Unit (EBU).
32 +
33 endif # MTD_NAND
34 --- a/drivers/mtd/nand/Makefile
35 +++ b/drivers/mtd/nand/Makefile
36 @@ -49,5 +49,6 @@ obj-$(CONFIG_MTD_NAND_JZ4740) += jz4740
37 obj-$(CONFIG_MTD_NAND_GPMI_NAND) += gpmi-nand/
38 obj-$(CONFIG_MTD_NAND_XWAY) += xway_nand.o
39 obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH) += bcm47xxnflash/
40 +obj-$(CONFIG_MTD_NAND_FALCON) += falcon_nand.o
41
42 nand-objs := nand_base.o nand_bbt.o
43 --- /dev/null
44 +++ b/drivers/mtd/nand/falcon_nand.c
45 @@ -0,0 +1,83 @@
46 +/*
47 + * This program is free software; you can redistribute it and/or modify it
48 + * under the terms of the GNU General Public License version 2 as published
49 + * by the Free Software Foundation.
50 + *
51 + * Copyright (C) 2011 Thomas Langer <thomas.langer@lantiq.com>
52 + * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
53 + */
54 +
55 +#include <linux/mtd/nand.h>
56 +#include <linux/of_platform.h>
57 +
58 +#include <lantiq_soc.h>
59 +
60 +/* address lines used for NAND control signals */
61 +#define NAND_ADDR_ALE 0x10000
62 +#define NAND_ADDR_CLE 0x20000
63 +
64 +/* Ready/Busy Status */
65 +#define MODCON_STS 0x0002
66 +
67 +/* Ready/Busy Status Edge */
68 +#define MODCON_STSEDGE 0x0004
69 +#define LTQ_EBU_MODCON 0x000C
70 +
71 +static const char const *part_probes[] = { "cmdlinepart", "ofpart", NULL };
72 +
73 +static int falcon_nand_ready(struct mtd_info *mtd)
74 +{
75 + u32 modcon = ltq_ebu_r32(LTQ_EBU_MODCON);
76 +
77 + return (((modcon & (MODCON_STS | MODCON_STSEDGE)) ==
78 + (MODCON_STS | MODCON_STSEDGE)));
79 +}
80 +
81 +static void falcon_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
82 +{
83 + struct nand_chip *this = mtd->priv;
84 + unsigned long nandaddr = (unsigned long) this->IO_ADDR_W;
85 +
86 + if (ctrl & NAND_CTRL_CHANGE) {
87 + nandaddr &= ~(NAND_ADDR_ALE | NAND_ADDR_CLE);
88 +
89 + if (ctrl & NAND_CLE)
90 + nandaddr |= NAND_ADDR_CLE;
91 + if (ctrl & NAND_ALE)
92 + nandaddr |= NAND_ADDR_ALE;
93 +
94 + this->IO_ADDR_W = (void __iomem *) nandaddr;
95 + }
96 +
97 + if (cmd != NAND_CMD_NONE)
98 + writeb(cmd, this->IO_ADDR_W);
99 +}
100 +
101 +static struct platform_nand_data falcon_nand_data = {
102 + .chip = {
103 + .nr_chips = 1,
104 + .chip_delay = 25,
105 + .part_probe_types = part_probes,
106 + },
107 + .ctrl = {
108 + .cmd_ctrl = falcon_hwcontrol,
109 + .dev_ready = falcon_nand_ready,
110 + }
111 +};
112 +
113 +int __init falcon_register_nand(void)
114 +{
115 + struct device_node *node;
116 + struct platform_device *pdev;
117 +
118 + node = of_find_compatible_node(NULL, NULL, "lantiq,nand-falcon");
119 + if (!node)
120 + return -1;
121 + pdev = of_find_device_by_node(node);
122 + if (pdev)
123 + pdev->dev.platform_data = &falcon_nand_data;
124 + of_node_put(node);
125 + return 0;
126 +}
127 +
128 +arch_initcall(falcon_register_nand);