diff options
Diffstat (limited to 'drivers/mtd/nand')
-rw-r--r-- | drivers/mtd/nand/Kconfig | 14 | ||||
-rw-r--r-- | drivers/mtd/nand/Makefile | 1 | ||||
-rw-r--r-- | drivers/mtd/nand/ams-delta.c | 74 | ||||
-rw-r--r-- | drivers/mtd/nand/atmel_nand.c | 136 | ||||
-rw-r--r-- | drivers/mtd/nand/bcm_umi_nand.c | 1 | ||||
-rw-r--r-- | drivers/mtd/nand/fsl_ifc_nand.c | 1072 | ||||
-rw-r--r-- | drivers/mtd/nand/gpmi-nand/gpmi-lib.c | 21 |
7 files changed, 1246 insertions, 73 deletions
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 0ea7084eabdc..7d17cecad69d 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig | |||
@@ -187,7 +187,7 @@ config MTD_NAND_PPCHAMELEONEVB | |||
187 | 187 | ||
188 | config MTD_NAND_S3C2410 | 188 | config MTD_NAND_S3C2410 |
189 | tristate "NAND Flash support for Samsung S3C SoCs" | 189 | tristate "NAND Flash support for Samsung S3C SoCs" |
190 | depends on ARCH_S3C2410 || ARCH_S3C64XX | 190 | depends on ARCH_S3C24XX || ARCH_S3C64XX |
191 | help | 191 | help |
192 | This enables the NAND flash controller on the S3C24xx and S3C64xx | 192 | This enables the NAND flash controller on the S3C24xx and S3C64xx |
193 | SoCs | 193 | SoCs |
@@ -246,6 +246,7 @@ config MTD_NAND_BCM_UMI_HWCS | |||
246 | config MTD_NAND_DISKONCHIP | 246 | config MTD_NAND_DISKONCHIP |
247 | tristate "DiskOnChip 2000, Millennium and Millennium Plus (NAND reimplementation) (EXPERIMENTAL)" | 247 | tristate "DiskOnChip 2000, Millennium and Millennium Plus (NAND reimplementation) (EXPERIMENTAL)" |
248 | depends on EXPERIMENTAL | 248 | depends on EXPERIMENTAL |
249 | depends on HAS_IOMEM | ||
249 | select REED_SOLOMON | 250 | select REED_SOLOMON |
250 | select REED_SOLOMON_DEC16 | 251 | select REED_SOLOMON_DEC16 |
251 | help | 252 | help |
@@ -450,6 +451,7 @@ config MTD_NAND_GPMI_NAND | |||
450 | 451 | ||
451 | config MTD_NAND_PLATFORM | 452 | config MTD_NAND_PLATFORM |
452 | tristate "Support for generic platform NAND driver" | 453 | tristate "Support for generic platform NAND driver" |
454 | depends on HAS_IOMEM | ||
453 | help | 455 | help |
454 | This implements a generic NAND driver for on-SOC platform | 456 | This implements a generic NAND driver for on-SOC platform |
455 | devices. You will need to provide platform-specific functions | 457 | devices. You will need to provide platform-specific functions |
@@ -481,6 +483,16 @@ config MTD_NAND_FSL_ELBC | |||
481 | Enabling this option will enable you to use this to control | 483 | Enabling this option will enable you to use this to control |
482 | external NAND devices. | 484 | external NAND devices. |
483 | 485 | ||
486 | config MTD_NAND_FSL_IFC | ||
487 | tristate "NAND support for Freescale IFC controller" | ||
488 | depends on MTD_NAND && FSL_SOC | ||
489 | select FSL_IFC | ||
490 | help | ||
491 | Various Freescale chips e.g P1010, include a NAND Flash machine | ||
492 | with built-in hardware ECC capabilities. | ||
493 | Enabling this option will enable you to use this to control | ||
494 | external NAND devices. | ||
495 | |||
484 | config MTD_NAND_FSL_UPM | 496 | config MTD_NAND_FSL_UPM |
485 | tristate "Support for NAND on Freescale UPM" | 497 | tristate "Support for NAND on Freescale UPM" |
486 | depends on PPC_83xx || PPC_85xx | 498 | depends on PPC_83xx || PPC_85xx |
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 36c26ab2ae16..d4b4d8739bd8 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile | |||
@@ -38,6 +38,7 @@ obj-$(CONFIG_MTD_ALAUDA) += alauda.o | |||
38 | obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o | 38 | obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o |
39 | obj-$(CONFIG_MTD_NAND_ORION) += orion_nand.o | 39 | obj-$(CONFIG_MTD_NAND_ORION) += orion_nand.o |
40 | obj-$(CONFIG_MTD_NAND_FSL_ELBC) += fsl_elbc_nand.o | 40 | obj-$(CONFIG_MTD_NAND_FSL_ELBC) += fsl_elbc_nand.o |
41 | obj-$(CONFIG_MTD_NAND_FSL_IFC) += fsl_ifc_nand.o | ||
41 | obj-$(CONFIG_MTD_NAND_FSL_UPM) += fsl_upm.o | 42 | obj-$(CONFIG_MTD_NAND_FSL_UPM) += fsl_upm.o |
42 | obj-$(CONFIG_MTD_NAND_SH_FLCTL) += sh_flctl.o | 43 | obj-$(CONFIG_MTD_NAND_SH_FLCTL) += sh_flctl.o |
43 | obj-$(CONFIG_MTD_NAND_MXC) += mxc_nand.o | 44 | obj-$(CONFIG_MTD_NAND_MXC) += mxc_nand.o |
diff --git a/drivers/mtd/nand/ams-delta.c b/drivers/mtd/nand/ams-delta.c index 3197e9764fcd..73416951f4c1 100644 --- a/drivers/mtd/nand/ams-delta.c +++ b/drivers/mtd/nand/ams-delta.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include <asm/io.h> | 26 | #include <asm/io.h> |
27 | #include <mach/hardware.h> | 27 | #include <mach/hardware.h> |
28 | #include <asm/sizes.h> | 28 | #include <asm/sizes.h> |
29 | #include <asm/gpio.h> | 29 | #include <linux/gpio.h> |
30 | #include <plat/board-ams-delta.h> | 30 | #include <plat/board-ams-delta.h> |
31 | 31 | ||
32 | /* | 32 | /* |
@@ -34,8 +34,6 @@ | |||
34 | */ | 34 | */ |
35 | static struct mtd_info *ams_delta_mtd = NULL; | 35 | static struct mtd_info *ams_delta_mtd = NULL; |
36 | 36 | ||
37 | #define NAND_MASK (AMS_DELTA_LATCH2_NAND_NRE | AMS_DELTA_LATCH2_NAND_NWE | AMS_DELTA_LATCH2_NAND_CLE | AMS_DELTA_LATCH2_NAND_ALE | AMS_DELTA_LATCH2_NAND_NCE | AMS_DELTA_LATCH2_NAND_NWP) | ||
38 | |||
39 | /* | 37 | /* |
40 | * Define partitions for flash devices | 38 | * Define partitions for flash devices |
41 | */ | 39 | */ |
@@ -68,10 +66,9 @@ static void ams_delta_write_byte(struct mtd_info *mtd, u_char byte) | |||
68 | 66 | ||
69 | writew(0, io_base + OMAP_MPUIO_IO_CNTL); | 67 | writew(0, io_base + OMAP_MPUIO_IO_CNTL); |
70 | writew(byte, this->IO_ADDR_W); | 68 | writew(byte, this->IO_ADDR_W); |
71 | ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NWE, 0); | 69 | gpio_set_value(AMS_DELTA_GPIO_PIN_NAND_NWE, 0); |
72 | ndelay(40); | 70 | ndelay(40); |
73 | ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NWE, | 71 | gpio_set_value(AMS_DELTA_GPIO_PIN_NAND_NWE, 1); |
74 | AMS_DELTA_LATCH2_NAND_NWE); | ||
75 | } | 72 | } |
76 | 73 | ||
77 | static u_char ams_delta_read_byte(struct mtd_info *mtd) | 74 | static u_char ams_delta_read_byte(struct mtd_info *mtd) |
@@ -80,12 +77,11 @@ static u_char ams_delta_read_byte(struct mtd_info *mtd) | |||
80 | struct nand_chip *this = mtd->priv; | 77 | struct nand_chip *this = mtd->priv; |
81 | void __iomem *io_base = this->priv; | 78 | void __iomem *io_base = this->priv; |
82 | 79 | ||
83 | ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NRE, 0); | 80 | gpio_set_value(AMS_DELTA_GPIO_PIN_NAND_NRE, 0); |
84 | ndelay(40); | 81 | ndelay(40); |
85 | writew(~0, io_base + OMAP_MPUIO_IO_CNTL); | 82 | writew(~0, io_base + OMAP_MPUIO_IO_CNTL); |
86 | res = readw(this->IO_ADDR_R); | 83 | res = readw(this->IO_ADDR_R); |
87 | ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NRE, | 84 | gpio_set_value(AMS_DELTA_GPIO_PIN_NAND_NRE, 1); |
88 | AMS_DELTA_LATCH2_NAND_NRE); | ||
89 | 85 | ||
90 | return res; | 86 | return res; |
91 | } | 87 | } |
@@ -132,15 +128,12 @@ static void ams_delta_hwcontrol(struct mtd_info *mtd, int cmd, | |||
132 | { | 128 | { |
133 | 129 | ||
134 | if (ctrl & NAND_CTRL_CHANGE) { | 130 | if (ctrl & NAND_CTRL_CHANGE) { |
135 | unsigned long bits; | 131 | gpio_set_value(AMS_DELTA_GPIO_PIN_NAND_NCE, |
136 | 132 | (ctrl & NAND_NCE) == 0); | |
137 | bits = (~ctrl & NAND_NCE) ? AMS_DELTA_LATCH2_NAND_NCE : 0; | 133 | gpio_set_value(AMS_DELTA_GPIO_PIN_NAND_CLE, |
138 | bits |= (ctrl & NAND_CLE) ? AMS_DELTA_LATCH2_NAND_CLE : 0; | 134 | (ctrl & NAND_CLE) != 0); |
139 | bits |= (ctrl & NAND_ALE) ? AMS_DELTA_LATCH2_NAND_ALE : 0; | 135 | gpio_set_value(AMS_DELTA_GPIO_PIN_NAND_ALE, |
140 | 136 | (ctrl & NAND_ALE) != 0); | |
141 | ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_CLE | | ||
142 | AMS_DELTA_LATCH2_NAND_ALE | | ||
143 | AMS_DELTA_LATCH2_NAND_NCE, bits); | ||
144 | } | 137 | } |
145 | 138 | ||
146 | if (cmd != NAND_CMD_NONE) | 139 | if (cmd != NAND_CMD_NONE) |
@@ -152,6 +145,39 @@ static int ams_delta_nand_ready(struct mtd_info *mtd) | |||
152 | return gpio_get_value(AMS_DELTA_GPIO_PIN_NAND_RB); | 145 | return gpio_get_value(AMS_DELTA_GPIO_PIN_NAND_RB); |
153 | } | 146 | } |
154 | 147 | ||
148 | static const struct gpio _mandatory_gpio[] = { | ||
149 | { | ||
150 | .gpio = AMS_DELTA_GPIO_PIN_NAND_NCE, | ||
151 | .flags = GPIOF_OUT_INIT_HIGH, | ||
152 | .label = "nand_nce", | ||
153 | }, | ||
154 | { | ||
155 | .gpio = AMS_DELTA_GPIO_PIN_NAND_NRE, | ||
156 | .flags = GPIOF_OUT_INIT_HIGH, | ||
157 | .label = "nand_nre", | ||
158 | }, | ||
159 | { | ||
160 | .gpio = AMS_DELTA_GPIO_PIN_NAND_NWP, | ||
161 | .flags = GPIOF_OUT_INIT_HIGH, | ||
162 | .label = "nand_nwp", | ||
163 | }, | ||
164 | { | ||
165 | .gpio = AMS_DELTA_GPIO_PIN_NAND_NWE, | ||
166 | .flags = GPIOF_OUT_INIT_HIGH, | ||
167 | .label = "nand_nwe", | ||
168 | }, | ||
169 | { | ||
170 | .gpio = AMS_DELTA_GPIO_PIN_NAND_ALE, | ||
171 | .flags = GPIOF_OUT_INIT_LOW, | ||
172 | .label = "nand_ale", | ||
173 | }, | ||
174 | { | ||
175 | .gpio = AMS_DELTA_GPIO_PIN_NAND_CLE, | ||
176 | .flags = GPIOF_OUT_INIT_LOW, | ||
177 | .label = "nand_cle", | ||
178 | }, | ||
179 | }; | ||
180 | |||
155 | /* | 181 | /* |
156 | * Main initialization routine | 182 | * Main initialization routine |
157 | */ | 183 | */ |
@@ -223,10 +249,9 @@ static int __devinit ams_delta_init(struct platform_device *pdev) | |||
223 | platform_set_drvdata(pdev, io_base); | 249 | platform_set_drvdata(pdev, io_base); |
224 | 250 | ||
225 | /* Set chip enabled, but */ | 251 | /* Set chip enabled, but */ |
226 | ams_delta_latch2_write(NAND_MASK, AMS_DELTA_LATCH2_NAND_NRE | | 252 | err = gpio_request_array(_mandatory_gpio, ARRAY_SIZE(_mandatory_gpio)); |
227 | AMS_DELTA_LATCH2_NAND_NWE | | 253 | if (err) |
228 | AMS_DELTA_LATCH2_NAND_NCE | | 254 | goto out_gpio; |
229 | AMS_DELTA_LATCH2_NAND_NWP); | ||
230 | 255 | ||
231 | /* Scan to find existence of the device */ | 256 | /* Scan to find existence of the device */ |
232 | if (nand_scan(ams_delta_mtd, 1)) { | 257 | if (nand_scan(ams_delta_mtd, 1)) { |
@@ -241,7 +266,10 @@ static int __devinit ams_delta_init(struct platform_device *pdev) | |||
241 | goto out; | 266 | goto out; |
242 | 267 | ||
243 | out_mtd: | 268 | out_mtd: |
269 | gpio_free_array(_mandatory_gpio, ARRAY_SIZE(_mandatory_gpio)); | ||
270 | out_gpio: | ||
244 | platform_set_drvdata(pdev, NULL); | 271 | platform_set_drvdata(pdev, NULL); |
272 | gpio_free(AMS_DELTA_GPIO_PIN_NAND_RB); | ||
245 | iounmap(io_base); | 273 | iounmap(io_base); |
246 | out_release_io: | 274 | out_release_io: |
247 | release_mem_region(res->start, resource_size(res)); | 275 | release_mem_region(res->start, resource_size(res)); |
@@ -262,6 +290,8 @@ static int __devexit ams_delta_cleanup(struct platform_device *pdev) | |||
262 | /* Release resources, unregister device */ | 290 | /* Release resources, unregister device */ |
263 | nand_release(ams_delta_mtd); | 291 | nand_release(ams_delta_mtd); |
264 | 292 | ||
293 | gpio_free_array(_mandatory_gpio, ARRAY_SIZE(_mandatory_gpio)); | ||
294 | gpio_free(AMS_DELTA_GPIO_PIN_NAND_RB); | ||
265 | iounmap(io_base); | 295 | iounmap(io_base); |
266 | release_mem_region(res->start, resource_size(res)); | 296 | release_mem_region(res->start, resource_size(res)); |
267 | 297 | ||
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 662abf08061a..2165576a1c67 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c | |||
@@ -27,6 +27,10 @@ | |||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/moduleparam.h> | 28 | #include <linux/moduleparam.h> |
29 | #include <linux/platform_device.h> | 29 | #include <linux/platform_device.h> |
30 | #include <linux/of.h> | ||
31 | #include <linux/of_device.h> | ||
32 | #include <linux/of_gpio.h> | ||
33 | #include <linux/of_mtd.h> | ||
30 | #include <linux/mtd/mtd.h> | 34 | #include <linux/mtd/mtd.h> |
31 | #include <linux/mtd/nand.h> | 35 | #include <linux/mtd/nand.h> |
32 | #include <linux/mtd/partitions.h> | 36 | #include <linux/mtd/partitions.h> |
@@ -34,22 +38,10 @@ | |||
34 | #include <linux/dmaengine.h> | 38 | #include <linux/dmaengine.h> |
35 | #include <linux/gpio.h> | 39 | #include <linux/gpio.h> |
36 | #include <linux/io.h> | 40 | #include <linux/io.h> |
41 | #include <linux/platform_data/atmel.h> | ||
37 | 42 | ||
38 | #include <mach/board.h> | ||
39 | #include <mach/cpu.h> | 43 | #include <mach/cpu.h> |
40 | 44 | ||
41 | #ifdef CONFIG_MTD_NAND_ATMEL_ECC_HW | ||
42 | #define hard_ecc 1 | ||
43 | #else | ||
44 | #define hard_ecc 0 | ||
45 | #endif | ||
46 | |||
47 | #ifdef CONFIG_MTD_NAND_ATMEL_ECC_NONE | ||
48 | #define no_ecc 1 | ||
49 | #else | ||
50 | #define no_ecc 0 | ||
51 | #endif | ||
52 | |||
53 | static int use_dma = 1; | 45 | static int use_dma = 1; |
54 | module_param(use_dma, int, 0); | 46 | module_param(use_dma, int, 0); |
55 | 47 | ||
@@ -95,7 +87,7 @@ struct atmel_nand_host { | |||
95 | struct mtd_info mtd; | 87 | struct mtd_info mtd; |
96 | void __iomem *io_base; | 88 | void __iomem *io_base; |
97 | dma_addr_t io_phys; | 89 | dma_addr_t io_phys; |
98 | struct atmel_nand_data *board; | 90 | struct atmel_nand_data board; |
99 | struct device *dev; | 91 | struct device *dev; |
100 | void __iomem *ecc; | 92 | void __iomem *ecc; |
101 | 93 | ||
@@ -113,8 +105,8 @@ static int cpu_has_dma(void) | |||
113 | */ | 105 | */ |
114 | static void atmel_nand_enable(struct atmel_nand_host *host) | 106 | static void atmel_nand_enable(struct atmel_nand_host *host) |
115 | { | 107 | { |
116 | if (gpio_is_valid(host->board->enable_pin)) | 108 | if (gpio_is_valid(host->board.enable_pin)) |
117 | gpio_set_value(host->board->enable_pin, 0); | 109 | gpio_set_value(host->board.enable_pin, 0); |
118 | } | 110 | } |
119 | 111 | ||
120 | /* | 112 | /* |
@@ -122,8 +114,8 @@ static void atmel_nand_enable(struct atmel_nand_host *host) | |||
122 | */ | 114 | */ |
123 | static void atmel_nand_disable(struct atmel_nand_host *host) | 115 | static void atmel_nand_disable(struct atmel_nand_host *host) |
124 | { | 116 | { |
125 | if (gpio_is_valid(host->board->enable_pin)) | 117 | if (gpio_is_valid(host->board.enable_pin)) |
126 | gpio_set_value(host->board->enable_pin, 1); | 118 | gpio_set_value(host->board.enable_pin, 1); |
127 | } | 119 | } |
128 | 120 | ||
129 | /* | 121 | /* |
@@ -144,9 +136,9 @@ static void atmel_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl | |||
144 | return; | 136 | return; |
145 | 137 | ||
146 | if (ctrl & NAND_CLE) | 138 | if (ctrl & NAND_CLE) |
147 | writeb(cmd, host->io_base + (1 << host->board->cle)); | 139 | writeb(cmd, host->io_base + (1 << host->board.cle)); |
148 | else | 140 | else |
149 | writeb(cmd, host->io_base + (1 << host->board->ale)); | 141 | writeb(cmd, host->io_base + (1 << host->board.ale)); |
150 | } | 142 | } |
151 | 143 | ||
152 | /* | 144 | /* |
@@ -157,8 +149,8 @@ static int atmel_nand_device_ready(struct mtd_info *mtd) | |||
157 | struct nand_chip *nand_chip = mtd->priv; | 149 | struct nand_chip *nand_chip = mtd->priv; |
158 | struct atmel_nand_host *host = nand_chip->priv; | 150 | struct atmel_nand_host *host = nand_chip->priv; |
159 | 151 | ||
160 | return gpio_get_value(host->board->rdy_pin) ^ | 152 | return gpio_get_value(host->board.rdy_pin) ^ |
161 | !!host->board->rdy_pin_active_low; | 153 | !!host->board.rdy_pin_active_low; |
162 | } | 154 | } |
163 | 155 | ||
164 | /* | 156 | /* |
@@ -273,7 +265,7 @@ static void atmel_read_buf(struct mtd_info *mtd, u8 *buf, int len) | |||
273 | if (atmel_nand_dma_op(mtd, buf, len, 1) == 0) | 265 | if (atmel_nand_dma_op(mtd, buf, len, 1) == 0) |
274 | return; | 266 | return; |
275 | 267 | ||
276 | if (host->board->bus_width_16) | 268 | if (host->board.bus_width_16) |
277 | atmel_read_buf16(mtd, buf, len); | 269 | atmel_read_buf16(mtd, buf, len); |
278 | else | 270 | else |
279 | atmel_read_buf8(mtd, buf, len); | 271 | atmel_read_buf8(mtd, buf, len); |
@@ -289,7 +281,7 @@ static void atmel_write_buf(struct mtd_info *mtd, const u8 *buf, int len) | |||
289 | if (atmel_nand_dma_op(mtd, (void *)buf, len, 0) == 0) | 281 | if (atmel_nand_dma_op(mtd, (void *)buf, len, 0) == 0) |
290 | return; | 282 | return; |
291 | 283 | ||
292 | if (host->board->bus_width_16) | 284 | if (host->board.bus_width_16) |
293 | atmel_write_buf16(mtd, buf, len); | 285 | atmel_write_buf16(mtd, buf, len); |
294 | else | 286 | else |
295 | atmel_write_buf8(mtd, buf, len); | 287 | atmel_write_buf8(mtd, buf, len); |
@@ -481,6 +473,56 @@ static void atmel_nand_hwctl(struct mtd_info *mtd, int mode) | |||
481 | } | 473 | } |
482 | } | 474 | } |
483 | 475 | ||
476 | #if defined(CONFIG_OF) | ||
477 | static int __devinit atmel_of_init_port(struct atmel_nand_host *host, | ||
478 | struct device_node *np) | ||
479 | { | ||
480 | u32 val; | ||
481 | int ecc_mode; | ||
482 | struct atmel_nand_data *board = &host->board; | ||
483 | enum of_gpio_flags flags; | ||
484 | |||
485 | if (of_property_read_u32(np, "atmel,nand-addr-offset", &val) == 0) { | ||
486 | if (val >= 32) { | ||
487 | dev_err(host->dev, "invalid addr-offset %u\n", val); | ||
488 | return -EINVAL; | ||
489 | } | ||
490 | board->ale = val; | ||
491 | } | ||
492 | |||
493 | if (of_property_read_u32(np, "atmel,nand-cmd-offset", &val) == 0) { | ||
494 | if (val >= 32) { | ||
495 | dev_err(host->dev, "invalid cmd-offset %u\n", val); | ||
496 | return -EINVAL; | ||
497 | } | ||
498 | board->cle = val; | ||
499 | } | ||
500 | |||
501 | ecc_mode = of_get_nand_ecc_mode(np); | ||
502 | |||
503 | board->ecc_mode = ecc_mode < 0 ? NAND_ECC_SOFT : ecc_mode; | ||
504 | |||
505 | board->on_flash_bbt = of_get_nand_on_flash_bbt(np); | ||
506 | |||
507 | if (of_get_nand_bus_width(np) == 16) | ||
508 | board->bus_width_16 = 1; | ||
509 | |||
510 | board->rdy_pin = of_get_gpio_flags(np, 0, &flags); | ||
511 | board->rdy_pin_active_low = (flags == OF_GPIO_ACTIVE_LOW); | ||
512 | |||
513 | board->enable_pin = of_get_gpio(np, 1); | ||
514 | board->det_pin = of_get_gpio(np, 2); | ||
515 | |||
516 | return 0; | ||
517 | } | ||
518 | #else | ||
519 | static int __devinit atmel_of_init_port(struct atmel_nand_host *host, | ||
520 | struct device_node *np) | ||
521 | { | ||
522 | return -EINVAL; | ||
523 | } | ||
524 | #endif | ||
525 | |||
484 | /* | 526 | /* |
485 | * Probe for the NAND device. | 527 | * Probe for the NAND device. |
486 | */ | 528 | */ |
@@ -491,6 +533,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev) | |||
491 | struct nand_chip *nand_chip; | 533 | struct nand_chip *nand_chip; |
492 | struct resource *regs; | 534 | struct resource *regs; |
493 | struct resource *mem; | 535 | struct resource *mem; |
536 | struct mtd_part_parser_data ppdata = {}; | ||
494 | int res; | 537 | int res; |
495 | 538 | ||
496 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 539 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
@@ -517,8 +560,15 @@ static int __init atmel_nand_probe(struct platform_device *pdev) | |||
517 | 560 | ||
518 | mtd = &host->mtd; | 561 | mtd = &host->mtd; |
519 | nand_chip = &host->nand_chip; | 562 | nand_chip = &host->nand_chip; |
520 | host->board = pdev->dev.platform_data; | ||
521 | host->dev = &pdev->dev; | 563 | host->dev = &pdev->dev; |
564 | if (pdev->dev.of_node) { | ||
565 | res = atmel_of_init_port(host, pdev->dev.of_node); | ||
566 | if (res) | ||
567 | goto err_nand_ioremap; | ||
568 | } else { | ||
569 | memcpy(&host->board, pdev->dev.platform_data, | ||
570 | sizeof(struct atmel_nand_data)); | ||
571 | } | ||
522 | 572 | ||
523 | nand_chip->priv = host; /* link the private data structures */ | 573 | nand_chip->priv = host; /* link the private data structures */ |
524 | mtd->priv = nand_chip; | 574 | mtd->priv = nand_chip; |
@@ -529,26 +579,25 @@ static int __init atmel_nand_probe(struct platform_device *pdev) | |||
529 | nand_chip->IO_ADDR_W = host->io_base; | 579 | nand_chip->IO_ADDR_W = host->io_base; |
530 | nand_chip->cmd_ctrl = atmel_nand_cmd_ctrl; | 580 | nand_chip->cmd_ctrl = atmel_nand_cmd_ctrl; |
531 | 581 | ||
532 | if (gpio_is_valid(host->board->rdy_pin)) | 582 | if (gpio_is_valid(host->board.rdy_pin)) |
533 | nand_chip->dev_ready = atmel_nand_device_ready; | 583 | nand_chip->dev_ready = atmel_nand_device_ready; |
534 | 584 | ||
585 | nand_chip->ecc.mode = host->board.ecc_mode; | ||
586 | |||
535 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 587 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
536 | if (!regs && hard_ecc) { | 588 | if (!regs && nand_chip->ecc.mode == NAND_ECC_HW) { |
537 | printk(KERN_ERR "atmel_nand: can't get I/O resource " | 589 | printk(KERN_ERR "atmel_nand: can't get I/O resource " |
538 | "regs\nFalling back on software ECC\n"); | 590 | "regs\nFalling back on software ECC\n"); |
591 | nand_chip->ecc.mode = NAND_ECC_SOFT; | ||
539 | } | 592 | } |
540 | 593 | ||
541 | nand_chip->ecc.mode = NAND_ECC_SOFT; /* enable ECC */ | 594 | if (nand_chip->ecc.mode == NAND_ECC_HW) { |
542 | if (no_ecc) | ||
543 | nand_chip->ecc.mode = NAND_ECC_NONE; | ||
544 | if (hard_ecc && regs) { | ||
545 | host->ecc = ioremap(regs->start, resource_size(regs)); | 595 | host->ecc = ioremap(regs->start, resource_size(regs)); |
546 | if (host->ecc == NULL) { | 596 | if (host->ecc == NULL) { |
547 | printk(KERN_ERR "atmel_nand: ioremap failed\n"); | 597 | printk(KERN_ERR "atmel_nand: ioremap failed\n"); |
548 | res = -EIO; | 598 | res = -EIO; |
549 | goto err_ecc_ioremap; | 599 | goto err_ecc_ioremap; |
550 | } | 600 | } |
551 | nand_chip->ecc.mode = NAND_ECC_HW; | ||
552 | nand_chip->ecc.calculate = atmel_nand_calculate; | 601 | nand_chip->ecc.calculate = atmel_nand_calculate; |
553 | nand_chip->ecc.correct = atmel_nand_correct; | 602 | nand_chip->ecc.correct = atmel_nand_correct; |
554 | nand_chip->ecc.hwctl = atmel_nand_hwctl; | 603 | nand_chip->ecc.hwctl = atmel_nand_hwctl; |
@@ -559,7 +608,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev) | |||
559 | 608 | ||
560 | nand_chip->chip_delay = 20; /* 20us command delay time */ | 609 | nand_chip->chip_delay = 20; /* 20us command delay time */ |
561 | 610 | ||
562 | if (host->board->bus_width_16) /* 16-bit bus width */ | 611 | if (host->board.bus_width_16) /* 16-bit bus width */ |
563 | nand_chip->options |= NAND_BUSWIDTH_16; | 612 | nand_chip->options |= NAND_BUSWIDTH_16; |
564 | 613 | ||
565 | nand_chip->read_buf = atmel_read_buf; | 614 | nand_chip->read_buf = atmel_read_buf; |
@@ -568,15 +617,15 @@ static int __init atmel_nand_probe(struct platform_device *pdev) | |||
568 | platform_set_drvdata(pdev, host); | 617 | platform_set_drvdata(pdev, host); |
569 | atmel_nand_enable(host); | 618 | atmel_nand_enable(host); |
570 | 619 | ||
571 | if (gpio_is_valid(host->board->det_pin)) { | 620 | if (gpio_is_valid(host->board.det_pin)) { |
572 | if (gpio_get_value(host->board->det_pin)) { | 621 | if (gpio_get_value(host->board.det_pin)) { |
573 | printk(KERN_INFO "No SmartMedia card inserted.\n"); | 622 | printk(KERN_INFO "No SmartMedia card inserted.\n"); |
574 | res = -ENXIO; | 623 | res = -ENXIO; |
575 | goto err_no_card; | 624 | goto err_no_card; |
576 | } | 625 | } |
577 | } | 626 | } |
578 | 627 | ||
579 | if (on_flash_bbt) { | 628 | if (host->board.on_flash_bbt || on_flash_bbt) { |
580 | printk(KERN_INFO "atmel_nand: Use On Flash BBT\n"); | 629 | printk(KERN_INFO "atmel_nand: Use On Flash BBT\n"); |
581 | nand_chip->bbt_options |= NAND_BBT_USE_FLASH; | 630 | nand_chip->bbt_options |= NAND_BBT_USE_FLASH; |
582 | } | 631 | } |
@@ -651,8 +700,9 @@ static int __init atmel_nand_probe(struct platform_device *pdev) | |||
651 | } | 700 | } |
652 | 701 | ||
653 | mtd->name = "atmel_nand"; | 702 | mtd->name = "atmel_nand"; |
654 | res = mtd_device_parse_register(mtd, NULL, NULL, host->board->parts, | 703 | ppdata.of_node = pdev->dev.of_node; |
655 | host->board->num_parts); | 704 | res = mtd_device_parse_register(mtd, NULL, &ppdata, |
705 | host->board.parts, host->board.num_parts); | ||
656 | if (!res) | 706 | if (!res) |
657 | return res; | 707 | return res; |
658 | 708 | ||
@@ -696,11 +746,21 @@ static int __exit atmel_nand_remove(struct platform_device *pdev) | |||
696 | return 0; | 746 | return 0; |
697 | } | 747 | } |
698 | 748 | ||
749 | #if defined(CONFIG_OF) | ||
750 | static const struct of_device_id atmel_nand_dt_ids[] = { | ||
751 | { .compatible = "atmel,at91rm9200-nand" }, | ||
752 | { /* sentinel */ } | ||
753 | }; | ||
754 | |||
755 | MODULE_DEVICE_TABLE(of, atmel_nand_dt_ids); | ||
756 | #endif | ||
757 | |||
699 | static struct platform_driver atmel_nand_driver = { | 758 | static struct platform_driver atmel_nand_driver = { |
700 | .remove = __exit_p(atmel_nand_remove), | 759 | .remove = __exit_p(atmel_nand_remove), |
701 | .driver = { | 760 | .driver = { |
702 | .name = "atmel_nand", | 761 | .name = "atmel_nand", |
703 | .owner = THIS_MODULE, | 762 | .owner = THIS_MODULE, |
763 | .of_match_table = of_match_ptr(atmel_nand_dt_ids), | ||
704 | }, | 764 | }, |
705 | }; | 765 | }; |
706 | 766 | ||
diff --git a/drivers/mtd/nand/bcm_umi_nand.c b/drivers/mtd/nand/bcm_umi_nand.c index fc600431f519..6908cdde3065 100644 --- a/drivers/mtd/nand/bcm_umi_nand.c +++ b/drivers/mtd/nand/bcm_umi_nand.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #include <linux/mtd/partitions.h> | 31 | #include <linux/mtd/partitions.h> |
32 | 32 | ||
33 | #include <asm/mach-types.h> | 33 | #include <asm/mach-types.h> |
34 | #include <asm/system.h> | ||
35 | 34 | ||
36 | #include <mach/reg_nand.h> | 35 | #include <mach/reg_nand.h> |
37 | #include <mach/reg_umi.h> | 36 | #include <mach/reg_umi.h> |
diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c new file mode 100644 index 000000000000..c30ac7b83d28 --- /dev/null +++ b/drivers/mtd/nand/fsl_ifc_nand.c | |||
@@ -0,0 +1,1072 @@ | |||
1 | /* | ||
2 | * Freescale Integrated Flash Controller NAND driver | ||
3 | * | ||
4 | * Copyright 2011-2012 Freescale Semiconductor, Inc | ||
5 | * | ||
6 | * Author: Dipen Dudhat <Dipen.Dudhat@freescale.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | */ | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/types.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/slab.h> | ||
28 | #include <linux/mtd/mtd.h> | ||
29 | #include <linux/mtd/nand.h> | ||
30 | #include <linux/mtd/partitions.h> | ||
31 | #include <linux/mtd/nand_ecc.h> | ||
32 | #include <asm/fsl_ifc.h> | ||
33 | |||
34 | #define ERR_BYTE 0xFF /* Value returned for read | ||
35 | bytes when read failed */ | ||
36 | #define IFC_TIMEOUT_MSECS 500 /* Maximum number of mSecs to wait | ||
37 | for IFC NAND Machine */ | ||
38 | |||
39 | struct fsl_ifc_ctrl; | ||
40 | |||
41 | /* mtd information per set */ | ||
42 | struct fsl_ifc_mtd { | ||
43 | struct mtd_info mtd; | ||
44 | struct nand_chip chip; | ||
45 | struct fsl_ifc_ctrl *ctrl; | ||
46 | |||
47 | struct device *dev; | ||
48 | int bank; /* Chip select bank number */ | ||
49 | unsigned int bufnum_mask; /* bufnum = page & bufnum_mask */ | ||
50 | u8 __iomem *vbase; /* Chip select base virtual address */ | ||
51 | }; | ||
52 | |||
53 | /* overview of the fsl ifc controller */ | ||
54 | struct fsl_ifc_nand_ctrl { | ||
55 | struct nand_hw_control controller; | ||
56 | struct fsl_ifc_mtd *chips[FSL_IFC_BANK_COUNT]; | ||
57 | |||
58 | u8 __iomem *addr; /* Address of assigned IFC buffer */ | ||
59 | unsigned int page; /* Last page written to / read from */ | ||
60 | unsigned int read_bytes;/* Number of bytes read during command */ | ||
61 | unsigned int column; /* Saved column from SEQIN */ | ||
62 | unsigned int index; /* Pointer to next byte to 'read' */ | ||
63 | unsigned int oob; /* Non zero if operating on OOB data */ | ||
64 | unsigned int eccread; /* Non zero for a full-page ECC read */ | ||
65 | unsigned int counter; /* counter for the initializations */ | ||
66 | }; | ||
67 | |||
68 | static struct fsl_ifc_nand_ctrl *ifc_nand_ctrl; | ||
69 | |||
70 | /* 512-byte page with 4-bit ECC, 8-bit */ | ||
71 | static struct nand_ecclayout oob_512_8bit_ecc4 = { | ||
72 | .eccbytes = 8, | ||
73 | .eccpos = {8, 9, 10, 11, 12, 13, 14, 15}, | ||
74 | .oobfree = { {0, 5}, {6, 2} }, | ||
75 | }; | ||
76 | |||
77 | /* 512-byte page with 4-bit ECC, 16-bit */ | ||
78 | static struct nand_ecclayout oob_512_16bit_ecc4 = { | ||
79 | .eccbytes = 8, | ||
80 | .eccpos = {8, 9, 10, 11, 12, 13, 14, 15}, | ||
81 | .oobfree = { {2, 6}, }, | ||
82 | }; | ||
83 | |||
84 | /* 2048-byte page size with 4-bit ECC */ | ||
85 | static struct nand_ecclayout oob_2048_ecc4 = { | ||
86 | .eccbytes = 32, | ||
87 | .eccpos = { | ||
88 | 8, 9, 10, 11, 12, 13, 14, 15, | ||
89 | 16, 17, 18, 19, 20, 21, 22, 23, | ||
90 | 24, 25, 26, 27, 28, 29, 30, 31, | ||
91 | 32, 33, 34, 35, 36, 37, 38, 39, | ||
92 | }, | ||
93 | .oobfree = { {2, 6}, {40, 24} }, | ||
94 | }; | ||
95 | |||
96 | /* 4096-byte page size with 4-bit ECC */ | ||
97 | static struct nand_ecclayout oob_4096_ecc4 = { | ||
98 | .eccbytes = 64, | ||
99 | .eccpos = { | ||
100 | 8, 9, 10, 11, 12, 13, 14, 15, | ||
101 | 16, 17, 18, 19, 20, 21, 22, 23, | ||
102 | 24, 25, 26, 27, 28, 29, 30, 31, | ||
103 | 32, 33, 34, 35, 36, 37, 38, 39, | ||
104 | 40, 41, 42, 43, 44, 45, 46, 47, | ||
105 | 48, 49, 50, 51, 52, 53, 54, 55, | ||
106 | 56, 57, 58, 59, 60, 61, 62, 63, | ||
107 | 64, 65, 66, 67, 68, 69, 70, 71, | ||
108 | }, | ||
109 | .oobfree = { {2, 6}, {72, 56} }, | ||
110 | }; | ||
111 | |||
112 | /* 4096-byte page size with 8-bit ECC -- requires 218-byte OOB */ | ||
113 | static struct nand_ecclayout oob_4096_ecc8 = { | ||
114 | .eccbytes = 128, | ||
115 | .eccpos = { | ||
116 | 8, 9, 10, 11, 12, 13, 14, 15, | ||
117 | 16, 17, 18, 19, 20, 21, 22, 23, | ||
118 | 24, 25, 26, 27, 28, 29, 30, 31, | ||
119 | 32, 33, 34, 35, 36, 37, 38, 39, | ||
120 | 40, 41, 42, 43, 44, 45, 46, 47, | ||
121 | 48, 49, 50, 51, 52, 53, 54, 55, | ||
122 | 56, 57, 58, 59, 60, 61, 62, 63, | ||
123 | 64, 65, 66, 67, 68, 69, 70, 71, | ||
124 | 72, 73, 74, 75, 76, 77, 78, 79, | ||
125 | 80, 81, 82, 83, 84, 85, 86, 87, | ||
126 | 88, 89, 90, 91, 92, 93, 94, 95, | ||
127 | 96, 97, 98, 99, 100, 101, 102, 103, | ||
128 | 104, 105, 106, 107, 108, 109, 110, 111, | ||
129 | 112, 113, 114, 115, 116, 117, 118, 119, | ||
130 | 120, 121, 122, 123, 124, 125, 126, 127, | ||
131 | 128, 129, 130, 131, 132, 133, 134, 135, | ||
132 | }, | ||
133 | .oobfree = { {2, 6}, {136, 82} }, | ||
134 | }; | ||
135 | |||
136 | |||
137 | /* | ||
138 | * Generic flash bbt descriptors | ||
139 | */ | ||
140 | static u8 bbt_pattern[] = {'B', 'b', 't', '0' }; | ||
141 | static u8 mirror_pattern[] = {'1', 't', 'b', 'B' }; | ||
142 | |||
143 | static struct nand_bbt_descr bbt_main_descr = { | ||
144 | .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | | ||
145 | NAND_BBT_2BIT | NAND_BBT_VERSION, | ||
146 | .offs = 2, /* 0 on 8-bit small page */ | ||
147 | .len = 4, | ||
148 | .veroffs = 6, | ||
149 | .maxblocks = 4, | ||
150 | .pattern = bbt_pattern, | ||
151 | }; | ||
152 | |||
153 | static struct nand_bbt_descr bbt_mirror_descr = { | ||
154 | .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | | ||
155 | NAND_BBT_2BIT | NAND_BBT_VERSION, | ||
156 | .offs = 2, /* 0 on 8-bit small page */ | ||
157 | .len = 4, | ||
158 | .veroffs = 6, | ||
159 | .maxblocks = 4, | ||
160 | .pattern = mirror_pattern, | ||
161 | }; | ||
162 | |||
163 | /* | ||
164 | * Set up the IFC hardware block and page address fields, and the ifc nand | ||
165 | * structure addr field to point to the correct IFC buffer in memory | ||
166 | */ | ||
167 | static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob) | ||
168 | { | ||
169 | struct nand_chip *chip = mtd->priv; | ||
170 | struct fsl_ifc_mtd *priv = chip->priv; | ||
171 | struct fsl_ifc_ctrl *ctrl = priv->ctrl; | ||
172 | struct fsl_ifc_regs __iomem *ifc = ctrl->regs; | ||
173 | int buf_num; | ||
174 | |||
175 | ifc_nand_ctrl->page = page_addr; | ||
176 | /* Program ROW0/COL0 */ | ||
177 | out_be32(&ifc->ifc_nand.row0, page_addr); | ||
178 | out_be32(&ifc->ifc_nand.col0, (oob ? IFC_NAND_COL_MS : 0) | column); | ||
179 | |||
180 | buf_num = page_addr & priv->bufnum_mask; | ||
181 | |||
182 | ifc_nand_ctrl->addr = priv->vbase + buf_num * (mtd->writesize * 2); | ||
183 | ifc_nand_ctrl->index = column; | ||
184 | |||
185 | /* for OOB data point to the second half of the buffer */ | ||
186 | if (oob) | ||
187 | ifc_nand_ctrl->index += mtd->writesize; | ||
188 | } | ||
189 | |||
190 | static int is_blank(struct mtd_info *mtd, unsigned int bufnum) | ||
191 | { | ||
192 | struct nand_chip *chip = mtd->priv; | ||
193 | struct fsl_ifc_mtd *priv = chip->priv; | ||
194 | u8 __iomem *addr = priv->vbase + bufnum * (mtd->writesize * 2); | ||
195 | u32 __iomem *mainarea = (u32 *)addr; | ||
196 | u8 __iomem *oob = addr + mtd->writesize; | ||
197 | int i; | ||
198 | |||
199 | for (i = 0; i < mtd->writesize / 4; i++) { | ||
200 | if (__raw_readl(&mainarea[i]) != 0xffffffff) | ||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | for (i = 0; i < chip->ecc.layout->eccbytes; i++) { | ||
205 | int pos = chip->ecc.layout->eccpos[i]; | ||
206 | |||
207 | if (__raw_readb(&oob[pos]) != 0xff) | ||
208 | return 0; | ||
209 | } | ||
210 | |||
211 | return 1; | ||
212 | } | ||
213 | |||
214 | /* returns nonzero if entire page is blank */ | ||
215 | static int check_read_ecc(struct mtd_info *mtd, struct fsl_ifc_ctrl *ctrl, | ||
216 | u32 *eccstat, unsigned int bufnum) | ||
217 | { | ||
218 | u32 reg = eccstat[bufnum / 4]; | ||
219 | int errors; | ||
220 | |||
221 | errors = (reg >> ((3 - bufnum % 4) * 8)) & 15; | ||
222 | |||
223 | return errors; | ||
224 | } | ||
225 | |||
226 | /* | ||
227 | * execute IFC NAND command and wait for it to complete | ||
228 | */ | ||
229 | static void fsl_ifc_run_command(struct mtd_info *mtd) | ||
230 | { | ||
231 | struct nand_chip *chip = mtd->priv; | ||
232 | struct fsl_ifc_mtd *priv = chip->priv; | ||
233 | struct fsl_ifc_ctrl *ctrl = priv->ctrl; | ||
234 | struct fsl_ifc_nand_ctrl *nctrl = ifc_nand_ctrl; | ||
235 | struct fsl_ifc_regs __iomem *ifc = ctrl->regs; | ||
236 | u32 eccstat[4]; | ||
237 | int i; | ||
238 | |||
239 | /* set the chip select for NAND Transaction */ | ||
240 | out_be32(&ifc->ifc_nand.nand_csel, priv->bank << IFC_NAND_CSEL_SHIFT); | ||
241 | |||
242 | dev_vdbg(priv->dev, | ||
243 | "%s: fir0=%08x fcr0=%08x\n", | ||
244 | __func__, | ||
245 | in_be32(&ifc->ifc_nand.nand_fir0), | ||
246 | in_be32(&ifc->ifc_nand.nand_fcr0)); | ||
247 | |||
248 | ctrl->nand_stat = 0; | ||
249 | |||
250 | /* start read/write seq */ | ||
251 | out_be32(&ifc->ifc_nand.nandseq_strt, IFC_NAND_SEQ_STRT_FIR_STRT); | ||
252 | |||
253 | /* wait for command complete flag or timeout */ | ||
254 | wait_event_timeout(ctrl->nand_wait, ctrl->nand_stat, | ||
255 | IFC_TIMEOUT_MSECS * HZ/1000); | ||
256 | |||
257 | /* ctrl->nand_stat will be updated from IRQ context */ | ||
258 | if (!ctrl->nand_stat) | ||
259 | dev_err(priv->dev, "Controller is not responding\n"); | ||
260 | if (ctrl->nand_stat & IFC_NAND_EVTER_STAT_FTOER) | ||
261 | dev_err(priv->dev, "NAND Flash Timeout Error\n"); | ||
262 | if (ctrl->nand_stat & IFC_NAND_EVTER_STAT_WPER) | ||
263 | dev_err(priv->dev, "NAND Flash Write Protect Error\n"); | ||
264 | |||
265 | if (nctrl->eccread) { | ||
266 | int errors; | ||
267 | int bufnum = nctrl->page & priv->bufnum_mask; | ||
268 | int sector = bufnum * chip->ecc.steps; | ||
269 | int sector_end = sector + chip->ecc.steps - 1; | ||
270 | |||
271 | for (i = sector / 4; i <= sector_end / 4; i++) | ||
272 | eccstat[i] = in_be32(&ifc->ifc_nand.nand_eccstat[i]); | ||
273 | |||
274 | for (i = sector; i <= sector_end; i++) { | ||
275 | errors = check_read_ecc(mtd, ctrl, eccstat, i); | ||
276 | |||
277 | if (errors == 15) { | ||
278 | /* | ||
279 | * Uncorrectable error. | ||
280 | * OK only if the whole page is blank. | ||
281 | * | ||
282 | * We disable ECCER reporting due to... | ||
283 | * erratum IFC-A002770 -- so report it now if we | ||
284 | * see an uncorrectable error in ECCSTAT. | ||
285 | */ | ||
286 | if (!is_blank(mtd, bufnum)) | ||
287 | ctrl->nand_stat |= | ||
288 | IFC_NAND_EVTER_STAT_ECCER; | ||
289 | break; | ||
290 | } | ||
291 | |||
292 | mtd->ecc_stats.corrected += errors; | ||
293 | } | ||
294 | |||
295 | nctrl->eccread = 0; | ||
296 | } | ||
297 | } | ||
298 | |||
299 | static void fsl_ifc_do_read(struct nand_chip *chip, | ||
300 | int oob, | ||
301 | struct mtd_info *mtd) | ||
302 | { | ||
303 | struct fsl_ifc_mtd *priv = chip->priv; | ||
304 | struct fsl_ifc_ctrl *ctrl = priv->ctrl; | ||
305 | struct fsl_ifc_regs __iomem *ifc = ctrl->regs; | ||
306 | |||
307 | /* Program FIR/IFC_NAND_FCR0 for Small/Large page */ | ||
308 | if (mtd->writesize > 512) { | ||
309 | out_be32(&ifc->ifc_nand.nand_fir0, | ||
310 | (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) | | ||
311 | (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP1_SHIFT) | | ||
312 | (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP2_SHIFT) | | ||
313 | (IFC_FIR_OP_CMD1 << IFC_NAND_FIR0_OP3_SHIFT) | | ||
314 | (IFC_FIR_OP_RBCD << IFC_NAND_FIR0_OP4_SHIFT)); | ||
315 | out_be32(&ifc->ifc_nand.nand_fir1, 0x0); | ||
316 | |||
317 | out_be32(&ifc->ifc_nand.nand_fcr0, | ||
318 | (NAND_CMD_READ0 << IFC_NAND_FCR0_CMD0_SHIFT) | | ||
319 | (NAND_CMD_READSTART << IFC_NAND_FCR0_CMD1_SHIFT)); | ||
320 | } else { | ||
321 | out_be32(&ifc->ifc_nand.nand_fir0, | ||
322 | (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) | | ||
323 | (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP1_SHIFT) | | ||
324 | (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP2_SHIFT) | | ||
325 | (IFC_FIR_OP_RBCD << IFC_NAND_FIR0_OP3_SHIFT)); | ||
326 | out_be32(&ifc->ifc_nand.nand_fir1, 0x0); | ||
327 | |||
328 | if (oob) | ||
329 | out_be32(&ifc->ifc_nand.nand_fcr0, | ||
330 | NAND_CMD_READOOB << IFC_NAND_FCR0_CMD0_SHIFT); | ||
331 | else | ||
332 | out_be32(&ifc->ifc_nand.nand_fcr0, | ||
333 | NAND_CMD_READ0 << IFC_NAND_FCR0_CMD0_SHIFT); | ||
334 | } | ||
335 | } | ||
336 | |||
337 | /* cmdfunc send commands to the IFC NAND Machine */ | ||
338 | static void fsl_ifc_cmdfunc(struct mtd_info *mtd, unsigned int command, | ||
339 | int column, int page_addr) { | ||
340 | struct nand_chip *chip = mtd->priv; | ||
341 | struct fsl_ifc_mtd *priv = chip->priv; | ||
342 | struct fsl_ifc_ctrl *ctrl = priv->ctrl; | ||
343 | struct fsl_ifc_regs __iomem *ifc = ctrl->regs; | ||
344 | |||
345 | /* clear the read buffer */ | ||
346 | ifc_nand_ctrl->read_bytes = 0; | ||
347 | if (command != NAND_CMD_PAGEPROG) | ||
348 | ifc_nand_ctrl->index = 0; | ||
349 | |||
350 | switch (command) { | ||
351 | /* READ0 read the entire buffer to use hardware ECC. */ | ||
352 | case NAND_CMD_READ0: | ||
353 | out_be32(&ifc->ifc_nand.nand_fbcr, 0); | ||
354 | set_addr(mtd, 0, page_addr, 0); | ||
355 | |||
356 | ifc_nand_ctrl->read_bytes = mtd->writesize + mtd->oobsize; | ||
357 | ifc_nand_ctrl->index += column; | ||
358 | |||
359 | if (chip->ecc.mode == NAND_ECC_HW) | ||
360 | ifc_nand_ctrl->eccread = 1; | ||
361 | |||
362 | fsl_ifc_do_read(chip, 0, mtd); | ||
363 | fsl_ifc_run_command(mtd); | ||
364 | return; | ||
365 | |||
366 | /* READOOB reads only the OOB because no ECC is performed. */ | ||
367 | case NAND_CMD_READOOB: | ||
368 | out_be32(&ifc->ifc_nand.nand_fbcr, mtd->oobsize - column); | ||
369 | set_addr(mtd, column, page_addr, 1); | ||
370 | |||
371 | ifc_nand_ctrl->read_bytes = mtd->writesize + mtd->oobsize; | ||
372 | |||
373 | fsl_ifc_do_read(chip, 1, mtd); | ||
374 | fsl_ifc_run_command(mtd); | ||
375 | |||
376 | return; | ||
377 | |||
378 | /* READID must read all 8 possible bytes */ | ||
379 | case NAND_CMD_READID: | ||
380 | out_be32(&ifc->ifc_nand.nand_fir0, | ||
381 | (IFC_FIR_OP_CMD0 << IFC_NAND_FIR0_OP0_SHIFT) | | ||
382 | (IFC_FIR_OP_UA << IFC_NAND_FIR0_OP1_SHIFT) | | ||
383 | (IFC_FIR_OP_RB << IFC_NAND_FIR0_OP2_SHIFT)); | ||
384 | out_be32(&ifc->ifc_nand.nand_fcr0, | ||
385 | NAND_CMD_READID << IFC_NAND_FCR0_CMD0_SHIFT); | ||
386 | /* 8 bytes for manuf, device and exts */ | ||
387 | out_be32(&ifc->ifc_nand.nand_fbcr, 8); | ||
388 | ifc_nand_ctrl->read_bytes = 8; | ||
389 | |||
390 | set_addr(mtd, 0, 0, 0); | ||
391 | fsl_ifc_run_command(mtd); | ||
392 | return; | ||
393 | |||
394 | /* ERASE1 stores the block and page address */ | ||
395 | case NAND_CMD_ERASE1: | ||
396 | set_addr(mtd, 0, page_addr, 0); | ||
397 | return; | ||
398 | |||
399 | /* ERASE2 uses the block and page address from ERASE1 */ | ||
400 | case NAND_CMD_ERASE2: | ||
401 | out_be32(&ifc->ifc_nand.nand_fir0, | ||
402 | (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) | | ||
403 | (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP1_SHIFT) | | ||
404 | (IFC_FIR_OP_CMD1 << IFC_NAND_FIR0_OP2_SHIFT)); | ||
405 | |||
406 | out_be32(&ifc->ifc_nand.nand_fcr0, | ||
407 | (NAND_CMD_ERASE1 << IFC_NAND_FCR0_CMD0_SHIFT) | | ||
408 | (NAND_CMD_ERASE2 << IFC_NAND_FCR0_CMD1_SHIFT)); | ||
409 | |||
410 | out_be32(&ifc->ifc_nand.nand_fbcr, 0); | ||
411 | ifc_nand_ctrl->read_bytes = 0; | ||
412 | fsl_ifc_run_command(mtd); | ||
413 | return; | ||
414 | |||
415 | /* SEQIN sets up the addr buffer and all registers except the length */ | ||
416 | case NAND_CMD_SEQIN: { | ||
417 | u32 nand_fcr0; | ||
418 | ifc_nand_ctrl->column = column; | ||
419 | ifc_nand_ctrl->oob = 0; | ||
420 | |||
421 | if (mtd->writesize > 512) { | ||
422 | nand_fcr0 = | ||
423 | (NAND_CMD_SEQIN << IFC_NAND_FCR0_CMD0_SHIFT) | | ||
424 | (NAND_CMD_PAGEPROG << IFC_NAND_FCR0_CMD1_SHIFT); | ||
425 | |||
426 | out_be32(&ifc->ifc_nand.nand_fir0, | ||
427 | (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) | | ||
428 | (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP1_SHIFT) | | ||
429 | (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP2_SHIFT) | | ||
430 | (IFC_FIR_OP_WBCD << IFC_NAND_FIR0_OP3_SHIFT) | | ||
431 | (IFC_FIR_OP_CW1 << IFC_NAND_FIR0_OP4_SHIFT)); | ||
432 | } else { | ||
433 | nand_fcr0 = ((NAND_CMD_PAGEPROG << | ||
434 | IFC_NAND_FCR0_CMD1_SHIFT) | | ||
435 | (NAND_CMD_SEQIN << | ||
436 | IFC_NAND_FCR0_CMD2_SHIFT)); | ||
437 | |||
438 | out_be32(&ifc->ifc_nand.nand_fir0, | ||
439 | (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) | | ||
440 | (IFC_FIR_OP_CMD2 << IFC_NAND_FIR0_OP1_SHIFT) | | ||
441 | (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP2_SHIFT) | | ||
442 | (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP3_SHIFT) | | ||
443 | (IFC_FIR_OP_WBCD << IFC_NAND_FIR0_OP4_SHIFT)); | ||
444 | out_be32(&ifc->ifc_nand.nand_fir1, | ||
445 | (IFC_FIR_OP_CW1 << IFC_NAND_FIR1_OP5_SHIFT)); | ||
446 | |||
447 | if (column >= mtd->writesize) | ||
448 | nand_fcr0 |= | ||
449 | NAND_CMD_READOOB << IFC_NAND_FCR0_CMD0_SHIFT; | ||
450 | else | ||
451 | nand_fcr0 |= | ||
452 | NAND_CMD_READ0 << IFC_NAND_FCR0_CMD0_SHIFT; | ||
453 | } | ||
454 | |||
455 | if (column >= mtd->writesize) { | ||
456 | /* OOB area --> READOOB */ | ||
457 | column -= mtd->writesize; | ||
458 | ifc_nand_ctrl->oob = 1; | ||
459 | } | ||
460 | out_be32(&ifc->ifc_nand.nand_fcr0, nand_fcr0); | ||
461 | set_addr(mtd, column, page_addr, ifc_nand_ctrl->oob); | ||
462 | return; | ||
463 | } | ||
464 | |||
465 | /* PAGEPROG reuses all of the setup from SEQIN and adds the length */ | ||
466 | case NAND_CMD_PAGEPROG: { | ||
467 | if (ifc_nand_ctrl->oob) { | ||
468 | out_be32(&ifc->ifc_nand.nand_fbcr, | ||
469 | ifc_nand_ctrl->index - ifc_nand_ctrl->column); | ||
470 | } else { | ||
471 | out_be32(&ifc->ifc_nand.nand_fbcr, 0); | ||
472 | } | ||
473 | |||
474 | fsl_ifc_run_command(mtd); | ||
475 | return; | ||
476 | } | ||
477 | |||
478 | case NAND_CMD_STATUS: | ||
479 | out_be32(&ifc->ifc_nand.nand_fir0, | ||
480 | (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) | | ||
481 | (IFC_FIR_OP_RB << IFC_NAND_FIR0_OP1_SHIFT)); | ||
482 | out_be32(&ifc->ifc_nand.nand_fcr0, | ||
483 | NAND_CMD_STATUS << IFC_NAND_FCR0_CMD0_SHIFT); | ||
484 | out_be32(&ifc->ifc_nand.nand_fbcr, 1); | ||
485 | set_addr(mtd, 0, 0, 0); | ||
486 | ifc_nand_ctrl->read_bytes = 1; | ||
487 | |||
488 | fsl_ifc_run_command(mtd); | ||
489 | |||
490 | /* | ||
491 | * The chip always seems to report that it is | ||
492 | * write-protected, even when it is not. | ||
493 | */ | ||
494 | setbits8(ifc_nand_ctrl->addr, NAND_STATUS_WP); | ||
495 | return; | ||
496 | |||
497 | case NAND_CMD_RESET: | ||
498 | out_be32(&ifc->ifc_nand.nand_fir0, | ||
499 | IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT); | ||
500 | out_be32(&ifc->ifc_nand.nand_fcr0, | ||
501 | NAND_CMD_RESET << IFC_NAND_FCR0_CMD0_SHIFT); | ||
502 | fsl_ifc_run_command(mtd); | ||
503 | return; | ||
504 | |||
505 | default: | ||
506 | dev_err(priv->dev, "%s: error, unsupported command 0x%x.\n", | ||
507 | __func__, command); | ||
508 | } | ||
509 | } | ||
510 | |||
511 | static void fsl_ifc_select_chip(struct mtd_info *mtd, int chip) | ||
512 | { | ||
513 | /* The hardware does not seem to support multiple | ||
514 | * chips per bank. | ||
515 | */ | ||
516 | } | ||
517 | |||
518 | /* | ||
519 | * Write buf to the IFC NAND Controller Data Buffer | ||
520 | */ | ||
521 | static void fsl_ifc_write_buf(struct mtd_info *mtd, const u8 *buf, int len) | ||
522 | { | ||
523 | struct nand_chip *chip = mtd->priv; | ||
524 | struct fsl_ifc_mtd *priv = chip->priv; | ||
525 | unsigned int bufsize = mtd->writesize + mtd->oobsize; | ||
526 | |||
527 | if (len <= 0) { | ||
528 | dev_err(priv->dev, "%s: len %d bytes", __func__, len); | ||
529 | return; | ||
530 | } | ||
531 | |||
532 | if ((unsigned int)len > bufsize - ifc_nand_ctrl->index) { | ||
533 | dev_err(priv->dev, | ||
534 | "%s: beyond end of buffer (%d requested, %u available)\n", | ||
535 | __func__, len, bufsize - ifc_nand_ctrl->index); | ||
536 | len = bufsize - ifc_nand_ctrl->index; | ||
537 | } | ||
538 | |||
539 | memcpy_toio(&ifc_nand_ctrl->addr[ifc_nand_ctrl->index], buf, len); | ||
540 | ifc_nand_ctrl->index += len; | ||
541 | } | ||
542 | |||
543 | /* | ||
544 | * Read a byte from either the IFC hardware buffer | ||
545 | * read function for 8-bit buswidth | ||
546 | */ | ||
547 | static uint8_t fsl_ifc_read_byte(struct mtd_info *mtd) | ||
548 | { | ||
549 | struct nand_chip *chip = mtd->priv; | ||
550 | struct fsl_ifc_mtd *priv = chip->priv; | ||
551 | |||
552 | /* | ||
553 | * If there are still bytes in the IFC buffer, then use the | ||
554 | * next byte. | ||
555 | */ | ||
556 | if (ifc_nand_ctrl->index < ifc_nand_ctrl->read_bytes) | ||
557 | return in_8(&ifc_nand_ctrl->addr[ifc_nand_ctrl->index++]); | ||
558 | |||
559 | dev_err(priv->dev, "%s: beyond end of buffer\n", __func__); | ||
560 | return ERR_BYTE; | ||
561 | } | ||
562 | |||
563 | /* | ||
564 | * Read two bytes from the IFC hardware buffer | ||
565 | * read function for 16-bit buswith | ||
566 | */ | ||
567 | static uint8_t fsl_ifc_read_byte16(struct mtd_info *mtd) | ||
568 | { | ||
569 | struct nand_chip *chip = mtd->priv; | ||
570 | struct fsl_ifc_mtd *priv = chip->priv; | ||
571 | uint16_t data; | ||
572 | |||
573 | /* | ||
574 | * If there are still bytes in the IFC buffer, then use the | ||
575 | * next byte. | ||
576 | */ | ||
577 | if (ifc_nand_ctrl->index < ifc_nand_ctrl->read_bytes) { | ||
578 | data = in_be16((uint16_t *)&ifc_nand_ctrl-> | ||
579 | addr[ifc_nand_ctrl->index]); | ||
580 | ifc_nand_ctrl->index += 2; | ||
581 | return (uint8_t) data; | ||
582 | } | ||
583 | |||
584 | dev_err(priv->dev, "%s: beyond end of buffer\n", __func__); | ||
585 | return ERR_BYTE; | ||
586 | } | ||
587 | |||
588 | /* | ||
589 | * Read from the IFC Controller Data Buffer | ||
590 | */ | ||
591 | static void fsl_ifc_read_buf(struct mtd_info *mtd, u8 *buf, int len) | ||
592 | { | ||
593 | struct nand_chip *chip = mtd->priv; | ||
594 | struct fsl_ifc_mtd *priv = chip->priv; | ||
595 | int avail; | ||
596 | |||
597 | if (len < 0) { | ||
598 | dev_err(priv->dev, "%s: len %d bytes", __func__, len); | ||
599 | return; | ||
600 | } | ||
601 | |||
602 | avail = min((unsigned int)len, | ||
603 | ifc_nand_ctrl->read_bytes - ifc_nand_ctrl->index); | ||
604 | memcpy_fromio(buf, &ifc_nand_ctrl->addr[ifc_nand_ctrl->index], avail); | ||
605 | ifc_nand_ctrl->index += avail; | ||
606 | |||
607 | if (len > avail) | ||
608 | dev_err(priv->dev, | ||
609 | "%s: beyond end of buffer (%d requested, %d available)\n", | ||
610 | __func__, len, avail); | ||
611 | } | ||
612 | |||
613 | /* | ||
614 | * Verify buffer against the IFC Controller Data Buffer | ||
615 | */ | ||
616 | static int fsl_ifc_verify_buf(struct mtd_info *mtd, | ||
617 | const u_char *buf, int len) | ||
618 | { | ||
619 | struct nand_chip *chip = mtd->priv; | ||
620 | struct fsl_ifc_mtd *priv = chip->priv; | ||
621 | struct fsl_ifc_ctrl *ctrl = priv->ctrl; | ||
622 | struct fsl_ifc_nand_ctrl *nctrl = ifc_nand_ctrl; | ||
623 | int i; | ||
624 | |||
625 | if (len < 0) { | ||
626 | dev_err(priv->dev, "%s: write_buf of %d bytes", __func__, len); | ||
627 | return -EINVAL; | ||
628 | } | ||
629 | |||
630 | if ((unsigned int)len > nctrl->read_bytes - nctrl->index) { | ||
631 | dev_err(priv->dev, | ||
632 | "%s: beyond end of buffer (%d requested, %u available)\n", | ||
633 | __func__, len, nctrl->read_bytes - nctrl->index); | ||
634 | |||
635 | nctrl->index = nctrl->read_bytes; | ||
636 | return -EINVAL; | ||
637 | } | ||
638 | |||
639 | for (i = 0; i < len; i++) | ||
640 | if (in_8(&nctrl->addr[nctrl->index + i]) != buf[i]) | ||
641 | break; | ||
642 | |||
643 | nctrl->index += len; | ||
644 | |||
645 | if (i != len) | ||
646 | return -EIO; | ||
647 | if (ctrl->nand_stat != IFC_NAND_EVTER_STAT_OPC) | ||
648 | return -EIO; | ||
649 | |||
650 | return 0; | ||
651 | } | ||
652 | |||
653 | /* | ||
654 | * This function is called after Program and Erase Operations to | ||
655 | * check for success or failure. | ||
656 | */ | ||
657 | static int fsl_ifc_wait(struct mtd_info *mtd, struct nand_chip *chip) | ||
658 | { | ||
659 | struct fsl_ifc_mtd *priv = chip->priv; | ||
660 | struct fsl_ifc_ctrl *ctrl = priv->ctrl; | ||
661 | struct fsl_ifc_regs __iomem *ifc = ctrl->regs; | ||
662 | u32 nand_fsr; | ||
663 | |||
664 | /* Use READ_STATUS command, but wait for the device to be ready */ | ||
665 | out_be32(&ifc->ifc_nand.nand_fir0, | ||
666 | (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) | | ||
667 | (IFC_FIR_OP_RDSTAT << IFC_NAND_FIR0_OP1_SHIFT)); | ||
668 | out_be32(&ifc->ifc_nand.nand_fcr0, NAND_CMD_STATUS << | ||
669 | IFC_NAND_FCR0_CMD0_SHIFT); | ||
670 | out_be32(&ifc->ifc_nand.nand_fbcr, 1); | ||
671 | set_addr(mtd, 0, 0, 0); | ||
672 | ifc_nand_ctrl->read_bytes = 1; | ||
673 | |||
674 | fsl_ifc_run_command(mtd); | ||
675 | |||
676 | nand_fsr = in_be32(&ifc->ifc_nand.nand_fsr); | ||
677 | |||
678 | /* | ||
679 | * The chip always seems to report that it is | ||
680 | * write-protected, even when it is not. | ||
681 | */ | ||
682 | return nand_fsr | NAND_STATUS_WP; | ||
683 | } | ||
684 | |||
685 | static int fsl_ifc_read_page(struct mtd_info *mtd, | ||
686 | struct nand_chip *chip, | ||
687 | uint8_t *buf, int page) | ||
688 | { | ||
689 | struct fsl_ifc_mtd *priv = chip->priv; | ||
690 | struct fsl_ifc_ctrl *ctrl = priv->ctrl; | ||
691 | |||
692 | fsl_ifc_read_buf(mtd, buf, mtd->writesize); | ||
693 | fsl_ifc_read_buf(mtd, chip->oob_poi, mtd->oobsize); | ||
694 | |||
695 | if (ctrl->nand_stat & IFC_NAND_EVTER_STAT_ECCER) | ||
696 | dev_err(priv->dev, "NAND Flash ECC Uncorrectable Error\n"); | ||
697 | |||
698 | if (ctrl->nand_stat != IFC_NAND_EVTER_STAT_OPC) | ||
699 | mtd->ecc_stats.failed++; | ||
700 | |||
701 | return 0; | ||
702 | } | ||
703 | |||
704 | /* ECC will be calculated automatically, and errors will be detected in | ||
705 | * waitfunc. | ||
706 | */ | ||
707 | static void fsl_ifc_write_page(struct mtd_info *mtd, | ||
708 | struct nand_chip *chip, | ||
709 | const uint8_t *buf) | ||
710 | { | ||
711 | fsl_ifc_write_buf(mtd, buf, mtd->writesize); | ||
712 | fsl_ifc_write_buf(mtd, chip->oob_poi, mtd->oobsize); | ||
713 | } | ||
714 | |||
715 | static int fsl_ifc_chip_init_tail(struct mtd_info *mtd) | ||
716 | { | ||
717 | struct nand_chip *chip = mtd->priv; | ||
718 | struct fsl_ifc_mtd *priv = chip->priv; | ||
719 | |||
720 | dev_dbg(priv->dev, "%s: nand->numchips = %d\n", __func__, | ||
721 | chip->numchips); | ||
722 | dev_dbg(priv->dev, "%s: nand->chipsize = %lld\n", __func__, | ||
723 | chip->chipsize); | ||
724 | dev_dbg(priv->dev, "%s: nand->pagemask = %8x\n", __func__, | ||
725 | chip->pagemask); | ||
726 | dev_dbg(priv->dev, "%s: nand->chip_delay = %d\n", __func__, | ||
727 | chip->chip_delay); | ||
728 | dev_dbg(priv->dev, "%s: nand->badblockpos = %d\n", __func__, | ||
729 | chip->badblockpos); | ||
730 | dev_dbg(priv->dev, "%s: nand->chip_shift = %d\n", __func__, | ||
731 | chip->chip_shift); | ||
732 | dev_dbg(priv->dev, "%s: nand->page_shift = %d\n", __func__, | ||
733 | chip->page_shift); | ||
734 | dev_dbg(priv->dev, "%s: nand->phys_erase_shift = %d\n", __func__, | ||
735 | chip->phys_erase_shift); | ||
736 | dev_dbg(priv->dev, "%s: nand->ecclayout = %p\n", __func__, | ||
737 | chip->ecclayout); | ||
738 | dev_dbg(priv->dev, "%s: nand->ecc.mode = %d\n", __func__, | ||
739 | chip->ecc.mode); | ||
740 | dev_dbg(priv->dev, "%s: nand->ecc.steps = %d\n", __func__, | ||
741 | chip->ecc.steps); | ||
742 | dev_dbg(priv->dev, "%s: nand->ecc.bytes = %d\n", __func__, | ||
743 | chip->ecc.bytes); | ||
744 | dev_dbg(priv->dev, "%s: nand->ecc.total = %d\n", __func__, | ||
745 | chip->ecc.total); | ||
746 | dev_dbg(priv->dev, "%s: nand->ecc.layout = %p\n", __func__, | ||
747 | chip->ecc.layout); | ||
748 | dev_dbg(priv->dev, "%s: mtd->flags = %08x\n", __func__, mtd->flags); | ||
749 | dev_dbg(priv->dev, "%s: mtd->size = %lld\n", __func__, mtd->size); | ||
750 | dev_dbg(priv->dev, "%s: mtd->erasesize = %d\n", __func__, | ||
751 | mtd->erasesize); | ||
752 | dev_dbg(priv->dev, "%s: mtd->writesize = %d\n", __func__, | ||
753 | mtd->writesize); | ||
754 | dev_dbg(priv->dev, "%s: mtd->oobsize = %d\n", __func__, | ||
755 | mtd->oobsize); | ||
756 | |||
757 | return 0; | ||
758 | } | ||
759 | |||
760 | static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv) | ||
761 | { | ||
762 | struct fsl_ifc_ctrl *ctrl = priv->ctrl; | ||
763 | struct fsl_ifc_regs __iomem *ifc = ctrl->regs; | ||
764 | struct nand_chip *chip = &priv->chip; | ||
765 | struct nand_ecclayout *layout; | ||
766 | u32 csor; | ||
767 | |||
768 | /* Fill in fsl_ifc_mtd structure */ | ||
769 | priv->mtd.priv = chip; | ||
770 | priv->mtd.owner = THIS_MODULE; | ||
771 | |||
772 | /* fill in nand_chip structure */ | ||
773 | /* set up function call table */ | ||
774 | if ((in_be32(&ifc->cspr_cs[priv->bank].cspr)) & CSPR_PORT_SIZE_16) | ||
775 | chip->read_byte = fsl_ifc_read_byte16; | ||
776 | else | ||
777 | chip->read_byte = fsl_ifc_read_byte; | ||
778 | |||
779 | chip->write_buf = fsl_ifc_write_buf; | ||
780 | chip->read_buf = fsl_ifc_read_buf; | ||
781 | chip->verify_buf = fsl_ifc_verify_buf; | ||
782 | chip->select_chip = fsl_ifc_select_chip; | ||
783 | chip->cmdfunc = fsl_ifc_cmdfunc; | ||
784 | chip->waitfunc = fsl_ifc_wait; | ||
785 | |||
786 | chip->bbt_td = &bbt_main_descr; | ||
787 | chip->bbt_md = &bbt_mirror_descr; | ||
788 | |||
789 | out_be32(&ifc->ifc_nand.ncfgr, 0x0); | ||
790 | |||
791 | /* set up nand options */ | ||
792 | chip->options = NAND_NO_READRDY | NAND_NO_AUTOINCR; | ||
793 | chip->bbt_options = NAND_BBT_USE_FLASH; | ||
794 | |||
795 | |||
796 | if (in_be32(&ifc->cspr_cs[priv->bank].cspr) & CSPR_PORT_SIZE_16) { | ||
797 | chip->read_byte = fsl_ifc_read_byte16; | ||
798 | chip->options |= NAND_BUSWIDTH_16; | ||
799 | } else { | ||
800 | chip->read_byte = fsl_ifc_read_byte; | ||
801 | } | ||
802 | |||
803 | chip->controller = &ifc_nand_ctrl->controller; | ||
804 | chip->priv = priv; | ||
805 | |||
806 | chip->ecc.read_page = fsl_ifc_read_page; | ||
807 | chip->ecc.write_page = fsl_ifc_write_page; | ||
808 | |||
809 | csor = in_be32(&ifc->csor_cs[priv->bank].csor); | ||
810 | |||
811 | /* Hardware generates ECC per 512 Bytes */ | ||
812 | chip->ecc.size = 512; | ||
813 | chip->ecc.bytes = 8; | ||
814 | |||
815 | switch (csor & CSOR_NAND_PGS_MASK) { | ||
816 | case CSOR_NAND_PGS_512: | ||
817 | if (chip->options & NAND_BUSWIDTH_16) { | ||
818 | layout = &oob_512_16bit_ecc4; | ||
819 | } else { | ||
820 | layout = &oob_512_8bit_ecc4; | ||
821 | |||
822 | /* Avoid conflict with bad block marker */ | ||
823 | bbt_main_descr.offs = 0; | ||
824 | bbt_mirror_descr.offs = 0; | ||
825 | } | ||
826 | |||
827 | priv->bufnum_mask = 15; | ||
828 | break; | ||
829 | |||
830 | case CSOR_NAND_PGS_2K: | ||
831 | layout = &oob_2048_ecc4; | ||
832 | priv->bufnum_mask = 3; | ||
833 | break; | ||
834 | |||
835 | case CSOR_NAND_PGS_4K: | ||
836 | if ((csor & CSOR_NAND_ECC_MODE_MASK) == | ||
837 | CSOR_NAND_ECC_MODE_4) { | ||
838 | layout = &oob_4096_ecc4; | ||
839 | } else { | ||
840 | layout = &oob_4096_ecc8; | ||
841 | chip->ecc.bytes = 16; | ||
842 | } | ||
843 | |||
844 | priv->bufnum_mask = 1; | ||
845 | break; | ||
846 | |||
847 | default: | ||
848 | dev_err(priv->dev, "bad csor %#x: bad page size\n", csor); | ||
849 | return -ENODEV; | ||
850 | } | ||
851 | |||
852 | /* Must also set CSOR_NAND_ECC_ENC_EN if DEC_EN set */ | ||
853 | if (csor & CSOR_NAND_ECC_DEC_EN) { | ||
854 | chip->ecc.mode = NAND_ECC_HW; | ||
855 | chip->ecc.layout = layout; | ||
856 | } else { | ||
857 | chip->ecc.mode = NAND_ECC_SOFT; | ||
858 | } | ||
859 | |||
860 | return 0; | ||
861 | } | ||
862 | |||
863 | static int fsl_ifc_chip_remove(struct fsl_ifc_mtd *priv) | ||
864 | { | ||
865 | nand_release(&priv->mtd); | ||
866 | |||
867 | kfree(priv->mtd.name); | ||
868 | |||
869 | if (priv->vbase) | ||
870 | iounmap(priv->vbase); | ||
871 | |||
872 | ifc_nand_ctrl->chips[priv->bank] = NULL; | ||
873 | dev_set_drvdata(priv->dev, NULL); | ||
874 | kfree(priv); | ||
875 | |||
876 | return 0; | ||
877 | } | ||
878 | |||
879 | static int match_bank(struct fsl_ifc_regs __iomem *ifc, int bank, | ||
880 | phys_addr_t addr) | ||
881 | { | ||
882 | u32 cspr = in_be32(&ifc->cspr_cs[bank].cspr); | ||
883 | |||
884 | if (!(cspr & CSPR_V)) | ||
885 | return 0; | ||
886 | if ((cspr & CSPR_MSEL) != CSPR_MSEL_NAND) | ||
887 | return 0; | ||
888 | |||
889 | return (cspr & CSPR_BA) == convert_ifc_address(addr); | ||
890 | } | ||
891 | |||
892 | static DEFINE_MUTEX(fsl_ifc_nand_mutex); | ||
893 | |||
894 | static int __devinit fsl_ifc_nand_probe(struct platform_device *dev) | ||
895 | { | ||
896 | struct fsl_ifc_regs __iomem *ifc; | ||
897 | struct fsl_ifc_mtd *priv; | ||
898 | struct resource res; | ||
899 | static const char *part_probe_types[] | ||
900 | = { "cmdlinepart", "RedBoot", "ofpart", NULL }; | ||
901 | int ret; | ||
902 | int bank; | ||
903 | struct device_node *node = dev->dev.of_node; | ||
904 | struct mtd_part_parser_data ppdata; | ||
905 | |||
906 | ppdata.of_node = dev->dev.of_node; | ||
907 | if (!fsl_ifc_ctrl_dev || !fsl_ifc_ctrl_dev->regs) | ||
908 | return -ENODEV; | ||
909 | ifc = fsl_ifc_ctrl_dev->regs; | ||
910 | |||
911 | /* get, allocate and map the memory resource */ | ||
912 | ret = of_address_to_resource(node, 0, &res); | ||
913 | if (ret) { | ||
914 | dev_err(&dev->dev, "%s: failed to get resource\n", __func__); | ||
915 | return ret; | ||
916 | } | ||
917 | |||
918 | /* find which chip select it is connected to */ | ||
919 | for (bank = 0; bank < FSL_IFC_BANK_COUNT; bank++) { | ||
920 | if (match_bank(ifc, bank, res.start)) | ||
921 | break; | ||
922 | } | ||
923 | |||
924 | if (bank >= FSL_IFC_BANK_COUNT) { | ||
925 | dev_err(&dev->dev, "%s: address did not match any chip selects\n", | ||
926 | __func__); | ||
927 | return -ENODEV; | ||
928 | } | ||
929 | |||
930 | priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL); | ||
931 | if (!priv) | ||
932 | return -ENOMEM; | ||
933 | |||
934 | mutex_lock(&fsl_ifc_nand_mutex); | ||
935 | if (!fsl_ifc_ctrl_dev->nand) { | ||
936 | ifc_nand_ctrl = kzalloc(sizeof(*ifc_nand_ctrl), GFP_KERNEL); | ||
937 | if (!ifc_nand_ctrl) { | ||
938 | dev_err(&dev->dev, "failed to allocate memory\n"); | ||
939 | mutex_unlock(&fsl_ifc_nand_mutex); | ||
940 | return -ENOMEM; | ||
941 | } | ||
942 | |||
943 | ifc_nand_ctrl->read_bytes = 0; | ||
944 | ifc_nand_ctrl->index = 0; | ||
945 | ifc_nand_ctrl->addr = NULL; | ||
946 | fsl_ifc_ctrl_dev->nand = ifc_nand_ctrl; | ||
947 | |||
948 | spin_lock_init(&ifc_nand_ctrl->controller.lock); | ||
949 | init_waitqueue_head(&ifc_nand_ctrl->controller.wq); | ||
950 | } else { | ||
951 | ifc_nand_ctrl = fsl_ifc_ctrl_dev->nand; | ||
952 | } | ||
953 | mutex_unlock(&fsl_ifc_nand_mutex); | ||
954 | |||
955 | ifc_nand_ctrl->chips[bank] = priv; | ||
956 | priv->bank = bank; | ||
957 | priv->ctrl = fsl_ifc_ctrl_dev; | ||
958 | priv->dev = &dev->dev; | ||
959 | |||
960 | priv->vbase = ioremap(res.start, resource_size(&res)); | ||
961 | if (!priv->vbase) { | ||
962 | dev_err(priv->dev, "%s: failed to map chip region\n", __func__); | ||
963 | ret = -ENOMEM; | ||
964 | goto err; | ||
965 | } | ||
966 | |||
967 | dev_set_drvdata(priv->dev, priv); | ||
968 | |||
969 | out_be32(&ifc->ifc_nand.nand_evter_en, | ||
970 | IFC_NAND_EVTER_EN_OPC_EN | | ||
971 | IFC_NAND_EVTER_EN_FTOER_EN | | ||
972 | IFC_NAND_EVTER_EN_WPER_EN); | ||
973 | |||
974 | /* enable NAND Machine Interrupts */ | ||
975 | out_be32(&ifc->ifc_nand.nand_evter_intr_en, | ||
976 | IFC_NAND_EVTER_INTR_OPCIR_EN | | ||
977 | IFC_NAND_EVTER_INTR_FTOERIR_EN | | ||
978 | IFC_NAND_EVTER_INTR_WPERIR_EN); | ||
979 | |||
980 | priv->mtd.name = kasprintf(GFP_KERNEL, "%x.flash", (unsigned)res.start); | ||
981 | if (!priv->mtd.name) { | ||
982 | ret = -ENOMEM; | ||
983 | goto err; | ||
984 | } | ||
985 | |||
986 | ret = fsl_ifc_chip_init(priv); | ||
987 | if (ret) | ||
988 | goto err; | ||
989 | |||
990 | ret = nand_scan_ident(&priv->mtd, 1, NULL); | ||
991 | if (ret) | ||
992 | goto err; | ||
993 | |||
994 | ret = fsl_ifc_chip_init_tail(&priv->mtd); | ||
995 | if (ret) | ||
996 | goto err; | ||
997 | |||
998 | ret = nand_scan_tail(&priv->mtd); | ||
999 | if (ret) | ||
1000 | goto err; | ||
1001 | |||
1002 | /* First look for RedBoot table or partitions on the command | ||
1003 | * line, these take precedence over device tree information */ | ||
1004 | mtd_device_parse_register(&priv->mtd, part_probe_types, &ppdata, | ||
1005 | NULL, 0); | ||
1006 | |||
1007 | dev_info(priv->dev, "IFC NAND device at 0x%llx, bank %d\n", | ||
1008 | (unsigned long long)res.start, priv->bank); | ||
1009 | return 0; | ||
1010 | |||
1011 | err: | ||
1012 | fsl_ifc_chip_remove(priv); | ||
1013 | return ret; | ||
1014 | } | ||
1015 | |||
1016 | static int fsl_ifc_nand_remove(struct platform_device *dev) | ||
1017 | { | ||
1018 | struct fsl_ifc_mtd *priv = dev_get_drvdata(&dev->dev); | ||
1019 | |||
1020 | fsl_ifc_chip_remove(priv); | ||
1021 | |||
1022 | mutex_lock(&fsl_ifc_nand_mutex); | ||
1023 | ifc_nand_ctrl->counter--; | ||
1024 | if (!ifc_nand_ctrl->counter) { | ||
1025 | fsl_ifc_ctrl_dev->nand = NULL; | ||
1026 | kfree(ifc_nand_ctrl); | ||
1027 | } | ||
1028 | mutex_unlock(&fsl_ifc_nand_mutex); | ||
1029 | |||
1030 | return 0; | ||
1031 | } | ||
1032 | |||
1033 | static const struct of_device_id fsl_ifc_nand_match[] = { | ||
1034 | { | ||
1035 | .compatible = "fsl,ifc-nand", | ||
1036 | }, | ||
1037 | {} | ||
1038 | }; | ||
1039 | |||
1040 | static struct platform_driver fsl_ifc_nand_driver = { | ||
1041 | .driver = { | ||
1042 | .name = "fsl,ifc-nand", | ||
1043 | .owner = THIS_MODULE, | ||
1044 | .of_match_table = fsl_ifc_nand_match, | ||
1045 | }, | ||
1046 | .probe = fsl_ifc_nand_probe, | ||
1047 | .remove = fsl_ifc_nand_remove, | ||
1048 | }; | ||
1049 | |||
1050 | static int __init fsl_ifc_nand_init(void) | ||
1051 | { | ||
1052 | int ret; | ||
1053 | |||
1054 | ret = platform_driver_register(&fsl_ifc_nand_driver); | ||
1055 | if (ret) | ||
1056 | printk(KERN_ERR "fsl-ifc: Failed to register platform" | ||
1057 | "driver\n"); | ||
1058 | |||
1059 | return ret; | ||
1060 | } | ||
1061 | |||
1062 | static void __exit fsl_ifc_nand_exit(void) | ||
1063 | { | ||
1064 | platform_driver_unregister(&fsl_ifc_nand_driver); | ||
1065 | } | ||
1066 | |||
1067 | module_init(fsl_ifc_nand_init); | ||
1068 | module_exit(fsl_ifc_nand_exit); | ||
1069 | |||
1070 | MODULE_LICENSE("GPL"); | ||
1071 | MODULE_AUTHOR("Freescale"); | ||
1072 | MODULE_DESCRIPTION("Freescale Integrated Flash Controller MTD NAND driver"); | ||
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c index c34dab17682e..e8ea7107932e 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c | |||
@@ -835,7 +835,7 @@ int gpmi_send_command(struct gpmi_nand_data *this) | |||
835 | | BM_GPMI_CTRL0_ADDRESS_INCREMENT | 835 | | BM_GPMI_CTRL0_ADDRESS_INCREMENT |
836 | | BF_GPMI_CTRL0_XFER_COUNT(this->command_length); | 836 | | BF_GPMI_CTRL0_XFER_COUNT(this->command_length); |
837 | pio[1] = pio[2] = 0; | 837 | pio[1] = pio[2] = 0; |
838 | desc = channel->device->device_prep_slave_sg(channel, | 838 | desc = dmaengine_prep_slave_sg(channel, |
839 | (struct scatterlist *)pio, | 839 | (struct scatterlist *)pio, |
840 | ARRAY_SIZE(pio), DMA_TRANS_NONE, 0); | 840 | ARRAY_SIZE(pio), DMA_TRANS_NONE, 0); |
841 | if (!desc) { | 841 | if (!desc) { |
@@ -848,7 +848,7 @@ int gpmi_send_command(struct gpmi_nand_data *this) | |||
848 | 848 | ||
849 | sg_init_one(sgl, this->cmd_buffer, this->command_length); | 849 | sg_init_one(sgl, this->cmd_buffer, this->command_length); |
850 | dma_map_sg(this->dev, sgl, 1, DMA_TO_DEVICE); | 850 | dma_map_sg(this->dev, sgl, 1, DMA_TO_DEVICE); |
851 | desc = channel->device->device_prep_slave_sg(channel, | 851 | desc = dmaengine_prep_slave_sg(channel, |
852 | sgl, 1, DMA_MEM_TO_DEV, | 852 | sgl, 1, DMA_MEM_TO_DEV, |
853 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 853 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
854 | 854 | ||
@@ -882,8 +882,7 @@ int gpmi_send_data(struct gpmi_nand_data *this) | |||
882 | | BF_GPMI_CTRL0_ADDRESS(address) | 882 | | BF_GPMI_CTRL0_ADDRESS(address) |
883 | | BF_GPMI_CTRL0_XFER_COUNT(this->upper_len); | 883 | | BF_GPMI_CTRL0_XFER_COUNT(this->upper_len); |
884 | pio[1] = 0; | 884 | pio[1] = 0; |
885 | desc = channel->device->device_prep_slave_sg(channel, | 885 | desc = dmaengine_prep_slave_sg(channel, (struct scatterlist *)pio, |
886 | (struct scatterlist *)pio, | ||
887 | ARRAY_SIZE(pio), DMA_TRANS_NONE, 0); | 886 | ARRAY_SIZE(pio), DMA_TRANS_NONE, 0); |
888 | if (!desc) { | 887 | if (!desc) { |
889 | pr_err("step 1 error\n"); | 888 | pr_err("step 1 error\n"); |
@@ -892,7 +891,7 @@ int gpmi_send_data(struct gpmi_nand_data *this) | |||
892 | 891 | ||
893 | /* [2] send DMA request */ | 892 | /* [2] send DMA request */ |
894 | prepare_data_dma(this, DMA_TO_DEVICE); | 893 | prepare_data_dma(this, DMA_TO_DEVICE); |
895 | desc = channel->device->device_prep_slave_sg(channel, &this->data_sgl, | 894 | desc = dmaengine_prep_slave_sg(channel, &this->data_sgl, |
896 | 1, DMA_MEM_TO_DEV, | 895 | 1, DMA_MEM_TO_DEV, |
897 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 896 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
898 | if (!desc) { | 897 | if (!desc) { |
@@ -919,7 +918,7 @@ int gpmi_read_data(struct gpmi_nand_data *this) | |||
919 | | BF_GPMI_CTRL0_ADDRESS(BV_GPMI_CTRL0_ADDRESS__NAND_DATA) | 918 | | BF_GPMI_CTRL0_ADDRESS(BV_GPMI_CTRL0_ADDRESS__NAND_DATA) |
920 | | BF_GPMI_CTRL0_XFER_COUNT(this->upper_len); | 919 | | BF_GPMI_CTRL0_XFER_COUNT(this->upper_len); |
921 | pio[1] = 0; | 920 | pio[1] = 0; |
922 | desc = channel->device->device_prep_slave_sg(channel, | 921 | desc = dmaengine_prep_slave_sg(channel, |
923 | (struct scatterlist *)pio, | 922 | (struct scatterlist *)pio, |
924 | ARRAY_SIZE(pio), DMA_TRANS_NONE, 0); | 923 | ARRAY_SIZE(pio), DMA_TRANS_NONE, 0); |
925 | if (!desc) { | 924 | if (!desc) { |
@@ -929,7 +928,7 @@ int gpmi_read_data(struct gpmi_nand_data *this) | |||
929 | 928 | ||
930 | /* [2] : send DMA request */ | 929 | /* [2] : send DMA request */ |
931 | prepare_data_dma(this, DMA_FROM_DEVICE); | 930 | prepare_data_dma(this, DMA_FROM_DEVICE); |
932 | desc = channel->device->device_prep_slave_sg(channel, &this->data_sgl, | 931 | desc = dmaengine_prep_slave_sg(channel, &this->data_sgl, |
933 | 1, DMA_DEV_TO_MEM, | 932 | 1, DMA_DEV_TO_MEM, |
934 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 933 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
935 | if (!desc) { | 934 | if (!desc) { |
@@ -976,7 +975,7 @@ int gpmi_send_page(struct gpmi_nand_data *this, | |||
976 | pio[4] = payload; | 975 | pio[4] = payload; |
977 | pio[5] = auxiliary; | 976 | pio[5] = auxiliary; |
978 | 977 | ||
979 | desc = channel->device->device_prep_slave_sg(channel, | 978 | desc = dmaengine_prep_slave_sg(channel, |
980 | (struct scatterlist *)pio, | 979 | (struct scatterlist *)pio, |
981 | ARRAY_SIZE(pio), DMA_TRANS_NONE, | 980 | ARRAY_SIZE(pio), DMA_TRANS_NONE, |
982 | DMA_CTRL_ACK); | 981 | DMA_CTRL_ACK); |
@@ -1012,7 +1011,7 @@ int gpmi_read_page(struct gpmi_nand_data *this, | |||
1012 | | BF_GPMI_CTRL0_ADDRESS(address) | 1011 | | BF_GPMI_CTRL0_ADDRESS(address) |
1013 | | BF_GPMI_CTRL0_XFER_COUNT(0); | 1012 | | BF_GPMI_CTRL0_XFER_COUNT(0); |
1014 | pio[1] = 0; | 1013 | pio[1] = 0; |
1015 | desc = channel->device->device_prep_slave_sg(channel, | 1014 | desc = dmaengine_prep_slave_sg(channel, |
1016 | (struct scatterlist *)pio, 2, | 1015 | (struct scatterlist *)pio, 2, |
1017 | DMA_TRANS_NONE, 0); | 1016 | DMA_TRANS_NONE, 0); |
1018 | if (!desc) { | 1017 | if (!desc) { |
@@ -1041,7 +1040,7 @@ int gpmi_read_page(struct gpmi_nand_data *this, | |||
1041 | pio[3] = geo->page_size; | 1040 | pio[3] = geo->page_size; |
1042 | pio[4] = payload; | 1041 | pio[4] = payload; |
1043 | pio[5] = auxiliary; | 1042 | pio[5] = auxiliary; |
1044 | desc = channel->device->device_prep_slave_sg(channel, | 1043 | desc = dmaengine_prep_slave_sg(channel, |
1045 | (struct scatterlist *)pio, | 1044 | (struct scatterlist *)pio, |
1046 | ARRAY_SIZE(pio), DMA_TRANS_NONE, | 1045 | ARRAY_SIZE(pio), DMA_TRANS_NONE, |
1047 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 1046 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
@@ -1062,7 +1061,7 @@ int gpmi_read_page(struct gpmi_nand_data *this, | |||
1062 | | BF_GPMI_CTRL0_XFER_COUNT(geo->page_size); | 1061 | | BF_GPMI_CTRL0_XFER_COUNT(geo->page_size); |
1063 | pio[1] = 0; | 1062 | pio[1] = 0; |
1064 | pio[2] = 0; /* clear GPMI_HW_GPMI_ECCCTRL, disable the BCH. */ | 1063 | pio[2] = 0; /* clear GPMI_HW_GPMI_ECCCTRL, disable the BCH. */ |
1065 | desc = channel->device->device_prep_slave_sg(channel, | 1064 | desc = dmaengine_prep_slave_sg(channel, |
1066 | (struct scatterlist *)pio, 3, | 1065 | (struct scatterlist *)pio, 3, |
1067 | DMA_TRANS_NONE, | 1066 | DMA_TRANS_NONE, |
1068 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 1067 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |