Upgrade to Linux 2.6.19
[openwrt/staging/mkresin.git] / target / linux / rb532-2.6 / patches / 500-Nand.patch
1 diff -urN linux.old/drivers/mtd/nand/Kconfig linux.dev/drivers/mtd/nand/Kconfig
2 --- linux.old/drivers/mtd/nand/Kconfig 2006-11-29 22:57:37.000000000 +0100
3 +++ linux.dev/drivers/mtd/nand/Kconfig 2006-12-14 04:38:51.000000000 +0100
4 @@ -75,6 +75,12 @@
5 help
6 Support for NAND flash on Technologic Systems TS-7250 platform.
7
8 +config MTD_NAND_RB500
9 + tristate "NAND Flash device on RB500 board"
10 + depends on MTD_NAND
11 + help
12 + Support for NAND flash on RB500 platform.
13 +
14 config MTD_NAND_IDS
15 tristate
16
17 diff -urN linux.old/drivers/mtd/nand/Makefile linux.dev/drivers/mtd/nand/Makefile
18 --- linux.old/drivers/mtd/nand/Makefile 2006-11-29 22:57:37.000000000 +0100
19 +++ linux.dev/drivers/mtd/nand/Makefile 2006-12-14 04:38:51.000000000 +0100
20 @@ -9,6 +9,7 @@
21 obj-$(CONFIG_MTD_NAND_SPIA) += spia.o
22 obj-$(CONFIG_MTD_NAND_AMS_DELTA) += ams-delta.o
23 obj-$(CONFIG_MTD_NAND_TOTO) += toto.o
24 +obj-$(CONFIG_MTD_NAND_RB500) += rbmipsnand.o
25 obj-$(CONFIG_MTD_NAND_AUTCPU12) += autcpu12.o
26 obj-$(CONFIG_MTD_NAND_EDB7312) += edb7312.o
27 obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o
28 diff -urN linux.old/drivers/mtd/nand/rbmipsnand.c linux.dev/drivers/mtd/nand/rbmipsnand.c
29 --- linux.old/drivers/mtd/nand/rbmipsnand.c 1970-01-01 01:00:00.000000000 +0100
30 +++ linux.dev/drivers/mtd/nand/rbmipsnand.c 2006-12-14 04:39:52.000000000 +0100
31 @@ -0,0 +1,137 @@
32 +#include <linux/init.h>
33 +#include <linux/mtd/nand.h>
34 +#include <linux/mtd/mtd.h>
35 +#include <linux/mtd/partitions.h>
36 +#include <linux/delay.h>
37 +#include <asm/io.h>
38 +#include <asm/irq.h>
39 +#include <asm/bootinfo.h>
40 +
41 +#define IDT434_REG_BASE ((volatile void *) KSEG1ADDR(0x18000000))
42 +
43 +#define GPIOF 0x050000
44 +#define GPIOC 0x050004
45 +#define GPIOD 0x050008
46 +
47 +#define GPIO_RDY (1 << 0x08)
48 +#define GPIO_WPX (1 << 0x09)
49 +#define GPIO_ALE (1 << 0x0a)
50 +#define GPIO_CLE (1 << 0x0b)
51 +
52 +#define DEV2BASE 0x010020
53 +
54 +#define LO_WPX (1 << 0)
55 +#define LO_ALE (1 << 1)
56 +#define LO_CLE (1 << 2)
57 +#define LO_CEX (1 << 3)
58 +#define LO_FOFF (1 << 5)
59 +#define LO_SPICS (1 << 6)
60 +#define LO_ULED (1 << 7)
61 +
62 +#define MEM32(x) *((volatile unsigned *) (x))
63 +static void __iomem *p_nand;
64 +
65 +extern void changeLatchU5(unsigned char orMask, unsigned char nandMask);
66 +
67 +static int rb500_dev_ready(struct mtd_info *mtd)
68 +{
69 + return MEM32(IDT434_REG_BASE + GPIOD) & GPIO_RDY;
70 +}
71 +
72 +/*
73 + * hardware specific access to control-lines
74 + *
75 + * ctrl:
76 + * NAND_CLE: bit 2 -> bit 3
77 + * NAND_ALE: bit 3 -> bit 2
78 + */
79 +static void rbmips_hwcontrol500(struct mtd_info *mtd, int cmd,
80 + unsigned int ctrl)
81 +{
82 + struct nand_chip *chip = mtd->priv;
83 + unsigned char orbits, nandbits;
84 +
85 + if (ctrl & NAND_CTRL_CHANGE) {
86 +
87 + orbits = (ctrl & NAND_CLE) << 1;
88 + orbits |= (ctrl & NAND_ALE) >> 1;
89 +
90 + nandbits = (~ctrl & NAND_CLE) << 1;
91 + nandbits |= (~ctrl & NAND_ALE) >> 1;
92 +
93 + changeLatchU5(orbits, nandbits);
94 + }
95 + if (cmd != NAND_CMD_NONE)
96 + writeb(cmd, chip->IO_ADDR_W);
97 +
98 +}
99 +
100 +static struct mtd_partition partition_info[] = {
101 + {
102 + name:"RouterBoard NAND Boot",
103 + offset:0,
104 + size:4 * 1024 * 1024},
105 + {
106 + name:"RouterBoard NAND Main",
107 + offset:MTDPART_OFS_NXTBLK,
108 + size:MTDPART_SIZ_FULL}
109 +};
110 +
111 +static struct mtd_info rmtd;
112 +static struct nand_chip rnand;
113 +
114 +static unsigned init_ok = 0;
115 +
116 +unsigned get_rbnand_block_size(void)
117 +{
118 + if (init_ok)
119 + return rmtd.writesize;
120 + else
121 + return 0;
122 +}
123 +
124 +EXPORT_SYMBOL(get_rbnand_block_size);
125 +
126 +int __init rbmips_init(void)
127 +{
128 + int *b;
129 + memset(&rmtd, 0, sizeof(rmtd));
130 + memset(&rnand, 0, sizeof(rnand));
131 +
132 + printk("RB500 nand\n");
133 + changeLatchU5(LO_WPX | LO_FOFF | LO_CEX,
134 + LO_ULED | LO_ALE | LO_CLE);
135 + rnand.cmd_ctrl = rbmips_hwcontrol500;
136 +
137 + rnand.dev_ready = rb500_dev_ready;
138 + rnand.IO_ADDR_W = (unsigned char *)
139 + KSEG1ADDR(MEM32(IDT434_REG_BASE + DEV2BASE));
140 + rnand.IO_ADDR_R = rnand.IO_ADDR_W;
141 +
142 + p_nand = (void __iomem *) ioremap((void *) 0x18a20000, 0x1000);
143 + if (!p_nand) {
144 + printk("RBnand Unable ioremap buffer");
145 + return -ENXIO;
146 + }
147 + rnand.ecc.mode = NAND_ECC_SOFT;
148 + rnand.chip_delay = 25;
149 + rnand.options |= NAND_NO_AUTOINCR;
150 + rmtd.priv = &rnand;
151 +
152 + b = (int *) KSEG1ADDR(0x18010020);
153 + printk("dev2base 0x%08x mask 0x%08x c 0x%08x tc 0x%08x\n", b[0],
154 + b[1], b[2], b[3]);
155 +
156 + if (nand_scan(&rmtd, 1) && nand_scan(&rmtd, 1)
157 + && nand_scan(&rmtd, 1) && nand_scan(&rmtd, 1)) {
158 + printk("RBxxx nand device not found");
159 + iounmap((void *) p_nand);
160 + return -ENXIO;
161 + }
162 +
163 + add_mtd_partitions(&rmtd, partition_info, 2);
164 + init_ok = 1;
165 + return 0;
166 +}
167 +
168 +module_init(rbmips_init);