diff options
| author | Sukumar Ghorai <s-ghorai@ti.com> | 2011-01-28 05:12:04 -0500 |
|---|---|---|
| committer | Tony Lindgren <tony@atomide.com> | 2011-02-17 18:32:52 -0500 |
| commit | 1b0b323c70cd5fdca967d89ed3a03dfebd84ada7 (patch) | |
| tree | 224d603ee170f3f2b3f45214d9fe2ae4181e9a27 | |
| parent | d5ce2b6592c49935462cba7317fa67fe8ee474ec (diff) | |
omap3: nand: configurable transfer type per board
nand transfer type (sDMA, Polled, prefetch) can be select from board file,
enabling all transfer type in driver, by default.
this helps in multi-omap build and to select different transfer type for
different board.
Signed-off-by: Sukumar Ghorai <s-ghorai@ti.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
| -rw-r--r-- | arch/arm/plat-omap/include/plat/nand.h | 7 | ||||
| -rw-r--r-- | drivers/mtd/nand/Kconfig | 17 | ||||
| -rw-r--r-- | drivers/mtd/nand/omap2.c | 94 |
3 files changed, 41 insertions, 77 deletions
diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h index 6562cd082bb1..78c0bdb98c18 100644 --- a/arch/arm/plat-omap/include/plat/nand.h +++ b/arch/arm/plat-omap/include/plat/nand.h | |||
| @@ -10,6 +10,12 @@ | |||
| 10 | 10 | ||
| 11 | #include <linux/mtd/partitions.h> | 11 | #include <linux/mtd/partitions.h> |
| 12 | 12 | ||
| 13 | enum nand_io { | ||
| 14 | NAND_OMAP_PREFETCH_POLLED = 0, /* prefetch polled mode, default */ | ||
| 15 | NAND_OMAP_POLLED, /* polled mode, without prefetch */ | ||
| 16 | NAND_OMAP_PREFETCH_DMA /* prefetch enabled sDMA mode */ | ||
| 17 | }; | ||
| 18 | |||
| 13 | struct omap_nand_platform_data { | 19 | struct omap_nand_platform_data { |
| 14 | unsigned int options; | 20 | unsigned int options; |
| 15 | int cs; | 21 | int cs; |
| @@ -20,6 +26,7 @@ struct omap_nand_platform_data { | |||
| 20 | int (*nand_setup)(void); | 26 | int (*nand_setup)(void); |
| 21 | int (*dev_ready)(struct omap_nand_platform_data *); | 27 | int (*dev_ready)(struct omap_nand_platform_data *); |
| 22 | int dma_channel; | 28 | int dma_channel; |
| 29 | enum nand_io xfer_type; | ||
| 23 | unsigned long phys_base; | 30 | unsigned long phys_base; |
| 24 | int devsize; | 31 | int devsize; |
| 25 | }; | 32 | }; |
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index c89592239bc7..178e2006063d 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig | |||
| @@ -106,23 +106,6 @@ config MTD_NAND_OMAP2 | |||
| 106 | help | 106 | help |
| 107 | Support for NAND flash on Texas Instruments OMAP2 and OMAP3 platforms. | 107 | Support for NAND flash on Texas Instruments OMAP2 and OMAP3 platforms. |
| 108 | 108 | ||
| 109 | config MTD_NAND_OMAP_PREFETCH | ||
| 110 | bool "GPMC prefetch support for NAND Flash device" | ||
| 111 | depends on MTD_NAND_OMAP2 | ||
| 112 | default y | ||
| 113 | help | ||
| 114 | The NAND device can be accessed for Read/Write using GPMC PREFETCH engine | ||
| 115 | to improve the performance. | ||
| 116 | |||
| 117 | config MTD_NAND_OMAP_PREFETCH_DMA | ||
| 118 | depends on MTD_NAND_OMAP_PREFETCH | ||
| 119 | bool "DMA mode" | ||
| 120 | default n | ||
| 121 | help | ||
| 122 | The GPMC PREFETCH engine can be configured eigther in MPU interrupt mode | ||
| 123 | or in DMA interrupt mode. | ||
| 124 | Say y for DMA mode or MPU mode will be used | ||
| 125 | |||
| 126 | config MTD_NAND_IDS | 109 | config MTD_NAND_IDS |
| 127 | tristate | 110 | tristate |
| 128 | 111 | ||
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 7c04cd6fb7aa..60bac8e6e9fa 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c | |||
| @@ -96,27 +96,6 @@ | |||
| 96 | static const char *part_probes[] = { "cmdlinepart", NULL }; | 96 | static const char *part_probes[] = { "cmdlinepart", NULL }; |
| 97 | #endif | 97 | #endif |
| 98 | 98 | ||
| 99 | #ifdef CONFIG_MTD_NAND_OMAP_PREFETCH | ||
| 100 | static int use_prefetch = 1; | ||
| 101 | |||
| 102 | /* "modprobe ... use_prefetch=0" etc */ | ||
| 103 | module_param(use_prefetch, bool, 0); | ||
| 104 | MODULE_PARM_DESC(use_prefetch, "enable/disable use of PREFETCH"); | ||
| 105 | |||
| 106 | #ifdef CONFIG_MTD_NAND_OMAP_PREFETCH_DMA | ||
| 107 | static int use_dma = 1; | ||
| 108 | |||
| 109 | /* "modprobe ... use_dma=0" etc */ | ||
| 110 | module_param(use_dma, bool, 0); | ||
| 111 | MODULE_PARM_DESC(use_dma, "enable/disable use of DMA"); | ||
| 112 | #else | ||
| 113 | static const int use_dma; | ||
| 114 | #endif | ||
| 115 | #else | ||
| 116 | const int use_prefetch; | ||
| 117 | static const int use_dma; | ||
| 118 | #endif | ||
| 119 | |||
| 120 | struct omap_nand_info { | 99 | struct omap_nand_info { |
| 121 | struct nand_hw_control controller; | 100 | struct nand_hw_control controller; |
| 122 | struct omap_nand_platform_data *pdata; | 101 | struct omap_nand_platform_data *pdata; |
| @@ -324,7 +303,6 @@ static void omap_write_buf_pref(struct mtd_info *mtd, | |||
| 324 | } | 303 | } |
| 325 | } | 304 | } |
| 326 | 305 | ||
| 327 | #ifdef CONFIG_MTD_NAND_OMAP_PREFETCH_DMA | ||
| 328 | /* | 306 | /* |
| 329 | * omap_nand_dma_cb: callback on the completion of dma transfer | 307 | * omap_nand_dma_cb: callback on the completion of dma transfer |
| 330 | * @lch: logical channel | 308 | * @lch: logical channel |
| @@ -426,14 +404,6 @@ out_copy: | |||
| 426 | : omap_write_buf8(mtd, (u_char *) addr, len); | 404 | : omap_write_buf8(mtd, (u_char *) addr, len); |
| 427 | return 0; | 405 | return 0; |
| 428 | } | 406 | } |
| 429 | #else | ||
| 430 | static void omap_nand_dma_cb(int lch, u16 ch_status, void *data) {} | ||
| 431 | static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, | ||
| 432 | unsigned int len, int is_write) | ||
| 433 | { | ||
| 434 | return 0; | ||
| 435 | } | ||
| 436 | #endif | ||
| 437 | 407 | ||
| 438 | /** | 408 | /** |
| 439 | * omap_read_buf_dma_pref - read data from NAND controller into buffer | 409 | * omap_read_buf_dma_pref - read data from NAND controller into buffer |
| @@ -842,28 +812,13 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) | |||
| 842 | info->nand.chip_delay = 50; | 812 | info->nand.chip_delay = 50; |
| 843 | } | 813 | } |
| 844 | 814 | ||
| 845 | if (use_prefetch) { | 815 | switch (pdata->xfer_type) { |
| 846 | 816 | case NAND_OMAP_PREFETCH_POLLED: | |
| 847 | info->nand.read_buf = omap_read_buf_pref; | 817 | info->nand.read_buf = omap_read_buf_pref; |
| 848 | info->nand.write_buf = omap_write_buf_pref; | 818 | info->nand.write_buf = omap_write_buf_pref; |
| 849 | if (use_dma) { | 819 | break; |
| 850 | err = omap_request_dma(OMAP24XX_DMA_GPMC, "NAND", | 820 | |
| 851 | omap_nand_dma_cb, &info->comp, &info->dma_ch); | 821 | case NAND_OMAP_POLLED: |
| 852 | if (err < 0) { | ||
| 853 | info->dma_ch = -1; | ||
| 854 | printk(KERN_WARNING "DMA request failed." | ||
| 855 | " Non-dma data transfer mode\n"); | ||
| 856 | } else { | ||
| 857 | omap_set_dma_dest_burst_mode(info->dma_ch, | ||
| 858 | OMAP_DMA_DATA_BURST_16); | ||
| 859 | omap_set_dma_src_burst_mode(info->dma_ch, | ||
| 860 | OMAP_DMA_DATA_BURST_16); | ||
| 861 | |||
| 862 | info->nand.read_buf = omap_read_buf_dma_pref; | ||
| 863 | info->nand.write_buf = omap_write_buf_dma_pref; | ||
| 864 | } | ||
| 865 | } | ||
| 866 | } else { | ||
| 867 | if (info->nand.options & NAND_BUSWIDTH_16) { | 822 | if (info->nand.options & NAND_BUSWIDTH_16) { |
| 868 | info->nand.read_buf = omap_read_buf16; | 823 | info->nand.read_buf = omap_read_buf16; |
| 869 | info->nand.write_buf = omap_write_buf16; | 824 | info->nand.write_buf = omap_write_buf16; |
| @@ -871,7 +826,33 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) | |||
| 871 | info->nand.read_buf = omap_read_buf8; | 826 | info->nand.read_buf = omap_read_buf8; |
| 872 | info->nand.write_buf = omap_write_buf8; | 827 | info->nand.write_buf = omap_write_buf8; |
| 873 | } | 828 | } |
| 829 | break; | ||
| 830 | |||
| 831 | case NAND_OMAP_PREFETCH_DMA: | ||
| 832 | err = omap_request_dma(OMAP24XX_DMA_GPMC, "NAND", | ||
| 833 | omap_nand_dma_cb, &info->comp, &info->dma_ch); | ||
| 834 | if (err < 0) { | ||
| 835 | info->dma_ch = -1; | ||
| 836 | dev_err(&pdev->dev, "DMA request failed!\n"); | ||
| 837 | goto out_release_mem_region; | ||
| 838 | } else { | ||
| 839 | omap_set_dma_dest_burst_mode(info->dma_ch, | ||
| 840 | OMAP_DMA_DATA_BURST_16); | ||
| 841 | omap_set_dma_src_burst_mode(info->dma_ch, | ||
| 842 | OMAP_DMA_DATA_BURST_16); | ||
| 843 | |||
| 844 | info->nand.read_buf = omap_read_buf_dma_pref; | ||
| 845 | info->nand.write_buf = omap_write_buf_dma_pref; | ||
| 846 | } | ||
| 847 | break; | ||
| 848 | |||
| 849 | default: | ||
| 850 | dev_err(&pdev->dev, | ||
| 851 | "xfer_type(%d) not supported!\n", pdata->xfer_type); | ||
| 852 | err = -EINVAL; | ||
| 853 | goto out_release_mem_region; | ||
| 874 | } | 854 | } |
| 855 | |||
| 875 | info->nand.verify_buf = omap_verify_buf; | 856 | info->nand.verify_buf = omap_verify_buf; |
| 876 | 857 | ||
| 877 | #ifdef CONFIG_MTD_NAND_OMAP_HWECC | 858 | #ifdef CONFIG_MTD_NAND_OMAP_HWECC |
| @@ -897,6 +878,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) | |||
| 897 | } | 878 | } |
| 898 | } | 879 | } |
| 899 | 880 | ||
| 881 | |||
| 900 | #ifdef CONFIG_MTD_PARTITIONS | 882 | #ifdef CONFIG_MTD_PARTITIONS |
| 901 | err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0); | 883 | err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0); |
| 902 | if (err > 0) | 884 | if (err > 0) |
| @@ -926,7 +908,7 @@ static int omap_nand_remove(struct platform_device *pdev) | |||
| 926 | mtd); | 908 | mtd); |
| 927 | 909 | ||
| 928 | platform_set_drvdata(pdev, NULL); | 910 | platform_set_drvdata(pdev, NULL); |
| 929 | if (use_dma) | 911 | if (info->dma_ch != -1) |
| 930 | omap_free_dma(info->dma_ch); | 912 | omap_free_dma(info->dma_ch); |
| 931 | 913 | ||
| 932 | /* Release NAND device, its internal structures and partitions */ | 914 | /* Release NAND device, its internal structures and partitions */ |
| @@ -947,16 +929,8 @@ static struct platform_driver omap_nand_driver = { | |||
| 947 | 929 | ||
| 948 | static int __init omap_nand_init(void) | 930 | static int __init omap_nand_init(void) |
| 949 | { | 931 | { |
| 950 | printk(KERN_INFO "%s driver initializing\n", DRIVER_NAME); | 932 | pr_info("%s driver initializing\n", DRIVER_NAME); |
| 951 | 933 | ||
| 952 | /* This check is required if driver is being | ||
| 953 | * loaded run time as a module | ||
| 954 | */ | ||
| 955 | if ((1 == use_dma) && (0 == use_prefetch)) { | ||
| 956 | printk(KERN_INFO"Wrong parameters: 'use_dma' can not be 1 " | ||
| 957 | "without use_prefetch'. Prefetch will not be" | ||
| 958 | " used in either mode (mpu or dma)\n"); | ||
| 959 | } | ||
| 960 | return platform_driver_register(&omap_nand_driver); | 934 | return platform_driver_register(&omap_nand_driver); |
| 961 | } | 935 | } |
| 962 | 936 | ||
