cb2346544cf7060047f457719c1a2c615643c2ca
[openwrt-10.03/.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);