aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2')
-rw-r--r--arch/arm/mach-omap2/board-2430sdp.c2
-rw-r--r--arch/arm/mach-omap2/board-3430sdp.c2
-rw-r--r--arch/arm/mach-omap2/board-apollon.c2
-rw-r--r--arch/arm/mach-omap2/board-cm-t35.c5
-rw-r--r--arch/arm/mach-omap2/board-cm-t3517.c5
-rw-r--r--arch/arm/mach-omap2/board-devkit8000.c10
-rw-r--r--arch/arm/mach-omap2/board-flash.c50
-rw-r--r--arch/arm/mach-omap2/board-flash.h8
-rw-r--r--arch/arm/mach-omap2/board-h4.c2
-rw-r--r--arch/arm/mach-omap2/board-igep0020.c5
-rw-r--r--arch/arm/mach-omap2/board-ldp.c6
-rw-r--r--arch/arm/mach-omap2/board-n8x0.c1
-rw-r--r--arch/arm/mach-omap2/board-omap3beagle.c10
-rw-r--r--arch/arm/mach-omap2/board-omap3evm.c8
-rw-r--r--arch/arm/mach-omap2/board-omap3logic.c2
-rw-r--r--arch/arm/mach-omap2/board-omap3pandora.c3
-rw-r--r--arch/arm/mach-omap2/board-omap3stalker.c2
-rw-r--r--arch/arm/mach-omap2/board-omap3touchbook.c10
-rw-r--r--arch/arm/mach-omap2/board-overo.c9
-rw-r--r--arch/arm/mach-omap2/board-rm680.c3
-rw-r--r--arch/arm/mach-omap2/board-rx51-peripherals.c3
-rw-r--r--arch/arm/mach-omap2/board-rx51.c4
-rw-r--r--arch/arm/mach-omap2/board-zoom-debugboard.c2
-rw-r--r--arch/arm/mach-omap2/board-zoom.c5
-rw-r--r--arch/arm/mach-omap2/common-board-devices.c46
-rw-r--r--arch/arm/mach-omap2/common-board-devices.h1
-rw-r--r--arch/arm/mach-omap2/gpmc-nand.c85
-rw-r--r--arch/arm/mach-omap2/gpmc-nand.h27
-rw-r--r--arch/arm/mach-omap2/gpmc-onenand.c214
-rw-r--r--arch/arm/mach-omap2/gpmc-onenand.h24
-rw-r--r--arch/arm/mach-omap2/gpmc-smc91x.c2
-rw-r--r--arch/arm/mach-omap2/gpmc-smsc911x.c2
-rw-r--r--arch/arm/mach-omap2/gpmc.c459
-rw-r--r--arch/arm/mach-omap2/gpmc.h135
-rw-r--r--arch/arm/mach-omap2/pm34xx.c2
-rw-r--r--arch/arm/mach-omap2/usb-tusb6010.c2
36 files changed, 480 insertions, 678 deletions
diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
index 95b384d54f8a..49e49d0b7cf5 100644
--- a/arch/arm/mach-omap2/board-2430sdp.c
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -34,7 +34,7 @@
34#include <asm/mach/map.h> 34#include <asm/mach/map.h>
35 35
36#include "common.h" 36#include "common.h"
37#include <plat/gpmc.h> 37#include "gpmc.h"
38#include <plat/usb.h> 38#include <plat/usb.h>
39#include "gpmc-smc91x.h" 39#include "gpmc-smc91x.h"
40 40
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index 2abbd6a9857a..3e8725b73161 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -33,10 +33,10 @@
33#include <plat/usb.h> 33#include <plat/usb.h>
34#include "common.h" 34#include "common.h"
35#include <plat-omap/dma-omap.h> 35#include <plat-omap/dma-omap.h>
36#include <plat/gpmc.h>
37#include <video/omapdss.h> 36#include <video/omapdss.h>
38#include <video/omap-panel-tfp410.h> 37#include <video/omap-panel-tfp410.h>
39 38
39#include "gpmc.h"
40#include "gpmc-smc91x.h" 40#include "gpmc-smc91x.h"
41 41
42#include "board-flash.h" 42#include "board-flash.h"
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
index cea3abace815..8cdd18699de6 100644
--- a/arch/arm/mach-omap2/board-apollon.c
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -35,7 +35,7 @@
35 35
36#include <plat/led.h> 36#include <plat/led.h>
37#include "common.h" 37#include "common.h"
38#include <plat/gpmc.h> 38#include "gpmc.h"
39 39
40#include <video/omapdss.h> 40#include <video/omapdss.h>
41#include <video/omap-panel-generic-dpi.h> 41#include <video/omap-panel-generic-dpi.h>
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index 376d26eb601c..73e2ba9b343b 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -40,7 +40,7 @@
40 40
41#include "common.h" 41#include "common.h"
42#include <linux/platform_data/mtd-nand-omap2.h> 42#include <linux/platform_data/mtd-nand-omap2.h>
43#include <plat/gpmc.h> 43#include "gpmc.h"
44#include <plat/usb.h> 44#include <plat/usb.h>
45#include <video/omapdss.h> 45#include <video/omapdss.h>
46#include <video/omap-panel-generic-dpi.h> 46#include <video/omap-panel-generic-dpi.h>
@@ -53,6 +53,7 @@
53#include "sdram-micron-mt46h32m32lf-6.h" 53#include "sdram-micron-mt46h32m32lf-6.h"
54#include "hsmmc.h" 54#include "hsmmc.h"
55#include "common-board-devices.h" 55#include "common-board-devices.h"
56#include "gpmc-nand.h"
56 57
57#define CM_T35_GPIO_PENDOWN 57 58#define CM_T35_GPIO_PENDOWN 57
58#define SB_T35_USB_HUB_RESET_GPIO 167 59#define SB_T35_USB_HUB_RESET_GPIO 167
@@ -181,7 +182,7 @@ static struct omap_nand_platform_data cm_t35_nand_data = {
181 182
182static void __init cm_t35_init_nand(void) 183static void __init cm_t35_init_nand(void)
183{ 184{
184 if (gpmc_nand_init(&cm_t35_nand_data) < 0) 185 if (gpmc_nand_init(&cm_t35_nand_data, NULL) < 0)
185 pr_err("CM-T35: Unable to register NAND device\n"); 186 pr_err("CM-T35: Unable to register NAND device\n");
186} 187}
187#else 188#else
diff --git a/arch/arm/mach-omap2/board-cm-t3517.c b/arch/arm/mach-omap2/board-cm-t3517.c
index 59c0a45f75b0..b5495e415024 100644
--- a/arch/arm/mach-omap2/board-cm-t3517.c
+++ b/arch/arm/mach-omap2/board-cm-t3517.c
@@ -41,7 +41,7 @@
41#include "common.h" 41#include "common.h"
42#include <plat/usb.h> 42#include <plat/usb.h>
43#include <linux/platform_data/mtd-nand-omap2.h> 43#include <linux/platform_data/mtd-nand-omap2.h>
44#include <plat/gpmc.h> 44#include "gpmc.h"
45 45
46#include "am35xx.h" 46#include "am35xx.h"
47 47
@@ -49,6 +49,7 @@
49#include "control.h" 49#include "control.h"
50#include "common-board-devices.h" 50#include "common-board-devices.h"
51#include "am35xx-emac.h" 51#include "am35xx-emac.h"
52#include "gpmc-nand.h"
52 53
53#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) 54#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
54static struct gpio_led cm_t3517_leds[] = { 55static struct gpio_led cm_t3517_leds[] = {
@@ -240,7 +241,7 @@ static struct omap_nand_platform_data cm_t3517_nand_data = {
240 241
241static void __init cm_t3517_init_nand(void) 242static void __init cm_t3517_init_nand(void)
242{ 243{
243 if (gpmc_nand_init(&cm_t3517_nand_data) < 0) 244 if (gpmc_nand_init(&cm_t3517_nand_data, NULL) < 0)
244 pr_err("CM-T3517: NAND initialization failed\n"); 245 pr_err("CM-T3517: NAND initialization failed\n");
245} 246}
246#else 247#else
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index 1fd161e934c7..3eedb8fd0370 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -39,7 +39,7 @@
39#include <asm/mach/flash.h> 39#include <asm/mach/flash.h>
40 40
41#include "common.h" 41#include "common.h"
42#include <plat/gpmc.h> 42#include "gpmc.h"
43#include <linux/platform_data/mtd-nand-omap2.h> 43#include <linux/platform_data/mtd-nand-omap2.h>
44#include <plat/usb.h> 44#include <plat/usb.h>
45#include <video/omapdss.h> 45#include <video/omapdss.h>
@@ -55,8 +55,11 @@
55#include "sdram-micron-mt46h32m32lf-6.h" 55#include "sdram-micron-mt46h32m32lf-6.h"
56#include "mux.h" 56#include "mux.h"
57#include "hsmmc.h" 57#include "hsmmc.h"
58#include "board-flash.h"
58#include "common-board-devices.h" 59#include "common-board-devices.h"
59 60
61#define NAND_CS 0
62
60#define OMAP_DM9000_GPIO_IRQ 25 63#define OMAP_DM9000_GPIO_IRQ 25
61#define OMAP3_DEVKIT_TS_GPIO 27 64#define OMAP3_DEVKIT_TS_GPIO 27
62 65
@@ -621,8 +624,9 @@ static void __init devkit8000_init(void)
621 624
622 usb_musb_init(NULL); 625 usb_musb_init(NULL);
623 usbhs_init(&usbhs_bdata); 626 usbhs_init(&usbhs_bdata);
624 omap_nand_flash_init(NAND_BUSWIDTH_16, devkit8000_nand_partitions, 627 board_nand_init(devkit8000_nand_partitions,
625 ARRAY_SIZE(devkit8000_nand_partitions)); 628 ARRAY_SIZE(devkit8000_nand_partitions), NAND_CS,
629 NAND_BUSWIDTH_16, NULL);
626 omap_twl4030_audio_init("omap3beagle"); 630 omap_twl4030_audio_init("omap3beagle");
627 631
628 /* Ensure SDRC pins are mux'd for self-refresh */ 632 /* Ensure SDRC pins are mux'd for self-refresh */
diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c
index e642acf9cad0..020b96b91f73 100644
--- a/arch/arm/mach-omap2/board-flash.c
+++ b/arch/arm/mach-omap2/board-flash.c
@@ -18,13 +18,15 @@
18#include <linux/io.h> 18#include <linux/io.h>
19 19
20#include <plat/cpu.h> 20#include <plat/cpu.h>
21#include <plat/gpmc.h> 21#include "gpmc.h"
22#include <linux/platform_data/mtd-nand-omap2.h> 22#include <linux/platform_data/mtd-nand-omap2.h>
23#include <linux/platform_data/mtd-onenand-omap2.h> 23#include <linux/platform_data/mtd-onenand-omap2.h>
24#include <plat/tc.h> 24#include <plat/tc.h>
25 25
26#include "common.h" 26#include "common.h"
27#include "board-flash.h" 27#include "board-flash.h"
28#include "gpmc-onenand.h"
29#include "gpmc-nand.h"
28 30
29#define REG_FPGA_REV 0x10 31#define REG_FPGA_REV 0x10
30#define REG_FPGA_DIP_SWITCH_INPUT2 0x60 32#define REG_FPGA_DIP_SWITCH_INPUT2 0x60
@@ -104,36 +106,35 @@ __init board_onenand_init(struct mtd_partition *onenand_parts,
104 defined(CONFIG_MTD_NAND_OMAP2_MODULE) 106 defined(CONFIG_MTD_NAND_OMAP2_MODULE)
105 107
106/* Note that all values in this struct are in nanoseconds */ 108/* Note that all values in this struct are in nanoseconds */
107static struct gpmc_timings nand_timings = { 109struct gpmc_timings nand_default_timings[1] = {
110 {
111 .sync_clk = 0,
108 112
109 .sync_clk = 0, 113 .cs_on = 0,
114 .cs_rd_off = 36,
115 .cs_wr_off = 36,
110 116
111 .cs_on = 0, 117 .adv_on = 6,
112 .cs_rd_off = 36, 118 .adv_rd_off = 24,
113 .cs_wr_off = 36, 119 .adv_wr_off = 36,
114 120
115 .adv_on = 6, 121 .we_off = 30,
116 .adv_rd_off = 24, 122 .oe_off = 48,
117 .adv_wr_off = 36,
118 123
119 .we_off = 30, 124 .access = 54,
120 .oe_off = 48, 125 .rd_cycle = 72,
126 .wr_cycle = 72,
121 127
122 .access = 54, 128 .wr_access = 30,
123 .rd_cycle = 72, 129 .wr_data_mux_bus = 0,
124 .wr_cycle = 72, 130 },
125
126 .wr_access = 30,
127 .wr_data_mux_bus = 0,
128}; 131};
129 132
130static struct omap_nand_platform_data board_nand_data = { 133static struct omap_nand_platform_data board_nand_data;
131 .gpmc_t = &nand_timings,
132};
133 134
134void 135void
135__init board_nand_init(struct mtd_partition *nand_parts, 136__init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs,
136 u8 nr_parts, u8 cs, int nand_type) 137 int nand_type, struct gpmc_timings *gpmc_t)
137{ 138{
138 board_nand_data.cs = cs; 139 board_nand_data.cs = cs;
139 board_nand_data.parts = nand_parts; 140 board_nand_data.parts = nand_parts;
@@ -141,7 +142,7 @@ __init board_nand_init(struct mtd_partition *nand_parts,
141 board_nand_data.devsize = nand_type; 142 board_nand_data.devsize = nand_type;
142 143
143 board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT; 144 board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT;
144 gpmc_nand_init(&board_nand_data); 145 gpmc_nand_init(&board_nand_data, gpmc_t);
145} 146}
146#endif /* CONFIG_MTD_NAND_OMAP2 || CONFIG_MTD_NAND_OMAP2_MODULE */ 147#endif /* CONFIG_MTD_NAND_OMAP2 || CONFIG_MTD_NAND_OMAP2_MODULE */
147 148
@@ -238,5 +239,6 @@ void __init board_flash_init(struct flash_partitions partition_info[],
238 pr_err("NAND: Unable to find configuration in GPMC\n"); 239 pr_err("NAND: Unable to find configuration in GPMC\n");
239 else 240 else
240 board_nand_init(partition_info[2].parts, 241 board_nand_init(partition_info[2].parts,
241 partition_info[2].nr_parts, nandcs, nand_type); 242 partition_info[2].nr_parts, nandcs,
243 nand_type, nand_default_timings);
242} 244}
diff --git a/arch/arm/mach-omap2/board-flash.h b/arch/arm/mach-omap2/board-flash.h
index c44b70d52021..2fb5d41a9fae 100644
--- a/arch/arm/mach-omap2/board-flash.h
+++ b/arch/arm/mach-omap2/board-flash.h
@@ -12,7 +12,7 @@
12 */ 12 */
13#include <linux/mtd/mtd.h> 13#include <linux/mtd/mtd.h>
14#include <linux/mtd/partitions.h> 14#include <linux/mtd/partitions.h>
15#include <plat/gpmc.h> 15#include "gpmc.h"
16 16
17#define PDC_NOR 1 17#define PDC_NOR 1
18#define PDC_NAND 2 18#define PDC_NAND 2
@@ -40,12 +40,14 @@ static inline void board_flash_init(struct flash_partitions part[],
40#if defined(CONFIG_MTD_NAND_OMAP2) || \ 40#if defined(CONFIG_MTD_NAND_OMAP2) || \
41 defined(CONFIG_MTD_NAND_OMAP2_MODULE) 41 defined(CONFIG_MTD_NAND_OMAP2_MODULE)
42extern void board_nand_init(struct mtd_partition *nand_parts, 42extern void board_nand_init(struct mtd_partition *nand_parts,
43 u8 nr_parts, u8 cs, int nand_type); 43 u8 nr_parts, u8 cs, int nand_type, struct gpmc_timings *gpmc_t);
44extern struct gpmc_timings nand_default_timings[];
44#else 45#else
45static inline void board_nand_init(struct mtd_partition *nand_parts, 46static inline void board_nand_init(struct mtd_partition *nand_parts,
46 u8 nr_parts, u8 cs, int nand_type) 47 u8 nr_parts, u8 cs, int nand_type, struct gpmc_timings *gpmc_t)
47{ 48{
48} 49}
50#define nand_default_timings NULL
49#endif 51#endif
50 52
51#if defined(CONFIG_MTD_ONENAND_OMAP2) || \ 53#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index b3bab62fd5ed..366ebd93ae24 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -33,7 +33,6 @@
33 33
34#include <plat/menelaus.h> 34#include <plat/menelaus.h>
35#include <plat-omap/dma-omap.h> 35#include <plat-omap/dma-omap.h>
36#include <plat/gpmc.h>
37#include "debug-devices.h" 36#include "debug-devices.h"
38 37
39#include <video/omapdss.h> 38#include <video/omapdss.h>
@@ -42,6 +41,7 @@
42#include "common.h" 41#include "common.h"
43#include "mux.h" 42#include "mux.h"
44#include "control.h" 43#include "control.h"
44#include "gpmc.h"
45 45
46#define H4_FLASH_CS 0 46#define H4_FLASH_CS 0
47#define H4_SMC91X_CS 1 47#define H4_SMC91X_CS 1
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index 48d5e41dfbfa..9a9a9b5f78b6 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -30,7 +30,7 @@
30#include <asm/mach/arch.h> 30#include <asm/mach/arch.h>
31 31
32#include "common.h" 32#include "common.h"
33#include <plat/gpmc.h> 33#include "gpmc.h"
34#include <plat/usb.h> 34#include <plat/usb.h>
35 35
36#include <video/omapdss.h> 36#include <video/omapdss.h>
@@ -43,6 +43,7 @@
43#include "common-board-devices.h" 43#include "common-board-devices.h"
44#include "board-flash.h" 44#include "board-flash.h"
45#include "control.h" 45#include "control.h"
46#include "gpmc-onenand.h"
46 47
47#define IGEP2_SMSC911X_CS 5 48#define IGEP2_SMSC911X_CS 5
48#define IGEP2_SMSC911X_GPIO 176 49#define IGEP2_SMSC911X_GPIO 176
@@ -175,7 +176,7 @@ static void __init igep_flash_init(void)
175 pr_info("IGEP: initializing NAND memory device\n"); 176 pr_info("IGEP: initializing NAND memory device\n");
176 board_nand_init(igep_flash_partitions, 177 board_nand_init(igep_flash_partitions,
177 ARRAY_SIZE(igep_flash_partitions), 178 ARRAY_SIZE(igep_flash_partitions),
178 0, NAND_BUSWIDTH_16); 179 0, NAND_BUSWIDTH_16, nand_default_timings);
179 } else if (mux == IGEP_SYSBOOT_ONENAND) { 180 } else if (mux == IGEP_SYSBOOT_ONENAND) {
180 pr_info("IGEP: initializing OneNAND memory device\n"); 181 pr_info("IGEP: initializing OneNAND memory device\n");
181 board_onenand_init(igep_flash_partitions, 182 board_onenand_init(igep_flash_partitions,
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index ee8c3cfb95b3..e1628cd25ab4 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -35,7 +35,7 @@
35#include <asm/mach/map.h> 35#include <asm/mach/map.h>
36 36
37#include "common.h" 37#include "common.h"
38#include <plat/gpmc.h> 38#include "gpmc.h"
39#include <mach/board-zoom.h> 39#include <mach/board-zoom.h>
40#include <plat/usb.h> 40#include <plat/usb.h>
41#include "gpmc-smsc911x.h" 41#include "gpmc-smsc911x.h"
@@ -420,8 +420,8 @@ static void __init omap_ldp_init(void)
420 omap_serial_init(); 420 omap_serial_init();
421 omap_sdrc_init(NULL, NULL); 421 omap_sdrc_init(NULL, NULL);
422 usb_musb_init(NULL); 422 usb_musb_init(NULL);
423 board_nand_init(ldp_nand_partitions, 423 board_nand_init(ldp_nand_partitions, ARRAY_SIZE(ldp_nand_partitions),
424 ARRAY_SIZE(ldp_nand_partitions), ZOOM_NAND_CS, 0); 424 ZOOM_NAND_CS, 0, nand_default_timings);
425 425
426 omap_hsmmc_init(mmc); 426 omap_hsmmc_init(mmc);
427 ldp_display_init(); 427 ldp_display_init();
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
index d95f727ca39a..92b19166aac8 100644
--- a/arch/arm/mach-omap2/board-n8x0.c
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -32,6 +32,7 @@
32#include <plat/mmc.h> 32#include <plat/mmc.h>
33 33
34#include "mux.h" 34#include "mux.h"
35#include "gpmc-onenand.h"
35 36
36#define TUSB6010_ASYNC_CS 1 37#define TUSB6010_ASYNC_CS 1
37#define TUSB6010_SYNC_CS 4 38#define TUSB6010_SYNC_CS 4
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 388c431c745a..f11a5eb595f7 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -41,7 +41,7 @@
41#include "common.h" 41#include "common.h"
42#include <video/omapdss.h> 42#include <video/omapdss.h>
43#include <video/omap-panel-tfp410.h> 43#include <video/omap-panel-tfp410.h>
44#include <plat/gpmc.h> 44#include "gpmc.h"
45#include <linux/platform_data/mtd-nand-omap2.h> 45#include <linux/platform_data/mtd-nand-omap2.h>
46#include <plat/usb.h> 46#include <plat/usb.h>
47#include <plat/omap_device.h> 47#include <plat/omap_device.h>
@@ -49,8 +49,11 @@
49#include "mux.h" 49#include "mux.h"
50#include "hsmmc.h" 50#include "hsmmc.h"
51#include "pm.h" 51#include "pm.h"
52#include "board-flash.h"
52#include "common-board-devices.h" 53#include "common-board-devices.h"
53 54
55#define NAND_CS 0
56
54/* 57/*
55 * OMAP3 Beagle revision 58 * OMAP3 Beagle revision
56 * Run time detection of Beagle revision is done by reading GPIO. 59 * Run time detection of Beagle revision is done by reading GPIO.
@@ -512,8 +515,9 @@ static void __init omap3_beagle_init(void)
512 515
513 usb_musb_init(NULL); 516 usb_musb_init(NULL);
514 usbhs_init(&usbhs_bdata); 517 usbhs_init(&usbhs_bdata);
515 omap_nand_flash_init(NAND_BUSWIDTH_16, omap3beagle_nand_partitions, 518 board_nand_init(omap3beagle_nand_partitions,
516 ARRAY_SIZE(omap3beagle_nand_partitions)); 519 ARRAY_SIZE(omap3beagle_nand_partitions), NAND_CS,
520 NAND_BUSWIDTH_16, NULL);
517 omap_twl4030_audio_init("omap3beagle"); 521 omap_twl4030_audio_init("omap3beagle");
518 522
519 /* Ensure msecure is mux'd to be able to set the RTC. */ 523 /* Ensure msecure is mux'd to be able to set the RTC. */
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index b9b776b6c954..1d8e926b52fe 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -56,6 +56,9 @@
56#include "sdram-micron-mt46h32m32lf-6.h" 56#include "sdram-micron-mt46h32m32lf-6.h"
57#include "hsmmc.h" 57#include "hsmmc.h"
58#include "common-board-devices.h" 58#include "common-board-devices.h"
59#include "board-flash.h"
60
61#define NAND_CS 0
59 62
60#define OMAP3_EVM_TS_GPIO 175 63#define OMAP3_EVM_TS_GPIO 175
61#define OMAP3_EVM_EHCI_VBUS 22 64#define OMAP3_EVM_EHCI_VBUS 22
@@ -731,8 +734,9 @@ static void __init omap3_evm_init(void)
731 } 734 }
732 usb_musb_init(&musb_board_data); 735 usb_musb_init(&musb_board_data);
733 usbhs_init(&usbhs_bdata); 736 usbhs_init(&usbhs_bdata);
734 omap_nand_flash_init(NAND_BUSWIDTH_16, omap3evm_nand_partitions, 737 board_nand_init(omap3evm_nand_partitions,
735 ARRAY_SIZE(omap3evm_nand_partitions)); 738 ARRAY_SIZE(omap3evm_nand_partitions), NAND_CS,
739 NAND_BUSWIDTH_16, NULL);
736 740
737 omap_ads7846_init(1, OMAP3_EVM_TS_GPIO, 310, NULL); 741 omap_ads7846_init(1, OMAP3_EVM_TS_GPIO, 310, NULL);
738 omap3evm_init_smsc911x(); 742 omap3evm_init_smsc911x();
diff --git a/arch/arm/mach-omap2/board-omap3logic.c b/arch/arm/mach-omap2/board-omap3logic.c
index 7bd8253b5d1d..5cfade235bb4 100644
--- a/arch/arm/mach-omap2/board-omap3logic.c
+++ b/arch/arm/mach-omap2/board-omap3logic.c
@@ -35,7 +35,7 @@
35#include <asm/mach/map.h> 35#include <asm/mach/map.h>
36 36
37#include "gpmc-smsc911x.h" 37#include "gpmc-smsc911x.h"
38#include <plat/gpmc.h> 38#include "gpmc.h"
39#include <plat/sdrc.h> 39#include <plat/sdrc.h>
40#include <plat/usb.h> 40#include <plat/usb.h>
41 41
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index 00a1f4ae6e44..f286b4b4bd5b 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -50,6 +50,7 @@
50#include "sdram-micron-mt46h32m32lf-6.h" 50#include "sdram-micron-mt46h32m32lf-6.h"
51#include "hsmmc.h" 51#include "hsmmc.h"
52#include "common-board-devices.h" 52#include "common-board-devices.h"
53#include "gpmc-nand.h"
53 54
54#define PANDORA_WIFI_IRQ_GPIO 21 55#define PANDORA_WIFI_IRQ_GPIO 21
55#define PANDORA_WIFI_NRESET_GPIO 23 56#define PANDORA_WIFI_NRESET_GPIO 23
@@ -602,7 +603,7 @@ static void __init omap3pandora_init(void)
602 omap_ads7846_init(1, OMAP3_PANDORA_TS_GPIO, 0, NULL); 603 omap_ads7846_init(1, OMAP3_PANDORA_TS_GPIO, 0, NULL);
603 usbhs_init(&usbhs_bdata); 604 usbhs_init(&usbhs_bdata);
604 usb_musb_init(NULL); 605 usb_musb_init(NULL);
605 gpmc_nand_init(&pandora_nand_data); 606 gpmc_nand_init(&pandora_nand_data, NULL);
606 607
607 /* Ensure SDRC pins are mux'd for self-refresh */ 608 /* Ensure SDRC pins are mux'd for self-refresh */
608 omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); 609 omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
index 731235eb319e..3c83b9fbff45 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -40,7 +40,7 @@
40#include <asm/mach/flash.h> 40#include <asm/mach/flash.h>
41 41
42#include "common.h" 42#include "common.h"
43#include <plat/gpmc.h> 43#include "gpmc.h"
44#include <linux/platform_data/mtd-nand-omap2.h> 44#include <linux/platform_data/mtd-nand-omap2.h>
45#include <plat/usb.h> 45#include <plat/usb.h>
46#include <video/omapdss.h> 46#include <video/omapdss.h>
diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c
index 944ffc436577..cd282ae0856b 100644
--- a/arch/arm/mach-omap2/board-omap3touchbook.c
+++ b/arch/arm/mach-omap2/board-omap3touchbook.c
@@ -44,12 +44,13 @@
44#include <asm/system_info.h> 44#include <asm/system_info.h>
45 45
46#include "common.h" 46#include "common.h"
47#include <plat/gpmc.h> 47#include "gpmc.h"
48#include <linux/platform_data/mtd-nand-omap2.h> 48#include <linux/platform_data/mtd-nand-omap2.h>
49#include <plat/usb.h> 49#include <plat/usb.h>
50 50
51#include "mux.h" 51#include "mux.h"
52#include "hsmmc.h" 52#include "hsmmc.h"
53#include "board-flash.h"
53#include "common-board-devices.h" 54#include "common-board-devices.h"
54 55
55#include <asm/setup.h> 56#include <asm/setup.h>
@@ -59,6 +60,8 @@
59#define TB_BL_PWM_TIMER 9 60#define TB_BL_PWM_TIMER 9
60#define TB_KILL_POWER_GPIO 168 61#define TB_KILL_POWER_GPIO 168
61 62
63#define NAND_CS 0
64
62static unsigned long touchbook_revision; 65static unsigned long touchbook_revision;
63 66
64static struct mtd_partition omap3touchbook_nand_partitions[] = { 67static struct mtd_partition omap3touchbook_nand_partitions[] = {
@@ -365,8 +368,9 @@ static void __init omap3_touchbook_init(void)
365 omap_ads7846_init(4, OMAP3_TS_GPIO, 310, &ads7846_pdata); 368 omap_ads7846_init(4, OMAP3_TS_GPIO, 310, &ads7846_pdata);
366 usb_musb_init(NULL); 369 usb_musb_init(NULL);
367 usbhs_init(&usbhs_bdata); 370 usbhs_init(&usbhs_bdata);
368 omap_nand_flash_init(NAND_BUSWIDTH_16, omap3touchbook_nand_partitions, 371 board_nand_init(omap3touchbook_nand_partitions,
369 ARRAY_SIZE(omap3touchbook_nand_partitions)); 372 ARRAY_SIZE(omap3touchbook_nand_partitions), NAND_CS,
373 NAND_BUSWIDTH_16, NULL);
370 374
371 /* Ensure SDRC pins are mux'd for self-refresh */ 375 /* Ensure SDRC pins are mux'd for self-refresh */
372 omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); 376 omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index b700685762b5..3a9d1fa8bebd 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -49,14 +49,17 @@
49#include <video/omapdss.h> 49#include <video/omapdss.h>
50#include <video/omap-panel-generic-dpi.h> 50#include <video/omap-panel-generic-dpi.h>
51#include <video/omap-panel-tfp410.h> 51#include <video/omap-panel-tfp410.h>
52#include <plat/gpmc.h> 52#include "gpmc.h"
53#include <plat/usb.h> 53#include <plat/usb.h>
54 54
55#include "mux.h" 55#include "mux.h"
56#include "sdram-micron-mt46h32m32lf-6.h" 56#include "sdram-micron-mt46h32m32lf-6.h"
57#include "hsmmc.h" 57#include "hsmmc.h"
58#include "board-flash.h"
58#include "common-board-devices.h" 59#include "common-board-devices.h"
59 60
61#define NAND_CS 0
62
60#define OVERO_GPIO_BT_XGATE 15 63#define OVERO_GPIO_BT_XGATE 15
61#define OVERO_GPIO_W2W_NRESET 16 64#define OVERO_GPIO_W2W_NRESET 16
62#define OVERO_GPIO_PENDOWN 114 65#define OVERO_GPIO_PENDOWN 114
@@ -495,8 +498,8 @@ static void __init overo_init(void)
495 omap_serial_init(); 498 omap_serial_init();
496 omap_sdrc_init(mt46h32m32lf6_sdrc_params, 499 omap_sdrc_init(mt46h32m32lf6_sdrc_params,
497 mt46h32m32lf6_sdrc_params); 500 mt46h32m32lf6_sdrc_params);
498 omap_nand_flash_init(0, overo_nand_partitions, 501 board_nand_init(overo_nand_partitions,
499 ARRAY_SIZE(overo_nand_partitions)); 502 ARRAY_SIZE(overo_nand_partitions), NAND_CS, 0, NULL);
500 usb_musb_init(NULL); 503 usb_musb_init(NULL);
501 usbhs_init(&usbhs_bdata); 504 usbhs_init(&usbhs_bdata);
502 overo_spi_init(); 505 overo_spi_init();
diff --git a/arch/arm/mach-omap2/board-rm680.c b/arch/arm/mach-omap2/board-rm680.c
index 45997bfbcbd2..3c3a47317f8f 100644
--- a/arch/arm/mach-omap2/board-rm680.c
+++ b/arch/arm/mach-omap2/board-rm680.c
@@ -25,7 +25,7 @@
25#include <plat/i2c.h> 25#include <plat/i2c.h>
26#include <plat/mmc.h> 26#include <plat/mmc.h>
27#include <plat/usb.h> 27#include <plat/usb.h>
28#include <plat/gpmc.h> 28#include "gpmc.h"
29#include "common.h" 29#include "common.h"
30#include <plat/serial.h> 30#include <plat/serial.h>
31 31
@@ -33,6 +33,7 @@
33#include "hsmmc.h" 33#include "hsmmc.h"
34#include "sdram-nokia.h" 34#include "sdram-nokia.h"
35#include "common-board-devices.h" 35#include "common-board-devices.h"
36#include "gpmc-onenand.h"
36 37
37static struct regulator_consumer_supply rm680_vemmc_consumers[] = { 38static struct regulator_consumer_supply rm680_vemmc_consumers[] = {
38 REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"), 39 REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"),
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index 38b3f6389d5b..c2eed847c05b 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -32,7 +32,6 @@
32 32
33#include "common.h" 33#include "common.h"
34#include <plat-omap/dma-omap.h> 34#include <plat-omap/dma-omap.h>
35#include <plat/gpmc.h>
36#include <plat/omap-pm.h> 35#include <plat/omap-pm.h>
37#include "gpmc-smc91x.h" 36#include "gpmc-smc91x.h"
38 37
@@ -54,6 +53,8 @@
54#include "mux.h" 53#include "mux.h"
55#include "hsmmc.h" 54#include "hsmmc.h"
56#include "common-board-devices.h" 55#include "common-board-devices.h"
56#include "gpmc.h"
57#include "gpmc-onenand.h"
57 58
58#define SYSTEM_REV_B_USES_VAUX3 0x1699 59#define SYSTEM_REV_B_USES_VAUX3 0x1699
59#define SYSTEM_REV_S_USES_VAUX3 0x8 60#define SYSTEM_REV_S_USES_VAUX3 0x8
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
index 3b1c03e1c741..63b33c63bd94 100644
--- a/arch/arm/mach-omap2/board-rx51.c
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -23,12 +23,12 @@
23#include <asm/mach/arch.h> 23#include <asm/mach/arch.h>
24#include <asm/mach/map.h> 24#include <asm/mach/map.h>
25 25
26#include "common.h"
27#include <plat-omap/dma-omap.h> 26#include <plat-omap/dma-omap.h>
28#include <plat/gpmc.h>
29#include <plat/usb.h> 27#include <plat/usb.h>
30 28
29#include "common.h"
31#include "mux.h" 30#include "mux.h"
31#include "gpmc.h"
32#include "pm.h" 32#include "pm.h"
33#include "sdram-nokia.h" 33#include "sdram-nokia.h"
34 34
diff --git a/arch/arm/mach-omap2/board-zoom-debugboard.c b/arch/arm/mach-omap2/board-zoom-debugboard.c
index afb2278a29f6..be9f71d436bf 100644
--- a/arch/arm/mach-omap2/board-zoom-debugboard.c
+++ b/arch/arm/mach-omap2/board-zoom-debugboard.c
@@ -17,7 +17,7 @@
17#include <linux/regulator/fixed.h> 17#include <linux/regulator/fixed.h>
18#include <linux/regulator/machine.h> 18#include <linux/regulator/machine.h>
19 19
20#include <plat/gpmc.h> 20#include "gpmc.h"
21#include "gpmc-smsc911x.h" 21#include "gpmc-smsc911x.h"
22 22
23#include <mach/board-zoom.h> 23#include <mach/board-zoom.h>
diff --git a/arch/arm/mach-omap2/board-zoom.c b/arch/arm/mach-omap2/board-zoom.c
index 4994438e1f46..c39578c1fa6d 100644
--- a/arch/arm/mach-omap2/board-zoom.c
+++ b/arch/arm/mach-omap2/board-zoom.c
@@ -113,8 +113,9 @@ static void __init omap_zoom_init(void)
113 usbhs_init(&usbhs_bdata); 113 usbhs_init(&usbhs_bdata);
114 } 114 }
115 115
116 board_nand_init(zoom_nand_partitions, ARRAY_SIZE(zoom_nand_partitions), 116 board_nand_init(zoom_nand_partitions,
117 ZOOM_NAND_CS, NAND_BUSWIDTH_16); 117 ARRAY_SIZE(zoom_nand_partitions), ZOOM_NAND_CS,
118 NAND_BUSWIDTH_16, nand_default_timings);
118 zoom_debugboard_init(); 119 zoom_debugboard_init();
119 zoom_peripherals_init(); 120 zoom_peripherals_init();
120 121
diff --git a/arch/arm/mach-omap2/common-board-devices.c b/arch/arm/mach-omap2/common-board-devices.c
index 48daac2581b4..ad856092c06a 100644
--- a/arch/arm/mach-omap2/common-board-devices.c
+++ b/arch/arm/mach-omap2/common-board-devices.c
@@ -25,7 +25,6 @@
25#include <linux/spi/ads7846.h> 25#include <linux/spi/ads7846.h>
26 26
27#include <linux/platform_data/spi-omap2-mcspi.h> 27#include <linux/platform_data/spi-omap2-mcspi.h>
28#include <linux/platform_data/mtd-nand-omap2.h>
29 28
30#include "common.h" 29#include "common.h"
31#include "common-board-devices.h" 30#include "common-board-devices.h"
@@ -96,48 +95,3 @@ void __init omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce,
96{ 95{
97} 96}
98#endif 97#endif
99
100#if defined(CONFIG_MTD_NAND_OMAP2) || defined(CONFIG_MTD_NAND_OMAP2_MODULE)
101static struct omap_nand_platform_data nand_data;
102
103void __init omap_nand_flash_init(int options, struct mtd_partition *parts,
104 int nr_parts)
105{
106 u8 cs = 0;
107 u8 nandcs = GPMC_CS_NUM + 1;
108
109 /* find out the chip-select on which NAND exists */
110 while (cs < GPMC_CS_NUM) {
111 u32 ret = 0;
112 ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
113
114 if ((ret & 0xC00) == 0x800) {
115 printk(KERN_INFO "Found NAND on CS%d\n", cs);
116 if (nandcs > GPMC_CS_NUM)
117 nandcs = cs;
118 }
119 cs++;
120 }
121
122 if (nandcs > GPMC_CS_NUM) {
123 pr_info("NAND: Unable to find configuration in GPMC\n");
124 return;
125 }
126
127 if (nandcs < GPMC_CS_NUM) {
128 nand_data.cs = nandcs;
129 nand_data.parts = parts;
130 nand_data.nr_parts = nr_parts;
131 nand_data.devsize = options;
132
133 printk(KERN_INFO "Registering NAND on CS%d\n", nandcs);
134 if (gpmc_nand_init(&nand_data) < 0)
135 printk(KERN_ERR "Unable to register NAND device\n");
136 }
137}
138#else
139void __init omap_nand_flash_init(int options, struct mtd_partition *parts,
140 int nr_parts)
141{
142}
143#endif
diff --git a/arch/arm/mach-omap2/common-board-devices.h b/arch/arm/mach-omap2/common-board-devices.h
index a0b4a42836ab..72bb41b3fd25 100644
--- a/arch/arm/mach-omap2/common-board-devices.h
+++ b/arch/arm/mach-omap2/common-board-devices.h
@@ -10,6 +10,5 @@ struct ads7846_platform_data;
10 10
11void omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce, 11void omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce,
12 struct ads7846_platform_data *board_pdata); 12 struct ads7846_platform_data *board_pdata);
13void omap_nand_flash_init(int opts, struct mtd_partition *parts, int n_parts);
14 13
15#endif /* __OMAP_COMMON_BOARD_DEVICES__ */ 14#endif /* __OMAP_COMMON_BOARD_DEVICES__ */
diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index 4acf497faeb3..8607735b3ab3 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -17,9 +17,12 @@
17 17
18#include <asm/mach/flash.h> 18#include <asm/mach/flash.h>
19 19
20#include <plat/gpmc.h> 20#include "gpmc.h"
21
22#include "soc.h" 21#include "soc.h"
22#include "gpmc-nand.h"
23
24/* minimum size for IO mapping */
25#define NAND_IO_SIZE 4
23 26
24static struct resource gpmc_nand_resource[] = { 27static struct resource gpmc_nand_resource[] = {
25 { 28 {
@@ -40,41 +43,36 @@ static struct platform_device gpmc_nand_device = {
40 .resource = gpmc_nand_resource, 43 .resource = gpmc_nand_resource,
41}; 44};
42 45
43static int omap2_nand_gpmc_retime(struct omap_nand_platform_data *gpmc_nand_data) 46static int omap2_nand_gpmc_retime(
47 struct omap_nand_platform_data *gpmc_nand_data,
48 struct gpmc_timings *gpmc_t)
44{ 49{
45 struct gpmc_timings t; 50 struct gpmc_timings t;
46 int err; 51 int err;
47 52
48 if (!gpmc_nand_data->gpmc_t)
49 return 0;
50
51 memset(&t, 0, sizeof(t)); 53 memset(&t, 0, sizeof(t));
52 t.sync_clk = gpmc_nand_data->gpmc_t->sync_clk; 54 t.sync_clk = gpmc_t->sync_clk;
53 t.cs_on = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->cs_on); 55 t.cs_on = gpmc_round_ns_to_ticks(gpmc_t->cs_on);
54 t.adv_on = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->adv_on); 56 t.adv_on = gpmc_round_ns_to_ticks(gpmc_t->adv_on);
55 57
56 /* Read */ 58 /* Read */
57 t.adv_rd_off = gpmc_round_ns_to_ticks( 59 t.adv_rd_off = gpmc_round_ns_to_ticks(gpmc_t->adv_rd_off);
58 gpmc_nand_data->gpmc_t->adv_rd_off);
59 t.oe_on = t.adv_on; 60 t.oe_on = t.adv_on;
60 t.access = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->access); 61 t.access = gpmc_round_ns_to_ticks(gpmc_t->access);
61 t.oe_off = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->oe_off); 62 t.oe_off = gpmc_round_ns_to_ticks(gpmc_t->oe_off);
62 t.cs_rd_off = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->cs_rd_off); 63 t.cs_rd_off = gpmc_round_ns_to_ticks(gpmc_t->cs_rd_off);
63 t.rd_cycle = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->rd_cycle); 64 t.rd_cycle = gpmc_round_ns_to_ticks(gpmc_t->rd_cycle);
64 65
65 /* Write */ 66 /* Write */
66 t.adv_wr_off = gpmc_round_ns_to_ticks( 67 t.adv_wr_off = gpmc_round_ns_to_ticks(gpmc_t->adv_wr_off);
67 gpmc_nand_data->gpmc_t->adv_wr_off);
68 t.we_on = t.oe_on; 68 t.we_on = t.oe_on;
69 if (cpu_is_omap34xx()) { 69 if (cpu_is_omap34xx()) {
70 t.wr_data_mux_bus = gpmc_round_ns_to_ticks( 70 t.wr_data_mux_bus = gpmc_round_ns_to_ticks(gpmc_t->wr_data_mux_bus);
71 gpmc_nand_data->gpmc_t->wr_data_mux_bus); 71 t.wr_access = gpmc_round_ns_to_ticks(gpmc_t->wr_access);
72 t.wr_access = gpmc_round_ns_to_ticks(
73 gpmc_nand_data->gpmc_t->wr_access);
74 } 72 }
75 t.we_off = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->we_off); 73 t.we_off = gpmc_round_ns_to_ticks(gpmc_t->we_off);
76 t.cs_wr_off = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->cs_wr_off); 74 t.cs_wr_off = gpmc_round_ns_to_ticks(gpmc_t->cs_wr_off);
77 t.wr_cycle = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->wr_cycle); 75 t.wr_cycle = gpmc_round_ns_to_ticks(gpmc_t->wr_cycle);
78 76
79 /* Configure GPMC */ 77 /* Configure GPMC */
80 if (gpmc_nand_data->devsize == NAND_BUSWIDTH_16) 78 if (gpmc_nand_data->devsize == NAND_BUSWIDTH_16)
@@ -91,7 +89,29 @@ static int omap2_nand_gpmc_retime(struct omap_nand_platform_data *gpmc_nand_data
91 return 0; 89 return 0;
92} 90}
93 91
94int __init gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data) 92static bool __init gpmc_hwecc_bch_capable(enum omap_ecc ecc_opt)
93{
94 /* support only OMAP3 class */
95 if (!cpu_is_omap34xx()) {
96 pr_err("BCH ecc is not supported on this CPU\n");
97 return 0;
98 }
99
100 /*
101 * For now, assume 4-bit mode is only supported on OMAP3630 ES1.x, x>=1.
102 * Other chips may be added if confirmed to work.
103 */
104 if ((ecc_opt == OMAP_ECC_BCH4_CODE_HW) &&
105 (!cpu_is_omap3630() || (GET_OMAP_REVISION() == 0))) {
106 pr_err("BCH 4-bit mode is not supported on this CPU\n");
107 return 0;
108 }
109
110 return 1;
111}
112
113int __init gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
114 struct gpmc_timings *gpmc_t)
95{ 115{
96 int err = 0; 116 int err = 0;
97 struct device *dev = &gpmc_nand_device.dev; 117 struct device *dev = &gpmc_nand_device.dev;
@@ -112,11 +132,13 @@ int __init gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data)
112 gpmc_get_client_irq(GPMC_IRQ_FIFOEVENTENABLE); 132 gpmc_get_client_irq(GPMC_IRQ_FIFOEVENTENABLE);
113 gpmc_nand_resource[2].start = 133 gpmc_nand_resource[2].start =
114 gpmc_get_client_irq(GPMC_IRQ_COUNT_EVENT); 134 gpmc_get_client_irq(GPMC_IRQ_COUNT_EVENT);
115 /* Set timings in GPMC */ 135
116 err = omap2_nand_gpmc_retime(gpmc_nand_data); 136 if (gpmc_t) {
117 if (err < 0) { 137 err = omap2_nand_gpmc_retime(gpmc_nand_data, gpmc_t);
118 dev_err(dev, "Unable to set gpmc timings: %d\n", err); 138 if (err < 0) {
119 return err; 139 dev_err(dev, "Unable to set gpmc timings: %d\n", err);
140 return err;
141 }
120 } 142 }
121 143
122 /* Enable RD PIN Monitoring Reg */ 144 /* Enable RD PIN Monitoring Reg */
@@ -126,6 +148,9 @@ int __init gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data)
126 148
127 gpmc_update_nand_reg(&gpmc_nand_data->reg, gpmc_nand_data->cs); 149 gpmc_update_nand_reg(&gpmc_nand_data->reg, gpmc_nand_data->cs);
128 150
151 if (!gpmc_hwecc_bch_capable(gpmc_nand_data->ecc_opt))
152 return -EINVAL;
153
129 err = platform_device_register(&gpmc_nand_device); 154 err = platform_device_register(&gpmc_nand_device);
130 if (err < 0) { 155 if (err < 0) {
131 dev_err(dev, "Unable to register NAND device\n"); 156 dev_err(dev, "Unable to register NAND device\n");
diff --git a/arch/arm/mach-omap2/gpmc-nand.h b/arch/arm/mach-omap2/gpmc-nand.h
new file mode 100644
index 000000000000..d59e1281e851
--- /dev/null
+++ b/arch/arm/mach-omap2/gpmc-nand.h
@@ -0,0 +1,27 @@
1/*
2 * arch/arm/mach-omap2/gpmc-nand.h
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 */
9
10#ifndef __OMAP2_GPMC_NAND_H
11#define __OMAP2_GPMC_NAND_H
12
13#include "gpmc.h"
14#include <linux/platform_data/mtd-nand-omap2.h>
15
16#if IS_ENABLED(CONFIG_MTD_NAND_OMAP2)
17extern int gpmc_nand_init(struct omap_nand_platform_data *d,
18 struct gpmc_timings *gpmc_t);
19#else
20static inline int gpmc_nand_init(struct omap_nand_platform_data *d,
21 struct gpmc_timings *gpmc_t)
22{
23 return 0;
24}
25#endif
26
27#endif
diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
index 916716e1da3b..d102183ed9a5 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -16,15 +16,25 @@
16#include <linux/mtd/onenand_regs.h> 16#include <linux/mtd/onenand_regs.h>
17#include <linux/io.h> 17#include <linux/io.h>
18#include <linux/platform_data/mtd-onenand-omap2.h> 18#include <linux/platform_data/mtd-onenand-omap2.h>
19#include <linux/err.h>
19 20
20#include <asm/mach/flash.h> 21#include <asm/mach/flash.h>
21 22
22#include <plat/gpmc.h> 23#include "gpmc.h"
23
24#include "soc.h" 24#include "soc.h"
25#include "gpmc-onenand.h"
25 26
26#define ONENAND_IO_SIZE SZ_128K 27#define ONENAND_IO_SIZE SZ_128K
27 28
29#define ONENAND_FLAG_SYNCREAD (1 << 0)
30#define ONENAND_FLAG_SYNCWRITE (1 << 1)
31#define ONENAND_FLAG_HF (1 << 2)
32#define ONENAND_FLAG_VHF (1 << 3)
33
34static unsigned onenand_flags;
35static unsigned latency;
36static int fclk_offset;
37
28static struct omap_onenand_platform_data *gpmc_onenand_data; 38static struct omap_onenand_platform_data *gpmc_onenand_data;
29 39
30static struct resource gpmc_onenand_resource = { 40static struct resource gpmc_onenand_resource = {
@@ -38,11 +48,9 @@ static struct platform_device gpmc_onenand_device = {
38 .resource = &gpmc_onenand_resource, 48 .resource = &gpmc_onenand_resource,
39}; 49};
40 50
41static int omap2_onenand_set_async_mode(int cs, void __iomem *onenand_base) 51static struct gpmc_timings omap2_onenand_calc_async_timings(void)
42{ 52{
43 struct gpmc_timings t; 53 struct gpmc_timings t;
44 u32 reg;
45 int err;
46 54
47 const int t_cer = 15; 55 const int t_cer = 15;
48 const int t_avdp = 12; 56 const int t_avdp = 12;
@@ -55,11 +63,6 @@ static int omap2_onenand_set_async_mode(int cs, void __iomem *onenand_base)
55 const int t_wpl = 40; 63 const int t_wpl = 40;
56 const int t_wph = 30; 64 const int t_wph = 30;
57 65
58 /* Ensure sync read and sync write are disabled */
59 reg = readw(onenand_base + ONENAND_REG_SYS_CFG1);
60 reg &= ~ONENAND_SYS_CFG1_SYNC_READ & ~ONENAND_SYS_CFG1_SYNC_WRITE;
61 writew(reg, onenand_base + ONENAND_REG_SYS_CFG1);
62
63 memset(&t, 0, sizeof(t)); 66 memset(&t, 0, sizeof(t));
64 t.sync_clk = 0; 67 t.sync_clk = 0;
65 t.cs_on = 0; 68 t.cs_on = 0;
@@ -86,25 +89,30 @@ static int omap2_onenand_set_async_mode(int cs, void __iomem *onenand_base)
86 t.cs_wr_off = t.we_off + gpmc_round_ns_to_ticks(t_wph); 89 t.cs_wr_off = t.we_off + gpmc_round_ns_to_ticks(t_wph);
87 t.wr_cycle = t.cs_wr_off + gpmc_round_ns_to_ticks(t_cez); 90 t.wr_cycle = t.cs_wr_off + gpmc_round_ns_to_ticks(t_cez);
88 91
92 return t;
93}
94
95static int gpmc_set_async_mode(int cs, struct gpmc_timings *t)
96{
89 /* Configure GPMC for asynchronous read */ 97 /* Configure GPMC for asynchronous read */
90 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, 98 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1,
91 GPMC_CONFIG1_DEVICESIZE_16 | 99 GPMC_CONFIG1_DEVICESIZE_16 |
92 GPMC_CONFIG1_MUXADDDATA); 100 GPMC_CONFIG1_MUXADDDATA);
93 101
94 err = gpmc_cs_set_timings(cs, &t); 102 return gpmc_cs_set_timings(cs, t);
95 if (err) 103}
96 return err; 104
105static void omap2_onenand_set_async_mode(void __iomem *onenand_base)
106{
107 u32 reg;
97 108
98 /* Ensure sync read and sync write are disabled */ 109 /* Ensure sync read and sync write are disabled */
99 reg = readw(onenand_base + ONENAND_REG_SYS_CFG1); 110 reg = readw(onenand_base + ONENAND_REG_SYS_CFG1);
100 reg &= ~ONENAND_SYS_CFG1_SYNC_READ & ~ONENAND_SYS_CFG1_SYNC_WRITE; 111 reg &= ~ONENAND_SYS_CFG1_SYNC_READ & ~ONENAND_SYS_CFG1_SYNC_WRITE;
101 writew(reg, onenand_base + ONENAND_REG_SYS_CFG1); 112 writew(reg, onenand_base + ONENAND_REG_SYS_CFG1);
102
103 return 0;
104} 113}
105 114
106static void set_onenand_cfg(void __iomem *onenand_base, int latency, 115static void set_onenand_cfg(void __iomem *onenand_base)
107 int sync_read, int sync_write, int hf, int vhf)
108{ 116{
109 u32 reg; 117 u32 reg;
110 118
@@ -112,19 +120,19 @@ static void set_onenand_cfg(void __iomem *onenand_base, int latency,
112 reg &= ~((0x7 << ONENAND_SYS_CFG1_BRL_SHIFT) | (0x7 << 9)); 120 reg &= ~((0x7 << ONENAND_SYS_CFG1_BRL_SHIFT) | (0x7 << 9));
113 reg |= (latency << ONENAND_SYS_CFG1_BRL_SHIFT) | 121 reg |= (latency << ONENAND_SYS_CFG1_BRL_SHIFT) |
114 ONENAND_SYS_CFG1_BL_16; 122 ONENAND_SYS_CFG1_BL_16;
115 if (sync_read) 123 if (onenand_flags & ONENAND_FLAG_SYNCREAD)
116 reg |= ONENAND_SYS_CFG1_SYNC_READ; 124 reg |= ONENAND_SYS_CFG1_SYNC_READ;
117 else 125 else
118 reg &= ~ONENAND_SYS_CFG1_SYNC_READ; 126 reg &= ~ONENAND_SYS_CFG1_SYNC_READ;
119 if (sync_write) 127 if (onenand_flags & ONENAND_FLAG_SYNCWRITE)
120 reg |= ONENAND_SYS_CFG1_SYNC_WRITE; 128 reg |= ONENAND_SYS_CFG1_SYNC_WRITE;
121 else 129 else
122 reg &= ~ONENAND_SYS_CFG1_SYNC_WRITE; 130 reg &= ~ONENAND_SYS_CFG1_SYNC_WRITE;
123 if (hf) 131 if (onenand_flags & ONENAND_FLAG_HF)
124 reg |= ONENAND_SYS_CFG1_HF; 132 reg |= ONENAND_SYS_CFG1_HF;
125 else 133 else
126 reg &= ~ONENAND_SYS_CFG1_HF; 134 reg &= ~ONENAND_SYS_CFG1_HF;
127 if (vhf) 135 if (onenand_flags & ONENAND_FLAG_VHF)
128 reg |= ONENAND_SYS_CFG1_VHF; 136 reg |= ONENAND_SYS_CFG1_VHF;
129 else 137 else
130 reg &= ~ONENAND_SYS_CFG1_VHF; 138 reg &= ~ONENAND_SYS_CFG1_VHF;
@@ -132,21 +140,10 @@ static void set_onenand_cfg(void __iomem *onenand_base, int latency,
132} 140}
133 141
134static int omap2_onenand_get_freq(struct omap_onenand_platform_data *cfg, 142static int omap2_onenand_get_freq(struct omap_onenand_platform_data *cfg,
135 void __iomem *onenand_base, bool *clk_dep) 143 void __iomem *onenand_base)
136{ 144{
137 u16 ver = readw(onenand_base + ONENAND_REG_VERSION_ID); 145 u16 ver = readw(onenand_base + ONENAND_REG_VERSION_ID);
138 int freq = 0; 146 int freq;
139
140 if (cfg->get_freq) {
141 struct onenand_freq_info fi;
142
143 fi.maf_id = readw(onenand_base + ONENAND_REG_MANUFACTURER_ID);
144 fi.dev_id = readw(onenand_base + ONENAND_REG_DEVICE_ID);
145 fi.ver_id = ver;
146 freq = cfg->get_freq(&fi, clk_dep);
147 if (freq)
148 return freq;
149 }
150 147
151 switch ((ver >> 4) & 0xf) { 148 switch ((ver >> 4) & 0xf) {
152 case 0: 149 case 0:
@@ -172,9 +169,9 @@ static int omap2_onenand_get_freq(struct omap_onenand_platform_data *cfg,
172 return freq; 169 return freq;
173} 170}
174 171
175static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg, 172static struct gpmc_timings
176 void __iomem *onenand_base, 173omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
177 int *freq_ptr) 174 int freq)
178{ 175{
179 struct gpmc_timings t; 176 struct gpmc_timings t;
180 const int t_cer = 15; 177 const int t_cer = 15;
@@ -184,29 +181,15 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
184 const int t_wpl = 40; 181 const int t_wpl = 40;
185 const int t_wph = 30; 182 const int t_wph = 30;
186 int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo; 183 int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo;
187 int div, fclk_offset_ns, fclk_offset, gpmc_clk_ns, latency;
188 int first_time = 0, hf = 0, vhf = 0, sync_read = 0, sync_write = 0;
189 int err, ticks_cez;
190 int cs = cfg->cs, freq = *freq_ptr;
191 u32 reg; 184 u32 reg;
192 bool clk_dep = false; 185 int div, fclk_offset_ns, gpmc_clk_ns;
186 int ticks_cez;
187 int cs = cfg->cs;
193 188
194 if (cfg->flags & ONENAND_SYNC_READ) { 189 if (cfg->flags & ONENAND_SYNC_READ)
195 sync_read = 1; 190 onenand_flags = ONENAND_FLAG_SYNCREAD;
196 } else if (cfg->flags & ONENAND_SYNC_READWRITE) { 191 else if (cfg->flags & ONENAND_SYNC_READWRITE)
197 sync_read = 1; 192 onenand_flags = ONENAND_FLAG_SYNCREAD | ONENAND_FLAG_SYNCWRITE;
198 sync_write = 1;
199 } else
200 return omap2_onenand_set_async_mode(cs, onenand_base);
201
202 if (!freq) {
203 /* Very first call freq is not known */
204 err = omap2_onenand_set_async_mode(cs, onenand_base);
205 if (err)
206 return err;
207 freq = omap2_onenand_get_freq(cfg, onenand_base, &clk_dep);
208 first_time = 1;
209 }
210 193
211 switch (freq) { 194 switch (freq) {
212 case 104: 195 case 104:
@@ -244,44 +227,31 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
244 t_ach = 9; 227 t_ach = 9;
245 t_aavdh = 7; 228 t_aavdh = 7;
246 t_rdyo = 15; 229 t_rdyo = 15;
247 sync_write = 0; 230 onenand_flags &= ~ONENAND_FLAG_SYNCWRITE;
248 break; 231 break;
249 } 232 }
250 233
251 div = gpmc_cs_calc_divider(cs, min_gpmc_clk_period); 234 div = gpmc_calc_divider(min_gpmc_clk_period);
252 gpmc_clk_ns = gpmc_ticks_to_ns(div); 235 gpmc_clk_ns = gpmc_ticks_to_ns(div);
253 if (gpmc_clk_ns < 15) /* >66Mhz */ 236 if (gpmc_clk_ns < 15) /* >66Mhz */
254 hf = 1; 237 onenand_flags |= ONENAND_FLAG_HF;
238 else
239 onenand_flags &= ~ONENAND_FLAG_HF;
255 if (gpmc_clk_ns < 12) /* >83Mhz */ 240 if (gpmc_clk_ns < 12) /* >83Mhz */
256 vhf = 1; 241 onenand_flags |= ONENAND_FLAG_VHF;
257 if (vhf) 242 else
243 onenand_flags &= ~ONENAND_FLAG_VHF;
244 if (onenand_flags & ONENAND_FLAG_VHF)
258 latency = 8; 245 latency = 8;
259 else if (hf) 246 else if (onenand_flags & ONENAND_FLAG_HF)
260 latency = 6; 247 latency = 6;
261 else if (gpmc_clk_ns >= 25) /* 40 MHz*/ 248 else if (gpmc_clk_ns >= 25) /* 40 MHz*/
262 latency = 3; 249 latency = 3;
263 else 250 else
264 latency = 4; 251 latency = 4;
265 252
266 if (clk_dep) { 253 /* Set synchronous read timings */
267 if (gpmc_clk_ns < 12) { /* >83Mhz */ 254 memset(&t, 0, sizeof(t));
268 t_ces = 3;
269 t_avds = 4;
270 } else if (gpmc_clk_ns < 15) { /* >66Mhz */
271 t_ces = 5;
272 t_avds = 4;
273 } else if (gpmc_clk_ns < 25) { /* >40Mhz */
274 t_ces = 6;
275 t_avds = 5;
276 } else {
277 t_ces = 7;
278 t_avds = 7;
279 }
280 }
281
282 if (first_time)
283 set_onenand_cfg(onenand_base, latency,
284 sync_read, sync_write, hf, vhf);
285 255
286 if (div == 1) { 256 if (div == 1) {
287 reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG2); 257 reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG2);
@@ -307,8 +277,6 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
307 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG4, reg); 277 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG4, reg);
308 } 278 }
309 279
310 /* Set synchronous read timings */
311 memset(&t, 0, sizeof(t));
312 t.sync_clk = min_gpmc_clk_period; 280 t.sync_clk = min_gpmc_clk_period;
313 t.cs_on = 0; 281 t.cs_on = 0;
314 t.adv_on = 0; 282 t.adv_on = 0;
@@ -330,7 +298,7 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
330 ticks_cez); 298 ticks_cez);
331 299
332 /* Write */ 300 /* Write */
333 if (sync_write) { 301 if (onenand_flags & ONENAND_FLAG_SYNCWRITE) {
334 t.adv_wr_off = t.adv_rd_off; 302 t.adv_wr_off = t.adv_rd_off;
335 t.we_on = 0; 303 t.we_on = 0;
336 t.we_off = t.cs_rd_off; 304 t.we_off = t.cs_rd_off;
@@ -355,6 +323,14 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
355 } 323 }
356 } 324 }
357 325
326 return t;
327}
328
329static int gpmc_set_sync_mode(int cs, struct gpmc_timings *t)
330{
331 unsigned sync_read = onenand_flags & ONENAND_FLAG_SYNCREAD;
332 unsigned sync_write = onenand_flags & ONENAND_FLAG_SYNCWRITE;
333
358 /* Configure GPMC for synchronous read */ 334 /* Configure GPMC for synchronous read */
359 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, 335 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1,
360 GPMC_CONFIG1_WRAPBURST_SUPP | 336 GPMC_CONFIG1_WRAPBURST_SUPP |
@@ -371,11 +347,45 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
371 GPMC_CONFIG1_DEVICETYPE_NOR | 347 GPMC_CONFIG1_DEVICETYPE_NOR |
372 GPMC_CONFIG1_MUXADDDATA); 348 GPMC_CONFIG1_MUXADDDATA);
373 349
374 err = gpmc_cs_set_timings(cs, &t); 350 return gpmc_cs_set_timings(cs, t);
375 if (err) 351}
376 return err; 352
353static int omap2_onenand_setup_async(void __iomem *onenand_base)
354{
355 struct gpmc_timings t;
356 int ret;
357
358 omap2_onenand_set_async_mode(onenand_base);
377 359
378 set_onenand_cfg(onenand_base, latency, sync_read, sync_write, hf, vhf); 360 t = omap2_onenand_calc_async_timings();
361
362 ret = gpmc_set_async_mode(gpmc_onenand_data->cs, &t);
363 if (IS_ERR_VALUE(ret))
364 return ret;
365
366 omap2_onenand_set_async_mode(onenand_base);
367
368 return 0;
369}
370
371static int omap2_onenand_setup_sync(void __iomem *onenand_base, int *freq_ptr)
372{
373 int ret, freq = *freq_ptr;
374 struct gpmc_timings t;
375
376 if (!freq) {
377 /* Very first call freq is not known */
378 freq = omap2_onenand_get_freq(gpmc_onenand_data, onenand_base);
379 set_onenand_cfg(onenand_base);
380 }
381
382 t = omap2_onenand_calc_sync_timings(gpmc_onenand_data, freq);
383
384 ret = gpmc_set_sync_mode(gpmc_onenand_data->cs, &t);
385 if (IS_ERR_VALUE(ret))
386 return ret;
387
388 set_onenand_cfg(onenand_base);
379 389
380 *freq_ptr = freq; 390 *freq_ptr = freq;
381 391
@@ -385,15 +395,22 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
385static int gpmc_onenand_setup(void __iomem *onenand_base, int *freq_ptr) 395static int gpmc_onenand_setup(void __iomem *onenand_base, int *freq_ptr)
386{ 396{
387 struct device *dev = &gpmc_onenand_device.dev; 397 struct device *dev = &gpmc_onenand_device.dev;
398 unsigned l = ONENAND_SYNC_READ | ONENAND_SYNC_READWRITE;
399 int ret;
388 400
389 /* Set sync timings in GPMC */ 401 ret = omap2_onenand_setup_async(onenand_base);
390 if (omap2_onenand_set_sync_mode(gpmc_onenand_data, onenand_base, 402 if (ret) {
391 freq_ptr) < 0) { 403 dev_err(dev, "unable to set to async mode\n");
392 dev_err(dev, "Unable to set synchronous mode\n"); 404 return ret;
393 return -EINVAL;
394 } 405 }
395 406
396 return 0; 407 if (!(gpmc_onenand_data->flags & l))
408 return 0;
409
410 ret = omap2_onenand_setup_sync(onenand_base, freq_ptr);
411 if (ret)
412 dev_err(dev, "unable to set to sync mode\n");
413 return ret;
397} 414}
398 415
399void __init gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data) 416void __init gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data)
@@ -411,6 +428,11 @@ void __init gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data)
411 gpmc_onenand_data->flags |= ONENAND_SYNC_READ; 428 gpmc_onenand_data->flags |= ONENAND_SYNC_READ;
412 } 429 }
413 430
431 if (cpu_is_omap34xx())
432 gpmc_onenand_data->flags |= ONENAND_IN_OMAP34XX;
433 else
434 gpmc_onenand_data->flags &= ~ONENAND_IN_OMAP34XX;
435
414 err = gpmc_cs_request(gpmc_onenand_data->cs, ONENAND_IO_SIZE, 436 err = gpmc_cs_request(gpmc_onenand_data->cs, ONENAND_IO_SIZE,
415 (unsigned long *)&gpmc_onenand_resource.start); 437 (unsigned long *)&gpmc_onenand_resource.start);
416 if (err < 0) { 438 if (err < 0) {
diff --git a/arch/arm/mach-omap2/gpmc-onenand.h b/arch/arm/mach-omap2/gpmc-onenand.h
new file mode 100644
index 000000000000..216f23a8b45c
--- /dev/null
+++ b/arch/arm/mach-omap2/gpmc-onenand.h
@@ -0,0 +1,24 @@
1/*
2 * arch/arm/mach-omap2/gpmc-onenand.h
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 */
9
10#ifndef __OMAP2_GPMC_ONENAND_H
11#define __OMAP2_GPMC_ONENAND_H
12
13#include <linux/platform_data/mtd-onenand-omap2.h>
14
15#if IS_ENABLED(CONFIG_MTD_ONENAND_OMAP2)
16extern void gpmc_onenand_init(struct omap_onenand_platform_data *d);
17#else
18#define board_onenand_data NULL
19static inline void gpmc_onenand_init(struct omap_onenand_platform_data *d)
20{
21}
22#endif
23
24#endif
diff --git a/arch/arm/mach-omap2/gpmc-smc91x.c b/arch/arm/mach-omap2/gpmc-smc91x.c
index 565475310374..6eed907d594c 100644
--- a/arch/arm/mach-omap2/gpmc-smc91x.c
+++ b/arch/arm/mach-omap2/gpmc-smc91x.c
@@ -17,7 +17,7 @@
17#include <linux/io.h> 17#include <linux/io.h>
18#include <linux/smc91x.h> 18#include <linux/smc91x.h>
19 19
20#include <plat/gpmc.h> 20#include "gpmc.h"
21#include "gpmc-smc91x.h" 21#include "gpmc-smc91x.h"
22 22
23#include "soc.h" 23#include "soc.h"
diff --git a/arch/arm/mach-omap2/gpmc-smsc911x.c b/arch/arm/mach-omap2/gpmc-smsc911x.c
index 249a0b440cd6..ef990118d32b 100644
--- a/arch/arm/mach-omap2/gpmc-smsc911x.c
+++ b/arch/arm/mach-omap2/gpmc-smsc911x.c
@@ -20,7 +20,7 @@
20#include <linux/io.h> 20#include <linux/io.h>
21#include <linux/smsc911x.h> 21#include <linux/smsc911x.h>
22 22
23#include <plat/gpmc.h> 23#include "gpmc.h"
24#include "gpmc-smsc911x.h" 24#include "gpmc-smsc911x.h"
25 25
26static struct resource gpmc_smsc911x_resources[] = { 26static struct resource gpmc_smsc911x_resources[] = {
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 5ac5cf30406a..f14bd3f55218 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -26,16 +26,17 @@
26#include <linux/interrupt.h> 26#include <linux/interrupt.h>
27#include <linux/platform_device.h> 27#include <linux/platform_device.h>
28 28
29#include <linux/platform_data/mtd-nand-omap2.h>
30
29#include <asm/mach-types.h> 31#include <asm/mach-types.h>
30#include <plat/gpmc.h>
31 32
32#include <plat/cpu.h> 33#include <plat/cpu.h>
33#include <plat/gpmc.h>
34#include <plat/sdrc.h> 34#include <plat/sdrc.h>
35#include <plat/omap_device.h> 35#include <plat/omap_device.h>
36 36
37#include "soc.h" 37#include "soc.h"
38#include "common.h" 38#include "common.h"
39#include "gpmc.h"
39 40
40#define DEVICE_NAME "omap-gpmc" 41#define DEVICE_NAME "omap-gpmc"
41 42
@@ -59,6 +60,9 @@
59#define GPMC_ECC_SIZE_CONFIG 0x1fc 60#define GPMC_ECC_SIZE_CONFIG 0x1fc
60#define GPMC_ECC1_RESULT 0x200 61#define GPMC_ECC1_RESULT 0x200
61#define GPMC_ECC_BCH_RESULT_0 0x240 /* not available on OMAP2 */ 62#define GPMC_ECC_BCH_RESULT_0 0x240 /* not available on OMAP2 */
63#define GPMC_ECC_BCH_RESULT_1 0x244 /* not available on OMAP2 */
64#define GPMC_ECC_BCH_RESULT_2 0x248 /* not available on OMAP2 */
65#define GPMC_ECC_BCH_RESULT_3 0x24c /* not available on OMAP2 */
62 66
63/* GPMC ECC control settings */ 67/* GPMC ECC control settings */
64#define GPMC_ECC_CTRL_ECCCLEAR 0x100 68#define GPMC_ECC_CTRL_ECCCLEAR 0x100
@@ -75,6 +79,7 @@
75 79
76#define GPMC_CS0_OFFSET 0x60 80#define GPMC_CS0_OFFSET 0x60
77#define GPMC_CS_SIZE 0x30 81#define GPMC_CS_SIZE 0x30
82#define GPMC_BCH_SIZE 0x10
78 83
79#define GPMC_MEM_START 0x00000000 84#define GPMC_MEM_START 0x00000000
80#define GPMC_MEM_END 0x3FFFFFFF 85#define GPMC_MEM_END 0x3FFFFFFF
@@ -137,7 +142,6 @@ static struct resource gpmc_mem_root;
137static struct resource gpmc_cs_mem[GPMC_CS_NUM]; 142static struct resource gpmc_cs_mem[GPMC_CS_NUM];
138static DEFINE_SPINLOCK(gpmc_mem_lock); 143static DEFINE_SPINLOCK(gpmc_mem_lock);
139static unsigned int gpmc_cs_map; /* flag for cs which are initialized */ 144static unsigned int gpmc_cs_map; /* flag for cs which are initialized */
140static int gpmc_ecc_used = -EINVAL; /* cs using ecc engine */
141static struct device *gpmc_dev; 145static struct device *gpmc_dev;
142static int gpmc_irq; 146static int gpmc_irq;
143static resource_size_t phys_base, mem_size; 147static resource_size_t phys_base, mem_size;
@@ -158,22 +162,6 @@ static u32 gpmc_read_reg(int idx)
158 return __raw_readl(gpmc_base + idx); 162 return __raw_readl(gpmc_base + idx);
159} 163}
160 164
161static void gpmc_cs_write_byte(int cs, int idx, u8 val)
162{
163 void __iomem *reg_addr;
164
165 reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx;
166 __raw_writeb(val, reg_addr);
167}
168
169static u8 gpmc_cs_read_byte(int cs, int idx)
170{
171 void __iomem *reg_addr;
172
173 reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx;
174 return __raw_readb(reg_addr);
175}
176
177void gpmc_cs_write_reg(int cs, int idx, u32 val) 165void gpmc_cs_write_reg(int cs, int idx, u32 val)
178{ 166{
179 void __iomem *reg_addr; 167 void __iomem *reg_addr;
@@ -288,7 +276,7 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
288 return -1 276 return -1
289#endif 277#endif
290 278
291int gpmc_cs_calc_divider(int cs, unsigned int sync_clk) 279int gpmc_calc_divider(unsigned int sync_clk)
292{ 280{
293 int div; 281 int div;
294 u32 l; 282 u32 l;
@@ -308,7 +296,7 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
308 int div; 296 int div;
309 u32 l; 297 u32 l;
310 298
311 div = gpmc_cs_calc_divider(cs, t->sync_clk); 299 div = gpmc_calc_divider(t->sync_clk);
312 if (div < 0) 300 if (div < 0)
313 return div; 301 return div;
314 302
@@ -509,44 +497,6 @@ void gpmc_cs_free(int cs)
509EXPORT_SYMBOL(gpmc_cs_free); 497EXPORT_SYMBOL(gpmc_cs_free);
510 498
511/** 499/**
512 * gpmc_read_status - read access request to get the different gpmc status
513 * @cmd: command type
514 * @return status
515 */
516int gpmc_read_status(int cmd)
517{
518 int status = -EINVAL;
519 u32 regval = 0;
520
521 switch (cmd) {
522 case GPMC_GET_IRQ_STATUS:
523 status = gpmc_read_reg(GPMC_IRQSTATUS);
524 break;
525
526 case GPMC_PREFETCH_FIFO_CNT:
527 regval = gpmc_read_reg(GPMC_PREFETCH_STATUS);
528 status = GPMC_PREFETCH_STATUS_FIFO_CNT(regval);
529 break;
530
531 case GPMC_PREFETCH_COUNT:
532 regval = gpmc_read_reg(GPMC_PREFETCH_STATUS);
533 status = GPMC_PREFETCH_STATUS_COUNT(regval);
534 break;
535
536 case GPMC_STATUS_BUFFER:
537 regval = gpmc_read_reg(GPMC_STATUS);
538 /* 1 : buffer is available to write */
539 status = regval & GPMC_STATUS_BUFF_EMPTY;
540 break;
541
542 default:
543 printk(KERN_ERR "gpmc_read_status: Not supported\n");
544 }
545 return status;
546}
547EXPORT_SYMBOL(gpmc_read_status);
548
549/**
550 * gpmc_cs_configure - write request to configure gpmc 500 * gpmc_cs_configure - write request to configure gpmc
551 * @cs: chip select number 501 * @cs: chip select number
552 * @cmd: command type 502 * @cmd: command type
@@ -614,121 +564,10 @@ int gpmc_cs_configure(int cs, int cmd, int wval)
614} 564}
615EXPORT_SYMBOL(gpmc_cs_configure); 565EXPORT_SYMBOL(gpmc_cs_configure);
616 566
617/**
618 * gpmc_nand_read - nand specific read access request
619 * @cs: chip select number
620 * @cmd: command type
621 */
622int gpmc_nand_read(int cs, int cmd)
623{
624 int rval = -EINVAL;
625
626 switch (cmd) {
627 case GPMC_NAND_DATA:
628 rval = gpmc_cs_read_byte(cs, GPMC_CS_NAND_DATA);
629 break;
630
631 default:
632 printk(KERN_ERR "gpmc_read_nand_ctrl: Not supported\n");
633 }
634 return rval;
635}
636EXPORT_SYMBOL(gpmc_nand_read);
637
638/**
639 * gpmc_nand_write - nand specific write request
640 * @cs: chip select number
641 * @cmd: command type
642 * @wval: value to write
643 */
644int gpmc_nand_write(int cs, int cmd, int wval)
645{
646 int err = 0;
647
648 switch (cmd) {
649 case GPMC_NAND_COMMAND:
650 gpmc_cs_write_byte(cs, GPMC_CS_NAND_COMMAND, wval);
651 break;
652
653 case GPMC_NAND_ADDRESS:
654 gpmc_cs_write_byte(cs, GPMC_CS_NAND_ADDRESS, wval);
655 break;
656
657 case GPMC_NAND_DATA:
658 gpmc_cs_write_byte(cs, GPMC_CS_NAND_DATA, wval);
659
660 default:
661 printk(KERN_ERR "gpmc_write_nand_ctrl: Not supported\n");
662 err = -EINVAL;
663 }
664 return err;
665}
666EXPORT_SYMBOL(gpmc_nand_write);
667
668
669
670/**
671 * gpmc_prefetch_enable - configures and starts prefetch transfer
672 * @cs: cs (chip select) number
673 * @fifo_th: fifo threshold to be used for read/ write
674 * @dma_mode: dma mode enable (1) or disable (0)
675 * @u32_count: number of bytes to be transferred
676 * @is_write: prefetch read(0) or write post(1) mode
677 */
678int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode,
679 unsigned int u32_count, int is_write)
680{
681
682 if (fifo_th > PREFETCH_FIFOTHRESHOLD_MAX) {
683 pr_err("gpmc: fifo threshold is not supported\n");
684 return -1;
685 } else if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) {
686 /* Set the amount of bytes to be prefetched */
687 gpmc_write_reg(GPMC_PREFETCH_CONFIG2, u32_count);
688
689 /* Set dma/mpu mode, the prefetch read / post write and
690 * enable the engine. Set which cs is has requested for.
691 */
692 gpmc_write_reg(GPMC_PREFETCH_CONFIG1, ((cs << CS_NUM_SHIFT) |
693 PREFETCH_FIFOTHRESHOLD(fifo_th) |
694 ENABLE_PREFETCH |
695 (dma_mode << DMA_MPU_MODE) |
696 (0x1 & is_write)));
697
698 /* Start the prefetch engine */
699 gpmc_write_reg(GPMC_PREFETCH_CONTROL, 0x1);
700 } else {
701 return -EBUSY;
702 }
703
704 return 0;
705}
706EXPORT_SYMBOL(gpmc_prefetch_enable);
707
708/**
709 * gpmc_prefetch_reset - disables and stops the prefetch engine
710 */
711int gpmc_prefetch_reset(int cs)
712{
713 u32 config1;
714
715 /* check if the same module/cs is trying to reset */
716 config1 = gpmc_read_reg(GPMC_PREFETCH_CONFIG1);
717 if (((config1 >> CS_NUM_SHIFT) & 0x7) != cs)
718 return -EINVAL;
719
720 /* Stop the PFPW engine */
721 gpmc_write_reg(GPMC_PREFETCH_CONTROL, 0x0);
722
723 /* Reset/disable the PFPW engine */
724 gpmc_write_reg(GPMC_PREFETCH_CONFIG1, 0x0);
725
726 return 0;
727}
728EXPORT_SYMBOL(gpmc_prefetch_reset);
729
730void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs) 567void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs)
731{ 568{
569 int i;
570
732 reg->gpmc_status = gpmc_base + GPMC_STATUS; 571 reg->gpmc_status = gpmc_base + GPMC_STATUS;
733 reg->gpmc_nand_command = gpmc_base + GPMC_CS0_OFFSET + 572 reg->gpmc_nand_command = gpmc_base + GPMC_CS0_OFFSET +
734 GPMC_CS_NAND_COMMAND + GPMC_CS_SIZE * cs; 573 GPMC_CS_NAND_COMMAND + GPMC_CS_SIZE * cs;
@@ -744,7 +583,17 @@ void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs)
744 reg->gpmc_ecc_control = gpmc_base + GPMC_ECC_CONTROL; 583 reg->gpmc_ecc_control = gpmc_base + GPMC_ECC_CONTROL;
745 reg->gpmc_ecc_size_config = gpmc_base + GPMC_ECC_SIZE_CONFIG; 584 reg->gpmc_ecc_size_config = gpmc_base + GPMC_ECC_SIZE_CONFIG;
746 reg->gpmc_ecc1_result = gpmc_base + GPMC_ECC1_RESULT; 585 reg->gpmc_ecc1_result = gpmc_base + GPMC_ECC1_RESULT;
747 reg->gpmc_bch_result0 = gpmc_base + GPMC_ECC_BCH_RESULT_0; 586
587 for (i = 0; i < GPMC_BCH_NUM_REMAINDER; i++) {
588 reg->gpmc_bch_result0[i] = gpmc_base + GPMC_ECC_BCH_RESULT_0 +
589 GPMC_BCH_SIZE * i;
590 reg->gpmc_bch_result1[i] = gpmc_base + GPMC_ECC_BCH_RESULT_1 +
591 GPMC_BCH_SIZE * i;
592 reg->gpmc_bch_result2[i] = gpmc_base + GPMC_ECC_BCH_RESULT_2 +
593 GPMC_BCH_SIZE * i;
594 reg->gpmc_bch_result3[i] = gpmc_base + GPMC_ECC_BCH_RESULT_3 +
595 GPMC_BCH_SIZE * i;
596 }
748} 597}
749 598
750int gpmc_get_client_irq(unsigned irq_config) 599int gpmc_get_client_irq(unsigned irq_config)
@@ -1079,267 +928,3 @@ void omap3_gpmc_restore_context(void)
1079 } 928 }
1080} 929}
1081#endif /* CONFIG_ARCH_OMAP3 */ 930#endif /* CONFIG_ARCH_OMAP3 */
1082
1083/**
1084 * gpmc_enable_hwecc - enable hardware ecc functionality
1085 * @cs: chip select number
1086 * @mode: read/write mode
1087 * @dev_width: device bus width(1 for x16, 0 for x8)
1088 * @ecc_size: bytes for which ECC will be generated
1089 */
1090int gpmc_enable_hwecc(int cs, int mode, int dev_width, int ecc_size)
1091{
1092 unsigned int val;
1093
1094 /* check if ecc module is in used */
1095 if (gpmc_ecc_used != -EINVAL)
1096 return -EINVAL;
1097
1098 gpmc_ecc_used = cs;
1099
1100 /* clear ecc and enable bits */
1101 gpmc_write_reg(GPMC_ECC_CONTROL,
1102 GPMC_ECC_CTRL_ECCCLEAR |
1103 GPMC_ECC_CTRL_ECCREG1);
1104
1105 /* program ecc and result sizes */
1106 val = ((((ecc_size >> 1) - 1) << 22) | (0x0000000F));
1107 gpmc_write_reg(GPMC_ECC_SIZE_CONFIG, val);
1108
1109 switch (mode) {
1110 case GPMC_ECC_READ:
1111 case GPMC_ECC_WRITE:
1112 gpmc_write_reg(GPMC_ECC_CONTROL,
1113 GPMC_ECC_CTRL_ECCCLEAR |
1114 GPMC_ECC_CTRL_ECCREG1);
1115 break;
1116 case GPMC_ECC_READSYN:
1117 gpmc_write_reg(GPMC_ECC_CONTROL,
1118 GPMC_ECC_CTRL_ECCCLEAR |
1119 GPMC_ECC_CTRL_ECCDISABLE);
1120 break;
1121 default:
1122 printk(KERN_INFO "Error: Unrecognized Mode[%d]!\n", mode);
1123 break;
1124 }
1125
1126 /* (ECC 16 or 8 bit col) | ( CS ) | ECC Enable */
1127 val = (dev_width << 7) | (cs << 1) | (0x1);
1128 gpmc_write_reg(GPMC_ECC_CONFIG, val);
1129 return 0;
1130}
1131EXPORT_SYMBOL_GPL(gpmc_enable_hwecc);
1132
1133/**
1134 * gpmc_calculate_ecc - generate non-inverted ecc bytes
1135 * @cs: chip select number
1136 * @dat: data pointer over which ecc is computed
1137 * @ecc_code: ecc code buffer
1138 *
1139 * Using non-inverted ECC is considered ugly since writing a blank
1140 * page (padding) will clear the ECC bytes. This is not a problem as long
1141 * no one is trying to write data on the seemingly unused page. Reading
1142 * an erased page will produce an ECC mismatch between generated and read
1143 * ECC bytes that has to be dealt with separately.
1144 */
1145int gpmc_calculate_ecc(int cs, const u_char *dat, u_char *ecc_code)
1146{
1147 unsigned int val = 0x0;
1148
1149 if (gpmc_ecc_used != cs)
1150 return -EINVAL;
1151
1152 /* read ecc result */
1153 val = gpmc_read_reg(GPMC_ECC1_RESULT);
1154 *ecc_code++ = val; /* P128e, ..., P1e */
1155 *ecc_code++ = val >> 16; /* P128o, ..., P1o */
1156 /* P2048o, P1024o, P512o, P256o, P2048e, P1024e, P512e, P256e */
1157 *ecc_code++ = ((val >> 8) & 0x0f) | ((val >> 20) & 0xf0);
1158
1159 gpmc_ecc_used = -EINVAL;
1160 return 0;
1161}
1162EXPORT_SYMBOL_GPL(gpmc_calculate_ecc);
1163
1164#ifdef CONFIG_ARCH_OMAP3
1165
1166/**
1167 * gpmc_init_hwecc_bch - initialize hardware BCH ecc functionality
1168 * @cs: chip select number
1169 * @nsectors: how many 512-byte sectors to process
1170 * @nerrors: how many errors to correct per sector (4 or 8)
1171 *
1172 * This function must be executed before any call to gpmc_enable_hwecc_bch.
1173 */
1174int gpmc_init_hwecc_bch(int cs, int nsectors, int nerrors)
1175{
1176 /* check if ecc module is in use */
1177 if (gpmc_ecc_used != -EINVAL)
1178 return -EINVAL;
1179
1180 /* support only OMAP3 class */
1181 if (!cpu_is_omap34xx()) {
1182 printk(KERN_ERR "BCH ecc is not supported on this CPU\n");
1183 return -EINVAL;
1184 }
1185
1186 /*
1187 * For now, assume 4-bit mode is only supported on OMAP3630 ES1.x, x>=1.
1188 * Other chips may be added if confirmed to work.
1189 */
1190 if ((nerrors == 4) &&
1191 (!cpu_is_omap3630() || (GET_OMAP_REVISION() == 0))) {
1192 printk(KERN_ERR "BCH 4-bit mode is not supported on this CPU\n");
1193 return -EINVAL;
1194 }
1195
1196 /* sanity check */
1197 if (nsectors > 8) {
1198 printk(KERN_ERR "BCH cannot process %d sectors (max is 8)\n",
1199 nsectors);
1200 return -EINVAL;
1201 }
1202
1203 return 0;
1204}
1205EXPORT_SYMBOL_GPL(gpmc_init_hwecc_bch);
1206
1207/**
1208 * gpmc_enable_hwecc_bch - enable hardware BCH ecc functionality
1209 * @cs: chip select number
1210 * @mode: read/write mode
1211 * @dev_width: device bus width(1 for x16, 0 for x8)
1212 * @nsectors: how many 512-byte sectors to process
1213 * @nerrors: how many errors to correct per sector (4 or 8)
1214 */
1215int gpmc_enable_hwecc_bch(int cs, int mode, int dev_width, int nsectors,
1216 int nerrors)
1217{
1218 unsigned int val;
1219
1220 /* check if ecc module is in use */
1221 if (gpmc_ecc_used != -EINVAL)
1222 return -EINVAL;
1223
1224 gpmc_ecc_used = cs;
1225
1226 /* clear ecc and enable bits */
1227 gpmc_write_reg(GPMC_ECC_CONTROL, 0x1);
1228
1229 /*
1230 * When using BCH, sector size is hardcoded to 512 bytes.
1231 * Here we are using wrapping mode 6 both for reading and writing, with:
1232 * size0 = 0 (no additional protected byte in spare area)
1233 * size1 = 32 (skip 32 nibbles = 16 bytes per sector in spare area)
1234 */
1235 gpmc_write_reg(GPMC_ECC_SIZE_CONFIG, (32 << 22) | (0 << 12));
1236
1237 /* BCH configuration */
1238 val = ((1 << 16) | /* enable BCH */
1239 (((nerrors == 8) ? 1 : 0) << 12) | /* 8 or 4 bits */
1240 (0x06 << 8) | /* wrap mode = 6 */
1241 (dev_width << 7) | /* bus width */
1242 (((nsectors-1) & 0x7) << 4) | /* number of sectors */
1243 (cs << 1) | /* ECC CS */
1244 (0x1)); /* enable ECC */
1245
1246 gpmc_write_reg(GPMC_ECC_CONFIG, val);
1247 gpmc_write_reg(GPMC_ECC_CONTROL, 0x101);
1248 return 0;
1249}
1250EXPORT_SYMBOL_GPL(gpmc_enable_hwecc_bch);
1251
1252/**
1253 * gpmc_calculate_ecc_bch4 - Generate 7 ecc bytes per sector of 512 data bytes
1254 * @cs: chip select number
1255 * @dat: The pointer to data on which ecc is computed
1256 * @ecc: The ecc output buffer
1257 */
1258int gpmc_calculate_ecc_bch4(int cs, const u_char *dat, u_char *ecc)
1259{
1260 int i;
1261 unsigned long nsectors, reg, val1, val2;
1262
1263 if (gpmc_ecc_used != cs)
1264 return -EINVAL;
1265
1266 nsectors = ((gpmc_read_reg(GPMC_ECC_CONFIG) >> 4) & 0x7) + 1;
1267
1268 for (i = 0; i < nsectors; i++) {
1269
1270 reg = GPMC_ECC_BCH_RESULT_0 + 16*i;
1271
1272 /* Read hw-computed remainder */
1273 val1 = gpmc_read_reg(reg + 0);
1274 val2 = gpmc_read_reg(reg + 4);
1275
1276 /*
1277 * Add constant polynomial to remainder, in order to get an ecc
1278 * sequence of 0xFFs for a buffer filled with 0xFFs; and
1279 * left-justify the resulting polynomial.
1280 */
1281 *ecc++ = 0x28 ^ ((val2 >> 12) & 0xFF);
1282 *ecc++ = 0x13 ^ ((val2 >> 4) & 0xFF);
1283 *ecc++ = 0xcc ^ (((val2 & 0xF) << 4)|((val1 >> 28) & 0xF));
1284 *ecc++ = 0x39 ^ ((val1 >> 20) & 0xFF);
1285 *ecc++ = 0x96 ^ ((val1 >> 12) & 0xFF);
1286 *ecc++ = 0xac ^ ((val1 >> 4) & 0xFF);
1287 *ecc++ = 0x7f ^ ((val1 & 0xF) << 4);
1288 }
1289
1290 gpmc_ecc_used = -EINVAL;
1291 return 0;
1292}
1293EXPORT_SYMBOL_GPL(gpmc_calculate_ecc_bch4);
1294
1295/**
1296 * gpmc_calculate_ecc_bch8 - Generate 13 ecc bytes per block of 512 data bytes
1297 * @cs: chip select number
1298 * @dat: The pointer to data on which ecc is computed
1299 * @ecc: The ecc output buffer
1300 */
1301int gpmc_calculate_ecc_bch8(int cs, const u_char *dat, u_char *ecc)
1302{
1303 int i;
1304 unsigned long nsectors, reg, val1, val2, val3, val4;
1305
1306 if (gpmc_ecc_used != cs)
1307 return -EINVAL;
1308
1309 nsectors = ((gpmc_read_reg(GPMC_ECC_CONFIG) >> 4) & 0x7) + 1;
1310
1311 for (i = 0; i < nsectors; i++) {
1312
1313 reg = GPMC_ECC_BCH_RESULT_0 + 16*i;
1314
1315 /* Read hw-computed remainder */
1316 val1 = gpmc_read_reg(reg + 0);
1317 val2 = gpmc_read_reg(reg + 4);
1318 val3 = gpmc_read_reg(reg + 8);
1319 val4 = gpmc_read_reg(reg + 12);
1320
1321 /*
1322 * Add constant polynomial to remainder, in order to get an ecc
1323 * sequence of 0xFFs for a buffer filled with 0xFFs.
1324 */
1325 *ecc++ = 0xef ^ (val4 & 0xFF);
1326 *ecc++ = 0x51 ^ ((val3 >> 24) & 0xFF);
1327 *ecc++ = 0x2e ^ ((val3 >> 16) & 0xFF);
1328 *ecc++ = 0x09 ^ ((val3 >> 8) & 0xFF);
1329 *ecc++ = 0xed ^ (val3 & 0xFF);
1330 *ecc++ = 0x93 ^ ((val2 >> 24) & 0xFF);
1331 *ecc++ = 0x9a ^ ((val2 >> 16) & 0xFF);
1332 *ecc++ = 0xc2 ^ ((val2 >> 8) & 0xFF);
1333 *ecc++ = 0x97 ^ (val2 & 0xFF);
1334 *ecc++ = 0x79 ^ ((val1 >> 24) & 0xFF);
1335 *ecc++ = 0xe5 ^ ((val1 >> 16) & 0xFF);
1336 *ecc++ = 0x24 ^ ((val1 >> 8) & 0xFF);
1337 *ecc++ = 0xb5 ^ (val1 & 0xFF);
1338 }
1339
1340 gpmc_ecc_used = -EINVAL;
1341 return 0;
1342}
1343EXPORT_SYMBOL_GPL(gpmc_calculate_ecc_bch8);
1344
1345#endif /* CONFIG_ARCH_OMAP3 */
diff --git a/arch/arm/mach-omap2/gpmc.h b/arch/arm/mach-omap2/gpmc.h
new file mode 100644
index 000000000000..79f4dfc2adb3
--- /dev/null
+++ b/arch/arm/mach-omap2/gpmc.h
@@ -0,0 +1,135 @@
1/*
2 * General-Purpose Memory Controller for OMAP2
3 *
4 * Copyright (C) 2005-2006 Nokia Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __OMAP2_GPMC_H
12#define __OMAP2_GPMC_H
13
14#include <linux/platform_data/mtd-nand-omap2.h>
15
16/* Maximum Number of Chip Selects */
17#define GPMC_CS_NUM 8
18
19#define GPMC_CS_CONFIG1 0x00
20#define GPMC_CS_CONFIG2 0x04
21#define GPMC_CS_CONFIG3 0x08
22#define GPMC_CS_CONFIG4 0x0c
23#define GPMC_CS_CONFIG5 0x10
24#define GPMC_CS_CONFIG6 0x14
25#define GPMC_CS_CONFIG7 0x18
26#define GPMC_CS_NAND_COMMAND 0x1c
27#define GPMC_CS_NAND_ADDRESS 0x20
28#define GPMC_CS_NAND_DATA 0x24
29
30/* Control Commands */
31#define GPMC_CONFIG_RDY_BSY 0x00000001
32#define GPMC_CONFIG_DEV_SIZE 0x00000002
33#define GPMC_CONFIG_DEV_TYPE 0x00000003
34#define GPMC_SET_IRQ_STATUS 0x00000004
35#define GPMC_CONFIG_WP 0x00000005
36
37#define GPMC_ENABLE_IRQ 0x0000000d
38
39/* ECC commands */
40#define GPMC_ECC_READ 0 /* Reset Hardware ECC for read */
41#define GPMC_ECC_WRITE 1 /* Reset Hardware ECC for write */
42#define GPMC_ECC_READSYN 2 /* Reset before syndrom is read back */
43
44#define GPMC_CONFIG1_WRAPBURST_SUPP (1 << 31)
45#define GPMC_CONFIG1_READMULTIPLE_SUPP (1 << 30)
46#define GPMC_CONFIG1_READTYPE_ASYNC (0 << 29)
47#define GPMC_CONFIG1_READTYPE_SYNC (1 << 29)
48#define GPMC_CONFIG1_WRITEMULTIPLE_SUPP (1 << 28)
49#define GPMC_CONFIG1_WRITETYPE_ASYNC (0 << 27)
50#define GPMC_CONFIG1_WRITETYPE_SYNC (1 << 27)
51#define GPMC_CONFIG1_CLKACTIVATIONTIME(val) ((val & 3) << 25)
52#define GPMC_CONFIG1_PAGE_LEN(val) ((val & 3) << 23)
53#define GPMC_CONFIG1_WAIT_READ_MON (1 << 22)
54#define GPMC_CONFIG1_WAIT_WRITE_MON (1 << 21)
55#define GPMC_CONFIG1_WAIT_MON_IIME(val) ((val & 3) << 18)
56#define GPMC_CONFIG1_WAIT_PIN_SEL(val) ((val & 3) << 16)
57#define GPMC_CONFIG1_DEVICESIZE(val) ((val & 3) << 12)
58#define GPMC_CONFIG1_DEVICESIZE_16 GPMC_CONFIG1_DEVICESIZE(1)
59#define GPMC_CONFIG1_DEVICETYPE(val) ((val & 3) << 10)
60#define GPMC_CONFIG1_DEVICETYPE_NOR GPMC_CONFIG1_DEVICETYPE(0)
61#define GPMC_CONFIG1_MUXADDDATA (1 << 9)
62#define GPMC_CONFIG1_TIME_PARA_GRAN (1 << 4)
63#define GPMC_CONFIG1_FCLK_DIV(val) (val & 3)
64#define GPMC_CONFIG1_FCLK_DIV2 (GPMC_CONFIG1_FCLK_DIV(1))
65#define GPMC_CONFIG1_FCLK_DIV3 (GPMC_CONFIG1_FCLK_DIV(2))
66#define GPMC_CONFIG1_FCLK_DIV4 (GPMC_CONFIG1_FCLK_DIV(3))
67#define GPMC_CONFIG7_CSVALID (1 << 6)
68
69#define GPMC_DEVICETYPE_NOR 0
70#define GPMC_DEVICETYPE_NAND 2
71#define GPMC_CONFIG_WRITEPROTECT 0x00000010
72#define WR_RD_PIN_MONITORING 0x00600000
73#define GPMC_IRQ_FIFOEVENTENABLE 0x01
74#define GPMC_IRQ_COUNT_EVENT 0x02
75
76
77/*
78 * Note that all values in this struct are in nanoseconds except sync_clk
79 * (which is in picoseconds), while the register values are in gpmc_fck cycles.
80 */
81struct gpmc_timings {
82 /* Minimum clock period for synchronous mode (in picoseconds) */
83 u32 sync_clk;
84
85 /* Chip-select signal timings corresponding to GPMC_CS_CONFIG2 */
86 u16 cs_on; /* Assertion time */
87 u16 cs_rd_off; /* Read deassertion time */
88 u16 cs_wr_off; /* Write deassertion time */
89
90 /* ADV signal timings corresponding to GPMC_CONFIG3 */
91 u16 adv_on; /* Assertion time */
92 u16 adv_rd_off; /* Read deassertion time */
93 u16 adv_wr_off; /* Write deassertion time */
94
95 /* WE signals timings corresponding to GPMC_CONFIG4 */
96 u16 we_on; /* WE assertion time */
97 u16 we_off; /* WE deassertion time */
98
99 /* OE signals timings corresponding to GPMC_CONFIG4 */
100 u16 oe_on; /* OE assertion time */
101 u16 oe_off; /* OE deassertion time */
102
103 /* Access time and cycle time timings corresponding to GPMC_CONFIG5 */
104 u16 page_burst_access; /* Multiple access word delay */
105 u16 access; /* Start-cycle to first data valid delay */
106 u16 rd_cycle; /* Total read cycle time */
107 u16 wr_cycle; /* Total write cycle time */
108
109 /* The following are only on OMAP3430 */
110 u16 wr_access; /* WRACCESSTIME */
111 u16 wr_data_mux_bus; /* WRDATAONADMUXBUS */
112};
113
114extern void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs);
115extern int gpmc_get_client_irq(unsigned irq_config);
116
117extern unsigned int gpmc_ns_to_ticks(unsigned int time_ns);
118extern unsigned int gpmc_ps_to_ticks(unsigned int time_ps);
119extern unsigned int gpmc_ticks_to_ns(unsigned int ticks);
120extern unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns);
121extern unsigned long gpmc_get_fclk_period(void);
122
123extern void gpmc_cs_write_reg(int cs, int idx, u32 val);
124extern u32 gpmc_cs_read_reg(int cs, int idx);
125extern int gpmc_calc_divider(unsigned int sync_clk);
126extern int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t);
127extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base);
128extern void gpmc_cs_free(int cs);
129extern int gpmc_cs_set_reserved(int cs, int reserved);
130extern int gpmc_cs_reserved(int cs);
131extern void omap3_gpmc_save_context(void);
132extern void omap3_gpmc_restore_context(void);
133extern int gpmc_cs_configure(int cs, int cmd, int wval);
134
135#endif
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index baee8722b477..001eff290cdb 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -40,12 +40,12 @@
40#include "powerdomain.h" 40#include "powerdomain.h"
41#include <plat/sdrc.h> 41#include <plat/sdrc.h>
42#include <plat/prcm.h> 42#include <plat/prcm.h>
43#include <plat/gpmc.h>
44#include <plat-omap/dma-omap.h> 43#include <plat-omap/dma-omap.h>
45 44
46#include "common.h" 45#include "common.h"
47#include "cm2xxx_3xxx.h" 46#include "cm2xxx_3xxx.h"
48#include "cm-regbits-34xx.h" 47#include "cm-regbits-34xx.h"
48#include "gpmc.h"
49#include "prm-regbits-34xx.h" 49#include "prm-regbits-34xx.h"
50 50
51#include "prm2xxx_3xxx.h" 51#include "prm2xxx_3xxx.h"
diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c
index 805bea6edf17..6064425ed47b 100644
--- a/arch/arm/mach-omap2/usb-tusb6010.c
+++ b/arch/arm/mach-omap2/usb-tusb6010.c
@@ -18,7 +18,7 @@
18 18
19#include <linux/usb/musb.h> 19#include <linux/usb/musb.h>
20 20
21#include <plat/gpmc.h> 21#include "gpmc.h"
22 22
23#include "mux.h" 23#include "mux.h"
24 24