diff options
| author | Arnd Bergmann <arnd@arndb.de> | 2018-03-12 10:27:14 -0400 |
|---|---|---|
| committer | Arnd Bergmann <arnd@arndb.de> | 2018-03-12 10:27:14 -0400 |
| commit | fdda85f6969cadf4fda8c1eb15c1ac7ec8798bcd (patch) | |
| tree | cbb17c3c986fbf84df25c0cd4d3e63d9e9d46ba3 | |
| parent | 40590db64fabb35d9e19d66bd0880dda9631ab6a (diff) | |
| parent | 0b8129278fdc30fa3281f435db419ab2d610085b (diff) | |
Merge tag 'pxa-for-4.17' of https://github.com/rjarzmik/linux into next/soc
Pull "This is the pxa changes for v4.17 cycle" from Robert Jarzmik:
- minor changes for property API
- clock API fix for ULPI driver warning
It exceptionally contains a merge from the mtd tree from Boris
to prevent any merge conflicts in the PXA tree.
* tag 'pxa-for-4.17' of https://github.com/rjarzmik/linux:
ARM: pxa/raumfeld: use PROPERTY_ENTRY_U32() directly
ARM: pxa: ulpi: fix ulpi timeout and slowpath warn
ARM: pxa: cm-x300: remove inline directive
ARM: pxa: fix static checker warning in pxa3xx-ulpi
MAINTAINERS: remove entry for deleted pxa3xx_nand driver
arm: dts: pxa: use reworked NAND controller driver
dt-bindings: mtd: remove pxa3xx NAND controller documentation
mtd: nand: remove useless fields from pxa3xx NAND platform data
mtd: nand: remove deprecated pxa3xx_nand driver
mtd: nand: use Marvell reworked NAND controller driver with all platforms
| -rw-r--r-- | Documentation/devicetree/bindings/mtd/pxa3xx-nand.txt | 50 | ||||
| -rw-r--r-- | MAINTAINERS | 6 | ||||
| -rw-r--r-- | arch/arm/boot/dts/pxa3xx.dtsi | 6 | ||||
| -rw-r--r-- | arch/arm/configs/cm_x300_defconfig | 2 | ||||
| -rw-r--r-- | arch/arm/configs/pxa3xx_defconfig | 3 | ||||
| -rw-r--r-- | arch/arm/configs/pxa_defconfig | 2 | ||||
| -rw-r--r-- | arch/arm/configs/raumfeld_defconfig | 2 | ||||
| -rw-r--r-- | arch/arm/mach-mmp/aspenite.c | 6 | ||||
| -rw-r--r-- | arch/arm/mach-mmp/ttc_dkb.c | 9 | ||||
| -rw-r--r-- | arch/arm/mach-pxa/cm-x300.c | 14 | ||||
| -rw-r--r-- | arch/arm/mach-pxa/colibri-pxa3xx.c | 8 | ||||
| -rw-r--r-- | arch/arm/mach-pxa/colibri.h | 2 | ||||
| -rw-r--r-- | arch/arm/mach-pxa/littleton.c | 10 | ||||
| -rw-r--r-- | arch/arm/mach-pxa/mxm8x10.c | 10 | ||||
| -rw-r--r-- | arch/arm/mach-pxa/pxa3xx-ulpi.c | 6 | ||||
| -rw-r--r-- | arch/arm/mach-pxa/raumfeld.c | 12 | ||||
| -rw-r--r-- | arch/arm/mach-pxa/zylonite.c | 10 | ||||
| -rw-r--r-- | drivers/mtd/nand/Kconfig | 11 | ||||
| -rw-r--r-- | drivers/mtd/nand/Makefile | 1 | ||||
| -rw-r--r-- | drivers/mtd/nand/marvell_nand.c | 3 | ||||
| -rw-r--r-- | drivers/mtd/nand/pxa3xx_nand.c | 2105 | ||||
| -rw-r--r-- | include/linux/platform_data/mtd-nand-pxa3xx.h | 43 |
22 files changed, 55 insertions, 2266 deletions
diff --git a/Documentation/devicetree/bindings/mtd/pxa3xx-nand.txt b/Documentation/devicetree/bindings/mtd/pxa3xx-nand.txt deleted file mode 100644 index d4ee4da58463..000000000000 --- a/Documentation/devicetree/bindings/mtd/pxa3xx-nand.txt +++ /dev/null | |||
| @@ -1,50 +0,0 @@ | |||
| 1 | PXA3xx NAND DT bindings | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | |||
| 5 | - compatible: Should be set to one of the following: | ||
| 6 | marvell,pxa3xx-nand | ||
| 7 | marvell,armada370-nand | ||
| 8 | marvell,armada-8k-nand | ||
| 9 | - reg: The register base for the controller | ||
| 10 | - interrupts: The interrupt to map | ||
| 11 | - #address-cells: Set to <1> if the node includes partitions | ||
| 12 | - marvell,system-controller: Set to retrieve the syscon node that handles | ||
| 13 | NAND controller related registers (only required | ||
| 14 | with marvell,armada-8k-nand compatible). | ||
| 15 | |||
| 16 | Optional properties: | ||
| 17 | |||
| 18 | - dmas: dma data channel, see dma.txt binding doc | ||
| 19 | - marvell,nand-enable-arbiter: Set to enable the bus arbiter | ||
| 20 | - marvell,nand-keep-config: Set to keep the NAND controller config as set | ||
| 21 | by the bootloader | ||
| 22 | - num-cs: Number of chipselect lines to use | ||
| 23 | - nand-on-flash-bbt: boolean to enable on flash bbt option if | ||
| 24 | not present false | ||
| 25 | - nand-ecc-strength: number of bits to correct per ECC step | ||
| 26 | - nand-ecc-step-size: number of data bytes covered by a single ECC step | ||
| 27 | |||
| 28 | The following ECC strength and step size are currently supported: | ||
| 29 | |||
| 30 | - nand-ecc-strength = <1>, nand-ecc-step-size = <512> | ||
| 31 | - nand-ecc-strength = <4>, nand-ecc-step-size = <512> | ||
| 32 | - nand-ecc-strength = <8>, nand-ecc-step-size = <512> | ||
| 33 | |||
| 34 | Example: | ||
| 35 | |||
| 36 | nand0: nand@43100000 { | ||
| 37 | compatible = "marvell,pxa3xx-nand"; | ||
| 38 | reg = <0x43100000 90>; | ||
| 39 | interrupts = <45>; | ||
| 40 | dmas = <&pdma 97 0>; | ||
| 41 | dma-names = "data"; | ||
| 42 | #address-cells = <1>; | ||
| 43 | |||
| 44 | marvell,nand-enable-arbiter; | ||
| 45 | marvell,nand-keep-config; | ||
| 46 | num-cs = <1>; | ||
| 47 | |||
| 48 | /* partitions (optional) */ | ||
| 49 | }; | ||
| 50 | |||
diff --git a/MAINTAINERS b/MAINTAINERS index 5accf0863142..cc5f70e746b4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -11365,12 +11365,6 @@ F: include/sound/pxa2xx-lib.h | |||
| 11365 | F: sound/arm/pxa* | 11365 | F: sound/arm/pxa* |
| 11366 | F: sound/soc/pxa/ | 11366 | F: sound/soc/pxa/ |
| 11367 | 11367 | ||
| 11368 | PXA3xx NAND FLASH DRIVER | ||
| 11369 | M: Ezequiel Garcia <ezequiel.garcia@free-electrons.com> | ||
| 11370 | L: linux-mtd@lists.infradead.org | ||
| 11371 | S: Maintained | ||
| 11372 | F: drivers/mtd/nand/pxa3xx_nand.c | ||
| 11373 | |||
| 11374 | QAT DRIVER | 11368 | QAT DRIVER |
| 11375 | M: Giovanni Cabiddu <giovanni.cabiddu@intel.com> | 11369 | M: Giovanni Cabiddu <giovanni.cabiddu@intel.com> |
| 11376 | L: qat-linux@intel.com | 11370 | L: qat-linux@intel.com |
diff --git a/arch/arm/boot/dts/pxa3xx.dtsi b/arch/arm/boot/dts/pxa3xx.dtsi index 55c75b67351c..982d1a62661d 100644 --- a/arch/arm/boot/dts/pxa3xx.dtsi +++ b/arch/arm/boot/dts/pxa3xx.dtsi | |||
| @@ -117,15 +117,15 @@ | |||
| 117 | status = "disabled"; | 117 | status = "disabled"; |
| 118 | }; | 118 | }; |
| 119 | 119 | ||
| 120 | nand0: nand@43100000 { | 120 | nand_controller: nand-controller@43100000 { |
| 121 | compatible = "marvell,pxa3xx-nand"; | 121 | compatible = "marvell,pxa3xx-nand-controller"; |
| 122 | reg = <0x43100000 90>; | 122 | reg = <0x43100000 90>; |
| 123 | interrupts = <45>; | 123 | interrupts = <45>; |
| 124 | clocks = <&clks CLK_NAND>; | 124 | clocks = <&clks CLK_NAND>; |
| 125 | dmas = <&pdma 97 3>; | 125 | dmas = <&pdma 97 3>; |
| 126 | dma-names = "data"; | 126 | dma-names = "data"; |
| 127 | #address-cells = <1>; | 127 | #address-cells = <1>; |
| 128 | #size-cells = <1>; | 128 | #size-cells = <0>; |
| 129 | status = "disabled"; | 129 | status = "disabled"; |
| 130 | }; | 130 | }; |
| 131 | 131 | ||
diff --git a/arch/arm/configs/cm_x300_defconfig b/arch/arm/configs/cm_x300_defconfig index c0418e03d180..5e349c625b71 100644 --- a/arch/arm/configs/cm_x300_defconfig +++ b/arch/arm/configs/cm_x300_defconfig | |||
| @@ -49,7 +49,7 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | |||
| 49 | CONFIG_MTD=y | 49 | CONFIG_MTD=y |
| 50 | CONFIG_MTD_BLOCK=y | 50 | CONFIG_MTD_BLOCK=y |
| 51 | CONFIG_MTD_NAND=y | 51 | CONFIG_MTD_NAND=y |
| 52 | CONFIG_MTD_NAND_PXA3xx=y | 52 | CONFIG_MTD_NAND_MARVELL=y |
| 53 | CONFIG_MTD_UBI=y | 53 | CONFIG_MTD_UBI=y |
| 54 | CONFIG_BLK_DEV_LOOP=y | 54 | CONFIG_BLK_DEV_LOOP=y |
| 55 | CONFIG_BLK_DEV_RAM=y | 55 | CONFIG_BLK_DEV_RAM=y |
diff --git a/arch/arm/configs/pxa3xx_defconfig b/arch/arm/configs/pxa3xx_defconfig index bfea6874b0a1..3e0de035ab77 100644 --- a/arch/arm/configs/pxa3xx_defconfig +++ b/arch/arm/configs/pxa3xx_defconfig | |||
| @@ -32,8 +32,7 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | |||
| 32 | CONFIG_MTD=y | 32 | CONFIG_MTD=y |
| 33 | CONFIG_MTD_BLOCK=y | 33 | CONFIG_MTD_BLOCK=y |
| 34 | CONFIG_MTD_NAND=y | 34 | CONFIG_MTD_NAND=y |
| 35 | CONFIG_MTD_NAND_PXA3xx=y | 35 | CONFIG_MTD_NAND_MARVELL=y |
| 36 | CONFIG_MTD_NAND_PXA3xx_BUILTIN=y | ||
| 37 | CONFIG_MTD_ONENAND=y | 36 | CONFIG_MTD_ONENAND=y |
| 38 | CONFIG_MTD_ONENAND_VERIFY_WRITE=y | 37 | CONFIG_MTD_ONENAND_VERIFY_WRITE=y |
| 39 | CONFIG_MTD_ONENAND_GENERIC=y | 38 | CONFIG_MTD_ONENAND_GENERIC=y |
diff --git a/arch/arm/configs/pxa_defconfig b/arch/arm/configs/pxa_defconfig index 837d0c9c8b0e..5655a1cee87d 100644 --- a/arch/arm/configs/pxa_defconfig +++ b/arch/arm/configs/pxa_defconfig | |||
| @@ -197,7 +197,7 @@ CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0x4000000 | |||
| 197 | CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH=y | 197 | CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH=y |
| 198 | CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE=y | 198 | CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE=y |
| 199 | CONFIG_MTD_NAND_SHARPSL=m | 199 | CONFIG_MTD_NAND_SHARPSL=m |
| 200 | CONFIG_MTD_NAND_PXA3xx=m | 200 | CONFIG_MTD_NAND_MARVELL=m |
| 201 | CONFIG_MTD_NAND_CM_X270=m | 201 | CONFIG_MTD_NAND_CM_X270=m |
| 202 | CONFIG_MTD_NAND_TMIO=m | 202 | CONFIG_MTD_NAND_TMIO=m |
| 203 | CONFIG_MTD_NAND_BRCMNAND=m | 203 | CONFIG_MTD_NAND_BRCMNAND=m |
diff --git a/arch/arm/configs/raumfeld_defconfig b/arch/arm/configs/raumfeld_defconfig index 77a56c23c6ef..2dd56e9a484e 100644 --- a/arch/arm/configs/raumfeld_defconfig +++ b/arch/arm/configs/raumfeld_defconfig | |||
| @@ -33,7 +33,7 @@ CONFIG_NFTL=y | |||
| 33 | CONFIG_NFTL_RW=y | 33 | CONFIG_NFTL_RW=y |
| 34 | CONFIG_MTD_BLOCK2MTD=y | 34 | CONFIG_MTD_BLOCK2MTD=y |
| 35 | CONFIG_MTD_NAND=y | 35 | CONFIG_MTD_NAND=y |
| 36 | CONFIG_MTD_NAND_PXA3xx=y | 36 | CONFIG_MTD_NAND_MARVELL=y |
| 37 | CONFIG_MTD_UBI=y | 37 | CONFIG_MTD_UBI=y |
| 38 | CONFIG_BLK_DEV_LOOP=y | 38 | CONFIG_BLK_DEV_LOOP=y |
| 39 | CONFIG_ISL29003=y | 39 | CONFIG_ISL29003=y |
diff --git a/arch/arm/mach-mmp/aspenite.c b/arch/arm/mach-mmp/aspenite.c index d2283009a5ff..6c2ebf01893a 100644 --- a/arch/arm/mach-mmp/aspenite.c +++ b/arch/arm/mach-mmp/aspenite.c | |||
| @@ -172,10 +172,8 @@ static struct mtd_partition aspenite_nand_partitions[] = { | |||
| 172 | }; | 172 | }; |
| 173 | 173 | ||
| 174 | static struct pxa3xx_nand_platform_data aspenite_nand_info = { | 174 | static struct pxa3xx_nand_platform_data aspenite_nand_info = { |
| 175 | .enable_arbiter = 1, | 175 | .parts = aspenite_nand_partitions, |
| 176 | .num_cs = 1, | 176 | .nr_parts = ARRAY_SIZE(aspenite_nand_partitions), |
| 177 | .parts[0] = aspenite_nand_partitions, | ||
| 178 | .nr_parts[0] = ARRAY_SIZE(aspenite_nand_partitions), | ||
| 179 | }; | 177 | }; |
| 180 | 178 | ||
| 181 | static struct i2c_board_info aspenite_i2c_info[] __initdata = { | 179 | static struct i2c_board_info aspenite_i2c_info[] __initdata = { |
diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c index d90c74fa614d..c7897fb2b6da 100644 --- a/arch/arm/mach-mmp/ttc_dkb.c +++ b/arch/arm/mach-mmp/ttc_dkb.c | |||
| @@ -178,11 +178,8 @@ static struct mv_usb_platform_data ttc_usb_pdata = { | |||
| 178 | #endif | 178 | #endif |
| 179 | #endif | 179 | #endif |
| 180 | 180 | ||
| 181 | #if IS_ENABLED(CONFIG_MTD_NAND_PXA3xx) | 181 | #if IS_ENABLED(CONFIG_MTD_NAND_MARVELL) |
| 182 | static struct pxa3xx_nand_platform_data dkb_nand_info = { | 182 | static struct pxa3xx_nand_platform_data dkb_nand_info = {}; |
| 183 | .enable_arbiter = 1, | ||
| 184 | .num_cs = 1, | ||
| 185 | }; | ||
| 186 | #endif | 183 | #endif |
| 187 | 184 | ||
| 188 | #if IS_ENABLED(CONFIG_MMP_DISP) | 185 | #if IS_ENABLED(CONFIG_MMP_DISP) |
| @@ -275,7 +272,7 @@ static void __init ttc_dkb_init(void) | |||
| 275 | 272 | ||
| 276 | /* on-chip devices */ | 273 | /* on-chip devices */ |
| 277 | pxa910_add_uart(1); | 274 | pxa910_add_uart(1); |
| 278 | #if IS_ENABLED(CONFIG_MTD_NAND_PXA3xx) | 275 | #if IS_ENABLED(CONFIG_MTD_NAND_MARVELL) |
| 279 | pxa910_add_nand(&dkb_nand_info); | 276 | pxa910_add_nand(&dkb_nand_info); |
| 280 | #endif | 277 | #endif |
| 281 | 278 | ||
diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c index c487401b6fdb..0b850237597b 100644 --- a/arch/arm/mach-pxa/cm-x300.c +++ b/arch/arm/mach-pxa/cm-x300.c | |||
| @@ -391,7 +391,7 @@ static void __init cm_x300_init_ac97(void) | |||
| 391 | static inline void cm_x300_init_ac97(void) {} | 391 | static inline void cm_x300_init_ac97(void) {} |
| 392 | #endif | 392 | #endif |
| 393 | 393 | ||
| 394 | #if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE) | 394 | #if IS_ENABLED(CONFIG_MTD_NAND_MARVELL) |
| 395 | static struct mtd_partition cm_x300_nand_partitions[] = { | 395 | static struct mtd_partition cm_x300_nand_partitions[] = { |
| 396 | [0] = { | 396 | [0] = { |
| 397 | .name = "OBM", | 397 | .name = "OBM", |
| @@ -429,11 +429,9 @@ static struct mtd_partition cm_x300_nand_partitions[] = { | |||
| 429 | }; | 429 | }; |
| 430 | 430 | ||
| 431 | static struct pxa3xx_nand_platform_data cm_x300_nand_info = { | 431 | static struct pxa3xx_nand_platform_data cm_x300_nand_info = { |
| 432 | .enable_arbiter = 1, | ||
| 433 | .keep_config = 1, | 432 | .keep_config = 1, |
| 434 | .num_cs = 1, | 433 | .parts = cm_x300_nand_partitions, |
| 435 | .parts[0] = cm_x300_nand_partitions, | 434 | .nr_parts = ARRAY_SIZE(cm_x300_nand_partitions), |
| 436 | .nr_parts[0] = ARRAY_SIZE(cm_x300_nand_partitions), | ||
| 437 | }; | 435 | }; |
| 438 | 436 | ||
| 439 | static void __init cm_x300_init_nand(void) | 437 | static void __init cm_x300_init_nand(void) |
| @@ -509,7 +507,7 @@ static int cm_x300_ulpi_phy_reset(void) | |||
| 509 | return 0; | 507 | return 0; |
| 510 | } | 508 | } |
| 511 | 509 | ||
| 512 | static inline int cm_x300_u2d_init(struct device *dev) | 510 | static int cm_x300_u2d_init(struct device *dev) |
| 513 | { | 511 | { |
| 514 | int err = 0; | 512 | int err = 0; |
| 515 | 513 | ||
| @@ -521,7 +519,7 @@ static inline int cm_x300_u2d_init(struct device *dev) | |||
| 521 | pr_err("failed to get CLK_POUT: %d\n", err); | 519 | pr_err("failed to get CLK_POUT: %d\n", err); |
| 522 | return err; | 520 | return err; |
| 523 | } | 521 | } |
| 524 | clk_enable(pout_clk); | 522 | clk_prepare_enable(pout_clk); |
| 525 | 523 | ||
| 526 | err = cm_x300_ulpi_phy_reset(); | 524 | err = cm_x300_ulpi_phy_reset(); |
| 527 | if (err) { | 525 | if (err) { |
| @@ -536,7 +534,7 @@ static inline int cm_x300_u2d_init(struct device *dev) | |||
| 536 | static void cm_x300_u2d_exit(struct device *dev) | 534 | static void cm_x300_u2d_exit(struct device *dev) |
| 537 | { | 535 | { |
| 538 | if (cpu_is_pxa310()) { | 536 | if (cpu_is_pxa310()) { |
| 539 | clk_disable(pout_clk); | 537 | clk_disable_unprepare(pout_clk); |
| 540 | clk_put(pout_clk); | 538 | clk_put(pout_clk); |
| 541 | } | 539 | } |
| 542 | } | 540 | } |
diff --git a/arch/arm/mach-pxa/colibri-pxa3xx.c b/arch/arm/mach-pxa/colibri-pxa3xx.c index b04431bb4ba7..e31a591e949f 100644 --- a/arch/arm/mach-pxa/colibri-pxa3xx.c +++ b/arch/arm/mach-pxa/colibri-pxa3xx.c | |||
| @@ -110,7 +110,7 @@ void __init colibri_pxa3xx_init_lcd(int bl_pin) | |||
| 110 | } | 110 | } |
| 111 | #endif | 111 | #endif |
| 112 | 112 | ||
| 113 | #if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE) | 113 | #if IS_ENABLED(CONFIG_MTD_NAND_MARVELL) |
| 114 | static struct mtd_partition colibri_nand_partitions[] = { | 114 | static struct mtd_partition colibri_nand_partitions[] = { |
| 115 | { | 115 | { |
| 116 | .name = "bootloader", | 116 | .name = "bootloader", |
| @@ -138,11 +138,9 @@ static struct mtd_partition colibri_nand_partitions[] = { | |||
| 138 | }; | 138 | }; |
| 139 | 139 | ||
| 140 | static struct pxa3xx_nand_platform_data colibri_nand_info = { | 140 | static struct pxa3xx_nand_platform_data colibri_nand_info = { |
| 141 | .enable_arbiter = 1, | ||
| 142 | .keep_config = 1, | 141 | .keep_config = 1, |
| 143 | .num_cs = 1, | 142 | .parts = colibri_nand_partitions, |
| 144 | .parts[0] = colibri_nand_partitions, | 143 | .nr_parts = ARRAY_SIZE(colibri_nand_partitions), |
| 145 | .nr_parts[0] = ARRAY_SIZE(colibri_nand_partitions), | ||
| 146 | }; | 144 | }; |
| 147 | 145 | ||
| 148 | void __init colibri_pxa3xx_init_nand(void) | 146 | void __init colibri_pxa3xx_init_nand(void) |
diff --git a/arch/arm/mach-pxa/colibri.h b/arch/arm/mach-pxa/colibri.h index 673a131da875..85525d49e321 100644 --- a/arch/arm/mach-pxa/colibri.h +++ b/arch/arm/mach-pxa/colibri.h | |||
| @@ -46,7 +46,7 @@ static inline void colibri_pxa3xx_init_lcd(int bl_pin) {} | |||
| 46 | extern void colibri_pxa3xx_init_eth(struct ax_plat_data *plat_data); | 46 | extern void colibri_pxa3xx_init_eth(struct ax_plat_data *plat_data); |
| 47 | #endif | 47 | #endif |
| 48 | 48 | ||
| 49 | #if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE) | 49 | #if IS_ENABLED(CONFIG_MTD_NAND_MARVELL) |
| 50 | extern void colibri_pxa3xx_init_nand(void); | 50 | extern void colibri_pxa3xx_init_nand(void); |
| 51 | #else | 51 | #else |
| 52 | static inline void colibri_pxa3xx_init_nand(void) {} | 52 | static inline void colibri_pxa3xx_init_nand(void) {} |
diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c index 4105614cc38e..9e132b3e48c6 100644 --- a/arch/arm/mach-pxa/littleton.c +++ b/arch/arm/mach-pxa/littleton.c | |||
| @@ -291,7 +291,7 @@ static void __init littleton_init_mmc(void) | |||
| 291 | static inline void littleton_init_mmc(void) {} | 291 | static inline void littleton_init_mmc(void) {} |
| 292 | #endif | 292 | #endif |
| 293 | 293 | ||
| 294 | #if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE) | 294 | #if IS_ENABLED(CONFIG_MTD_NAND_MARVELL) |
| 295 | static struct mtd_partition littleton_nand_partitions[] = { | 295 | static struct mtd_partition littleton_nand_partitions[] = { |
| 296 | [0] = { | 296 | [0] = { |
| 297 | .name = "Bootloader", | 297 | .name = "Bootloader", |
| @@ -329,10 +329,8 @@ static struct mtd_partition littleton_nand_partitions[] = { | |||
| 329 | }; | 329 | }; |
| 330 | 330 | ||
| 331 | static struct pxa3xx_nand_platform_data littleton_nand_info = { | 331 | static struct pxa3xx_nand_platform_data littleton_nand_info = { |
| 332 | .enable_arbiter = 1, | 332 | .parts = littleton_nand_partitions, |
| 333 | .num_cs = 1, | 333 | .nr_parts = ARRAY_SIZE(littleton_nand_partitions), |
| 334 | .parts[0] = littleton_nand_partitions, | ||
| 335 | .nr_parts[0] = ARRAY_SIZE(littleton_nand_partitions), | ||
| 336 | }; | 334 | }; |
| 337 | 335 | ||
| 338 | static void __init littleton_init_nand(void) | 336 | static void __init littleton_init_nand(void) |
| @@ -341,7 +339,7 @@ static void __init littleton_init_nand(void) | |||
| 341 | } | 339 | } |
| 342 | #else | 340 | #else |
| 343 | static inline void littleton_init_nand(void) {} | 341 | static inline void littleton_init_nand(void) {} |
| 344 | #endif /* CONFIG_MTD_NAND_PXA3xx || CONFIG_MTD_NAND_PXA3xx_MODULE */ | 342 | #endif /* IS_ENABLED(CONFIG_MTD_NAND_MARVELL) */ |
| 345 | 343 | ||
| 346 | #if defined(CONFIG_I2C_PXA) || defined(CONFIG_I2C_PXA_MODULE) | 344 | #if defined(CONFIG_I2C_PXA) || defined(CONFIG_I2C_PXA_MODULE) |
| 347 | static struct led_info littleton_da9034_leds[] = { | 345 | static struct led_info littleton_da9034_leds[] = { |
diff --git a/arch/arm/mach-pxa/mxm8x10.c b/arch/arm/mach-pxa/mxm8x10.c index f9e3d41a4609..616b22397d73 100644 --- a/arch/arm/mach-pxa/mxm8x10.c +++ b/arch/arm/mach-pxa/mxm8x10.c | |||
| @@ -359,7 +359,7 @@ void __init mxm_8x10_ac97_init(void) | |||
| 359 | } | 359 | } |
| 360 | 360 | ||
| 361 | /* NAND flash Support */ | 361 | /* NAND flash Support */ |
| 362 | #if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE) | 362 | #if IS_ENABLED(CONFIG_MTD_NAND_MARVELL) |
| 363 | #define NAND_BLOCK_SIZE SZ_128K | 363 | #define NAND_BLOCK_SIZE SZ_128K |
| 364 | #define NB(x) (NAND_BLOCK_SIZE * (x)) | 364 | #define NB(x) (NAND_BLOCK_SIZE * (x)) |
| 365 | static struct mtd_partition mxm_8x10_nand_partitions[] = { | 365 | static struct mtd_partition mxm_8x10_nand_partitions[] = { |
| @@ -389,11 +389,9 @@ static struct mtd_partition mxm_8x10_nand_partitions[] = { | |||
| 389 | }; | 389 | }; |
| 390 | 390 | ||
| 391 | static struct pxa3xx_nand_platform_data mxm_8x10_nand_info = { | 391 | static struct pxa3xx_nand_platform_data mxm_8x10_nand_info = { |
| 392 | .enable_arbiter = 1, | ||
| 393 | .keep_config = 1, | 392 | .keep_config = 1, |
| 394 | .num_cs = 1, | 393 | .parts = mxm_8x10_nand_partitions, |
| 395 | .parts[0] = mxm_8x10_nand_partitions, | 394 | .nr_parts = ARRAY_SIZE(mxm_8x10_nand_partitions) |
| 396 | .nr_parts[0] = ARRAY_SIZE(mxm_8x10_nand_partitions) | ||
| 397 | }; | 395 | }; |
| 398 | 396 | ||
| 399 | static void __init mxm_8x10_nand_init(void) | 397 | static void __init mxm_8x10_nand_init(void) |
| @@ -402,7 +400,7 @@ static void __init mxm_8x10_nand_init(void) | |||
| 402 | } | 400 | } |
| 403 | #else | 401 | #else |
| 404 | static inline void mxm_8x10_nand_init(void) {} | 402 | static inline void mxm_8x10_nand_init(void) {} |
| 405 | #endif /* CONFIG_MTD_NAND_PXA3xx || CONFIG_MTD_NAND_PXA3xx_MODULE */ | 403 | #endif /* IS_ENABLED(CONFIG_MTD_NAND_MARVELL) */ |
| 406 | 404 | ||
| 407 | /* Ethernet support: Davicom DM9000 */ | 405 | /* Ethernet support: Davicom DM9000 */ |
| 408 | static struct resource dm9k_resources[] = { | 406 | static struct resource dm9k_resources[] = { |
diff --git a/arch/arm/mach-pxa/pxa3xx-ulpi.c b/arch/arm/mach-pxa/pxa3xx-ulpi.c index 60cb59a7ebd1..b3e2016f24b1 100644 --- a/arch/arm/mach-pxa/pxa3xx-ulpi.c +++ b/arch/arm/mach-pxa/pxa3xx-ulpi.c | |||
| @@ -256,7 +256,7 @@ int pxa3xx_u2d_start_hc(struct usb_bus *host) | |||
| 256 | if (!u2d) | 256 | if (!u2d) |
| 257 | return 0; | 257 | return 0; |
| 258 | 258 | ||
| 259 | clk_enable(u2d->clk); | 259 | clk_prepare_enable(u2d->clk); |
| 260 | 260 | ||
| 261 | if (cpu_is_pxa310()) { | 261 | if (cpu_is_pxa310()) { |
| 262 | pxa310_u2d_setup_otg_hc(); | 262 | pxa310_u2d_setup_otg_hc(); |
| @@ -276,7 +276,7 @@ void pxa3xx_u2d_stop_hc(struct usb_bus *host) | |||
| 276 | if (cpu_is_pxa310()) | 276 | if (cpu_is_pxa310()) |
| 277 | pxa310_stop_otg_hc(); | 277 | pxa310_stop_otg_hc(); |
| 278 | 278 | ||
| 279 | clk_disable(u2d->clk); | 279 | clk_disable_unprepare(u2d->clk); |
| 280 | } | 280 | } |
| 281 | EXPORT_SYMBOL_GPL(pxa3xx_u2d_stop_hc); | 281 | EXPORT_SYMBOL_GPL(pxa3xx_u2d_stop_hc); |
| 282 | 282 | ||
| @@ -331,7 +331,7 @@ static int pxa3xx_u2d_probe(struct platform_device *pdev) | |||
| 331 | goto err_free_plat; | 331 | goto err_free_plat; |
| 332 | } | 332 | } |
| 333 | 333 | ||
| 334 | platform_set_drvdata(pdev, &u2d); | 334 | platform_set_drvdata(pdev, u2d); |
| 335 | 335 | ||
| 336 | return 0; | 336 | return 0; |
| 337 | 337 | ||
diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c index 4d5d05cf87d6..fd0283a3d093 100644 --- a/arch/arm/mach-pxa/raumfeld.c +++ b/arch/arm/mach-pxa/raumfeld.c | |||
| @@ -346,11 +346,9 @@ static struct mtd_partition raumfeld_nand_partitions[] = { | |||
| 346 | }; | 346 | }; |
| 347 | 347 | ||
| 348 | static struct pxa3xx_nand_platform_data raumfeld_nand_info = { | 348 | static struct pxa3xx_nand_platform_data raumfeld_nand_info = { |
| 349 | .enable_arbiter = 1, | ||
| 350 | .keep_config = 1, | 349 | .keep_config = 1, |
| 351 | .num_cs = 1, | 350 | .parts = raumfeld_nand_partitions, |
| 352 | .parts[0] = raumfeld_nand_partitions, | 351 | .nr_parts = ARRAY_SIZE(raumfeld_nand_partitions), |
| 353 | .nr_parts[0] = ARRAY_SIZE(raumfeld_nand_partitions), | ||
| 354 | }; | 352 | }; |
| 355 | 353 | ||
| 356 | /** | 354 | /** |
| @@ -378,9 +376,9 @@ static struct gpiod_lookup_table raumfeld_rotary_gpios_table = { | |||
| 378 | }; | 376 | }; |
| 379 | 377 | ||
| 380 | static const struct property_entry raumfeld_rotary_properties[] __initconst = { | 378 | static const struct property_entry raumfeld_rotary_properties[] __initconst = { |
| 381 | PROPERTY_ENTRY_INTEGER("rotary-encoder,steps-per-period", u32, 24), | 379 | PROPERTY_ENTRY_U32("rotary-encoder,steps-per-period", 24), |
| 382 | PROPERTY_ENTRY_INTEGER("linux,axis", u32, REL_X), | 380 | PROPERTY_ENTRY_U32("linux,axis", REL_X), |
| 383 | PROPERTY_ENTRY_INTEGER("rotary-encoder,relative_axis", u32, 1), | 381 | PROPERTY_ENTRY_U32("rotary-encoder,relative_axis", 1), |
| 384 | { }, | 382 | { }, |
| 385 | }; | 383 | }; |
| 386 | 384 | ||
diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c index 4268552d600d..d69de312d8d9 100644 --- a/arch/arm/mach-pxa/zylonite.c +++ b/arch/arm/mach-pxa/zylonite.c | |||
| @@ -338,7 +338,7 @@ static void __init zylonite_init_keypad(void) | |||
| 338 | static inline void zylonite_init_keypad(void) {} | 338 | static inline void zylonite_init_keypad(void) {} |
| 339 | #endif | 339 | #endif |
| 340 | 340 | ||
| 341 | #if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE) | 341 | #if IS_ENABLED(CONFIG_MTD_NAND_MARVELL) |
| 342 | static struct mtd_partition zylonite_nand_partitions[] = { | 342 | static struct mtd_partition zylonite_nand_partitions[] = { |
| 343 | [0] = { | 343 | [0] = { |
| 344 | .name = "Bootloader", | 344 | .name = "Bootloader", |
| @@ -376,10 +376,8 @@ static struct mtd_partition zylonite_nand_partitions[] = { | |||
| 376 | }; | 376 | }; |
| 377 | 377 | ||
| 378 | static struct pxa3xx_nand_platform_data zylonite_nand_info = { | 378 | static struct pxa3xx_nand_platform_data zylonite_nand_info = { |
| 379 | .enable_arbiter = 1, | 379 | .parts = zylonite_nand_partitions, |
| 380 | .num_cs = 1, | 380 | .nr_parts = ARRAY_SIZE(zylonite_nand_partitions), |
| 381 | .parts[0] = zylonite_nand_partitions, | ||
| 382 | .nr_parts[0] = ARRAY_SIZE(zylonite_nand_partitions), | ||
| 383 | }; | 381 | }; |
| 384 | 382 | ||
| 385 | static void __init zylonite_init_nand(void) | 383 | static void __init zylonite_init_nand(void) |
| @@ -388,7 +386,7 @@ static void __init zylonite_init_nand(void) | |||
| 388 | } | 386 | } |
| 389 | #else | 387 | #else |
| 390 | static inline void zylonite_init_nand(void) {} | 388 | static inline void zylonite_init_nand(void) {} |
| 391 | #endif /* CONFIG_MTD_NAND_PXA3xx || CONFIG_MTD_NAND_PXA3xx_MODULE */ | 389 | #endif /* IS_ENABLED(CONFIG_MTD_NAND_MARVELL) */ |
| 392 | 390 | ||
| 393 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) | 391 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) |
| 394 | static struct pxaohci_platform_data zylonite_ohci_info = { | 392 | static struct pxaohci_platform_data zylonite_ohci_info = { |
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 736ac887303c..605ec8cce67b 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig | |||
| @@ -313,17 +313,6 @@ config MTD_NAND_ATMEL | |||
| 313 | Enables support for NAND Flash / Smart Media Card interface | 313 | Enables support for NAND Flash / Smart Media Card interface |
| 314 | on Atmel AT91 processors. | 314 | on Atmel AT91 processors. |
| 315 | 315 | ||
| 316 | config MTD_NAND_PXA3xx | ||
| 317 | tristate "NAND support on PXA3xx and Armada 370/XP" | ||
| 318 | depends on !MTD_NAND_MARVELL | ||
| 319 | depends on PXA3xx || ARCH_MMP || PLAT_ORION || ARCH_MVEBU | ||
| 320 | help | ||
| 321 | |||
| 322 | This enables the driver for the NAND flash device found on | ||
| 323 | PXA3xx processors (NFCv1) and also on 32-bit Armada | ||
| 324 | platforms (XP, 370, 375, 38x, 39x) and 64-bit Armada | ||
| 325 | platforms (7K, 8K) (NFCv2). | ||
| 326 | |||
| 327 | config MTD_NAND_MARVELL | 316 | config MTD_NAND_MARVELL |
| 328 | tristate "NAND controller support on Marvell boards" | 317 | tristate "NAND controller support on Marvell boards" |
| 329 | depends on PXA3xx || ARCH_MMP || PLAT_ORION || ARCH_MVEBU || \ | 318 | depends on PXA3xx || ARCH_MMP || PLAT_ORION || ARCH_MVEBU || \ |
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 921634ba400c..c882d5ef192a 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile | |||
| @@ -31,7 +31,6 @@ omap2_nand-objs := omap2.o | |||
| 31 | obj-$(CONFIG_MTD_NAND_OMAP2) += omap2_nand.o | 31 | obj-$(CONFIG_MTD_NAND_OMAP2) += omap2_nand.o |
| 32 | obj-$(CONFIG_MTD_NAND_OMAP_BCH_BUILD) += omap_elm.o | 32 | obj-$(CONFIG_MTD_NAND_OMAP_BCH_BUILD) += omap_elm.o |
| 33 | obj-$(CONFIG_MTD_NAND_CM_X270) += cmx270_nand.o | 33 | obj-$(CONFIG_MTD_NAND_CM_X270) += cmx270_nand.o |
| 34 | obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o | ||
| 35 | obj-$(CONFIG_MTD_NAND_MARVELL) += marvell_nand.o | 34 | obj-$(CONFIG_MTD_NAND_MARVELL) += marvell_nand.o |
| 36 | obj-$(CONFIG_MTD_NAND_TMIO) += tmio_nand.o | 35 | obj-$(CONFIG_MTD_NAND_TMIO) += tmio_nand.o |
| 37 | obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o | 36 | obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o |
diff --git a/drivers/mtd/nand/marvell_nand.c b/drivers/mtd/nand/marvell_nand.c index 2196f2a233d6..03805f9669da 100644 --- a/drivers/mtd/nand/marvell_nand.c +++ b/drivers/mtd/nand/marvell_nand.c | |||
| @@ -2520,8 +2520,7 @@ static int marvell_nand_chip_init(struct device *dev, struct marvell_nfc *nfc, | |||
| 2520 | 2520 | ||
| 2521 | if (pdata) | 2521 | if (pdata) |
| 2522 | /* Legacy bindings support only one chip */ | 2522 | /* Legacy bindings support only one chip */ |
| 2523 | ret = mtd_device_register(mtd, pdata->parts[0], | 2523 | ret = mtd_device_register(mtd, pdata->parts, pdata->nr_parts); |
| 2524 | pdata->nr_parts[0]); | ||
| 2525 | else | 2524 | else |
| 2526 | ret = mtd_device_register(mtd, NULL, 0); | 2525 | ret = mtd_device_register(mtd, NULL, 0); |
| 2527 | if (ret) { | 2526 | if (ret) { |
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c deleted file mode 100644 index d1979c7dbe7e..000000000000 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ /dev/null | |||
| @@ -1,2105 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * drivers/mtd/nand/pxa3xx_nand.c | ||
| 3 | * | ||
| 4 | * Copyright © 2005 Intel Corporation | ||
| 5 | * Copyright © 2006 Marvell International Ltd. | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License version 2 as | ||
| 9 | * published by the Free Software Foundation. | ||
| 10 | * | ||
| 11 | * See Documentation/mtd/nand/pxa3xx-nand.txt for more details. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/module.h> | ||
| 16 | #include <linux/interrupt.h> | ||
| 17 | #include <linux/platform_device.h> | ||
| 18 | #include <linux/dmaengine.h> | ||
| 19 | #include <linux/dma-mapping.h> | ||
| 20 | #include <linux/dma/pxa-dma.h> | ||
| 21 | #include <linux/delay.h> | ||
| 22 | #include <linux/clk.h> | ||
| 23 | #include <linux/mtd/mtd.h> | ||
| 24 | #include <linux/mtd/rawnand.h> | ||
| 25 | #include <linux/mtd/partitions.h> | ||
| 26 | #include <linux/io.h> | ||
| 27 | #include <linux/iopoll.h> | ||
| 28 | #include <linux/irq.h> | ||
| 29 | #include <linux/slab.h> | ||
| 30 | #include <linux/of.h> | ||
| 31 | #include <linux/of_device.h> | ||
| 32 | #include <linux/platform_data/mtd-nand-pxa3xx.h> | ||
| 33 | #include <linux/mfd/syscon.h> | ||
| 34 | #include <linux/regmap.h> | ||
| 35 | |||
| 36 | #define CHIP_DELAY_TIMEOUT msecs_to_jiffies(200) | ||
| 37 | #define NAND_STOP_DELAY msecs_to_jiffies(40) | ||
| 38 | #define PAGE_CHUNK_SIZE (2048) | ||
| 39 | |||
| 40 | /* | ||
| 41 | * Define a buffer size for the initial command that detects the flash device: | ||
| 42 | * STATUS, READID and PARAM. | ||
| 43 | * ONFI param page is 256 bytes, and there are three redundant copies | ||
| 44 | * to be read. JEDEC param page is 512 bytes, and there are also three | ||
| 45 | * redundant copies to be read. | ||
| 46 | * Hence this buffer should be at least 512 x 3. Let's pick 2048. | ||
| 47 | */ | ||
| 48 | #define INIT_BUFFER_SIZE 2048 | ||
| 49 | |||
| 50 | /* System control register and bit to enable NAND on some SoCs */ | ||
| 51 | #define GENCONF_SOC_DEVICE_MUX 0x208 | ||
| 52 | #define GENCONF_SOC_DEVICE_MUX_NFC_EN BIT(0) | ||
| 53 | |||
| 54 | /* registers and bit definitions */ | ||
| 55 | #define NDCR (0x00) /* Control register */ | ||
| 56 | #define NDTR0CS0 (0x04) /* Timing Parameter 0 for CS0 */ | ||
| 57 | #define NDTR1CS0 (0x0C) /* Timing Parameter 1 for CS0 */ | ||
| 58 | #define NDSR (0x14) /* Status Register */ | ||
| 59 | #define NDPCR (0x18) /* Page Count Register */ | ||
| 60 | #define NDBDR0 (0x1C) /* Bad Block Register 0 */ | ||
| 61 | #define NDBDR1 (0x20) /* Bad Block Register 1 */ | ||
| 62 | #define NDECCCTRL (0x28) /* ECC control */ | ||
| 63 | #define NDDB (0x40) /* Data Buffer */ | ||
| 64 | #define NDCB0 (0x48) /* Command Buffer0 */ | ||
| 65 | #define NDCB1 (0x4C) /* Command Buffer1 */ | ||
| 66 | #define NDCB2 (0x50) /* Command Buffer2 */ | ||
| 67 | |||
| 68 | #define NDCR_SPARE_EN (0x1 << 31) | ||
| 69 | #define NDCR_ECC_EN (0x1 << 30) | ||
| 70 | #define NDCR_DMA_EN (0x1 << 29) | ||
| 71 | #define NDCR_ND_RUN (0x1 << 28) | ||
| 72 | #define NDCR_DWIDTH_C (0x1 << 27) | ||
| 73 | #define NDCR_DWIDTH_M (0x1 << 26) | ||
| 74 | #define NDCR_PAGE_SZ (0x1 << 24) | ||
| 75 | #define NDCR_NCSX (0x1 << 23) | ||
| 76 | #define NDCR_ND_MODE (0x3 << 21) | ||
| 77 | #define NDCR_NAND_MODE (0x0) | ||
| 78 | #define NDCR_CLR_PG_CNT (0x1 << 20) | ||
| 79 | #define NFCV1_NDCR_ARB_CNTL (0x1 << 19) | ||
| 80 | #define NFCV2_NDCR_STOP_ON_UNCOR (0x1 << 19) | ||
| 81 | #define NDCR_RD_ID_CNT_MASK (0x7 << 16) | ||
| 82 | #define NDCR_RD_ID_CNT(x) (((x) << 16) & NDCR_RD_ID_CNT_MASK) | ||
| 83 | |||
| 84 | #define NDCR_RA_START (0x1 << 15) | ||
| 85 | #define NDCR_PG_PER_BLK (0x1 << 14) | ||
| 86 | #define NDCR_ND_ARB_EN (0x1 << 12) | ||
| 87 | #define NDCR_INT_MASK (0xFFF) | ||
| 88 | |||
| 89 | #define NDSR_MASK (0xfff) | ||
| 90 | #define NDSR_ERR_CNT_OFF (16) | ||
| 91 | #define NDSR_ERR_CNT_MASK (0x1f) | ||
| 92 | #define NDSR_ERR_CNT(sr) ((sr >> NDSR_ERR_CNT_OFF) & NDSR_ERR_CNT_MASK) | ||
| 93 | #define NDSR_RDY (0x1 << 12) | ||
| 94 | #define NDSR_FLASH_RDY (0x1 << 11) | ||
| 95 | #define NDSR_CS0_PAGED (0x1 << 10) | ||
| 96 | #define NDSR_CS1_PAGED (0x1 << 9) | ||
| 97 | #define NDSR_CS0_CMDD (0x1 << 8) | ||
| 98 | #define NDSR_CS1_CMDD (0x1 << 7) | ||
| 99 | #define NDSR_CS0_BBD (0x1 << 6) | ||
| 100 | #define NDSR_CS1_BBD (0x1 << 5) | ||
| 101 | #define NDSR_UNCORERR (0x1 << 4) | ||
| 102 | #define NDSR_CORERR (0x1 << 3) | ||
| 103 | #define NDSR_WRDREQ (0x1 << 2) | ||
| 104 | #define NDSR_RDDREQ (0x1 << 1) | ||
| 105 | #define NDSR_WRCMDREQ (0x1) | ||
| 106 | |||
| 107 | #define NDCB0_LEN_OVRD (0x1 << 28) | ||
| 108 | #define NDCB0_ST_ROW_EN (0x1 << 26) | ||
| 109 | #define NDCB0_AUTO_RS (0x1 << 25) | ||
| 110 | #define NDCB0_CSEL (0x1 << 24) | ||
| 111 | #define NDCB0_EXT_CMD_TYPE_MASK (0x7 << 29) | ||
| 112 | #define NDCB0_EXT_CMD_TYPE(x) (((x) << 29) & NDCB0_EXT_CMD_TYPE_MASK) | ||
| 113 | #define NDCB0_CMD_TYPE_MASK (0x7 << 21) | ||
| 114 | #define NDCB0_CMD_TYPE(x) (((x) << 21) & NDCB0_CMD_TYPE_MASK) | ||
| 115 | #define NDCB0_NC (0x1 << 20) | ||
| 116 | #define NDCB0_DBC (0x1 << 19) | ||
| 117 | #define NDCB0_ADDR_CYC_MASK (0x7 << 16) | ||
| 118 | #define NDCB0_ADDR_CYC(x) (((x) << 16) & NDCB0_ADDR_CYC_MASK) | ||
| 119 | #define NDCB0_CMD2_MASK (0xff << 8) | ||
| 120 | #define NDCB0_CMD1_MASK (0xff) | ||
| 121 | #define NDCB0_ADDR_CYC_SHIFT (16) | ||
| 122 | |||
| 123 | #define EXT_CMD_TYPE_DISPATCH 6 /* Command dispatch */ | ||
| 124 | #define EXT_CMD_TYPE_NAKED_RW 5 /* Naked read or Naked write */ | ||
| 125 | #define EXT_CMD_TYPE_READ 4 /* Read */ | ||
| 126 | #define EXT_CMD_TYPE_DISP_WR 4 /* Command dispatch with write */ | ||
| 127 | #define EXT_CMD_TYPE_FINAL 3 /* Final command */ | ||
| 128 | #define EXT_CMD_TYPE_LAST_RW 1 /* Last naked read/write */ | ||
| 129 | #define EXT_CMD_TYPE_MONO 0 /* Monolithic read/write */ | ||
| 130 | |||
| 131 | /* | ||
| 132 | * This should be large enough to read 'ONFI' and 'JEDEC'. | ||
| 133 | * Let's use 7 bytes, which is the maximum ID count supported | ||
| 134 | * by the controller (see NDCR_RD_ID_CNT_MASK). | ||
| 135 | */ | ||
| 136 | #define READ_ID_BYTES 7 | ||
| 137 | |||
| 138 | /* macros for registers read/write */ | ||
| 139 | #define nand_writel(info, off, val) \ | ||
| 140 | do { \ | ||
| 141 | dev_vdbg(&info->pdev->dev, \ | ||
| 142 | "%s():%d nand_writel(0x%x, 0x%04x)\n", \ | ||
| 143 | __func__, __LINE__, (val), (off)); \ | ||
| 144 | writel_relaxed((val), (info)->mmio_base + (off)); \ | ||
| 145 | } while (0) | ||
| 146 | |||
| 147 | #define nand_readl(info, off) \ | ||
| 148 | ({ \ | ||
| 149 | unsigned int _v; \ | ||
| 150 | _v = readl_relaxed((info)->mmio_base + (off)); \ | ||
| 151 | dev_vdbg(&info->pdev->dev, \ | ||
| 152 | "%s():%d nand_readl(0x%04x) = 0x%x\n", \ | ||
| 153 | __func__, __LINE__, (off), _v); \ | ||
| 154 | _v; \ | ||
| 155 | }) | ||
| 156 | |||
| 157 | /* error code and state */ | ||
| 158 | enum { | ||
| 159 | ERR_NONE = 0, | ||
| 160 | ERR_DMABUSERR = -1, | ||
| 161 | ERR_SENDCMD = -2, | ||
| 162 | ERR_UNCORERR = -3, | ||
| 163 | ERR_BBERR = -4, | ||
| 164 | ERR_CORERR = -5, | ||
| 165 | }; | ||
| 166 | |||
| 167 | enum { | ||
| 168 | STATE_IDLE = 0, | ||
| 169 | STATE_PREPARED, | ||
| 170 | STATE_CMD_HANDLE, | ||
| 171 | STATE_DMA_READING, | ||
| 172 | STATE_DMA_WRITING, | ||
| 173 | STATE_DMA_DONE, | ||
| 174 | STATE_PIO_READING, | ||
| 175 | STATE_PIO_WRITING, | ||
| 176 | STATE_CMD_DONE, | ||
| 177 | STATE_READY, | ||
| 178 | }; | ||
| 179 | |||
| 180 | enum pxa3xx_nand_variant { | ||
| 181 | PXA3XX_NAND_VARIANT_PXA, | ||
| 182 | PXA3XX_NAND_VARIANT_ARMADA370, | ||
| 183 | PXA3XX_NAND_VARIANT_ARMADA_8K, | ||
| 184 | }; | ||
| 185 | |||
| 186 | struct pxa3xx_nand_host { | ||
| 187 | struct nand_chip chip; | ||
| 188 | void *info_data; | ||
| 189 | |||
| 190 | /* page size of attached chip */ | ||
| 191 | int use_ecc; | ||
| 192 | int cs; | ||
| 193 | |||
| 194 | /* calculated from pxa3xx_nand_flash data */ | ||
| 195 | unsigned int col_addr_cycles; | ||
| 196 | unsigned int row_addr_cycles; | ||
| 197 | }; | ||
| 198 | |||
| 199 | struct pxa3xx_nand_info { | ||
| 200 | struct nand_hw_control controller; | ||
| 201 | struct platform_device *pdev; | ||
| 202 | |||
| 203 | struct clk *clk; | ||
| 204 | void __iomem *mmio_base; | ||
| 205 | unsigned long mmio_phys; | ||
| 206 | struct completion cmd_complete, dev_ready; | ||
| 207 | |||
| 208 | unsigned int buf_start; | ||
| 209 | unsigned int buf_count; | ||
| 210 | unsigned int buf_size; | ||
| 211 | unsigned int data_buff_pos; | ||
| 212 | unsigned int oob_buff_pos; | ||
| 213 | |||
| 214 | /* DMA information */ | ||
| 215 | struct scatterlist sg; | ||
| 216 | enum dma_data_direction dma_dir; | ||
| 217 | struct dma_chan *dma_chan; | ||
| 218 | dma_cookie_t dma_cookie; | ||
| 219 | int drcmr_dat; | ||
| 220 | |||
| 221 | unsigned char *data_buff; | ||
| 222 | unsigned char *oob_buff; | ||
| 223 | dma_addr_t data_buff_phys; | ||
| 224 | int data_dma_ch; | ||
| 225 | |||
| 226 | struct pxa3xx_nand_host *host[NUM_CHIP_SELECT]; | ||
| 227 | unsigned int state; | ||
| 228 | |||
| 229 | /* | ||
| 230 | * This driver supports NFCv1 (as found in PXA SoC) | ||
| 231 | * and NFCv2 (as found in Armada 370/XP SoC). | ||
| 232 | */ | ||
| 233 | enum pxa3xx_nand_variant variant; | ||
| 234 | |||
| 235 | int cs; | ||
| 236 | int use_ecc; /* use HW ECC ? */ | ||
| 237 | int ecc_bch; /* using BCH ECC? */ | ||
| 238 | int use_dma; /* use DMA ? */ | ||
| 239 | int use_spare; /* use spare ? */ | ||
| 240 | int need_wait; | ||
| 241 | |||
| 242 | /* Amount of real data per full chunk */ | ||
| 243 | unsigned int chunk_size; | ||
| 244 | |||
| 245 | /* Amount of spare data per full chunk */ | ||
| 246 | unsigned int spare_size; | ||
| 247 | |||
| 248 | /* Number of full chunks (i.e chunk_size + spare_size) */ | ||
| 249 | unsigned int nfullchunks; | ||
| 250 | |||
| 251 | /* | ||
| 252 | * Total number of chunks. If equal to nfullchunks, then there | ||
| 253 | * are only full chunks. Otherwise, there is one last chunk of | ||
| 254 | * size (last_chunk_size + last_spare_size) | ||
| 255 | */ | ||
| 256 | unsigned int ntotalchunks; | ||
| 257 | |||
| 258 | /* Amount of real data in the last chunk */ | ||
| 259 | unsigned int last_chunk_size; | ||
| 260 | |||
| 261 | /* Amount of spare data in the last chunk */ | ||
| 262 | unsigned int last_spare_size; | ||
| 263 | |||
| 264 | unsigned int ecc_size; | ||
| 265 | unsigned int ecc_err_cnt; | ||
| 266 | unsigned int max_bitflips; | ||
| 267 | int retcode; | ||
| 268 | |||
| 269 | /* | ||
| 270 | * Variables only valid during command | ||
| 271 | * execution. step_chunk_size and step_spare_size is the | ||
| 272 | * amount of real data and spare data in the current | ||
| 273 | * chunk. cur_chunk is the current chunk being | ||
| 274 | * read/programmed. | ||
| 275 | */ | ||
| 276 | unsigned int step_chunk_size; | ||
| 277 | unsigned int step_spare_size; | ||
| 278 | unsigned int cur_chunk; | ||
| 279 | |||
| 280 | /* cached register value */ | ||
| 281 | uint32_t reg_ndcr; | ||
| 282 | uint32_t ndtr0cs0; | ||
| 283 | uint32_t ndtr1cs0; | ||
| 284 | |||
| 285 | /* generated NDCBx register values */ | ||
| 286 | uint32_t ndcb0; | ||
| 287 | uint32_t ndcb1; | ||
| 288 | uint32_t ndcb2; | ||
| 289 | uint32_t ndcb3; | ||
| 290 | }; | ||
| 291 | |||
| 292 | static bool use_dma = 1; | ||
| 293 | module_param(use_dma, bool, 0444); | ||
| 294 | MODULE_PARM_DESC(use_dma, "enable DMA for data transferring to/from NAND HW"); | ||
| 295 | |||
| 296 | struct pxa3xx_nand_timing { | ||
| 297 | unsigned int tCH; /* Enable signal hold time */ | ||
| 298 | unsigned int tCS; /* Enable signal setup time */ | ||
| 299 | unsigned int tWH; /* ND_nWE high duration */ | ||
| 300 | unsigned int tWP; /* ND_nWE pulse time */ | ||
| 301 | unsigned int tRH; /* ND_nRE high duration */ | ||
| 302 | unsigned int tRP; /* ND_nRE pulse width */ | ||
| 303 | unsigned int tR; /* ND_nWE high to ND_nRE low for read */ | ||
| 304 | unsigned int tWHR; /* ND_nWE high to ND_nRE low for status read */ | ||
| 305 | unsigned int tAR; /* ND_ALE low to ND_nRE low delay */ | ||
| 306 | }; | ||
| 307 | |||
| 308 | struct pxa3xx_nand_flash { | ||
| 309 | uint32_t chip_id; | ||
| 310 | unsigned int flash_width; /* Width of Flash memory (DWIDTH_M) */ | ||
| 311 | unsigned int dfc_width; /* Width of flash controller(DWIDTH_C) */ | ||
| 312 | struct pxa3xx_nand_timing *timing; /* NAND Flash timing */ | ||
| 313 | }; | ||
| 314 | |||
| 315 | static struct pxa3xx_nand_timing timing[] = { | ||
| 316 | { 40, 80, 60, 100, 80, 100, 90000, 400, 40, }, | ||
| 317 | { 10, 0, 20, 40, 30, 40, 11123, 110, 10, }, | ||
| 318 | { 10, 25, 15, 25, 15, 30, 25000, 60, 10, }, | ||
| 319 | { 10, 35, 15, 25, 15, 25, 25000, 60, 10, }, | ||
| 320 | }; | ||
| 321 | |||
| 322 | static struct pxa3xx_nand_flash builtin_flash_types[] = { | ||
| 323 | { 0x46ec, 16, 16, &timing[1] }, | ||
| 324 | { 0xdaec, 8, 8, &timing[1] }, | ||
| 325 | { 0xd7ec, 8, 8, &timing[1] }, | ||
| 326 | { 0xa12c, 8, 8, &timing[2] }, | ||
| 327 | { 0xb12c, 16, 16, &timing[2] }, | ||
| 328 | { 0xdc2c, 8, 8, &timing[2] }, | ||
| 329 | { 0xcc2c, 16, 16, &timing[2] }, | ||
| 330 | { 0xba20, 16, 16, &timing[3] }, | ||
| 331 | }; | ||
| 332 | |||
| 333 | static int pxa3xx_ooblayout_ecc(struct mtd_info *mtd, int section, | ||
| 334 | struct mtd_oob_region *oobregion) | ||
| 335 | { | ||
| 336 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
| 337 | struct pxa3xx_nand_host *host = nand_get_controller_data(chip); | ||
| 338 | struct pxa3xx_nand_info *info = host->info_data; | ||
| 339 | int nchunks = mtd->writesize / info->chunk_size; | ||
| 340 | |||
| 341 | if (section >= nchunks) | ||
| 342 | return -ERANGE; | ||
| 343 | |||
| 344 | oobregion->offset = ((info->ecc_size + info->spare_size) * section) + | ||
| 345 | info->spare_size; | ||
| 346 | oobregion->length = info->ecc_size; | ||
| 347 | |||
| 348 | return 0; | ||
| 349 | } | ||
| 350 | |||
| 351 | static int pxa3xx_ooblayout_free(struct mtd_info *mtd, int section, | ||
| 352 | struct mtd_oob_region *oobregion) | ||
| 353 | { | ||
| 354 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
| 355 | struct pxa3xx_nand_host *host = nand_get_controller_data(chip); | ||
| 356 | struct pxa3xx_nand_info *info = host->info_data; | ||
| 357 | int nchunks = mtd->writesize / info->chunk_size; | ||
| 358 | |||
| 359 | if (section >= nchunks) | ||
| 360 | return -ERANGE; | ||
| 361 | |||
| 362 | if (!info->spare_size) | ||
| 363 | return 0; | ||
| 364 | |||
| 365 | oobregion->offset = section * (info->ecc_size + info->spare_size); | ||
| 366 | oobregion->length = info->spare_size; | ||
| 367 | if (!section) { | ||
| 368 | /* | ||
| 369 | * Bootrom looks in bytes 0 & 5 for bad blocks for the | ||
| 370 | * 4KB page / 4bit BCH combination. | ||
| 371 | */ | ||
| 372 | if (mtd->writesize == 4096 && info->chunk_size == 2048) { | ||
| 373 | oobregion->offset += 6; | ||
| 374 | oobregion->length -= 6; | ||
| 375 | } else { | ||
| 376 | oobregion->offset += 2; | ||
| 377 | oobregion->length -= 2; | ||
| 378 | } | ||
| 379 | } | ||
| 380 | |||
| 381 | return 0; | ||
| 382 | } | ||
| 383 | |||
| 384 | static const struct mtd_ooblayout_ops pxa3xx_ooblayout_ops = { | ||
| 385 | .ecc = pxa3xx_ooblayout_ecc, | ||
| 386 | .free = pxa3xx_ooblayout_free, | ||
| 387 | }; | ||
| 388 | |||
| 389 | static u8 bbt_pattern[] = {'M', 'V', 'B', 'b', 't', '0' }; | ||
| 390 | static u8 bbt_mirror_pattern[] = {'1', 't', 'b', 'B', 'V', 'M' }; | ||
| 391 | |||
| 392 | static struct nand_bbt_descr bbt_main_descr = { | ||
| 393 | .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | ||
| 394 | | NAND_BBT_2BIT | NAND_BBT_VERSION, | ||
| 395 | .offs = 8, | ||
| 396 | .len = 6, | ||
| 397 | .veroffs = 14, | ||
| 398 | .maxblocks = 8, /* Last 8 blocks in each chip */ | ||
| 399 | .pattern = bbt_pattern | ||
| 400 | }; | ||
| 401 | |||
| 402 | static struct nand_bbt_descr bbt_mirror_descr = { | ||
| 403 | .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | ||
| 404 | | NAND_BBT_2BIT | NAND_BBT_VERSION, | ||
| 405 | .offs = 8, | ||
| 406 | .len = 6, | ||
| 407 | .veroffs = 14, | ||
| 408 | .maxblocks = 8, /* Last 8 blocks in each chip */ | ||
| 409 | .pattern = bbt_mirror_pattern | ||
| 410 | }; | ||
| 411 | |||
| 412 | #define NDTR0_tCH(c) (min((c), 7) << 19) | ||
| 413 | #define NDTR0_tCS(c) (min((c), 7) << 16) | ||
| 414 | #define NDTR0_tWH(c) (min((c), 7) << 11) | ||
| 415 | #define NDTR0_tWP(c) (min((c), 7) << 8) | ||
| 416 | #define NDTR0_tRH(c) (min((c), 7) << 3) | ||
| 417 | #define NDTR0_tRP(c) (min((c), 7) << 0) | ||
| 418 | |||
| 419 | #define NDTR1_tR(c) (min((c), 65535) << 16) | ||
| 420 | #define NDTR1_tWHR(c) (min((c), 15) << 4) | ||
| 421 | #define NDTR1_tAR(c) (min((c), 15) << 0) | ||
| 422 | |||
| 423 | /* convert nano-seconds to nand flash controller clock cycles */ | ||
| 424 | #define ns2cycle(ns, clk) (int)((ns) * (clk / 1000000) / 1000) | ||
| 425 | |||
| 426 | static const struct of_device_id pxa3xx_nand_dt_ids[] = { | ||
| 427 | { | ||
| 428 | .compatible = "marvell,pxa3xx-nand", | ||
| 429 | .data = (void *)PXA3XX_NAND_VARIANT_PXA, | ||
| 430 | }, | ||
| 431 | { | ||
| 432 | .compatible = "marvell,armada370-nand", | ||
| 433 | .data = (void *)PXA3XX_NAND_VARIANT_ARMADA370, | ||
| 434 | }, | ||
| 435 | { | ||
| 436 | .compatible = "marvell,armada-8k-nand", | ||
| 437 | .data = (void *)PXA3XX_NAND_VARIANT_ARMADA_8K, | ||
| 438 | }, | ||
| 439 | {} | ||
| 440 | }; | ||
| 441 | MODULE_DEVICE_TABLE(of, pxa3xx_nand_dt_ids); | ||
| 442 | |||
| 443 | static enum pxa3xx_nand_variant | ||
| 444 | pxa3xx_nand_get_variant(struct platform_device *pdev) | ||
| 445 | { | ||
| 446 | const struct of_device_id *of_id = | ||
| 447 | of_match_device(pxa3xx_nand_dt_ids, &pdev->dev); | ||
| 448 | if (!of_id) | ||
| 449 | return PXA3XX_NAND_VARIANT_PXA; | ||
| 450 | return (enum pxa3xx_nand_variant)of_id->data; | ||
| 451 | } | ||
| 452 | |||
| 453 | static void pxa3xx_nand_set_timing(struct pxa3xx_nand_host *host, | ||
| 454 | const struct pxa3xx_nand_timing *t) | ||
| 455 | { | ||
| 456 | struct pxa3xx_nand_info *info = host->info_data; | ||
| 457 | unsigned long nand_clk = clk_get_rate(info->clk); | ||
| 458 | uint32_t ndtr0, ndtr1; | ||
| 459 | |||
| 460 | ndtr0 = NDTR0_tCH(ns2cycle(t->tCH, nand_clk)) | | ||
| 461 | NDTR0_tCS(ns2cycle(t->tCS, nand_clk)) | | ||
| 462 | NDTR0_tWH(ns2cycle(t->tWH, nand_clk)) | | ||
| 463 | NDTR0_tWP(ns2cycle(t->tWP, nand_clk)) | | ||
| 464 | NDTR0_tRH(ns2cycle(t->tRH, nand_clk)) | | ||
| 465 | NDTR0_tRP(ns2cycle(t->tRP, nand_clk)); | ||
| 466 | |||
| 467 | ndtr1 = NDTR1_tR(ns2cycle(t->tR, nand_clk)) | | ||
| 468 | NDTR1_tWHR(ns2cycle(t->tWHR, nand_clk)) | | ||
| 469 | NDTR1_tAR(ns2cycle(t->tAR, nand_clk)); | ||
| 470 | |||
| 471 | info->ndtr0cs0 = ndtr0; | ||
| 472 | info->ndtr1cs0 = ndtr1; | ||
| 473 | nand_writel(info, NDTR0CS0, ndtr0); | ||
| 474 | nand_writel(info, NDTR1CS0, ndtr1); | ||
| 475 | } | ||
| 476 | |||
| 477 | static void pxa3xx_nand_set_sdr_timing(struct pxa3xx_nand_host *host, | ||
| 478 | const struct nand_sdr_timings *t) | ||
| 479 | { | ||
| 480 | struct pxa3xx_nand_info *info = host->info_data; | ||
| 481 | struct nand_chip *chip = &host->chip; | ||
| 482 | unsigned long nand_clk = clk_get_rate(info->clk); | ||
| 483 | uint32_t ndtr0, ndtr1; | ||
| 484 | |||
| 485 | u32 tCH_min = DIV_ROUND_UP(t->tCH_min, 1000); | ||
| 486 | u32 tCS_min = DIV_ROUND_UP(t->tCS_min, 1000); | ||
| 487 | u32 tWH_min = DIV_ROUND_UP(t->tWH_min, 1000); | ||
| 488 | u32 tWP_min = DIV_ROUND_UP(t->tWC_min - t->tWH_min, 1000); | ||
| 489 | u32 tREH_min = DIV_ROUND_UP(t->tREH_min, 1000); | ||
| 490 | u32 tRP_min = DIV_ROUND_UP(t->tRC_min - t->tREH_min, 1000); | ||
| 491 | u32 tR = chip->chip_delay * 1000; | ||
| 492 | u32 tWHR_min = DIV_ROUND_UP(t->tWHR_min, 1000); | ||
| 493 | u32 tAR_min = DIV_ROUND_UP(t->tAR_min, 1000); | ||
| 494 | |||
| 495 | /* fallback to a default value if tR = 0 */ | ||
| 496 | if (!tR) | ||
| 497 | tR = 20000; | ||
| 498 | |||
| 499 | ndtr0 = NDTR0_tCH(ns2cycle(tCH_min, nand_clk)) | | ||
| 500 | NDTR0_tCS(ns2cycle(tCS_min, nand_clk)) | | ||
| 501 | NDTR0_tWH(ns2cycle(tWH_min, nand_clk)) | | ||
| 502 | NDTR0_tWP(ns2cycle(tWP_min, nand_clk)) | | ||
| 503 | NDTR0_tRH(ns2cycle(tREH_min, nand_clk)) | | ||
| 504 | NDTR0_tRP(ns2cycle(tRP_min, nand_clk)); | ||
| 505 | |||
| 506 | ndtr1 = NDTR1_tR(ns2cycle(tR, nand_clk)) | | ||
| 507 | NDTR1_tWHR(ns2cycle(tWHR_min, nand_clk)) | | ||
| 508 | NDTR1_tAR(ns2cycle(tAR_min, nand_clk)); | ||
| 509 | |||
| 510 | info->ndtr0cs0 = ndtr0; | ||
| 511 | info->ndtr1cs0 = ndtr1; | ||
| 512 | nand_writel(info, NDTR0CS0, ndtr0); | ||
| 513 | nand_writel(info, NDTR1CS0, ndtr1); | ||
| 514 | } | ||
| 515 | |||
| 516 | static int pxa3xx_nand_init_timings_compat(struct pxa3xx_nand_host *host, | ||
| 517 | unsigned int *flash_width, | ||
| 518 | unsigned int *dfc_width) | ||
| 519 | { | ||
| 520 | struct nand_chip *chip = &host->chip; | ||
| 521 | struct pxa3xx_nand_info *info = host->info_data; | ||
| 522 | const struct pxa3xx_nand_flash *f = NULL; | ||
| 523 | int i, id, ntypes; | ||
| 524 | u8 idbuf[2]; | ||
| 525 | |||
| 526 | ntypes = ARRAY_SIZE(builtin_flash_types); | ||
| 527 | |||
| 528 | nand_readid_op(chip, 0, idbuf, sizeof(idbuf)); | ||
| 529 | id = idbuf[0] | (idbuf[1] << 8); | ||
| 530 | |||
| 531 | for (i = 0; i < ntypes; i++) { | ||
| 532 | f = &builtin_flash_types[i]; | ||
| 533 | |||
| 534 | if (f->chip_id == id) | ||
| 535 | break; | ||
| 536 | } | ||
| 537 | |||
| 538 | if (i == ntypes) { | ||
| 539 | dev_err(&info->pdev->dev, "Error: timings not found\n"); | ||
| 540 | return -EINVAL; | ||
| 541 | } | ||
| 542 | |||
| 543 | pxa3xx_nand_set_timing(host, f->timing); | ||
| 544 | |||
| 545 | *flash_width = f->flash_width; | ||
| 546 | *dfc_width = f->dfc_width; | ||
| 547 | |||
| 548 | return 0; | ||
| 549 | } | ||
| 550 | |||
| 551 | static int pxa3xx_nand_init_timings_onfi(struct pxa3xx_nand_host *host, | ||
| 552 | int mode) | ||
| 553 | { | ||
| 554 | const struct nand_sdr_timings *timings; | ||
| 555 | |||
| 556 | mode = fls(mode) - 1; | ||
| 557 | if (mode < 0) | ||
| 558 | mode = 0; | ||
| 559 | |||
| 560 | timings = onfi_async_timing_mode_to_sdr_timings(mode); | ||
| 561 | if (IS_ERR(timings)) | ||
| 562 | return PTR_ERR(timings); | ||
| 563 | |||
| 564 | pxa3xx_nand_set_sdr_timing(host, timings); | ||
| 565 | |||
| 566 | return 0; | ||
| 567 | } | ||
| 568 | |||
| 569 | static int pxa3xx_nand_init(struct pxa3xx_nand_host *host) | ||
| 570 | { | ||
| 571 | struct nand_chip *chip = &host->chip; | ||
| 572 | struct pxa3xx_nand_info *info = host->info_data; | ||
| 573 | unsigned int flash_width = 0, dfc_width = 0; | ||
| 574 | int mode, err; | ||
| 575 | |||
| 576 | mode = onfi_get_async_timing_mode(chip); | ||
| 577 | if (mode == ONFI_TIMING_MODE_UNKNOWN) { | ||
| 578 | err = pxa3xx_nand_init_timings_compat(host, &flash_width, | ||
| 579 | &dfc_width); | ||
| 580 | if (err) | ||
| 581 | return err; | ||
| 582 | |||
| 583 | if (flash_width == 16) { | ||
| 584 | info->reg_ndcr |= NDCR_DWIDTH_M; | ||
| 585 | chip->options |= NAND_BUSWIDTH_16; | ||
| 586 | } | ||
| 587 | |||
| 588 | info->reg_ndcr |= (dfc_width == 16) ? NDCR_DWIDTH_C : 0; | ||
| 589 | } else { | ||
| 590 | err = pxa3xx_nand_init_timings_onfi(host, mode); | ||
| 591 | if (err) | ||
| 592 | return err; | ||
| 593 | } | ||
| 594 | |||
| 595 | return 0; | ||
| 596 | } | ||
| 597 | |||
| 598 | /** | ||
| 599 | * NOTE: it is a must to set ND_RUN firstly, then write | ||
| 600 | * command buffer, otherwise, it does not work. | ||
| 601 | * We enable all the interrupt at the same time, and | ||
| 602 | * let pxa3xx_nand_irq to handle all logic. | ||
| 603 | */ | ||
| 604 | static void pxa3xx_nand_start(struct pxa3xx_nand_info *info) | ||
| 605 | { | ||
| 606 | uint32_t ndcr; | ||
| 607 | |||
| 608 | ndcr = info->reg_ndcr; | ||
| 609 | |||
| 610 | if (info->use_ecc) { | ||
| 611 | ndcr |= NDCR_ECC_EN; | ||
| 612 | if (info->ecc_bch) | ||
| 613 | nand_writel(info, NDECCCTRL, 0x1); | ||
| 614 | } else { | ||
| 615 | ndcr &= ~NDCR_ECC_EN; | ||
| 616 | if (info->ecc_bch) | ||
| 617 | nand_writel(info, NDECCCTRL, 0x0); | ||
| 618 | } | ||
| 619 | |||
| 620 | if (info->use_dma) | ||
| 621 | ndcr |= NDCR_DMA_EN; | ||
| 622 | else | ||
| 623 | ndcr &= ~NDCR_DMA_EN; | ||
| 624 | |||
| 625 | if (info->use_spare) | ||
| 626 | ndcr |= NDCR_SPARE_EN; | ||
| 627 | else | ||
| 628 | ndcr &= ~NDCR_SPARE_EN; | ||
| 629 | |||
| 630 | ndcr |= NDCR_ND_RUN; | ||
| 631 | |||
| 632 | /* clear status bits and run */ | ||
| 633 | nand_writel(info, NDSR, NDSR_MASK); | ||
| 634 | nand_writel(info, NDCR, 0); | ||
| 635 | nand_writel(info, NDCR, ndcr); | ||
| 636 | } | ||
| 637 | |||
| 638 | static void pxa3xx_nand_stop(struct pxa3xx_nand_info *info) | ||
| 639 | { | ||
| 640 | uint32_t ndcr; | ||
| 641 | int timeout = NAND_STOP_DELAY; | ||
| 642 | |||
| 643 | /* wait RUN bit in NDCR become 0 */ | ||
| 644 | ndcr = nand_readl(info, NDCR); | ||
| 645 | while ((ndcr & NDCR_ND_RUN) && (timeout-- > 0)) { | ||
| 646 | ndcr = nand_readl(info, NDCR); | ||
| 647 | udelay(1); | ||
| 648 | } | ||
| 649 | |||
| 650 | if (timeout <= 0) { | ||
| 651 | ndcr &= ~NDCR_ND_RUN; | ||
| 652 | nand_writel(info, NDCR, ndcr); | ||
| 653 | } | ||
| 654 | if (info->dma_chan) | ||
| 655 | dmaengine_terminate_all(info->dma_chan); | ||
| 656 | |||
| 657 | /* clear status bits */ | ||
| 658 | nand_writel(info, NDSR, NDSR_MASK); | ||
| 659 | } | ||
| 660 | |||
| 661 | static void __maybe_unused | ||
| 662 | enable_int(struct pxa3xx_nand_info *info, uint32_t int_mask) | ||
| 663 | { | ||
| 664 | uint32_t ndcr; | ||
| 665 | |||
| 666 | ndcr = nand_readl(info, NDCR); | ||
| 667 | nand_writel(info, NDCR, ndcr & ~int_mask); | ||
| 668 | } | ||
| 669 | |||
| 670 | static void disable_int(struct pxa3xx_nand_info *info, uint32_t int_mask) | ||
| 671 | { | ||
| 672 | uint32_t ndcr; | ||
| 673 | |||
| 674 | ndcr = nand_readl(info, NDCR); | ||
| 675 | nand_writel(info, NDCR, ndcr | int_mask); | ||
| 676 | } | ||
| 677 | |||
| 678 | static void drain_fifo(struct pxa3xx_nand_info *info, void *data, int len) | ||
| 679 | { | ||
| 680 | if (info->ecc_bch) { | ||
| 681 | u32 val; | ||
| 682 | int ret; | ||
| 683 | |||
| 684 | /* | ||
| 685 | * According to the datasheet, when reading from NDDB | ||
| 686 | * with BCH enabled, after each 32 bytes reads, we | ||
| 687 | * have to make sure that the NDSR.RDDREQ bit is set. | ||
| 688 | * | ||
| 689 | * Drain the FIFO 8 32 bits reads at a time, and skip | ||
| 690 | * the polling on the last read. | ||
| 691 | */ | ||
| 692 | while (len > 8) { | ||
| 693 | ioread32_rep(info->mmio_base + NDDB, data, 8); | ||
| 694 | |||
| 695 | ret = readl_relaxed_poll_timeout(info->mmio_base + NDSR, val, | ||
| 696 | val & NDSR_RDDREQ, 1000, 5000); | ||
| 697 | if (ret) { | ||
| 698 | dev_err(&info->pdev->dev, | ||
| 699 | "Timeout on RDDREQ while draining the FIFO\n"); | ||
| 700 | return; | ||
| 701 | } | ||
| 702 | |||
| 703 | data += 32; | ||
| 704 | len -= 8; | ||
| 705 | } | ||
| 706 | } | ||
| 707 | |||
| 708 | ioread32_rep(info->mmio_base + NDDB, data, len); | ||
| 709 | } | ||
| 710 | |||
| 711 | static void handle_data_pio(struct pxa3xx_nand_info *info) | ||
| 712 | { | ||
| 713 | switch (info->state) { | ||
| 714 | case STATE_PIO_WRITING: | ||
| 715 | if (info->step_chunk_size) | ||
| 716 | writesl(info->mmio_base + NDDB, | ||
| 717 | info->data_buff + info->data_buff_pos, | ||
| 718 | DIV_ROUND_UP(info->step_chunk_size, 4)); | ||
| 719 | |||
| 720 | if (info->step_spare_size) | ||
| 721 | writesl(info->mmio_base + NDDB, | ||
| 722 | info->oob_buff + info->oob_buff_pos, | ||
| 723 | DIV_ROUND_UP(info->step_spare_size, 4)); | ||
| 724 | break; | ||
| 725 | case STATE_PIO_READING: | ||
| 726 | if (info->step_chunk_size) | ||
| 727 | drain_fifo(info, | ||
| 728 | info->data_buff + info->data_buff_pos, | ||
| 729 | DIV_ROUND_UP(info->step_chunk_size, 4)); | ||
| 730 | |||
| 731 | if (info->step_spare_size) | ||
| 732 | drain_fifo(info, | ||
| 733 | info->oob_buff + info->oob_buff_pos, | ||
| 734 | DIV_ROUND_UP(info->step_spare_size, 4)); | ||
| 735 | break; | ||
| 736 | default: | ||
| 737 | dev_err(&info->pdev->dev, "%s: invalid state %d\n", __func__, | ||
| 738 | info->state); | ||
| 739 | BUG(); | ||
| 740 | } | ||
| 741 | |||
| 742 | /* Update buffer pointers for multi-page read/write */ | ||
| 743 | info->data_buff_pos += info->step_chunk_size; | ||
| 744 | info->oob_buff_pos += info->step_spare_size; | ||
| 745 | } | ||
| 746 | |||
| 747 | static void pxa3xx_nand_data_dma_irq(void *data) | ||
| 748 | { | ||
| 749 | struct pxa3xx_nand_info *info = data; | ||
| 750 | struct dma_tx_state state; | ||
| 751 | enum dma_status status; | ||
| 752 | |||
| 753 | status = dmaengine_tx_status(info->dma_chan, info->dma_cookie, &state); | ||
| 754 | if (likely(status == DMA_COMPLETE)) { | ||
| 755 | info->state = STATE_DMA_DONE; | ||
| 756 | } else { | ||
| 757 | dev_err(&info->pdev->dev, "DMA error on data channel\n"); | ||
| 758 | info->retcode = ERR_DMABUSERR; | ||
| 759 | } | ||
| 760 | dma_unmap_sg(info->dma_chan->device->dev, &info->sg, 1, info->dma_dir); | ||
| 761 | |||
| 762 | nand_writel(info, NDSR, NDSR_WRDREQ | NDSR_RDDREQ); | ||
| 763 | enable_int(info, NDCR_INT_MASK); | ||
| 764 | } | ||
| 765 | |||
| 766 | static void start_data_dma(struct pxa3xx_nand_info *info) | ||
| 767 | { | ||
| 768 | enum dma_transfer_direction direction; | ||
| 769 | struct dma_async_tx_descriptor *tx; | ||
| 770 | |||
| 771 | switch (info->state) { | ||
| 772 | case STATE_DMA_WRITING: | ||
| 773 | info->dma_dir = DMA_TO_DEVICE; | ||
| 774 | direction = DMA_MEM_TO_DEV; | ||
| 775 | break; | ||
| 776 | case STATE_DMA_READING: | ||
| 777 | info->dma_dir = DMA_FROM_DEVICE; | ||
| 778 | direction = DMA_DEV_TO_MEM; | ||
| 779 | break; | ||
| 780 | default: | ||
| 781 | dev_err(&info->pdev->dev, "%s: invalid state %d\n", __func__, | ||
| 782 | info->state); | ||
| 783 | BUG(); | ||
| 784 | } | ||
| 785 | info->sg.length = info->chunk_size; | ||
| 786 | if (info->use_spare) | ||
| 787 | info->sg.length += info->spare_size + info->ecc_size; | ||
| 788 | dma_map_sg(info->dma_chan->device->dev, &info->sg, 1, info->dma_dir); | ||
| 789 | |||
| 790 | tx = dmaengine_prep_slave_sg(info->dma_chan, &info->sg, 1, direction, | ||
| 791 | DMA_PREP_INTERRUPT); | ||
| 792 | if (!tx) { | ||
| 793 | dev_err(&info->pdev->dev, "prep_slave_sg() failed\n"); | ||
| 794 | return; | ||
| 795 | } | ||
| 796 | tx->callback = pxa3xx_nand_data_dma_irq; | ||
| 797 | tx->callback_param = info; | ||
| 798 | info->dma_cookie = dmaengine_submit(tx); | ||
| 799 | dma_async_issue_pending(info->dma_chan); | ||
| 800 | dev_dbg(&info->pdev->dev, "%s(dir=%d cookie=%x size=%u)\n", | ||
| 801 | __func__, direction, info->dma_cookie, info->sg.length); | ||
| 802 | } | ||
| 803 | |||
| 804 | static irqreturn_t pxa3xx_nand_irq_thread(int irq, void *data) | ||
| 805 | { | ||
| 806 | struct pxa3xx_nand_info *info = data; | ||
| 807 | |||
| 808 | handle_data_pio(info); | ||
| 809 | |||
| 810 | info->state = STATE_CMD_DONE; | ||
| 811 | nand_writel(info, NDSR, NDSR_WRDREQ | NDSR_RDDREQ); | ||
| 812 | |||
| 813 | return IRQ_HANDLED; | ||
| 814 | } | ||
| 815 | |||
| 816 | static irqreturn_t pxa3xx_nand_irq(int irq, void *devid) | ||
| 817 | { | ||
| 818 | struct pxa3xx_nand_info *info = devid; | ||
| 819 | unsigned int status, is_completed = 0, is_ready = 0; | ||
| 820 | unsigned int ready, cmd_done; | ||
| 821 | irqreturn_t ret = IRQ_HANDLED; | ||
| 822 | |||
| 823 | if (info->cs == 0) { | ||
| 824 | ready = NDSR_FLASH_RDY; | ||
| 825 | cmd_done = NDSR_CS0_CMDD; | ||
| 826 | } else { | ||
| 827 | ready = NDSR_RDY; | ||
| 828 | cmd_done = NDSR_CS1_CMDD; | ||
| 829 | } | ||
| 830 | |||
| 831 | status = nand_readl(info, NDSR); | ||
| 832 | |||
| 833 | if (status & NDSR_UNCORERR) | ||
| 834 | info->retcode = ERR_UNCORERR; | ||
| 835 | if (status & NDSR_CORERR) { | ||
| 836 | info->retcode = ERR_CORERR; | ||
| 837 | if ((info->variant == PXA3XX_NAND_VARIANT_ARMADA370 || | ||
| 838 | info->variant == PXA3XX_NAND_VARIANT_ARMADA_8K) && | ||
| 839 | info->ecc_bch) | ||
| 840 | info->ecc_err_cnt = NDSR_ERR_CNT(status); | ||
| 841 | else | ||
| 842 | info->ecc_err_cnt = 1; | ||
| 843 | |||
| 844 | /* | ||
| 845 | * Each chunk composing a page is corrected independently, | ||
| 846 | * and we need to store maximum number of corrected bitflips | ||
| 847 | * to return it to the MTD layer in ecc.read_page(). | ||
| 848 | */ | ||
| 849 | info->max_bitflips = max_t(unsigned int, | ||
| 850 | info->max_bitflips, | ||
| 851 | info->ecc_err_cnt); | ||
| 852 | } | ||
| 853 | if (status & (NDSR_RDDREQ | NDSR_WRDREQ)) { | ||
| 854 | /* whether use dma to transfer data */ | ||
| 855 | if (info->use_dma) { | ||
| 856 | disable_int(info, NDCR_INT_MASK); | ||
| 857 | info->state = (status & NDSR_RDDREQ) ? | ||
| 858 | STATE_DMA_READING : STATE_DMA_WRITING; | ||
| 859 | start_data_dma(info); | ||
| 860 | goto NORMAL_IRQ_EXIT; | ||
| 861 | } else { | ||
| 862 | info->state = (status & NDSR_RDDREQ) ? | ||
| 863 | STATE_PIO_READING : STATE_PIO_WRITING; | ||
| 864 | ret = IRQ_WAKE_THREAD; | ||
| 865 | goto NORMAL_IRQ_EXIT; | ||
| 866 | } | ||
| 867 | } | ||
| 868 | if (status & cmd_done) { | ||
| 869 | info->state = STATE_CMD_DONE; | ||
| 870 | is_completed = 1; | ||
| 871 | } | ||
| 872 | if (status & ready) { | ||
| 873 | info->state = STATE_READY; | ||
| 874 | is_ready = 1; | ||
| 875 | } | ||
| 876 | |||
| 877 | /* | ||
| 878 | * Clear all status bit before issuing the next command, which | ||
| 879 | * can and will alter the status bits and will deserve a new | ||
| 880 | * interrupt on its own. This lets the controller exit the IRQ | ||
| 881 | */ | ||
| 882 | nand_writel(info, NDSR, status); | ||
| 883 | |||
| 884 | if (status & NDSR_WRCMDREQ) { | ||
| 885 | status &= ~NDSR_WRCMDREQ; | ||
| 886 | info->state = STATE_CMD_HANDLE; | ||
| 887 | |||
| 888 | /* | ||
| 889 | * Command buffer registers NDCB{0-2} (and optionally NDCB3) | ||
| 890 | * must be loaded by writing directly either 12 or 16 | ||
| 891 | * bytes directly to NDCB0, four bytes at a time. | ||
| 892 | * | ||
| 893 | * Direct write access to NDCB1, NDCB2 and NDCB3 is ignored | ||
| 894 | * but each NDCBx register can be read. | ||
| 895 | */ | ||
| 896 | nand_writel(info, NDCB0, info->ndcb0); | ||
| 897 | nand_writel(info, NDCB0, info->ndcb1); | ||
| 898 | nand_writel(info, NDCB0, info->ndcb2); | ||
| 899 | |||
| 900 | /* NDCB3 register is available in NFCv2 (Armada 370/XP SoC) */ | ||
| 901 | if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370 || | ||
| 902 | info->variant == PXA3XX_NAND_VARIANT_ARMADA_8K) | ||
| 903 | nand_writel(info, NDCB0, info->ndcb3); | ||
| 904 | } | ||
| 905 | |||
| 906 | if (is_completed) | ||
| 907 | complete(&info->cmd_complete); | ||
| 908 | if (is_ready) | ||
| 909 | complete(&info->dev_ready); | ||
| 910 | NORMAL_IRQ_EXIT: | ||
| 911 | return ret; | ||
| 912 | } | ||
| 913 | |||
| 914 | static inline int is_buf_blank(uint8_t *buf, size_t len) | ||
| 915 | { | ||
| 916 | for (; len > 0; len--) | ||
| 917 | if (*buf++ != 0xff) | ||
| 918 | return 0; | ||
| 919 | return 1; | ||
| 920 | } | ||
| 921 | |||
| 922 | static void set_command_address(struct pxa3xx_nand_info *info, | ||
| 923 | unsigned int page_size, uint16_t column, int page_addr) | ||
| 924 | { | ||
| 925 | /* small page addr setting */ | ||
| 926 | if (page_size < PAGE_CHUNK_SIZE) { | ||
| 927 | info->ndcb1 = ((page_addr & 0xFFFFFF) << 8) | ||
| 928 | | (column & 0xFF); | ||
| 929 | |||
| 930 | info->ndcb2 = 0; | ||
| 931 | } else { | ||
| 932 | info->ndcb1 = ((page_addr & 0xFFFF) << 16) | ||
| 933 | | (column & 0xFFFF); | ||
| 934 | |||
| 935 | if (page_addr & 0xFF0000) | ||
| 936 | info->ndcb2 = (page_addr & 0xFF0000) >> 16; | ||
| 937 | else | ||
| 938 | info->ndcb2 = 0; | ||
| 939 | } | ||
| 940 | } | ||
| 941 | |||
| 942 | static void prepare_start_command(struct pxa3xx_nand_info *info, int command) | ||
| 943 | { | ||
| 944 | struct pxa3xx_nand_host *host = info->host[info->cs]; | ||
| 945 | struct mtd_info *mtd = nand_to_mtd(&host->chip); | ||
| 946 | |||
| 947 | /* reset data and oob column point to handle data */ | ||
| 948 | info->buf_start = 0; | ||
| 949 | info->buf_count = 0; | ||
| 950 | info->data_buff_pos = 0; | ||
| 951 | info->oob_buff_pos = 0; | ||
| 952 | info->step_chunk_size = 0; | ||
| 953 | info->step_spare_size = 0; | ||
| 954 | info->cur_chunk = 0; | ||
| 955 | info->use_ecc = 0; | ||
| 956 | info->use_spare = 1; | ||
| 957 | info->retcode = ERR_NONE; | ||
| 958 | info->ecc_err_cnt = 0; | ||
| 959 | info->ndcb3 = 0; | ||
| 960 | info->need_wait = 0; | ||
| 961 | |||
| 962 | switch (command) { | ||
| 963 | case NAND_CMD_READ0: | ||
| 964 | case NAND_CMD_READOOB: | ||
| 965 | case NAND_CMD_PAGEPROG: | ||
| 966 | info->use_ecc = 1; | ||
| 967 | break; | ||
| 968 | case NAND_CMD_PARAM: | ||
| 969 | info->use_spare = 0; | ||
| 970 | break; | ||
| 971 | default: | ||
| 972 | info->ndcb1 = 0; | ||
| 973 | info->ndcb2 = 0; | ||
| 974 | break; | ||
| 975 | } | ||
| 976 | |||
| 977 | /* | ||
| 978 | * If we are about to issue a read command, or about to set | ||
| 979 | * the write address, then clean the data buffer. | ||
| 980 | */ | ||
| 981 | if (command == NAND_CMD_READ0 || | ||
| 982 | command == NAND_CMD_READOOB || | ||
| 983 | command == NAND_CMD_SEQIN) { | ||
| 984 | |||
| 985 | info->buf_count = mtd->writesize + mtd->oobsize; | ||
| 986 | memset(info->data_buff, 0xFF, info->buf_count); | ||
| 987 | } | ||
| 988 | |||
| 989 | } | ||
| 990 | |||
| 991 | static int prepare_set_command(struct pxa3xx_nand_info *info, int command, | ||
| 992 | int ext_cmd_type, uint16_t column, int page_addr) | ||
| 993 | { | ||
| 994 | int addr_cycle, exec_cmd; | ||
| 995 | struct pxa3xx_nand_host *host; | ||
| 996 | struct mtd_info *mtd; | ||
| 997 | |||
| 998 | host = info->host[info->cs]; | ||
| 999 | mtd = nand_to_mtd(&host->chip); | ||
| 1000 | addr_cycle = 0; | ||
| 1001 | exec_cmd = 1; | ||
| 1002 | |||
| 1003 | if (info->cs != 0) | ||
| 1004 | info->ndcb0 = NDCB0_CSEL; | ||
| 1005 | else | ||
| 1006 | info->ndcb0 = 0; | ||
| 1007 | |||
| 1008 | if (command == NAND_CMD_SEQIN) | ||
| 1009 | exec_cmd = 0; | ||
| 1010 | |||
| 1011 | addr_cycle = NDCB0_ADDR_CYC(host->row_addr_cycles | ||
| 1012 | + host->col_addr_cycles); | ||
| 1013 | |||
| 1014 | switch (command) { | ||
| 1015 | case NAND_CMD_READOOB: | ||
| 1016 | case NAND_CMD_READ0: | ||
| 1017 | info->buf_start = column; | ||
| 1018 | info->ndcb0 |= NDCB0_CMD_TYPE(0) | ||
| 1019 | | addr_cycle | ||
| 1020 | | NAND_CMD_READ0; | ||
| 1021 | |||
| 1022 | if (command == NAND_CMD_READOOB) | ||
| 1023 | info->buf_start += mtd->writesize; | ||
| 1024 | |||
| 1025 | if (info->cur_chunk < info->nfullchunks) { | ||
| 1026 | info->step_chunk_size = info->chunk_size; | ||
| 1027 | info->step_spare_size = info->spare_size; | ||
| 1028 | } else { | ||
| 1029 | info->step_chunk_size = info->last_chunk_size; | ||
| 1030 | info->step_spare_size = info->last_spare_size; | ||
| 1031 | } | ||
| 1032 | |||
| 1033 | /* | ||
| 1034 | * Multiple page read needs an 'extended command type' field, | ||
| 1035 | * which is either naked-read or last-read according to the | ||
| 1036 | * state. | ||
| 1037 | */ | ||
| 1038 | if (mtd->writesize == PAGE_CHUNK_SIZE) { | ||
| 1039 | info->ndcb0 |= NDCB0_DBC | (NAND_CMD_READSTART << 8); | ||
| 1040 | } else if (mtd->writesize > PAGE_CHUNK_SIZE) { | ||
| 1041 | info->ndcb0 |= NDCB0_DBC | (NAND_CMD_READSTART << 8) | ||
| 1042 | | NDCB0_LEN_OVRD | ||
| 1043 | | NDCB0_EXT_CMD_TYPE(ext_cmd_type); | ||
| 1044 | info->ndcb3 = info->step_chunk_size + | ||
| 1045 | info->step_spare_size; | ||
| 1046 | } | ||
| 1047 | |||
| 1048 | set_command_address(info, mtd->writesize, column, page_addr); | ||
| 1049 | break; | ||
| 1050 | |||
| 1051 | case NAND_CMD_SEQIN: | ||
| 1052 | |||
| 1053 | info->buf_start = column; | ||
| 1054 | set_command_address(info, mtd->writesize, 0, page_addr); | ||
| 1055 | |||
| 1056 | /* | ||
| 1057 | * Multiple page programming needs to execute the initial | ||
| 1058 | * SEQIN command that sets the page address. | ||
| 1059 | */ | ||
| 1060 | if (mtd->writesize > PAGE_CHUNK_SIZE) { | ||
| 1061 | info->ndcb0 |= NDCB0_CMD_TYPE(0x1) | ||
| 1062 | | NDCB0_EXT_CMD_TYPE(ext_cmd_type) | ||
| 1063 | | addr_cycle | ||
| 1064 | | command; | ||
| 1065 | exec_cmd = 1; | ||
| 1066 | } | ||
| 1067 | break; | ||
| 1068 | |||
| 1069 | case NAND_CMD_PAGEPROG: | ||
| 1070 | if (is_buf_blank(info->data_buff, | ||
| 1071 | (mtd->writesize + mtd->oobsize))) { | ||
| 1072 | exec_cmd = 0; | ||
| 1073 | break; | ||
| 1074 | } | ||
| 1075 | |||
| 1076 | if (info->cur_chunk < info->nfullchunks) { | ||
| 1077 | info->step_chunk_size = info->chunk_size; | ||
| 1078 | info->step_spare_size = info->spare_size; | ||
| 1079 | } else { | ||
| 1080 | info->step_chunk_size = info->last_chunk_size; | ||
| 1081 | info->step_spare_size = info->last_spare_size; | ||
| 1082 | } | ||
| 1083 | |||
| 1084 | /* Second command setting for large pages */ | ||
| 1085 | if (mtd->writesize > PAGE_CHUNK_SIZE) { | ||
| 1086 | /* | ||
| 1087 | * Multiple page write uses the 'extended command' | ||
| 1088 | * field. This can be used to issue a command dispatch | ||
| 1089 | * or a naked-write depending on the current stage. | ||
| 1090 | */ | ||
| 1091 | info->ndcb0 |= NDCB0_CMD_TYPE(0x1) | ||
| 1092 | | NDCB0_LEN_OVRD | ||
| 1093 | | NDCB0_EXT_CMD_TYPE(ext_cmd_type); | ||
| 1094 | info->ndcb3 = info->step_chunk_size + | ||
| 1095 | info->step_spare_size; | ||
| 1096 | |||
| 1097 | /* | ||
| 1098 | * This is the command dispatch that completes a chunked | ||
| 1099 | * page program operation. | ||
| 1100 | */ | ||
| 1101 | if (info->cur_chunk == info->ntotalchunks) { | ||
| 1102 | info->ndcb0 = NDCB0_CMD_TYPE(0x1) | ||
| 1103 | | NDCB0_EXT_CMD_TYPE(ext_cmd_type) | ||
| 1104 | | command; | ||
| 1105 | info->ndcb1 = 0; | ||
| 1106 | info->ndcb2 = 0; | ||
| 1107 | info->ndcb3 = 0; | ||
| 1108 | } | ||
| 1109 | } else { | ||
| 1110 | info->ndcb0 |= NDCB0_CMD_TYPE(0x1) | ||
| 1111 | | NDCB0_AUTO_RS | ||
| 1112 | | NDCB0_ST_ROW_EN | ||
| 1113 | | NDCB0_DBC | ||
| 1114 | | (NAND_CMD_PAGEPROG << 8) | ||
| 1115 | | NAND_CMD_SEQIN | ||
| 1116 | | addr_cycle; | ||
| 1117 | } | ||
| 1118 | break; | ||
| 1119 | |||
| 1120 | case NAND_CMD_PARAM: | ||
| 1121 | info->buf_count = INIT_BUFFER_SIZE; | ||
| 1122 | info->ndcb0 |= NDCB0_CMD_TYPE(0) | ||
| 1123 | | NDCB0_ADDR_CYC(1) | ||
| 1124 | | NDCB0_LEN_OVRD | ||
| 1125 | | command; | ||
| 1126 | info->ndcb1 = (column & 0xFF); | ||
| 1127 | info->ndcb3 = INIT_BUFFER_SIZE; | ||
| 1128 | info->step_chunk_size = INIT_BUFFER_SIZE; | ||
| 1129 | break; | ||
| 1130 | |||
| 1131 | case NAND_CMD_READID: | ||
| 1132 | info->buf_count = READ_ID_BYTES; | ||
| 1133 | info->ndcb0 |= NDCB0_CMD_TYPE(3) | ||
| 1134 | | NDCB0_ADDR_CYC(1) | ||
| 1135 | | command; | ||
| 1136 | info->ndcb1 = (column & 0xFF); | ||
| 1137 | |||
| 1138 | info->step_chunk_size = 8; | ||
| 1139 | break; | ||
| 1140 | case NAND_CMD_STATUS: | ||
| 1141 | info->buf_count = 1; | ||
| 1142 | info->ndcb0 |= NDCB0_CMD_TYPE(4) | ||
| 1143 | | NDCB0_ADDR_CYC(1) | ||
| 1144 | | command; | ||
| 1145 | |||
| 1146 | info->step_chunk_size = 8; | ||
| 1147 | break; | ||
| 1148 | |||
| 1149 | case NAND_CMD_ERASE1: | ||
| 1150 | info->ndcb0 |= NDCB0_CMD_TYPE(2) | ||
| 1151 | | NDCB0_AUTO_RS | ||
| 1152 | | NDCB0_ADDR_CYC(3) | ||
| 1153 | | NDCB0_DBC | ||
| 1154 | | (NAND_CMD_ERASE2 << 8) | ||
| 1155 | | NAND_CMD_ERASE1; | ||
| 1156 | info->ndcb1 = page_addr; | ||
| 1157 | info->ndcb2 = 0; | ||
| 1158 | |||
| 1159 | break; | ||
| 1160 | case NAND_CMD_RESET: | ||
| 1161 | info->ndcb0 |= NDCB0_CMD_TYPE(5) | ||
| 1162 | | command; | ||
| 1163 | |||
| 1164 | break; | ||
| 1165 | |||
| 1166 | case NAND_CMD_ERASE2: | ||
| 1167 | exec_cmd = 0; | ||
| 1168 | break; | ||
| 1169 | |||
| 1170 | default: | ||
| 1171 | exec_cmd = 0; | ||
| 1172 | dev_err(&info->pdev->dev, "non-supported command %x\n", | ||
| 1173 | command); | ||
| 1174 | break; | ||
| 1175 | } | ||
| 1176 | |||
| 1177 | return exec_cmd; | ||
| 1178 | } | ||
| 1179 | |||
| 1180 | static void nand_cmdfunc(struct mtd_info *mtd, unsigned command, | ||
| 1181 | int column, int page_addr) | ||
| 1182 | { | ||
| 1183 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
| 1184 | struct pxa3xx_nand_host *host = nand_get_controller_data(chip); | ||
| 1185 | struct pxa3xx_nand_info *info = host->info_data; | ||
| 1186 | int exec_cmd; | ||
| 1187 | |||
| 1188 | /* | ||
| 1189 | * if this is a x16 device ,then convert the input | ||
| 1190 | * "byte" address into a "word" address appropriate | ||
| 1191 | * for indexing a word-oriented device | ||
| 1192 | */ | ||
| 1193 | if (info->reg_ndcr & NDCR_DWIDTH_M) | ||
| 1194 | column /= 2; | ||
| 1195 | |||
| 1196 | /* | ||
| 1197 | * There may be different NAND chip hooked to | ||
| 1198 | * different chip select, so check whether | ||
| 1199 | * chip select has been changed, if yes, reset the timing | ||
| 1200 | */ | ||
| 1201 | if (info->cs != host->cs) { | ||
| 1202 | info->cs = host->cs; | ||
| 1203 | nand_writel(info, NDTR0CS0, info->ndtr0cs0); | ||
| 1204 | nand_writel(info, NDTR1CS0, info->ndtr1cs0); | ||
| 1205 | } | ||
| 1206 | |||
| 1207 | prepare_start_command(info, command); | ||
| 1208 | |||
| 1209 | info->state = STATE_PREPARED; | ||
| 1210 | exec_cmd = prepare_set_command(info, command, 0, column, page_addr); | ||
| 1211 | |||
| 1212 | if (exec_cmd) { | ||
| 1213 | init_completion(&info->cmd_complete); | ||
| 1214 | init_completion(&info->dev_ready); | ||
| 1215 | info->need_wait = 1; | ||
| 1216 | pxa3xx_nand_start(info); | ||
| 1217 | |||
| 1218 | if (!wait_for_completion_timeout(&info->cmd_complete, | ||
| 1219 | CHIP_DELAY_TIMEOUT)) { | ||
| 1220 | dev_err(&info->pdev->dev, "Wait time out!!!\n"); | ||
| 1221 | /* Stop State Machine for next command cycle */ | ||
| 1222 | pxa3xx_nand_stop(info); | ||
| 1223 | } | ||
| 1224 | } | ||
| 1225 | info->state = STATE_IDLE; | ||
| 1226 | } | ||
| 1227 | |||
| 1228 | static void nand_cmdfunc_extended(struct mtd_info *mtd, | ||
| 1229 | const unsigned command, | ||
| 1230 | int column, int page_addr) | ||
| 1231 | { | ||
| 1232 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
| 1233 | struct pxa3xx_nand_host *host = nand_get_controller_data(chip); | ||
| 1234 | struct pxa3xx_nand_info *info = host->info_data; | ||
| 1235 | int exec_cmd, ext_cmd_type; | ||
| 1236 | |||
| 1237 | /* | ||
| 1238 | * if this is a x16 device then convert the input | ||
| 1239 | * "byte" address into a "word" address appropriate | ||
| 1240 | * for indexing a word-oriented device | ||
| 1241 | */ | ||
| 1242 | if (info->reg_ndcr & NDCR_DWIDTH_M) | ||
| 1243 | column /= 2; | ||
| 1244 | |||
| 1245 | /* | ||
| 1246 | * There may be different NAND chip hooked to | ||
| 1247 | * different chip select, so check whether | ||
| 1248 | * chip select has been changed, if yes, reset the timing | ||
| 1249 | */ | ||
| 1250 | if (info->cs != host->cs) { | ||
| 1251 | info->cs = host->cs; | ||
| 1252 | nand_writel(info, NDTR0CS0, info->ndtr0cs0); | ||
| 1253 | nand_writel(info, NDTR1CS0, info->ndtr1cs0); | ||
| 1254 | } | ||
| 1255 | |||
| 1256 | /* Select the extended command for the first command */ | ||
| 1257 | switch (command) { | ||
| 1258 | case NAND_CMD_READ0: | ||
| 1259 | case NAND_CMD_READOOB: | ||
| 1260 | ext_cmd_type = EXT_CMD_TYPE_MONO; | ||
| 1261 | break; | ||
| 1262 | case NAND_CMD_SEQIN: | ||
| 1263 | ext_cmd_type = EXT_CMD_TYPE_DISPATCH; | ||
| 1264 | break; | ||
| 1265 | case NAND_CMD_PAGEPROG: | ||
| 1266 | ext_cmd_type = EXT_CMD_TYPE_NAKED_RW; | ||
| 1267 | break; | ||
| 1268 | default: | ||
| 1269 | ext_cmd_type = 0; | ||
| 1270 | break; | ||
| 1271 | } | ||
| 1272 | |||
| 1273 | prepare_start_command(info, command); | ||
| 1274 | |||
| 1275 | /* | ||
| 1276 | * Prepare the "is ready" completion before starting a command | ||
| 1277 | * transaction sequence. If the command is not executed the | ||
| 1278 | * completion will be completed, see below. | ||
| 1279 | * | ||
| 1280 | * We can do that inside the loop because the command variable | ||
| 1281 | * is invariant and thus so is the exec_cmd. | ||
| 1282 | */ | ||
| 1283 | info->need_wait = 1; | ||
| 1284 | init_completion(&info->dev_ready); | ||
| 1285 | do { | ||
| 1286 | info->state = STATE_PREPARED; | ||
| 1287 | |||
| 1288 | exec_cmd = prepare_set_command(info, command, ext_cmd_type, | ||
| 1289 | column, page_addr); | ||
| 1290 | if (!exec_cmd) { | ||
| 1291 | info->need_wait = 0; | ||
| 1292 | complete(&info->dev_ready); | ||
| 1293 | break; | ||
| 1294 | } | ||
| 1295 | |||
| 1296 | init_completion(&info->cmd_complete); | ||
| 1297 | pxa3xx_nand_start(info); | ||
| 1298 | |||
| 1299 | if (!wait_for_completion_timeout(&info->cmd_complete, | ||
| 1300 | CHIP_DELAY_TIMEOUT)) { | ||
| 1301 | dev_err(&info->pdev->dev, "Wait time out!!!\n"); | ||
| 1302 | /* Stop State Machine for next command cycle */ | ||
| 1303 | pxa3xx_nand_stop(info); | ||
| 1304 | break; | ||
| 1305 | } | ||
| 1306 | |||
| 1307 | /* Only a few commands need several steps */ | ||
| 1308 | if (command != NAND_CMD_PAGEPROG && | ||
| 1309 | command != NAND_CMD_READ0 && | ||
| 1310 | command != NAND_CMD_READOOB) | ||
| 1311 | break; | ||
| 1312 | |||
| 1313 | info->cur_chunk++; | ||
| 1314 | |||
| 1315 | /* Check if the sequence is complete */ | ||
| 1316 | if (info->cur_chunk == info->ntotalchunks && command != NAND_CMD_PAGEPROG) | ||
| 1317 | break; | ||
| 1318 | |||
| 1319 | /* | ||
| 1320 | * After a splitted program command sequence has issued | ||
| 1321 | * the command dispatch, the command sequence is complete. | ||
| 1322 | */ | ||
| 1323 | if (info->cur_chunk == (info->ntotalchunks + 1) && | ||
| 1324 | command == NAND_CMD_PAGEPROG && | ||
| 1325 | ext_cmd_type == EXT_CMD_TYPE_DISPATCH) | ||
| 1326 | break; | ||
| 1327 | |||
| 1328 | if (command == NAND_CMD_READ0 || command == NAND_CMD_READOOB) { | ||
| 1329 | /* Last read: issue a 'last naked read' */ | ||
| 1330 | if (info->cur_chunk == info->ntotalchunks - 1) | ||
| 1331 | ext_cmd_type = EXT_CMD_TYPE_LAST_RW; | ||
| 1332 | else | ||
| 1333 | ext_cmd_type = EXT_CMD_TYPE_NAKED_RW; | ||
| 1334 | |||
| 1335 | /* | ||
| 1336 | * If a splitted program command has no more data to transfer, | ||
| 1337 | * the command dispatch must be issued to complete. | ||
| 1338 | */ | ||
| 1339 | } else if (command == NAND_CMD_PAGEPROG && | ||
| 1340 | info->cur_chunk == info->ntotalchunks) { | ||
| 1341 | ext_cmd_type = EXT_CMD_TYPE_DISPATCH; | ||
| 1342 | } | ||
| 1343 | } while (1); | ||
| 1344 | |||
| 1345 | info->state = STATE_IDLE; | ||
| 1346 | } | ||
| 1347 | |||
| 1348 | static int pxa3xx_nand_write_page_hwecc(struct mtd_info *mtd, | ||
| 1349 | struct nand_chip *chip, const uint8_t *buf, int oob_required, | ||
| 1350 | int page) | ||
| 1351 | { | ||
| 1352 | nand_prog_page_begin_op(chip, page, 0, buf, mtd->writesize); | ||
| 1353 | chip->write_buf(mtd, chip->oob_poi, mtd->oobsize); | ||
| 1354 | |||
| 1355 | return nand_prog_page_end_op(chip); | ||
| 1356 | } | ||
| 1357 | |||
| 1358 | static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd, | ||
| 1359 | struct nand_chip *chip, uint8_t *buf, int oob_required, | ||
| 1360 | int page) | ||
| 1361 | { | ||
| 1362 | struct pxa3xx_nand_host *host = nand_get_controller_data(chip); | ||
| 1363 | struct pxa3xx_nand_info *info = host->info_data; | ||
| 1364 | |||
| 1365 | nand_read_page_op(chip, page, 0, buf, mtd->writesize); | ||
| 1366 | chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); | ||
| 1367 | |||
| 1368 | if (info->retcode == ERR_CORERR && info->use_ecc) { | ||
| 1369 | mtd->ecc_stats.corrected += info->ecc_err_cnt; | ||
| 1370 | |||
| 1371 | } else if (info->retcode == ERR_UNCORERR) { | ||
| 1372 | /* | ||
| 1373 | * for blank page (all 0xff), HW will calculate its ECC as | ||
| 1374 | * 0, which is different from the ECC information within | ||
| 1375 | * OOB, ignore such uncorrectable errors | ||
| 1376 | */ | ||
| 1377 | if (is_buf_blank(buf, mtd->writesize)) | ||
| 1378 | info->retcode = ERR_NONE; | ||
| 1379 | else | ||
| 1380 | mtd->ecc_stats.failed++; | ||
| 1381 | } | ||
| 1382 | |||
| 1383 | return info->max_bitflips; | ||
| 1384 | } | ||
| 1385 | |||
| 1386 | static uint8_t pxa3xx_nand_read_byte(struct mtd_info *mtd) | ||
| 1387 | { | ||
| 1388 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
| 1389 | struct pxa3xx_nand_host *host = nand_get_controller_data(chip); | ||
| 1390 | struct pxa3xx_nand_info *info = host->info_data; | ||
| 1391 | char retval = 0xFF; | ||
| 1392 | |||
| 1393 | if (info->buf_start < info->buf_count) | ||
| 1394 | /* Has just send a new command? */ | ||
| 1395 | retval = info->data_buff[info->buf_start++]; | ||
| 1396 | |||
| 1397 | return retval; | ||
| 1398 | } | ||
| 1399 | |||
| 1400 | static u16 pxa3xx_nand_read_word(struct mtd_info *mtd) | ||
| 1401 | { | ||
| 1402 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
| 1403 | struct pxa3xx_nand_host *host = nand_get_controller_data(chip); | ||
| 1404 | struct pxa3xx_nand_info *info = host->info_data; | ||
| 1405 | u16 retval = 0xFFFF; | ||
| 1406 | |||
| 1407 | if (!(info->buf_start & 0x01) && info->buf_start < info->buf_count) { | ||
| 1408 | retval = *((u16 *)(info->data_buff+info->buf_start)); | ||
| 1409 | info->buf_start += 2; | ||
| 1410 | } | ||
| 1411 | return retval; | ||
| 1412 | } | ||
| 1413 | |||
| 1414 | static void pxa3xx_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | ||
| 1415 | { | ||
| 1416 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
| 1417 | struct pxa3xx_nand_host *host = nand_get_controller_data(chip); | ||
| 1418 | struct pxa3xx_nand_info *info = host->info_data; | ||
| 1419 | int real_len = min_t(size_t, len, info->buf_count - info->buf_start); | ||
| 1420 | |||
| 1421 | memcpy(buf, info->data_buff + info->buf_start, real_len); | ||
| 1422 | info->buf_start += real_len; | ||
| 1423 | } | ||
| 1424 | |||
| 1425 | static void pxa3xx_nand_write_buf(struct mtd_info *mtd, | ||
| 1426 | const uint8_t *buf, int len) | ||
| 1427 | { | ||
| 1428 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
| 1429 | struct pxa3xx_nand_host *host = nand_get_controller_data(chip); | ||
| 1430 | struct pxa3xx_nand_info *info = host->info_data; | ||
| 1431 | int real_len = min_t(size_t, len, info->buf_count - info->buf_start); | ||
| 1432 | |||
| 1433 | memcpy(info->data_buff + info->buf_start, buf, real_len); | ||
| 1434 | info->buf_start += real_len; | ||
| 1435 | } | ||
| 1436 | |||
| 1437 | static void pxa3xx_nand_select_chip(struct mtd_info *mtd, int chip) | ||
| 1438 | { | ||
| 1439 | return; | ||
| 1440 | } | ||
| 1441 | |||
| 1442 | static int pxa3xx_nand_waitfunc(struct mtd_info *mtd, struct nand_chip *this) | ||
| 1443 | { | ||
| 1444 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
| 1445 | struct pxa3xx_nand_host *host = nand_get_controller_data(chip); | ||
| 1446 | struct pxa3xx_nand_info *info = host->info_data; | ||
| 1447 | |||
| 1448 | if (info->need_wait) { | ||
| 1449 | info->need_wait = 0; | ||
| 1450 | if (!wait_for_completion_timeout(&info->dev_ready, | ||
| 1451 | CHIP_DELAY_TIMEOUT)) { | ||
| 1452 | dev_err(&info->pdev->dev, "Ready time out!!!\n"); | ||
| 1453 | return NAND_STATUS_FAIL; | ||
| 1454 | } | ||
| 1455 | } | ||
| 1456 | |||
| 1457 | /* pxa3xx_nand_send_command has waited for command complete */ | ||
| 1458 | if (this->state == FL_WRITING || this->state == FL_ERASING) { | ||
| 1459 | if (info->retcode == ERR_NONE) | ||
| 1460 | return 0; | ||
| 1461 | else | ||
| 1462 | return NAND_STATUS_FAIL; | ||
| 1463 | } | ||
| 1464 | |||
| 1465 | return NAND_STATUS_READY; | ||
| 1466 | } | ||
| 1467 | |||
| 1468 | static int pxa3xx_nand_config_ident(struct pxa3xx_nand_info *info) | ||
| 1469 | { | ||
| 1470 | struct pxa3xx_nand_host *host = info->host[info->cs]; | ||
| 1471 | struct platform_device *pdev = info->pdev; | ||
| 1472 | struct pxa3xx_nand_platform_data *pdata = dev_get_platdata(&pdev->dev); | ||
| 1473 | const struct nand_sdr_timings *timings; | ||
| 1474 | |||
| 1475 | /* Configure default flash values */ | ||
| 1476 | info->chunk_size = PAGE_CHUNK_SIZE; | ||
| 1477 | info->reg_ndcr = 0x0; /* enable all interrupts */ | ||
| 1478 | info->reg_ndcr |= (pdata->enable_arbiter) ? NDCR_ND_ARB_EN : 0; | ||
| 1479 | info->reg_ndcr |= NDCR_RD_ID_CNT(READ_ID_BYTES); | ||
| 1480 | info->reg_ndcr |= NDCR_SPARE_EN; | ||
| 1481 | |||
| 1482 | /* use the common timing to make a try */ | ||
| 1483 | timings = onfi_async_timing_mode_to_sdr_timings(0); | ||
| 1484 | if (IS_ERR(timings)) | ||
| 1485 | return PTR_ERR(timings); | ||
| 1486 | |||
| 1487 | pxa3xx_nand_set_sdr_timing(host, timings); | ||
| 1488 | return 0; | ||
| 1489 | } | ||
| 1490 | |||
| 1491 | static void pxa3xx_nand_config_tail(struct pxa3xx_nand_info *info) | ||
| 1492 | { | ||
| 1493 | struct pxa3xx_nand_host *host = info->host[info->cs]; | ||
| 1494 | struct nand_chip *chip = &host->chip; | ||
| 1495 | struct mtd_info *mtd = nand_to_mtd(chip); | ||
| 1496 | |||
| 1497 | info->reg_ndcr |= (host->col_addr_cycles == 2) ? NDCR_RA_START : 0; | ||
| 1498 | info->reg_ndcr |= (chip->page_shift == 6) ? NDCR_PG_PER_BLK : 0; | ||
| 1499 | info->reg_ndcr |= (mtd->writesize == 2048) ? NDCR_PAGE_SZ : 0; | ||
| 1500 | } | ||
| 1501 | |||
| 1502 | static void pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info) | ||
| 1503 | { | ||
| 1504 | struct platform_device *pdev = info->pdev; | ||
| 1505 | struct pxa3xx_nand_platform_data *pdata = dev_get_platdata(&pdev->dev); | ||
| 1506 | uint32_t ndcr = nand_readl(info, NDCR); | ||
| 1507 | |||
| 1508 | /* Set an initial chunk size */ | ||
| 1509 | info->chunk_size = ndcr & NDCR_PAGE_SZ ? 2048 : 512; | ||
| 1510 | info->reg_ndcr = ndcr & | ||
| 1511 | ~(NDCR_INT_MASK | NDCR_ND_ARB_EN | NFCV1_NDCR_ARB_CNTL); | ||
| 1512 | info->reg_ndcr |= (pdata->enable_arbiter) ? NDCR_ND_ARB_EN : 0; | ||
| 1513 | info->ndtr0cs0 = nand_readl(info, NDTR0CS0); | ||
| 1514 | info->ndtr1cs0 = nand_readl(info, NDTR1CS0); | ||
| 1515 | } | ||
| 1516 | |||
| 1517 | static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info) | ||
| 1518 | { | ||
| 1519 | struct platform_device *pdev = info->pdev; | ||
| 1520 | struct dma_slave_config config; | ||
| 1521 | dma_cap_mask_t mask; | ||
| 1522 | struct pxad_param param; | ||
| 1523 | int ret; | ||
| 1524 | |||
| 1525 | info->data_buff = kmalloc(info->buf_size, GFP_KERNEL); | ||
| 1526 | if (info->data_buff == NULL) | ||
| 1527 | return -ENOMEM; | ||
| 1528 | if (use_dma == 0) | ||
| 1529 | return 0; | ||
| 1530 | |||
| 1531 | ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); | ||
| 1532 | if (ret) | ||
| 1533 | return ret; | ||
| 1534 | |||
| 1535 | sg_init_one(&info->sg, info->data_buff, info->buf_size); | ||
| 1536 | dma_cap_zero(mask); | ||
| 1537 | dma_cap_set(DMA_SLAVE, mask); | ||
| 1538 | param.prio = PXAD_PRIO_LOWEST; | ||
| 1539 | param.drcmr = info->drcmr_dat; | ||
| 1540 | info->dma_chan = dma_request_slave_channel_compat(mask, pxad_filter_fn, | ||
| 1541 | ¶m, &pdev->dev, | ||
| 1542 | "data"); | ||
| 1543 | if (!info->dma_chan) { | ||
| 1544 | dev_err(&pdev->dev, "unable to request data dma channel\n"); | ||
| 1545 | return -ENODEV; | ||
| 1546 | } | ||
| 1547 | |||
| 1548 | memset(&config, 0, sizeof(config)); | ||
| 1549 | config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
| 1550 | config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
| 1551 | config.src_addr = info->mmio_phys + NDDB; | ||
| 1552 | config.dst_addr = info->mmio_phys + NDDB; | ||
| 1553 | config.src_maxburst = 32; | ||
| 1554 | config.dst_maxburst = 32; | ||
| 1555 | ret = dmaengine_slave_config(info->dma_chan, &config); | ||
| 1556 | if (ret < 0) { | ||
| 1557 | dev_err(&info->pdev->dev, | ||
| 1558 | "dma channel configuration failed: %d\n", | ||
| 1559 | ret); | ||
| 1560 | return ret; | ||
| 1561 | } | ||
| 1562 | |||
| 1563 | /* | ||
| 1564 | * Now that DMA buffers are allocated we turn on | ||
| 1565 | * DMA proper for I/O operations. | ||
| 1566 | */ | ||
| 1567 | info->use_dma = 1; | ||
| 1568 | return 0; | ||
| 1569 | } | ||
| 1570 | |||
| 1571 | static void pxa3xx_nand_free_buff(struct pxa3xx_nand_info *info) | ||
| 1572 | { | ||
| 1573 | if (info->use_dma) { | ||
| 1574 | dmaengine_terminate_all(info->dma_chan); | ||
| 1575 | dma_release_channel(info->dma_chan); | ||
| 1576 | } | ||
| 1577 | kfree(info->data_buff); | ||
| 1578 | } | ||
| 1579 | |||
| 1580 | static int pxa_ecc_init(struct pxa3xx_nand_info *info, | ||
| 1581 | struct mtd_info *mtd, | ||
| 1582 | int strength, int ecc_stepsize, int page_size) | ||
| 1583 | { | ||
| 1584 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
| 1585 | struct nand_ecc_ctrl *ecc = &chip->ecc; | ||
| 1586 | |||
| 1587 | if (strength == 1 && ecc_stepsize == 512 && page_size == 2048) { | ||
| 1588 | info->nfullchunks = 1; | ||
| 1589 | info->ntotalchunks = 1; | ||
| 1590 | info->chunk_size = 2048; | ||
| 1591 | info->spare_size = 40; | ||
| 1592 | info->ecc_size = 24; | ||
| 1593 | ecc->mode = NAND_ECC_HW; | ||
| 1594 | ecc->size = 512; | ||
| 1595 | ecc->strength = 1; | ||
| 1596 | |||
| 1597 | } else if (strength == 1 && ecc_stepsize == 512 && page_size == 512) { | ||
| 1598 | info->nfullchunks = 1; | ||
| 1599 | info->ntotalchunks = 1; | ||
| 1600 | info->chunk_size = 512; | ||
| 1601 | info->spare_size = 8; | ||
| 1602 | info->ecc_size = 8; | ||
| 1603 | ecc->mode = NAND_ECC_HW; | ||
| 1604 | ecc->size = 512; | ||
| 1605 | ecc->strength = 1; | ||
| 1606 | |||
| 1607 | /* | ||
| 1608 | * Required ECC: 4-bit correction per 512 bytes | ||
| 1609 | * Select: 16-bit correction per 2048 bytes | ||
| 1610 | */ | ||
| 1611 | } else if (strength == 4 && ecc_stepsize == 512 && page_size == 2048) { | ||
| 1612 | info->ecc_bch = 1; | ||
| 1613 | info->nfullchunks = 1; | ||
| 1614 | info->ntotalchunks = 1; | ||
| 1615 | info->chunk_size = 2048; | ||
| 1616 | info->spare_size = 32; | ||
| 1617 | info->ecc_size = 32; | ||
| 1618 | ecc->mode = NAND_ECC_HW; | ||
| 1619 | ecc->size = info->chunk_size; | ||
| 1620 | mtd_set_ooblayout(mtd, &pxa3xx_ooblayout_ops); | ||
| 1621 | ecc->strength = 16; | ||
| 1622 | |||
| 1623 | } else if (strength == 4 && ecc_stepsize == 512 && page_size == 4096) { | ||
| 1624 | info->ecc_bch = 1; | ||
| 1625 | info->nfullchunks = 2; | ||
| 1626 | info->ntotalchunks = 2; | ||
| 1627 | info->chunk_size = 2048; | ||
| 1628 | info->spare_size = 32; | ||
| 1629 | info->ecc_size = 32; | ||
| 1630 | ecc->mode = NAND_ECC_HW; | ||
| 1631 | ecc->size = info->chunk_size; | ||
| 1632 | mtd_set_ooblayout(mtd, &pxa3xx_ooblayout_ops); | ||
| 1633 | ecc->strength = 16; | ||
| 1634 | |||
| 1635 | /* | ||
| 1636 | * Required ECC: 8-bit correction per 512 bytes | ||
| 1637 | * Select: 16-bit correction per 1024 bytes | ||
| 1638 | */ | ||
| 1639 | } else if (strength == 8 && ecc_stepsize == 512 && page_size == 4096) { | ||
| 1640 | info->ecc_bch = 1; | ||
| 1641 | info->nfullchunks = 4; | ||
| 1642 | info->ntotalchunks = 5; | ||
| 1643 | info->chunk_size = 1024; | ||
| 1644 | info->spare_size = 0; | ||
| 1645 | info->last_chunk_size = 0; | ||
| 1646 | info->last_spare_size = 64; | ||
| 1647 | info->ecc_size = 32; | ||
| 1648 | ecc->mode = NAND_ECC_HW; | ||
| 1649 | ecc->size = info->chunk_size; | ||
| 1650 | mtd_set_ooblayout(mtd, &pxa3xx_ooblayout_ops); | ||
| 1651 | ecc->strength = 16; | ||
| 1652 | } else { | ||
| 1653 | dev_err(&info->pdev->dev, | ||
| 1654 | "ECC strength %d at page size %d is not supported\n", | ||
| 1655 | strength, page_size); | ||
| 1656 | return -ENODEV; | ||
| 1657 | } | ||
| 1658 | |||
| 1659 | dev_info(&info->pdev->dev, "ECC strength %d, ECC step size %d\n", | ||
| 1660 | ecc->strength, ecc->size); | ||
| 1661 | return 0; | ||
| 1662 | } | ||
| 1663 | |||
| 1664 | static int pxa3xx_nand_scan(struct mtd_info *mtd) | ||
| 1665 | { | ||
| 1666 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
| 1667 | struct pxa3xx_nand_host *host = nand_get_controller_data(chip); | ||
| 1668 | struct pxa3xx_nand_info *info = host->info_data; | ||
| 1669 | struct platform_device *pdev = info->pdev; | ||
| 1670 | struct pxa3xx_nand_platform_data *pdata = dev_get_platdata(&pdev->dev); | ||
| 1671 | int ret; | ||
| 1672 | uint16_t ecc_strength, ecc_step; | ||
| 1673 | |||
| 1674 | if (pdata->keep_config) { | ||
| 1675 | pxa3xx_nand_detect_config(info); | ||
| 1676 | } else { | ||
| 1677 | ret = pxa3xx_nand_config_ident(info); | ||
| 1678 | if (ret) | ||
| 1679 | return ret; | ||
| 1680 | } | ||
| 1681 | |||
| 1682 | if (info->reg_ndcr & NDCR_DWIDTH_M) | ||
| 1683 | chip->options |= NAND_BUSWIDTH_16; | ||
| 1684 | |||
| 1685 | /* Device detection must be done with ECC disabled */ | ||
| 1686 | if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370 || | ||
| 1687 | info->variant == PXA3XX_NAND_VARIANT_ARMADA_8K) | ||
| 1688 | nand_writel(info, NDECCCTRL, 0x0); | ||
| 1689 | |||
| 1690 | if (pdata->flash_bbt) | ||
| 1691 | chip->bbt_options |= NAND_BBT_USE_FLASH; | ||
| 1692 | |||
| 1693 | chip->ecc.strength = pdata->ecc_strength; | ||
| 1694 | chip->ecc.size = pdata->ecc_step_size; | ||
| 1695 | |||
| 1696 | ret = nand_scan_ident(mtd, 1, NULL); | ||
| 1697 | if (ret) | ||
| 1698 | return ret; | ||
| 1699 | |||
| 1700 | if (!pdata->keep_config) { | ||
| 1701 | ret = pxa3xx_nand_init(host); | ||
| 1702 | if (ret) { | ||
| 1703 | dev_err(&info->pdev->dev, "Failed to init nand: %d\n", | ||
| 1704 | ret); | ||
| 1705 | return ret; | ||
| 1706 | } | ||
| 1707 | } | ||
| 1708 | |||
| 1709 | if (chip->bbt_options & NAND_BBT_USE_FLASH) { | ||
| 1710 | /* | ||
| 1711 | * We'll use a bad block table stored in-flash and don't | ||
| 1712 | * allow writing the bad block marker to the flash. | ||
| 1713 | */ | ||
| 1714 | chip->bbt_options |= NAND_BBT_NO_OOB_BBM; | ||
| 1715 | chip->bbt_td = &bbt_main_descr; | ||
| 1716 | chip->bbt_md = &bbt_mirror_descr; | ||
| 1717 | } | ||
| 1718 | |||
| 1719 | /* | ||
| 1720 | * If the page size is bigger than the FIFO size, let's check | ||
| 1721 | * we are given the right variant and then switch to the extended | ||
| 1722 | * (aka splitted) command handling, | ||
| 1723 | */ | ||
| 1724 | if (mtd->writesize > PAGE_CHUNK_SIZE) { | ||
| 1725 | if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370 || | ||
| 1726 | info->variant == PXA3XX_NAND_VARIANT_ARMADA_8K) { | ||
| 1727 | chip->cmdfunc = nand_cmdfunc_extended; | ||
| 1728 | } else { | ||
| 1729 | dev_err(&info->pdev->dev, | ||
| 1730 | "unsupported page size on this variant\n"); | ||
| 1731 | return -ENODEV; | ||
| 1732 | } | ||
| 1733 | } | ||
| 1734 | |||
| 1735 | ecc_strength = chip->ecc.strength; | ||
| 1736 | ecc_step = chip->ecc.size; | ||
| 1737 | if (!ecc_strength || !ecc_step) { | ||
| 1738 | ecc_strength = chip->ecc_strength_ds; | ||
| 1739 | ecc_step = chip->ecc_step_ds; | ||
| 1740 | } | ||
| 1741 | |||
| 1742 | /* Set default ECC strength requirements on non-ONFI devices */ | ||
| 1743 | if (ecc_strength < 1 && ecc_step < 1) { | ||
| 1744 | ecc_strength = 1; | ||
| 1745 | ecc_step = 512; | ||
| 1746 | } | ||
| 1747 | |||
| 1748 | ret = pxa_ecc_init(info, mtd, ecc_strength, | ||
| 1749 | ecc_step, mtd->writesize); | ||
| 1750 | if (ret) | ||
| 1751 | return ret; | ||
| 1752 | |||
| 1753 | /* calculate addressing information */ | ||
| 1754 | if (mtd->writesize >= 2048) | ||
| 1755 | host->col_addr_cycles = 2; | ||
| 1756 | else | ||
| 1757 | host->col_addr_cycles = 1; | ||
| 1758 | |||
| 1759 | /* release the initial buffer */ | ||
| 1760 | kfree(info->data_buff); | ||
| 1761 | |||
| 1762 | /* allocate the real data + oob buffer */ | ||
| 1763 | info->buf_size = mtd->writesize + mtd->oobsize; | ||
| 1764 | ret = pxa3xx_nand_init_buff(info); | ||
| 1765 | if (ret) | ||
| 1766 | return ret; | ||
| 1767 | info->oob_buff = info->data_buff + mtd->writesize; | ||
| 1768 | |||
| 1769 | if ((mtd->size >> chip->page_shift) > 65536) | ||
| 1770 | host->row_addr_cycles = 3; | ||
| 1771 | else | ||
| 1772 | host->row_addr_cycles = 2; | ||
| 1773 | |||
| 1774 | if (!pdata->keep_config) | ||
| 1775 | pxa3xx_nand_config_tail(info); | ||
| 1776 | |||
| 1777 | return nand_scan_tail(mtd); | ||
| 1778 | } | ||
| 1779 | |||
| 1780 | static int alloc_nand_resource(struct platform_device *pdev) | ||
| 1781 | { | ||
| 1782 | struct device_node *np = pdev->dev.of_node; | ||
| 1783 | struct pxa3xx_nand_platform_data *pdata; | ||
| 1784 | struct pxa3xx_nand_info *info; | ||
| 1785 | struct pxa3xx_nand_host *host; | ||
| 1786 | struct nand_chip *chip = NULL; | ||
| 1787 | struct mtd_info *mtd; | ||
| 1788 | struct resource *r; | ||
| 1789 | int ret, irq, cs; | ||
| 1790 | |||
| 1791 | pdata = dev_get_platdata(&pdev->dev); | ||
| 1792 | if (pdata->num_cs <= 0) { | ||
| 1793 | dev_err(&pdev->dev, "invalid number of chip selects\n"); | ||
| 1794 | return -ENODEV; | ||
| 1795 | } | ||
| 1796 | |||
| 1797 | info = devm_kzalloc(&pdev->dev, | ||
| 1798 | sizeof(*info) + sizeof(*host) * pdata->num_cs, | ||
| 1799 | GFP_KERNEL); | ||
| 1800 | if (!info) | ||
| 1801 | return -ENOMEM; | ||
| 1802 | |||
| 1803 | info->pdev = pdev; | ||
| 1804 | info->variant = pxa3xx_nand_get_variant(pdev); | ||
| 1805 | for (cs = 0; cs < pdata->num_cs; cs++) { | ||
| 1806 | host = (void *)&info[1] + sizeof(*host) * cs; | ||
| 1807 | chip = &host->chip; | ||
| 1808 | nand_set_controller_data(chip, host); | ||
| 1809 | mtd = nand_to_mtd(chip); | ||
| 1810 | info->host[cs] = host; | ||
| 1811 | host->cs = cs; | ||
| 1812 | host->info_data = info; | ||
| 1813 | mtd->dev.parent = &pdev->dev; | ||
| 1814 | /* FIXME: all chips use the same device tree partitions */ | ||
| 1815 | nand_set_flash_node(chip, np); | ||
| 1816 | |||
| 1817 | nand_set_controller_data(chip, host); | ||
| 1818 | chip->ecc.read_page = pxa3xx_nand_read_page_hwecc; | ||
| 1819 | chip->ecc.write_page = pxa3xx_nand_write_page_hwecc; | ||
| 1820 | chip->controller = &info->controller; | ||
| 1821 | chip->waitfunc = pxa3xx_nand_waitfunc; | ||
| 1822 | chip->select_chip = pxa3xx_nand_select_chip; | ||
| 1823 | chip->read_word = pxa3xx_nand_read_word; | ||
| 1824 | chip->read_byte = pxa3xx_nand_read_byte; | ||
| 1825 | chip->read_buf = pxa3xx_nand_read_buf; | ||
| 1826 | chip->write_buf = pxa3xx_nand_write_buf; | ||
| 1827 | chip->options |= NAND_NO_SUBPAGE_WRITE; | ||
| 1828 | chip->cmdfunc = nand_cmdfunc; | ||
| 1829 | chip->onfi_set_features = nand_onfi_get_set_features_notsupp; | ||
| 1830 | chip->onfi_get_features = nand_onfi_get_set_features_notsupp; | ||
| 1831 | } | ||
| 1832 | |||
| 1833 | nand_hw_control_init(chip->controller); | ||
| 1834 | info->clk = devm_clk_get(&pdev->dev, NULL); | ||
| 1835 | if (IS_ERR(info->clk)) { | ||
| 1836 | ret = PTR_ERR(info->clk); | ||
| 1837 | dev_err(&pdev->dev, "failed to get nand clock: %d\n", ret); | ||
| 1838 | return ret; | ||
| 1839 | } | ||
| 1840 | ret = clk_prepare_enable(info->clk); | ||
| 1841 | if (ret < 0) | ||
| 1842 | return ret; | ||
| 1843 | |||
| 1844 | if (!np && use_dma) { | ||
| 1845 | r = platform_get_resource(pdev, IORESOURCE_DMA, 0); | ||
| 1846 | if (r == NULL) { | ||
| 1847 | dev_err(&pdev->dev, | ||
| 1848 | "no resource defined for data DMA\n"); | ||
| 1849 | ret = -ENXIO; | ||
| 1850 | goto fail_disable_clk; | ||
| 1851 | } | ||
| 1852 | info->drcmr_dat = r->start; | ||
| 1853 | } | ||
| 1854 | |||
| 1855 | irq = platform_get_irq(pdev, 0); | ||
| 1856 | if (irq < 0) { | ||
| 1857 | dev_err(&pdev->dev, "no IRQ resource defined\n"); | ||
| 1858 | ret = -ENXIO; | ||
| 1859 | goto fail_disable_clk; | ||
| 1860 | } | ||
| 1861 | |||
| 1862 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 1863 | info->mmio_base = devm_ioremap_resource(&pdev->dev, r); | ||
| 1864 | if (IS_ERR(info->mmio_base)) { | ||
| 1865 | ret = PTR_ERR(info->mmio_base); | ||
| 1866 | dev_err(&pdev->dev, "failed to map register space: %d\n", ret); | ||
| 1867 | goto fail_disable_clk; | ||
| 1868 | } | ||
| 1869 | info->mmio_phys = r->start; | ||
| 1870 | |||
| 1871 | /* Allocate a buffer to allow flash detection */ | ||
| 1872 | info->buf_size = INIT_BUFFER_SIZE; | ||
| 1873 | info->data_buff = kmalloc(info->buf_size, GFP_KERNEL); | ||
| 1874 | if (info->data_buff == NULL) { | ||
| 1875 | ret = -ENOMEM; | ||
| 1876 | goto fail_disable_clk; | ||
| 1877 | } | ||
| 1878 | |||
| 1879 | /* initialize all interrupts to be disabled */ | ||
| 1880 | disable_int(info, NDSR_MASK); | ||
| 1881 | |||
| 1882 | ret = request_threaded_irq(irq, pxa3xx_nand_irq, | ||
| 1883 | pxa3xx_nand_irq_thread, IRQF_ONESHOT, | ||
| 1884 | pdev->name, info); | ||
| 1885 | if (ret < 0) { | ||
| 1886 | dev_err(&pdev->dev, "failed to request IRQ: %d\n", ret); | ||
| 1887 | goto fail_free_buf; | ||
| 1888 | } | ||
| 1889 | |||
| 1890 | platform_set_drvdata(pdev, info); | ||
| 1891 | |||
| 1892 | return 0; | ||
| 1893 | |||
| 1894 | fail_free_buf: | ||
| 1895 | free_irq(irq, info); | ||
| 1896 | kfree(info->data_buff); | ||
| 1897 | fail_disable_clk: | ||
| 1898 | clk_disable_unprepare(info->clk); | ||
| 1899 | return ret; | ||
| 1900 | } | ||
| 1901 | |||
| 1902 | static int pxa3xx_nand_remove(struct platform_device *pdev) | ||
| 1903 | { | ||
| 1904 | struct pxa3xx_nand_info *info = platform_get_drvdata(pdev); | ||
| 1905 | struct pxa3xx_nand_platform_data *pdata; | ||
| 1906 | int irq, cs; | ||
| 1907 | |||
| 1908 | if (!info) | ||
| 1909 | return 0; | ||
| 1910 | |||
| 1911 | pdata = dev_get_platdata(&pdev->dev); | ||
| 1912 | |||
| 1913 | irq = platform_get_irq(pdev, 0); | ||
| 1914 | if (irq >= 0) | ||
| 1915 | free_irq(irq, info); | ||
| 1916 | pxa3xx_nand_free_buff(info); | ||
| 1917 | |||
| 1918 | /* | ||
| 1919 | * In the pxa3xx case, the DFI bus is shared between the SMC and NFC. | ||
| 1920 | * In order to prevent a lockup of the system bus, the DFI bus | ||
| 1921 | * arbitration is granted to SMC upon driver removal. This is done by | ||
| 1922 | * setting the x_ARB_CNTL bit, which also prevents the NAND to have | ||
| 1923 | * access to the bus anymore. | ||
| 1924 | */ | ||
| 1925 | nand_writel(info, NDCR, | ||
| 1926 | (nand_readl(info, NDCR) & ~NDCR_ND_ARB_EN) | | ||
| 1927 | NFCV1_NDCR_ARB_CNTL); | ||
| 1928 | clk_disable_unprepare(info->clk); | ||
| 1929 | |||
| 1930 | for (cs = 0; cs < pdata->num_cs; cs++) | ||
| 1931 | nand_release(nand_to_mtd(&info->host[cs]->chip)); | ||
| 1932 | return 0; | ||
| 1933 | } | ||
| 1934 | |||
| 1935 | static int pxa3xx_nand_probe_dt(struct platform_device *pdev) | ||
| 1936 | { | ||
| 1937 | struct pxa3xx_nand_platform_data *pdata; | ||
| 1938 | struct device_node *np = pdev->dev.of_node; | ||
| 1939 | const struct of_device_id *of_id = | ||
| 1940 | of_match_device(pxa3xx_nand_dt_ids, &pdev->dev); | ||
| 1941 | |||
| 1942 | if (!of_id) | ||
| 1943 | return 0; | ||
| 1944 | |||
| 1945 | /* | ||
| 1946 | * Some SoCs like A7k/A8k need to enable manually the NAND | ||
| 1947 | * controller to avoid being bootloader dependent. This is done | ||
| 1948 | * through the use of a single bit in the System Functions registers. | ||
| 1949 | */ | ||
| 1950 | if (pxa3xx_nand_get_variant(pdev) == PXA3XX_NAND_VARIANT_ARMADA_8K) { | ||
| 1951 | struct regmap *sysctrl_base = syscon_regmap_lookup_by_phandle( | ||
| 1952 | pdev->dev.of_node, "marvell,system-controller"); | ||
| 1953 | u32 reg; | ||
| 1954 | |||
| 1955 | if (IS_ERR(sysctrl_base)) | ||
| 1956 | return PTR_ERR(sysctrl_base); | ||
| 1957 | |||
| 1958 | regmap_read(sysctrl_base, GENCONF_SOC_DEVICE_MUX, ®); | ||
| 1959 | reg |= GENCONF_SOC_DEVICE_MUX_NFC_EN; | ||
| 1960 | regmap_write(sysctrl_base, GENCONF_SOC_DEVICE_MUX, reg); | ||
| 1961 | } | ||
| 1962 | |||
| 1963 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | ||
| 1964 | if (!pdata) | ||
| 1965 | return -ENOMEM; | ||
| 1966 | |||
| 1967 | if (of_get_property(np, "marvell,nand-enable-arbiter", NULL)) | ||
| 1968 | pdata->enable_arbiter = 1; | ||
| 1969 | if (of_get_property(np, "marvell,nand-keep-config", NULL)) | ||
| 1970 | pdata->keep_config = 1; | ||
| 1971 | of_property_read_u32(np, "num-cs", &pdata->num_cs); | ||
| 1972 | |||
| 1973 | pdev->dev.platform_data = pdata; | ||
| 1974 | |||
| 1975 | return 0; | ||
| 1976 | } | ||
| 1977 | |||
| 1978 | static int pxa3xx_nand_probe(struct platform_device *pdev) | ||
| 1979 | { | ||
| 1980 | struct pxa3xx_nand_platform_data *pdata; | ||
| 1981 | struct pxa3xx_nand_info *info; | ||
| 1982 | int ret, cs, probe_success, dma_available; | ||
| 1983 | |||
| 1984 | dma_available = IS_ENABLED(CONFIG_ARM) && | ||
| 1985 | (IS_ENABLED(CONFIG_ARCH_PXA) || IS_ENABLED(CONFIG_ARCH_MMP)); | ||
| 1986 | if (use_dma && !dma_available) { | ||
| 1987 | use_dma = 0; | ||
| 1988 | dev_warn(&pdev->dev, | ||
| 1989 | "This platform can't do DMA on this device\n"); | ||
| 1990 | } | ||
| 1991 | |||
| 1992 | ret = pxa3xx_nand_probe_dt(pdev); | ||
| 1993 | if (ret) | ||
| 1994 | return ret; | ||
| 1995 | |||
| 1996 | pdata = dev_get_platdata(&pdev->dev); | ||
| 1997 | if (!pdata) { | ||
| 1998 | dev_err(&pdev->dev, "no platform data defined\n"); | ||
| 1999 | return -ENODEV; | ||
| 2000 | } | ||
| 2001 | |||
| 2002 | ret = alloc_nand_resource(pdev); | ||
| 2003 | if (ret) | ||
| 2004 | return ret; | ||
| 2005 | |||
| 2006 | info = platform_get_drvdata(pdev); | ||
| 2007 | probe_success = 0; | ||
| 2008 | for (cs = 0; cs < pdata->num_cs; cs++) { | ||
| 2009 | struct mtd_info *mtd = nand_to_mtd(&info->host[cs]->chip); | ||
| 2010 | |||
| 2011 | /* | ||
| 2012 | * The mtd name matches the one used in 'mtdparts' kernel | ||
| 2013 | * parameter. This name cannot be changed or otherwise | ||
| 2014 | * user's mtd partitions configuration would get broken. | ||
| 2015 | */ | ||
| 2016 | mtd->name = "pxa3xx_nand-0"; | ||
| 2017 | info->cs = cs; | ||
| 2018 | ret = pxa3xx_nand_scan(mtd); | ||
| 2019 | if (ret) { | ||
| 2020 | dev_warn(&pdev->dev, "failed to scan nand at cs %d\n", | ||
| 2021 | cs); | ||
| 2022 | continue; | ||
| 2023 | } | ||
| 2024 | |||
| 2025 | ret = mtd_device_register(mtd, pdata->parts[cs], | ||
| 2026 | pdata->nr_parts[cs]); | ||
| 2027 | if (!ret) | ||
| 2028 | probe_success = 1; | ||
| 2029 | } | ||
| 2030 | |||
| 2031 | if (!probe_success) { | ||
| 2032 | pxa3xx_nand_remove(pdev); | ||
| 2033 | return -ENODEV; | ||
| 2034 | } | ||
| 2035 | |||
| 2036 | return 0; | ||
| 2037 | } | ||
| 2038 | |||
| 2039 | #ifdef CONFIG_PM | ||
| 2040 | static int pxa3xx_nand_suspend(struct device *dev) | ||
| 2041 | { | ||
| 2042 | struct pxa3xx_nand_info *info = dev_get_drvdata(dev); | ||
| 2043 | |||
| 2044 | if (info->state) { | ||
| 2045 | dev_err(dev, "driver busy, state = %d\n", info->state); | ||
| 2046 | return -EAGAIN; | ||
| 2047 | } | ||
| 2048 | |||
| 2049 | clk_disable(info->clk); | ||
| 2050 | return 0; | ||
| 2051 | } | ||
| 2052 | |||
| 2053 | static int pxa3xx_nand_resume(struct device *dev) | ||
| 2054 | { | ||
| 2055 | struct pxa3xx_nand_info *info = dev_get_drvdata(dev); | ||
| 2056 | int ret; | ||
| 2057 | |||
| 2058 | ret = clk_enable(info->clk); | ||
| 2059 | if (ret < 0) | ||
| 2060 | return ret; | ||
| 2061 | |||
| 2062 | /* We don't want to handle interrupt without calling mtd routine */ | ||
| 2063 | disable_int(info, NDCR_INT_MASK); | ||
| 2064 | |||
| 2065 | /* | ||
| 2066 | * Directly set the chip select to a invalid value, | ||
| 2067 | * then the driver would reset the timing according | ||
| 2068 | * to current chip select at the beginning of cmdfunc | ||
| 2069 | */ | ||
| 2070 | info->cs = 0xff; | ||
| 2071 | |||
| 2072 | /* | ||
| 2073 | * As the spec says, the NDSR would be updated to 0x1800 when | ||
| 2074 | * doing the nand_clk disable/enable. | ||
| 2075 | * To prevent it damaging state machine of the driver, clear | ||
| 2076 | * all status before resume | ||
| 2077 | */ | ||
| 2078 | nand_writel(info, NDSR, NDSR_MASK); | ||
| 2079 | |||
| 2080 | return 0; | ||
| 2081 | } | ||
| 2082 | #else | ||
| 2083 | #define pxa3xx_nand_suspend NULL | ||
| 2084 | #define pxa3xx_nand_resume NULL | ||
| 2085 | #endif | ||
| 2086 | |||
| 2087 | static const struct dev_pm_ops pxa3xx_nand_pm_ops = { | ||
| 2088 | .suspend = pxa3xx_nand_suspend, | ||
| 2089 | .resume = pxa3xx_nand_resume, | ||
| 2090 | }; | ||
| 2091 | |||
| 2092 | static struct platform_driver pxa3xx_nand_driver = { | ||
| 2093 | .driver = { | ||
| 2094 | .name = "pxa3xx-nand", | ||
| 2095 | .of_match_table = pxa3xx_nand_dt_ids, | ||
| 2096 | .pm = &pxa3xx_nand_pm_ops, | ||
| 2097 | }, | ||
| 2098 | .probe = pxa3xx_nand_probe, | ||
| 2099 | .remove = pxa3xx_nand_remove, | ||
| 2100 | }; | ||
| 2101 | |||
| 2102 | module_platform_driver(pxa3xx_nand_driver); | ||
| 2103 | |||
| 2104 | MODULE_LICENSE("GPL"); | ||
| 2105 | MODULE_DESCRIPTION("PXA3xx NAND controller driver"); | ||
diff --git a/include/linux/platform_data/mtd-nand-pxa3xx.h b/include/linux/platform_data/mtd-nand-pxa3xx.h index b42ad83cbc20..4fd0f592a2d2 100644 --- a/include/linux/platform_data/mtd-nand-pxa3xx.h +++ b/include/linux/platform_data/mtd-nand-pxa3xx.h | |||
| @@ -6,41 +6,22 @@ | |||
| 6 | #include <linux/mtd/partitions.h> | 6 | #include <linux/mtd/partitions.h> |
| 7 | 7 | ||
| 8 | /* | 8 | /* |
| 9 | * Current pxa3xx_nand controller has two chip select which | 9 | * Current pxa3xx_nand controller has two chip select which both be workable but |
| 10 | * both be workable. | 10 | * historically all platforms remaining on platform data used only one. Switch |
| 11 | * | 11 | * to device tree if you need more. |
| 12 | * Notice should be taken that: | ||
| 13 | * When you want to use this feature, you should not enable the | ||
| 14 | * keep configuration feature, for two chip select could be | ||
| 15 | * attached with different nand chip. The different page size | ||
| 16 | * and timing requirement make the keep configuration impossible. | ||
| 17 | */ | 12 | */ |
| 18 | |||
| 19 | /* The max num of chip select current support */ | ||
| 20 | #define NUM_CHIP_SELECT (2) | ||
| 21 | struct pxa3xx_nand_platform_data { | 13 | struct pxa3xx_nand_platform_data { |
| 22 | 14 | /* Keep OBM/bootloader NFC timing configuration */ | |
| 23 | /* the data flash bus is shared between the Static Memory | 15 | bool keep_config; |
| 24 | * Controller and the Data Flash Controller, the arbiter | 16 | /* Use a flash-based bad block table */ |
| 25 | * controls the ownership of the bus | 17 | bool flash_bbt; |
| 26 | */ | 18 | /* Requested ECC strength and ECC step size */ |
| 27 | int enable_arbiter; | ||
| 28 | |||
| 29 | /* allow platform code to keep OBM/bootloader defined NFC config */ | ||
| 30 | int keep_config; | ||
| 31 | |||
| 32 | /* indicate how many chip selects will be used */ | ||
| 33 | int num_cs; | ||
| 34 | |||
| 35 | /* use an flash-based bad block table */ | ||
| 36 | bool flash_bbt; | ||
| 37 | |||
| 38 | /* requested ECC strength and ECC step size */ | ||
| 39 | int ecc_strength, ecc_step_size; | 19 | int ecc_strength, ecc_step_size; |
| 40 | 20 | /* Partitions */ | |
| 41 | const struct mtd_partition *parts[NUM_CHIP_SELECT]; | 21 | const struct mtd_partition *parts; |
| 42 | unsigned int nr_parts[NUM_CHIP_SELECT]; | 22 | unsigned int nr_parts; |
| 43 | }; | 23 | }; |
| 44 | 24 | ||
| 45 | extern void pxa3xx_set_nand_info(struct pxa3xx_nand_platform_data *info); | 25 | extern void pxa3xx_set_nand_info(struct pxa3xx_nand_platform_data *info); |
| 26 | |||
| 46 | #endif /* __ASM_ARCH_PXA3XX_NAND_H */ | 27 | #endif /* __ASM_ARCH_PXA3XX_NAND_H */ |
