ar71xx: fix sections mismatch warnings in the nand drivers
[openwrt.git] / target / linux / ar71xx / files / drivers / mtd / nand / rb750_nand.c
1 /*
2  *  NAND flash driver for the MikroTik RouterBOARD 750
3  *
4  *  Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
5  *
6  *  This program is free software; you can redistribute it and/or modify it
7  *  under the terms of the GNU General Public License version 2 as published
8  *  by the Free Software Foundation.
9  */
10
11 #include <linux/init.h>
12 #include <linux/mtd/nand.h>
13 #include <linux/mtd/mtd.h>
14 #include <linux/mtd/partitions.h>
15 #include <linux/platform_device.h>
16 #include <linux/io.h>
17 #include <linux/slab.h>
18
19 #include <asm/mach-ar71xx/ar71xx.h>
20 #include <asm/mach-ar71xx/mach-rb750.h>
21
22 #define DRV_NAME        "rb750-nand"
23 #define DRV_VERSION     "0.1.0"
24 #define DRV_DESC        "NAND flash driver for the RouterBOARD 750"
25
26 #define RB750_NAND_IO0          BIT(RB750_GPIO_NAND_IO0)
27 #define RB750_NAND_ALE          BIT(RB750_GPIO_NAND_ALE)
28 #define RB750_NAND_CLE          BIT(RB750_GPIO_NAND_CLE)
29 #define RB750_NAND_NRE          BIT(RB750_GPIO_NAND_NRE)
30 #define RB750_NAND_NWE          BIT(RB750_GPIO_NAND_NWE)
31 #define RB750_NAND_RDY          BIT(RB750_GPIO_NAND_RDY)
32 #define RB750_NAND_NCE          BIT(RB750_GPIO_NAND_NCE)
33
34 #define RB750_NAND_DATA_SHIFT   1
35 #define RB750_NAND_DATA_BITS    (0xff << RB750_NAND_DATA_SHIFT)
36 #define RB750_NAND_INPUT_BITS   (RB750_NAND_DATA_BITS | RB750_NAND_RDY)
37 #define RB750_NAND_OUTPUT_BITS  (RB750_NAND_ALE | RB750_NAND_CLE | \
38                                  RB750_NAND_NRE | RB750_NAND_NWE | \
39                                  RB750_NAND_NCE)
40
41 struct rb750_nand_info {
42         struct nand_chip        chip;
43         struct mtd_info         mtd;
44 };
45
46 /*
47  * We need to use the OLD Yaffs-1 OOB layout, otherwise the RB bootloader
48  * will not be able to find the kernel that we load.
49  */
50 static struct nand_ecclayout rb750_nand_ecclayout = {
51         .eccbytes       = 6,
52         .eccpos         = { 8, 9, 10, 13, 14, 15 },
53         .oobavail       = 9,
54         .oobfree        = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } }
55 };
56
57 static struct mtd_partition rb750_nand_partitions[] = {
58         {
59                 .name   = "booter",
60                 .offset = 0,
61                 .size   = (256 * 1024),
62                 .mask_flags = MTD_WRITEABLE,
63         }, {
64                 .name   = "kernel",
65                 .offset = (256 * 1024),
66                 .size   = (4 * 1024 * 1024) - (256 * 1024),
67         }, {
68                 .name   = "rootfs",
69                 .offset = MTDPART_OFS_NXTBLK,
70                 .size   = MTDPART_SIZ_FULL,
71         },
72 };
73
74 static void rb750_nand_write(const u8 *buf, unsigned len)
75 {
76         void __iomem *base = ar71xx_gpio_base;
77         u32 out;
78         u32 t;
79         unsigned i;
80
81         /* set data lines to output mode */
82         t = __raw_readl(base + AR71XX_GPIO_REG_OE);
83         __raw_writel(t | RB750_NAND_DATA_BITS, base + AR71XX_GPIO_REG_OE);
84
85         out = __raw_readl(base + AR71XX_GPIO_REG_OUT);
86         out &= ~(RB750_NAND_DATA_BITS | RB750_NAND_NWE);
87         for (i = 0; i != len; i++) {
88                 u32 data;
89
90                 data = buf[i];
91                 data <<= RB750_NAND_DATA_SHIFT;
92                 data |= out;
93                 __raw_writel(data, base + AR71XX_GPIO_REG_OUT);
94
95                 __raw_writel(data | RB750_NAND_NWE, base + AR71XX_GPIO_REG_OUT);
96                 /* flush write */
97                 __raw_readl(base + AR71XX_GPIO_REG_OUT);
98         }
99
100         /* set data lines to input mode */
101         t = __raw_readl(base + AR71XX_GPIO_REG_OE);
102         __raw_writel(t & ~RB750_NAND_DATA_BITS, base + AR71XX_GPIO_REG_OE);
103         /* flush write */
104         __raw_readl(base + AR71XX_GPIO_REG_OE);
105 }
106
107 static int rb750_nand_read_verify(u8 *read_buf, unsigned len,
108                                   const u8 *verify_buf)
109 {
110         void __iomem *base = ar71xx_gpio_base;
111         unsigned i;
112
113         for (i = 0; i < len; i++) {
114                 u8 data;
115
116                 /* activate RE line */
117                 __raw_writel(RB750_NAND_NRE, base + AR71XX_GPIO_REG_CLEAR);
118                 /* flush write */
119                 __raw_readl(base + AR71XX_GPIO_REG_CLEAR);
120
121                 /* read input lines */
122                 data = __raw_readl(base + AR71XX_GPIO_REG_IN) >>
123                        RB750_NAND_DATA_SHIFT;
124
125                 /* deactivate RE line */
126                 __raw_writel(RB750_NAND_NRE, base + AR71XX_GPIO_REG_SET);
127
128                 if (read_buf)
129                         read_buf[i] = data;
130                 else if (verify_buf && verify_buf[i] != data)
131                         return -EFAULT;
132         }
133
134         return 0;
135 }
136
137 static void rb750_nand_select_chip(struct mtd_info *mtd, int chip)
138 {
139         void __iomem *base = ar71xx_gpio_base;
140         u32 func;
141         u32 t;
142
143         func = __raw_readl(base + AR71XX_GPIO_REG_FUNC);
144         if (chip >= 0) {
145                 /* disable latch */
146                 rb750_latch_change(RB750_LVC573_LE, 0);
147
148                 /* disable alternate functions */
149                 ar71xx_gpio_function_setup(AR724X_GPIO_FUNC_JTAG_DISABLE,
150                                            AR724X_GPIO_FUNC_SPI_EN);
151
152                 /* set input mode for data lines */
153                 t = __raw_readl(base + AR71XX_GPIO_REG_OE);
154                 __raw_writel(t & ~RB750_NAND_INPUT_BITS,
155                              base + AR71XX_GPIO_REG_OE);
156
157                 /* deactivate RE and WE lines */
158                 __raw_writel(RB750_NAND_NRE | RB750_NAND_NWE,
159                              base + AR71XX_GPIO_REG_SET);
160                 /* flush write */
161                 (void) __raw_readl(base + AR71XX_GPIO_REG_SET);
162
163                 /* activate CE line */
164                 __raw_writel(RB750_NAND_NCE, base + AR71XX_GPIO_REG_CLEAR);
165         } else {
166                 /* deactivate CE line */
167                 __raw_writel(RB750_NAND_NCE, base + AR71XX_GPIO_REG_SET);
168                 /* flush write */
169                 (void) __raw_readl(base + AR71XX_GPIO_REG_SET);
170
171                 t = __raw_readl(base + AR71XX_GPIO_REG_OE);
172                 __raw_writel(t | RB750_NAND_IO0 | RB750_NAND_RDY,
173                              base + AR71XX_GPIO_REG_OE);
174
175                 /* restore alternate functions */
176                 ar71xx_gpio_function_setup(AR724X_GPIO_FUNC_SPI_EN,
177                                            AR724X_GPIO_FUNC_JTAG_DISABLE);
178
179                 /* enable latch */
180                 rb750_latch_change(0, RB750_LVC573_LE);
181         }
182 }
183
184 static int rb750_nand_dev_ready(struct mtd_info *mtd)
185 {
186         void __iomem *base = ar71xx_gpio_base;
187
188         return !!(__raw_readl(base + AR71XX_GPIO_REG_IN) & RB750_NAND_RDY);
189 }
190
191 static void rb750_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
192                                 unsigned int ctrl)
193 {
194         if (ctrl & NAND_CTRL_CHANGE) {
195                 void __iomem *base = ar71xx_gpio_base;
196                 u32 t;
197
198                 t = __raw_readl(base + AR71XX_GPIO_REG_OUT);
199
200                 t &= ~(RB750_NAND_CLE | RB750_NAND_ALE);
201                 t |= (ctrl & NAND_CLE) ? RB750_NAND_CLE : 0;
202                 t |= (ctrl & NAND_ALE) ? RB750_NAND_ALE : 0;
203
204                 __raw_writel(t, base + AR71XX_GPIO_REG_OUT);
205                 /* flush write */
206                 __raw_readl(base + AR71XX_GPIO_REG_OUT);
207         }
208
209         if (cmd != NAND_CMD_NONE) {
210                 u8 t = cmd;
211                 rb750_nand_write(&t, 1);
212         }
213 }
214
215 static u8 rb750_nand_read_byte(struct mtd_info *mtd)
216 {
217         u8 data = 0;
218         rb750_nand_read_verify(&data, 1, NULL);
219         return data;
220 }
221
222 static void rb750_nand_read_buf(struct mtd_info *mtd, u8 *buf, int len)
223 {
224         rb750_nand_read_verify(buf, len, NULL);
225 }
226
227 static void rb750_nand_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
228 {
229         rb750_nand_write(buf, len);
230 }
231
232 static int rb750_nand_verify_buf(struct mtd_info *mtd, const u8 *buf, int len)
233 {
234         return rb750_nand_read_verify(NULL, len, buf);
235 }
236
237 static void __init rb750_nand_gpio_init(void)
238 {
239         void __iomem *base = ar71xx_gpio_base;
240         u32 out;
241         u32 t;
242
243         out = __raw_readl(base + AR71XX_GPIO_REG_OUT);
244
245         /* setup output levels */
246         __raw_writel(RB750_NAND_NCE | RB750_NAND_NRE | RB750_NAND_NWE,
247                      base + AR71XX_GPIO_REG_SET);
248
249         __raw_writel(RB750_NAND_ALE | RB750_NAND_CLE,
250                      base + AR71XX_GPIO_REG_CLEAR);
251
252         /* setup input lines */
253         t = __raw_readl(base + AR71XX_GPIO_REG_OE);
254         __raw_writel(t & ~(RB750_NAND_INPUT_BITS), base + AR71XX_GPIO_REG_OE);
255
256         /* setup output lines */
257         t = __raw_readl(base + AR71XX_GPIO_REG_OE);
258         __raw_writel(t | RB750_NAND_OUTPUT_BITS, base + AR71XX_GPIO_REG_OE);
259
260         rb750_latch_change(~out & RB750_NAND_IO0, out & RB750_NAND_IO0);
261 }
262
263 static int __devinit rb750_nand_probe(struct platform_device *pdev)
264 {
265         struct rb750_nand_info  *info;
266         int ret;
267
268         printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n");
269
270         rb750_nand_gpio_init();
271
272         info = kzalloc(sizeof(*info), GFP_KERNEL);
273         if (!info)
274                 return -ENOMEM;
275
276         info->chip.priv = &info;
277         info->mtd.priv  = &info->chip;
278         info->mtd.owner = THIS_MODULE;
279
280         info->chip.select_chip  = rb750_nand_select_chip;
281         info->chip.cmd_ctrl     = rb750_nand_cmd_ctrl;
282         info->chip.dev_ready    = rb750_nand_dev_ready;
283         info->chip.read_byte    = rb750_nand_read_byte;
284         info->chip.write_buf    = rb750_nand_write_buf;
285         info->chip.read_buf     = rb750_nand_read_buf;
286         info->chip.verify_buf   = rb750_nand_verify_buf;
287
288         info->chip.chip_delay   = 25;
289         info->chip.ecc.mode     = NAND_ECC_SOFT;
290         info->chip.options      |= NAND_NO_AUTOINCR;
291
292         platform_set_drvdata(pdev, info);
293
294         ret = nand_scan_ident(&info->mtd, 1, NULL);
295         if (ret) {
296                 ret = -ENXIO;
297                 goto err_free_info;
298         }
299
300         if (info->mtd.writesize == 512)
301                 info->chip.ecc.layout = &rb750_nand_ecclayout;
302
303         ret = nand_scan_tail(&info->mtd);
304         if (ret) {
305                 return -ENXIO;
306                 goto err_set_drvdata;
307         }
308
309 #ifdef CONFIG_MTD_PARTITIONS
310         ret = add_mtd_partitions(&info->mtd, rb750_nand_partitions,
311                                  ARRAY_SIZE(rb750_nand_partitions));
312 #else
313         ret = add_mtd_device(&info->mtd);
314 #endif
315         if (ret)
316                 goto err_release_nand;
317
318         return 0;
319
320 err_release_nand:
321         nand_release(&info->mtd);
322 err_set_drvdata:
323         platform_set_drvdata(pdev, NULL);
324 err_free_info:
325         kfree(info);
326         return ret;
327 }
328
329 static int __devexit rb750_nand_remove(struct platform_device *pdev)
330 {
331         struct rb750_nand_info *info = platform_get_drvdata(pdev);
332
333         nand_release(&info->mtd);
334         platform_set_drvdata(pdev, NULL);
335         kfree(info);
336
337         return 0;
338 }
339
340 static struct platform_driver rb750_nand_driver = {
341         .probe  = rb750_nand_probe,
342         .remove = __devexit_p(rb750_nand_remove),
343         .driver = {
344                 .name   = DRV_NAME,
345                 .owner  = THIS_MODULE,
346         },
347 };
348
349 static int __init rb750_nand_init(void)
350 {
351         return platform_driver_register(&rb750_nand_driver);
352 }
353
354 static void __exit rb750_nand_exit(void)
355 {
356         platform_driver_unregister(&rb750_nand_driver);
357 }
358
359 module_init(rb750_nand_init);
360 module_exit(rb750_nand_exit);
361
362 MODULE_DESCRIPTION(DRV_DESC);
363 MODULE_VERSION(DRV_VERSION);
364 MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
365 MODULE_LICENSE("GPL v2");