186f37598d3f5e056665d01710b5cba29841a207
[linux-2.6.34-lpc32xx.git] / drivers / mtd / nand / lpc32xx_nand.c
1 /*
2  *  drivers/mtd/nand/lpc32xx_nand.c
3  *
4  *  Copyright (C) 2008 NXP Semiconductors
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <linux/slab.h>
22 #include <linux/module.h>
23 #include <linux/platform_device.h>
24 #include <linux/mtd/mtd.h>
25 #include <linux/mtd/nand.h>
26 #include <linux/mtd/partitions.h>
27 #include <linux/clk.h>
28 #include <linux/err.h>
29 #include <linux/delay.h>
30
31 #include <asm/io.h>
32 #include <asm/sizes.h>
33 #include <mach/hardware.h>
34 #include <mach/board.h>
35 #include <mach/slcnand.h>
36
37 struct lpc32xx_nand_host {
38         struct nand_chip        nand_chip;
39         struct clk              *clk;
40         struct mtd_info         mtd;
41         void __iomem            *io_base;
42         struct lpc32XX_nand_cfg *ncfg;
43 };
44
45 static void lpc32xx_nand_setup(struct lpc32xx_nand_host *host)
46 {
47         u32 clkrate, tmp;
48
49         /* Reset SLC controller */
50         __raw_writel(SLCCTRL_SW_RESET, SLC_CTRL(host->io_base));
51         udelay(1000);
52
53         /* Basic setup */
54         __raw_writel(0, SLC_CFG(host->io_base));
55         __raw_writel(0, SLC_IEN(host->io_base));
56         __raw_writel((SLCSTAT_INT_TC | SLCSTAT_INT_RDY_EN), SLC_ICR(host->io_base));
57
58         /* Get base clock for SLC block */
59         clkrate = clk_get_rate(host->clk);
60         if (clkrate == 0)
61                 clkrate = 104000000;
62
63         /* Compute clock setup values */
64         tmp = SLCTAC_WDR(host->ncfg->wdr_clks) |
65                 SLCTAC_WWIDTH(1 + (clkrate / host->ncfg->wwidth)) |
66                 SLCTAC_WHOLD(1 + (clkrate / host->ncfg->whold)) |
67                 SLCTAC_WSETUP(1 + (clkrate / host->ncfg->wsetup)) |
68                 SLCTAC_RDR(host->ncfg->rdr_clks) |
69                 SLCTAC_RWIDTH(1 + (clkrate / host->ncfg->rwidth)) |
70                 SLCTAC_RHOLD(1 + (clkrate / host->ncfg->rhold)) |
71                 SLCTAC_RSETUP(1 + (clkrate / host->ncfg->rsetup));
72         __raw_writel(tmp, SLC_TAC(host->io_base));
73 }
74
75 /*
76  * Hardware specific access to control lines
77  */
78 static void lpc32xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
79 {
80         u32 tmp;
81         struct nand_chip *nand_chip = mtd->priv;
82         struct lpc32xx_nand_host *host = nand_chip->priv;
83
84         /* Does CE state need to be changed? */
85         tmp = __raw_readl(SLC_CFG(host->io_base));
86         if (ctrl & NAND_NCE)
87                 tmp |= SLCCFG_CE_LOW;
88         else
89                 tmp &= ~SLCCFG_CE_LOW;
90         __raw_writel(tmp, SLC_CFG(host->io_base));
91
92         if (cmd != NAND_CMD_NONE) {
93                 if (ctrl & NAND_CLE)
94                         __raw_writel(cmd, SLC_CMD(host->io_base));
95                 else
96                         __raw_writel(cmd, SLC_ADDR(host->io_base));
97         }
98 }
99
100 /*
101  * Read the Device Ready pin.
102  */
103 static int lpc32xx_nand_device_ready(struct mtd_info *mtd)
104 {
105         struct nand_chip *nand_chip = mtd->priv;
106         struct lpc32xx_nand_host *host = nand_chip->priv;
107         int rdy = 0;
108
109         if ((__raw_readl(SLC_STAT(host->io_base)) & SLCSTAT_NAND_READY) != 0)
110                 rdy = 1;
111
112         return rdy;
113 }
114
115 /*
116  * Enable NAND write protect
117  */
118 static void lpc32xx_wp_enable(struct lpc32xx_nand_host *host)
119 {
120         if (host->ncfg->enable_write_prot != NULL)
121                 /* Disable write protection */
122                 host->ncfg->enable_write_prot(1);
123 }
124
125 /*
126  * Disable NAND write protect
127  */
128 static void lpc32xx_wp_disable(struct lpc32xx_nand_host *host)
129 {
130         if (host->ncfg->enable_write_prot != NULL)
131                 /* Enable write protection */
132                 host->ncfg->enable_write_prot(0);
133 }
134
135 static uint8_t lpc32xx_read_byte(struct mtd_info *mtd)
136 {
137         struct nand_chip *nand_chip = mtd->priv;
138         struct lpc32xx_nand_host *host = nand_chip->priv;
139
140         return (uint8_t) __raw_readl(SLC_DATA(host->io_base));
141 }
142
143 static void lpc32xx_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
144 {
145         struct nand_chip *nand_chip = mtd->priv;
146         struct lpc32xx_nand_host *host = nand_chip->priv;
147         int i;
148
149         for (i = 0; i < len; i++)
150                 buf[i] = (uint8_t) __raw_readl(SLC_DATA(host->io_base));
151 }
152
153 static int lpc32xx_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
154 {
155         struct nand_chip *nand_chip = mtd->priv;
156         struct lpc32xx_nand_host *host = nand_chip->priv;
157         int i;
158
159         for (i = 0; i < len; i++) {
160                 if (buf[i] != (uint8_t) __raw_readl(SLC_DATA(host->io_base)))
161                         return -EFAULT;
162         }
163
164         return 0;
165 }
166
167 static void lpc32xx_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
168 {
169         struct nand_chip *nand_chip = mtd->priv;
170         struct lpc32xx_nand_host *host = nand_chip->priv;
171         int i;
172
173         for (i = 0; i < len; i++)
174                 __raw_writel((u32) buf[i], SLC_DATA(host->io_base));
175 }
176
177 #ifdef CONFIG_MTD_PARTITIONS
178 const char *part_probes[] = { "cmdlinepart", NULL };
179 #endif
180
181 /*
182  * Probe for NAND controller
183  */
184 static int __init lpc32xx_nand_probe(struct platform_device *pdev)
185 {
186         struct lpc32xx_nand_host *host;
187         struct mtd_info *mtd;
188         struct nand_chip *nand_chip;
189         int res;
190
191 #ifdef CONFIG_MTD_PARTITIONS
192         struct mtd_partition *partitions = NULL;
193         int num_partitions = 0;
194 #endif
195
196         /* Allocate memory for the device structure (and zero it) */
197         host = kzalloc(sizeof(struct lpc32xx_nand_host), GFP_KERNEL);
198         if (!host) {
199                 printk(KERN_ERR "lpc32xx_nand: failed to allocate device structure.\n");
200                 return -ENOMEM;
201         }
202
203         host->io_base = ioremap(pdev->resource[0].start,
204                                 pdev->resource[0].end - pdev->resource[0].start + 1);
205         if (host->io_base == NULL) {
206                 printk(KERN_ERR "lpc32xx_nand: ioremap failed\n");
207                 res = -EIO;
208                 goto err_exit1;
209         }
210
211         mtd = &host->mtd;
212         nand_chip = &host->nand_chip;
213         host->ncfg = pdev->dev.platform_data;
214
215         nand_chip->priv = host;         /* link the private data structures */
216         mtd->priv = nand_chip;
217         mtd->owner = THIS_MODULE;
218
219         /* Get NAND clock */
220         host->clk = clk_get(&pdev->dev, "nand_ck");
221         if (IS_ERR(host->clk)) {
222                 printk(KERN_ERR "lpc32xx_nand: Clock failure\n");
223                 res = -ENOENT;
224                 goto err_exit2;
225         }
226         clk_enable(host->clk);
227
228         /* Set address of NAND IO lines */
229         nand_chip->IO_ADDR_R = SLC_DATA(host->io_base);
230         nand_chip->IO_ADDR_W = SLC_DATA(host->io_base);
231         nand_chip->cmd_ctrl = lpc32xx_nand_cmd_ctrl;
232         nand_chip->dev_ready = lpc32xx_nand_device_ready;
233         nand_chip->ecc.mode = NAND_ECC_SOFT;    /* enable ECC */
234         nand_chip->chip_delay = 20;             /* 20us command delay time */
235         nand_chip->read_byte = lpc32xx_read_byte;
236         nand_chip->read_buf = lpc32xx_read_buf;
237         nand_chip->verify_buf = lpc32xx_verify_buf;
238         nand_chip->write_buf = lpc32xx_write_buf;
239
240         /* Init NAND controller */
241         lpc32xx_nand_setup(host);
242         lpc32xx_wp_disable(host);
243
244         platform_set_drvdata(pdev, host);
245
246         /* Scan to find existance of the device */
247         if (nand_scan(mtd, 1)) {
248                 res = -ENXIO;
249                 goto err_exit3;
250         }
251
252 #ifdef CONFIG_MTD_PARTITIONS
253 #ifdef CONFIG_MTD_CMDLINE_PARTS
254         mtd->name = "lpc32xx_nand";
255         num_partitions = parse_mtd_partitions(mtd, part_probes,
256                                               &partitions, 0);
257 #endif
258         if ((num_partitions <= 0) && (host->ncfg->partition_info)) {
259                 partitions = host->ncfg->partition_info(mtd->size,
260                                                          &num_partitions);
261         }
262
263         if ((!partitions) || (num_partitions == 0)) {
264                 printk(KERN_ERR "lpc32xx_nand: No parititions defined, or unsupported device.\n");
265                 res = ENXIO;
266                 nand_release(mtd);
267                 goto err_exit3;
268         }
269
270         res = add_mtd_partitions(mtd, partitions, num_partitions);
271 #else
272         res = add_mtd_device(mtd);
273 #endif
274
275         if (!res)
276                 return res;
277
278         nand_release(mtd);
279 err_exit3:
280         clk_put(host->clk);
281         platform_set_drvdata(pdev, NULL);
282 err_exit2:
283         lpc32xx_wp_enable(host);
284         iounmap(host->io_base);
285 err_exit1:
286         kfree(host);
287
288         return res;
289 }
290
291 /*
292  * Remove NAND device.
293  */
294 static int __devexit lpc32xx_nand_remove(struct platform_device *pdev)
295 {
296         u32 tmp;
297         struct lpc32xx_nand_host *host = platform_get_drvdata(pdev);
298         struct mtd_info *mtd = &host->mtd;
299
300         nand_release(mtd);
301
302         /* Force CE high */
303         tmp = __raw_readl(SLC_CTRL(host->io_base));
304         tmp &= ~SLCCFG_CE_LOW;
305         __raw_writel(tmp, SLC_CTRL(host->io_base));
306
307         lpc32xx_wp_enable(host);
308         clk_disable(host->clk);
309         clk_put(host->clk);
310
311         iounmap(host->io_base);
312         kfree(host);
313
314         return 0;
315 }
316
317 #if defined(CONFIG_PM)
318 static int lpc32xx_nand_resume(struct platform_device *pdev)
319 {
320         struct lpc32xx_nand_host *host = platform_get_drvdata(pdev);
321
322         /* Re-enable NAND clock */
323         clk_enable(host->clk);
324
325         /* Fresh init of NAND controller */
326         lpc32xx_nand_setup(host);
327
328         /* Disable write protect */
329         lpc32xx_wp_disable(host);
330
331         return 0;
332 }
333
334 static int lpc32xx_nand_suspend(struct platform_device *pdev, pm_message_t pm)
335 {
336         u32 tmp;
337         struct lpc32xx_nand_host *host = platform_get_drvdata(pdev);
338
339         /* Force CE high */
340         tmp = __raw_readl(SLC_CTRL(host->io_base));
341         tmp &= ~SLCCFG_CE_LOW;
342         __raw_writel(tmp, SLC_CTRL(host->io_base));
343
344         /* Enable write protect for safety */
345         lpc32xx_wp_enable(host);
346
347         /* Disable clock */
348         clk_disable(host->clk);
349
350         return 0;
351 }
352
353 #else
354 #define lpc32xx_nand_resume NULL
355 #define lpc32xx_nand_suspend NULL
356 #endif
357
358 static struct platform_driver lpc32xx_nand_driver = {
359         .probe          = lpc32xx_nand_probe,
360         .remove         = __devexit_p(lpc32xx_nand_remove),
361         .resume         = lpc32xx_nand_resume,
362         .suspend        = lpc32xx_nand_suspend,
363         .driver         = {
364                 .name   = "lpc32xx-nand",
365                 .owner  = THIS_MODULE,
366         },
367 };
368
369 static int __init lpc32xx_nand_init(void)
370 {
371         return platform_driver_register(&lpc32xx_nand_driver);
372 }
373
374 static void __exit lpc32xx_nand_exit(void)
375 {
376         platform_driver_unregister(&lpc32xx_nand_driver);
377 }
378
379
380 module_init(lpc32xx_nand_init);
381 module_exit(lpc32xx_nand_exit);
382
383 MODULE_LICENSE("GPL");
384 MODULE_AUTHOR("Kevin Wells(kevin.wells@nxp.com)");
385 MODULE_DESCRIPTION("NAND driver for the NXP LPC32XX SLC controller");
386