aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/omap2.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/nand/omap2.c')
-rw-r--r--drivers/mtd/nand/omap2.c347
1 files changed, 336 insertions, 11 deletions
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index ebd07e95b814..090ab87086b5 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -18,8 +18,7 @@
18#include <linux/mtd/partitions.h> 18#include <linux/mtd/partitions.h>
19#include <linux/io.h> 19#include <linux/io.h>
20 20
21#include <asm/dma.h> 21#include <mach/dma.h>
22
23#include <mach/gpmc.h> 22#include <mach/gpmc.h>
24#include <mach/nand.h> 23#include <mach/nand.h>
25 24
@@ -112,6 +111,27 @@
112static const char *part_probes[] = { "cmdlinepart", NULL }; 111static const char *part_probes[] = { "cmdlinepart", NULL };
113#endif 112#endif
114 113
114#ifdef CONFIG_MTD_NAND_OMAP_PREFETCH
115static int use_prefetch = 1;
116
117/* "modprobe ... use_prefetch=0" etc */
118module_param(use_prefetch, bool, 0);
119MODULE_PARM_DESC(use_prefetch, "enable/disable use of PREFETCH");
120
121#ifdef CONFIG_MTD_NAND_OMAP_PREFETCH_DMA
122static int use_dma = 1;
123
124/* "modprobe ... use_dma=0" etc */
125module_param(use_dma, bool, 0);
126MODULE_PARM_DESC(use_dma, "enable/disable use of DMA");
127#else
128const int use_dma;
129#endif
130#else
131const int use_prefetch;
132const int use_dma;
133#endif
134
115struct omap_nand_info { 135struct omap_nand_info {
116 struct nand_hw_control controller; 136 struct nand_hw_control controller;
117 struct omap_nand_platform_data *pdata; 137 struct omap_nand_platform_data *pdata;
@@ -124,6 +144,9 @@ struct omap_nand_info {
124 unsigned long phys_base; 144 unsigned long phys_base;
125 void __iomem *gpmc_cs_baseaddr; 145 void __iomem *gpmc_cs_baseaddr;
126 void __iomem *gpmc_baseaddr; 146 void __iomem *gpmc_baseaddr;
147 void __iomem *nand_pref_fifo_add;
148 struct completion comp;
149 int dma_ch;
127}; 150};
128 151
129/** 152/**
@@ -189,6 +212,38 @@ static void omap_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
189} 212}
190 213
191/** 214/**
215 * omap_read_buf8 - read data from NAND controller into buffer
216 * @mtd: MTD device structure
217 * @buf: buffer to store date
218 * @len: number of bytes to read
219 */
220static void omap_read_buf8(struct mtd_info *mtd, u_char *buf, int len)
221{
222 struct nand_chip *nand = mtd->priv;
223
224 ioread8_rep(nand->IO_ADDR_R, buf, len);
225}
226
227/**
228 * omap_write_buf8 - write buffer to NAND controller
229 * @mtd: MTD device structure
230 * @buf: data buffer
231 * @len: number of bytes to write
232 */
233static void omap_write_buf8(struct mtd_info *mtd, const u_char *buf, int len)
234{
235 struct omap_nand_info *info = container_of(mtd,
236 struct omap_nand_info, mtd);
237 u_char *p = (u_char *)buf;
238
239 while (len--) {
240 iowrite8(*p++, info->nand.IO_ADDR_W);
241 while (GPMC_BUF_EMPTY == (readl(info->gpmc_baseaddr +
242 GPMC_STATUS) & GPMC_BUF_FULL));
243 }
244}
245
246/**
192 * omap_read_buf16 - read data from NAND controller into buffer 247 * omap_read_buf16 - read data from NAND controller into buffer
193 * @mtd: MTD device structure 248 * @mtd: MTD device structure
194 * @buf: buffer to store date 249 * @buf: buffer to store date
@@ -198,7 +253,7 @@ static void omap_read_buf16(struct mtd_info *mtd, u_char *buf, int len)
198{ 253{
199 struct nand_chip *nand = mtd->priv; 254 struct nand_chip *nand = mtd->priv;
200 255
201 __raw_readsw(nand->IO_ADDR_R, buf, len / 2); 256 ioread16_rep(nand->IO_ADDR_R, buf, len / 2);
202} 257}
203 258
204/** 259/**
@@ -217,13 +272,242 @@ static void omap_write_buf16(struct mtd_info *mtd, const u_char * buf, int len)
217 len >>= 1; 272 len >>= 1;
218 273
219 while (len--) { 274 while (len--) {
220 writew(*p++, info->nand.IO_ADDR_W); 275 iowrite16(*p++, info->nand.IO_ADDR_W);
221 276
222 while (GPMC_BUF_EMPTY == (readl(info->gpmc_baseaddr + 277 while (GPMC_BUF_EMPTY == (readl(info->gpmc_baseaddr +
223 GPMC_STATUS) & GPMC_BUF_FULL)) 278 GPMC_STATUS) & GPMC_BUF_FULL))
224 ; 279 ;
225 } 280 }
226} 281}
282
283/**
284 * omap_read_buf_pref - read data from NAND controller into buffer
285 * @mtd: MTD device structure
286 * @buf: buffer to store date
287 * @len: number of bytes to read
288 */
289static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len)
290{
291 struct omap_nand_info *info = container_of(mtd,
292 struct omap_nand_info, mtd);
293 uint32_t pfpw_status = 0, r_count = 0;
294 int ret = 0;
295 u32 *p = (u32 *)buf;
296
297 /* take care of subpage reads */
298 for (; len % 4 != 0; ) {
299 *buf++ = __raw_readb(info->nand.IO_ADDR_R);
300 len--;
301 }
302 p = (u32 *) buf;
303
304 /* configure and start prefetch transfer */
305 ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x0);
306 if (ret) {
307 /* PFPW engine is busy, use cpu copy method */
308 if (info->nand.options & NAND_BUSWIDTH_16)
309 omap_read_buf16(mtd, buf, len);
310 else
311 omap_read_buf8(mtd, buf, len);
312 } else {
313 do {
314 pfpw_status = gpmc_prefetch_status();
315 r_count = ((pfpw_status >> 24) & 0x7F) >> 2;
316 ioread32_rep(info->nand_pref_fifo_add, p, r_count);
317 p += r_count;
318 len -= r_count << 2;
319 } while (len);
320
321 /* disable and stop the PFPW engine */
322 gpmc_prefetch_reset();
323 }
324}
325
326/**
327 * omap_write_buf_pref - write buffer to NAND controller
328 * @mtd: MTD device structure
329 * @buf: data buffer
330 * @len: number of bytes to write
331 */
332static void omap_write_buf_pref(struct mtd_info *mtd,
333 const u_char *buf, int len)
334{
335 struct omap_nand_info *info = container_of(mtd,
336 struct omap_nand_info, mtd);
337 uint32_t pfpw_status = 0, w_count = 0;
338 int i = 0, ret = 0;
339 u16 *p = (u16 *) buf;
340
341 /* take care of subpage writes */
342 if (len % 2 != 0) {
343 writeb(*buf, info->nand.IO_ADDR_R);
344 p = (u16 *)(buf + 1);
345 len--;
346 }
347
348 /* configure and start prefetch transfer */
349 ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x1);
350 if (ret) {
351 /* PFPW engine is busy, use cpu copy method */
352 if (info->nand.options & NAND_BUSWIDTH_16)
353 omap_write_buf16(mtd, buf, len);
354 else
355 omap_write_buf8(mtd, buf, len);
356 } else {
357 pfpw_status = gpmc_prefetch_status();
358 while (pfpw_status & 0x3FFF) {
359 w_count = ((pfpw_status >> 24) & 0x7F) >> 1;
360 for (i = 0; (i < w_count) && len; i++, len -= 2)
361 iowrite16(*p++, info->nand_pref_fifo_add);
362 pfpw_status = gpmc_prefetch_status();
363 }
364
365 /* disable and stop the PFPW engine */
366 gpmc_prefetch_reset();
367 }
368}
369
370#ifdef CONFIG_MTD_NAND_OMAP_PREFETCH_DMA
371/*
372 * omap_nand_dma_cb: callback on the completion of dma transfer
373 * @lch: logical channel
374 * @ch_satuts: channel status
375 * @data: pointer to completion data structure
376 */
377static void omap_nand_dma_cb(int lch, u16 ch_status, void *data)
378{
379 complete((struct completion *) data);
380}
381
382/*
383 * omap_nand_dma_transfer: configer and start dma transfer
384 * @mtd: MTD device structure
385 * @addr: virtual address in RAM of source/destination
386 * @len: number of data bytes to be transferred
387 * @is_write: flag for read/write operation
388 */
389static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr,
390 unsigned int len, int is_write)
391{
392 struct omap_nand_info *info = container_of(mtd,
393 struct omap_nand_info, mtd);
394 uint32_t prefetch_status = 0;
395 enum dma_data_direction dir = is_write ? DMA_TO_DEVICE :
396 DMA_FROM_DEVICE;
397 dma_addr_t dma_addr;
398 int ret;
399
400 /* The fifo depth is 64 bytes. We have a sync at each frame and frame
401 * length is 64 bytes.
402 */
403 int buf_len = len >> 6;
404
405 if (addr >= high_memory) {
406 struct page *p1;
407
408 if (((size_t)addr & PAGE_MASK) !=
409 ((size_t)(addr + len - 1) & PAGE_MASK))
410 goto out_copy;
411 p1 = vmalloc_to_page(addr);
412 if (!p1)
413 goto out_copy;
414 addr = page_address(p1) + ((size_t)addr & ~PAGE_MASK);
415 }
416
417 dma_addr = dma_map_single(&info->pdev->dev, addr, len, dir);
418 if (dma_mapping_error(&info->pdev->dev, dma_addr)) {
419 dev_err(&info->pdev->dev,
420 "Couldn't DMA map a %d byte buffer\n", len);
421 goto out_copy;
422 }
423
424 if (is_write) {
425 omap_set_dma_dest_params(info->dma_ch, 0, OMAP_DMA_AMODE_CONSTANT,
426 info->phys_base, 0, 0);
427 omap_set_dma_src_params(info->dma_ch, 0, OMAP_DMA_AMODE_POST_INC,
428 dma_addr, 0, 0);
429 omap_set_dma_transfer_params(info->dma_ch, OMAP_DMA_DATA_TYPE_S32,
430 0x10, buf_len, OMAP_DMA_SYNC_FRAME,
431 OMAP24XX_DMA_GPMC, OMAP_DMA_DST_SYNC);
432 } else {
433 omap_set_dma_src_params(info->dma_ch, 0, OMAP_DMA_AMODE_CONSTANT,
434 info->phys_base, 0, 0);
435 omap_set_dma_dest_params(info->dma_ch, 0, OMAP_DMA_AMODE_POST_INC,
436 dma_addr, 0, 0);
437 omap_set_dma_transfer_params(info->dma_ch, OMAP_DMA_DATA_TYPE_S32,
438 0x10, buf_len, OMAP_DMA_SYNC_FRAME,
439 OMAP24XX_DMA_GPMC, OMAP_DMA_SRC_SYNC);
440 }
441 /* configure and start prefetch transfer */
442 ret = gpmc_prefetch_enable(info->gpmc_cs, 0x1, len, is_write);
443 if (ret)
444 /* PFPW engine is busy, use cpu copy methode */
445 goto out_copy;
446
447 init_completion(&info->comp);
448
449 omap_start_dma(info->dma_ch);
450
451 /* setup and start DMA using dma_addr */
452 wait_for_completion(&info->comp);
453
454 while (0x3fff & (prefetch_status = gpmc_prefetch_status()))
455 ;
456 /* disable and stop the PFPW engine */
457 gpmc_prefetch_reset();
458
459 dma_unmap_single(&info->pdev->dev, dma_addr, len, dir);
460 return 0;
461
462out_copy:
463 if (info->nand.options & NAND_BUSWIDTH_16)
464 is_write == 0 ? omap_read_buf16(mtd, (u_char *) addr, len)
465 : omap_write_buf16(mtd, (u_char *) addr, len);
466 else
467 is_write == 0 ? omap_read_buf8(mtd, (u_char *) addr, len)
468 : omap_write_buf8(mtd, (u_char *) addr, len);
469 return 0;
470}
471#else
472static void omap_nand_dma_cb(int lch, u16 ch_status, void *data) {}
473static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr,
474 unsigned int len, int is_write)
475{
476 return 0;
477}
478#endif
479
480/**
481 * omap_read_buf_dma_pref - read data from NAND controller into buffer
482 * @mtd: MTD device structure
483 * @buf: buffer to store date
484 * @len: number of bytes to read
485 */
486static void omap_read_buf_dma_pref(struct mtd_info *mtd, u_char *buf, int len)
487{
488 if (len <= mtd->oobsize)
489 omap_read_buf_pref(mtd, buf, len);
490 else
491 /* start transfer in DMA mode */
492 omap_nand_dma_transfer(mtd, buf, len, 0x0);
493}
494
495/**
496 * omap_write_buf_dma_pref - write buffer to NAND controller
497 * @mtd: MTD device structure
498 * @buf: data buffer
499 * @len: number of bytes to write
500 */
501static void omap_write_buf_dma_pref(struct mtd_info *mtd,
502 const u_char *buf, int len)
503{
504 if (len <= mtd->oobsize)
505 omap_write_buf_pref(mtd, buf, len);
506 else
507 /* start transfer in DMA mode */
508 omap_nand_dma_transfer(mtd, buf, len, 0x1);
509}
510
227/** 511/**
228 * omap_verify_buf - Verify chip data against buffer 512 * omap_verify_buf - Verify chip data against buffer
229 * @mtd: MTD device structure 513 * @mtd: MTD device structure
@@ -658,17 +942,12 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
658 err = -ENOMEM; 942 err = -ENOMEM;
659 goto out_release_mem_region; 943 goto out_release_mem_region;
660 } 944 }
945
661 info->nand.controller = &info->controller; 946 info->nand.controller = &info->controller;
662 947
663 info->nand.IO_ADDR_W = info->nand.IO_ADDR_R; 948 info->nand.IO_ADDR_W = info->nand.IO_ADDR_R;
664 info->nand.cmd_ctrl = omap_hwcontrol; 949 info->nand.cmd_ctrl = omap_hwcontrol;
665 950
666 /* REVISIT: only supports 16-bit NAND flash */
667
668 info->nand.read_buf = omap_read_buf16;
669 info->nand.write_buf = omap_write_buf16;
670 info->nand.verify_buf = omap_verify_buf;
671
672 /* 951 /*
673 * If RDY/BSY line is connected to OMAP then use the omap ready 952 * If RDY/BSY line is connected to OMAP then use the omap ready
674 * funcrtion and the generic nand_wait function which reads the status 953 * funcrtion and the generic nand_wait function which reads the status
@@ -689,6 +968,40 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
689 == 0x1000) 968 == 0x1000)
690 info->nand.options |= NAND_BUSWIDTH_16; 969 info->nand.options |= NAND_BUSWIDTH_16;
691 970
971 if (use_prefetch) {
972 /* copy the virtual address of nand base for fifo access */
973 info->nand_pref_fifo_add = info->nand.IO_ADDR_R;
974
975 info->nand.read_buf = omap_read_buf_pref;
976 info->nand.write_buf = omap_write_buf_pref;
977 if (use_dma) {
978 err = omap_request_dma(OMAP24XX_DMA_GPMC, "NAND",
979 omap_nand_dma_cb, &info->comp, &info->dma_ch);
980 if (err < 0) {
981 info->dma_ch = -1;
982 printk(KERN_WARNING "DMA request failed."
983 " Non-dma data transfer mode\n");
984 } else {
985 omap_set_dma_dest_burst_mode(info->dma_ch,
986 OMAP_DMA_DATA_BURST_16);
987 omap_set_dma_src_burst_mode(info->dma_ch,
988 OMAP_DMA_DATA_BURST_16);
989
990 info->nand.read_buf = omap_read_buf_dma_pref;
991 info->nand.write_buf = omap_write_buf_dma_pref;
992 }
993 }
994 } else {
995 if (info->nand.options & NAND_BUSWIDTH_16) {
996 info->nand.read_buf = omap_read_buf16;
997 info->nand.write_buf = omap_write_buf16;
998 } else {
999 info->nand.read_buf = omap_read_buf8;
1000 info->nand.write_buf = omap_write_buf8;
1001 }
1002 }
1003 info->nand.verify_buf = omap_verify_buf;
1004
692#ifdef CONFIG_MTD_NAND_OMAP_HWECC 1005#ifdef CONFIG_MTD_NAND_OMAP_HWECC
693 info->nand.ecc.bytes = 3; 1006 info->nand.ecc.bytes = 3;
694 info->nand.ecc.size = 512; 1007 info->nand.ecc.size = 512;
@@ -744,9 +1057,12 @@ static int omap_nand_remove(struct platform_device *pdev)
744 struct omap_nand_info *info = mtd->priv; 1057 struct omap_nand_info *info = mtd->priv;
745 1058
746 platform_set_drvdata(pdev, NULL); 1059 platform_set_drvdata(pdev, NULL);
1060 if (use_dma)
1061 omap_free_dma(info->dma_ch);
1062
747 /* Release NAND device, its internal structures and partitions */ 1063 /* Release NAND device, its internal structures and partitions */
748 nand_release(&info->mtd); 1064 nand_release(&info->mtd);
749 iounmap(info->nand.IO_ADDR_R); 1065 iounmap(info->nand_pref_fifo_add);
750 kfree(&info->mtd); 1066 kfree(&info->mtd);
751 return 0; 1067 return 0;
752} 1068}
@@ -763,6 +1079,15 @@ static struct platform_driver omap_nand_driver = {
763static int __init omap_nand_init(void) 1079static int __init omap_nand_init(void)
764{ 1080{
765 printk(KERN_INFO "%s driver initializing\n", DRIVER_NAME); 1081 printk(KERN_INFO "%s driver initializing\n", DRIVER_NAME);
1082
1083 /* This check is required if driver is being
1084 * loaded run time as a module
1085 */
1086 if ((1 == use_dma) && (0 == use_prefetch)) {
1087 printk(KERN_INFO"Wrong parameters: 'use_dma' can not be 1 "
1088 "without use_prefetch'. Prefetch will not be"
1089 " used in either mode (mpu or dma)\n");
1090 }
766 return platform_driver_register(&omap_nand_driver); 1091 return platform_driver_register(&omap_nand_driver);
767} 1092}
768 1093