Fix rb523 nand detection (#1723)
[openwrt/svn-archive/archive.git] / target / linux / rb532-2.6 / files / drivers / mtd / nand / rbmipsnand.c
1 #include <linux/init.h>
2 #include <linux/mtd/nand.h>
3 #include <linux/mtd/mtd.h>
4 #include <linux/mtd/partitions.h>
5 #include <linux/delay.h>
6 #include <asm/io.h>
7 #include <asm/irq.h>
8 #include <asm/bootinfo.h>
9
10 #define IDT434_REG_BASE ((volatile void *) KSEG1ADDR(0x18000000))
11
12 #define GPIOF 0x050000
13 #define GPIOC 0x050004
14 #define GPIOD 0x050008
15
16 #define GPIO_RDY (1 << 0x08)
17 #define GPIO_WPX (1 << 0x09)
18 #define GPIO_ALE (1 << 0x0a)
19 #define GPIO_CLE (1 << 0x0b)
20
21 #define DEV2BASE 0x010020
22
23 #define LO_WPX (1 << 0)
24 #define LO_ALE (1 << 1)
25 #define LO_CLE (1 << 2)
26 #define LO_CEX (1 << 3)
27 #define LO_FOFF (1 << 5)
28 #define LO_SPICS (1 << 6)
29 #define LO_ULED (1 << 7)
30
31 #define MEM32(x) *((volatile unsigned *) (x))
32 static void __iomem *p_nand;
33
34 extern void changeLatchU5(unsigned char orMask, unsigned char nandMask);
35
36 static int rb500_dev_ready(struct mtd_info *mtd)
37 {
38 return MEM32(IDT434_REG_BASE + GPIOD) & GPIO_RDY;
39 }
40
41 /*
42 * hardware specific access to control-lines
43 *
44 * ctrl:
45 * NAND_CLE: bit 2 -> bit 3
46 * NAND_ALE: bit 3 -> bit 2
47 */
48 static void rbmips_hwcontrol500(struct mtd_info *mtd, int cmd,
49 unsigned int ctrl)
50 {
51 struct nand_chip *chip = mtd->priv;
52 unsigned char orbits, nandbits;
53
54 if (ctrl & NAND_CTRL_CHANGE) {
55
56 orbits = (ctrl & NAND_CLE) << 1;
57 orbits |= (ctrl & NAND_ALE) >> 1;
58
59 nandbits = (~ctrl & NAND_CLE) << 1;
60 nandbits |= (~ctrl & NAND_ALE) >> 1;
61
62 changeLatchU5(orbits, nandbits);
63 }
64 if (cmd != NAND_CMD_NONE)
65 writeb(cmd, chip->IO_ADDR_W);
66
67 }
68
69 static struct mtd_partition partition_info[] = {
70 {
71 name:"RouterBoard NAND Boot",
72 offset:0,
73 size:4 * 1024 * 1024},
74 {
75 name:"RouterBoard NAND Main",
76 offset:MTDPART_OFS_NXTBLK,
77 size:MTDPART_SIZ_FULL}
78 };
79
80 static struct mtd_info rmtd;
81 static struct nand_chip rnand;
82
83 static unsigned init_ok = 0;
84
85 unsigned get_rbnand_block_size(void)
86 {
87 if (init_ok)
88 return rmtd.writesize;
89 else
90 return 0;
91 }
92
93 EXPORT_SYMBOL(get_rbnand_block_size);
94
95 int __init rbmips_init(void)
96 {
97 int *b;
98 memset(&rmtd, 0, sizeof(rmtd));
99 memset(&rnand, 0, sizeof(rnand));
100
101 printk("RB500 nand\n");
102 changeLatchU5(LO_FOFF | LO_CEX,
103 LO_ULED | LO_ALE | LO_CLE | LO_WPX);
104 rnand.cmd_ctrl = rbmips_hwcontrol500;
105
106 rnand.dev_ready = rb500_dev_ready;
107 rnand.IO_ADDR_W = (unsigned char *)
108 KSEG1ADDR(MEM32(IDT434_REG_BASE + DEV2BASE));
109 rnand.IO_ADDR_R = rnand.IO_ADDR_W;
110
111 p_nand = (void __iomem *) ioremap((void *) 0x18a20000, 0x1000);
112 if (!p_nand) {
113 printk("RBnand Unable ioremap buffer");
114 return -ENXIO;
115 }
116 rnand.ecc.mode = NAND_ECC_SOFT;
117 rnand.chip_delay = 25;
118 rnand.options |= NAND_NO_AUTOINCR;
119 rmtd.priv = &rnand;
120
121 b = (int *) KSEG1ADDR(0x18010020);
122 printk("dev2base 0x%08x mask 0x%08x c 0x%08x tc 0x%08x\n", b[0],
123 b[1], b[2], b[3]);
124
125 if (nand_scan(&rmtd, 1) && nand_scan(&rmtd, 1)
126 && nand_scan(&rmtd, 1) && nand_scan(&rmtd, 1)) {
127 printk("RBxxx nand device not found\n");
128 iounmap((void *) p_nand);
129 return -ENXIO;
130 }
131
132 add_mtd_partitions(&rmtd, partition_info, 2);
133 init_ok = 1;
134 return 0;
135 }
136
137 module_init(rbmips_init);