aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-omap2/gpmc-nand.c37
-rw-r--r--arch/arm/mach-omap2/gpmc.c9
-rw-r--r--arch/arm/plat-omap/include/plat/gpmc.h5
-rw-r--r--arch/arm/plat-omap/include/plat/nand.h6
-rw-r--r--drivers/mtd/nand/omap2.c214
5 files changed, 64 insertions, 207 deletions
diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index e57fb29ff855..722209601927 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -19,8 +19,6 @@
19#include <plat/board.h> 19#include <plat/board.h>
20#include <plat/gpmc.h> 20#include <plat/gpmc.h>
21 21
22#define WR_RD_PIN_MONITORING 0x00600000
23
24static struct omap_nand_platform_data *gpmc_nand_data; 22static struct omap_nand_platform_data *gpmc_nand_data;
25 23
26static struct resource gpmc_nand_resource = { 24static struct resource gpmc_nand_resource = {
@@ -71,10 +69,10 @@ static int omap2_nand_gpmc_retime(void)
71 t.wr_cycle = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->wr_cycle); 69 t.wr_cycle = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->wr_cycle);
72 70
73 /* Configure GPMC */ 71 /* Configure GPMC */
74 gpmc_cs_write_reg(gpmc_nand_data->cs, GPMC_CS_CONFIG1, 72 gpmc_cs_configure(gpmc_nand_data->cs,
75 GPMC_CONFIG1_DEVICESIZE(gpmc_nand_data->devsize) | 73 GPMC_CONFIG_DEV_SIZE, gpmc_nand_data->devsize);
76 GPMC_CONFIG1_DEVICETYPE_NAND); 74 gpmc_cs_configure(gpmc_nand_data->cs,
77 75 GPMC_CONFIG_DEV_TYPE, GPMC_DEVICETYPE_NAND);
78 err = gpmc_cs_set_timings(gpmc_nand_data->cs, &t); 76 err = gpmc_cs_set_timings(gpmc_nand_data->cs, &t);
79 if (err) 77 if (err)
80 return err; 78 return err;
@@ -82,27 +80,13 @@ static int omap2_nand_gpmc_retime(void)
82 return 0; 80 return 0;
83} 81}
84 82
85static int gpmc_nand_setup(void)
86{
87 struct device *dev = &gpmc_nand_device.dev;
88
89 /* Set timings in GPMC */
90 if (omap2_nand_gpmc_retime() < 0) {
91 dev_err(dev, "Unable to set gpmc timings\n");
92 return -EINVAL;
93 }
94
95 return 0;
96}
97
98int __init gpmc_nand_init(struct omap_nand_platform_data *_nand_data) 83int __init gpmc_nand_init(struct omap_nand_platform_data *_nand_data)
99{ 84{
100 unsigned int val;
101 int err = 0; 85 int err = 0;
102 struct device *dev = &gpmc_nand_device.dev; 86 struct device *dev = &gpmc_nand_device.dev;
103 87
104 gpmc_nand_data = _nand_data; 88 gpmc_nand_data = _nand_data;
105 gpmc_nand_data->nand_setup = gpmc_nand_setup; 89 gpmc_nand_data->nand_setup = omap2_nand_gpmc_retime;
106 gpmc_nand_device.dev.platform_data = gpmc_nand_data; 90 gpmc_nand_device.dev.platform_data = gpmc_nand_data;
107 91
108 err = gpmc_cs_request(gpmc_nand_data->cs, NAND_IO_SIZE, 92 err = gpmc_cs_request(gpmc_nand_data->cs, NAND_IO_SIZE,
@@ -112,19 +96,16 @@ int __init gpmc_nand_init(struct omap_nand_platform_data *_nand_data)
112 return err; 96 return err;
113 } 97 }
114 98
115 err = gpmc_nand_setup(); 99 /* Set timings in GPMC */
100 err = omap2_nand_gpmc_retime();
116 if (err < 0) { 101 if (err < 0) {
117 dev_err(dev, "NAND platform setup failed: %d\n", err); 102 dev_err(dev, "Unable to set gpmc timings: %d\n", err);
118 return err; 103 return err;
119 } 104 }
120 105
121 /* Enable RD PIN Monitoring Reg */ 106 /* Enable RD PIN Monitoring Reg */
122 if (gpmc_nand_data->dev_ready) { 107 if (gpmc_nand_data->dev_ready) {
123 val = gpmc_cs_read_reg(gpmc_nand_data->cs, 108 gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_RDY_BSY, 1);
124 GPMC_CS_CONFIG1);
125 val |= WR_RD_PIN_MONITORING;
126 gpmc_cs_write_reg(gpmc_nand_data->cs,
127 GPMC_CS_CONFIG1, val);
128 } 109 }
129 110
130 err = platform_device_register(&gpmc_nand_device); 111 err = platform_device_register(&gpmc_nand_device);
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 1be8f9ae8437..f46933bc9373 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -641,15 +641,6 @@ int gpmc_prefetch_reset(int cs)
641} 641}
642EXPORT_SYMBOL(gpmc_prefetch_reset); 642EXPORT_SYMBOL(gpmc_prefetch_reset);
643 643
644/**
645 * gpmc_prefetch_status - reads prefetch status of engine
646 */
647int gpmc_prefetch_status(void)
648{
649 return gpmc_read_reg(GPMC_PREFETCH_STATUS);
650}
651EXPORT_SYMBOL(gpmc_prefetch_status);
652
653static void __init gpmc_mem_init(void) 644static void __init gpmc_mem_init(void)
654{ 645{
655 int cs; 646 int cs;
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h
index 561c64f5ab50..9fd99b9e40ab 100644
--- a/arch/arm/plat-omap/include/plat/gpmc.h
+++ b/arch/arm/plat-omap/include/plat/gpmc.h
@@ -25,9 +25,6 @@
25#define GPMC_CS_NAND_ADDRESS 0x20 25#define GPMC_CS_NAND_ADDRESS 0x20
26#define GPMC_CS_NAND_DATA 0x24 26#define GPMC_CS_NAND_DATA 0x24
27 27
28#define GPMC_CONFIG 0x50
29#define GPMC_STATUS 0x54
30
31/* Control Commands */ 28/* Control Commands */
32#define GPMC_CONFIG_RDY_BSY 0x00000001 29#define GPMC_CONFIG_RDY_BSY 0x00000001
33#define GPMC_CONFIG_DEV_SIZE 0x00000002 30#define GPMC_CONFIG_DEV_SIZE 0x00000002
@@ -66,7 +63,6 @@
66#define GPMC_CONFIG1_DEVICESIZE_16 GPMC_CONFIG1_DEVICESIZE(1) 63#define GPMC_CONFIG1_DEVICESIZE_16 GPMC_CONFIG1_DEVICESIZE(1)
67#define GPMC_CONFIG1_DEVICETYPE(val) ((val & 3) << 10) 64#define GPMC_CONFIG1_DEVICETYPE(val) ((val & 3) << 10)
68#define GPMC_CONFIG1_DEVICETYPE_NOR GPMC_CONFIG1_DEVICETYPE(0) 65#define GPMC_CONFIG1_DEVICETYPE_NOR GPMC_CONFIG1_DEVICETYPE(0)
69#define GPMC_CONFIG1_DEVICETYPE_NAND GPMC_CONFIG1_DEVICETYPE(2)
70#define GPMC_CONFIG1_MUXADDDATA (1 << 9) 66#define GPMC_CONFIG1_MUXADDDATA (1 << 9)
71#define GPMC_CONFIG1_TIME_PARA_GRAN (1 << 4) 67#define GPMC_CONFIG1_TIME_PARA_GRAN (1 << 4)
72#define GPMC_CONFIG1_FCLK_DIV(val) (val & 3) 68#define GPMC_CONFIG1_FCLK_DIV(val) (val & 3)
@@ -136,7 +132,6 @@ extern int gpmc_cs_reserved(int cs);
136extern int gpmc_prefetch_enable(int cs, int dma_mode, 132extern int gpmc_prefetch_enable(int cs, int dma_mode,
137 unsigned int u32_count, int is_write); 133 unsigned int u32_count, int is_write);
138extern int gpmc_prefetch_reset(int cs); 134extern int gpmc_prefetch_reset(int cs);
139extern int gpmc_prefetch_status(void);
140extern void omap3_gpmc_save_context(void); 135extern void omap3_gpmc_save_context(void);
141extern void omap3_gpmc_restore_context(void); 136extern void omap3_gpmc_restore_context(void);
142extern void gpmc_init(void); 137extern void gpmc_init(void);
diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h
index f8efd5466b1d..6562cd082bb1 100644
--- a/arch/arm/plat-omap/include/plat/nand.h
+++ b/arch/arm/plat-omap/include/plat/nand.h
@@ -21,13 +21,11 @@ struct omap_nand_platform_data {
21 int (*dev_ready)(struct omap_nand_platform_data *); 21 int (*dev_ready)(struct omap_nand_platform_data *);
22 int dma_channel; 22 int dma_channel;
23 unsigned long phys_base; 23 unsigned long phys_base;
24 void __iomem *gpmc_cs_baseaddr;
25 void __iomem *gpmc_baseaddr;
26 int devsize; 24 int devsize;
27}; 25};
28 26
29/* size (4 KiB) for IO mapping */ 27/* minimum size for IO mapping */
30#define NAND_IO_SIZE SZ_4K 28#define NAND_IO_SIZE 4
31 29
32#if defined(CONFIG_MTD_NAND_OMAP2) || defined(CONFIG_MTD_NAND_OMAP2_MODULE) 30#if defined(CONFIG_MTD_NAND_OMAP2) || defined(CONFIG_MTD_NAND_OMAP2_MODULE)
33extern int gpmc_nand_init(struct omap_nand_platform_data *d); 31extern int gpmc_nand_init(struct omap_nand_platform_data *d);
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index ec8eb3109d0d..133d51528f8d 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -7,6 +7,7 @@
7 * it under the terms of the GNU General Public License version 2 as 7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 */ 9 */
10#define CONFIG_MTD_NAND_OMAP_HWECC
10 11
11#include <linux/platform_device.h> 12#include <linux/platform_device.h>
12#include <linux/dma-mapping.h> 13#include <linux/dma-mapping.h>
@@ -23,20 +24,8 @@
23#include <plat/gpmc.h> 24#include <plat/gpmc.h>
24#include <plat/nand.h> 25#include <plat/nand.h>
25 26
26#define GPMC_IRQ_STATUS 0x18
27#define GPMC_ECC_CONFIG 0x1F4
28#define GPMC_ECC_CONTROL 0x1F8
29#define GPMC_ECC_SIZE_CONFIG 0x1FC
30#define GPMC_ECC1_RESULT 0x200
31
32#define DRIVER_NAME "omap2-nand" 27#define DRIVER_NAME "omap2-nand"
33 28
34#define NAND_WP_OFF 0
35#define NAND_WP_BIT 0x00000010
36
37#define GPMC_BUF_FULL 0x00000001
38#define GPMC_BUF_EMPTY 0x00000000
39
40#define NAND_Ecc_P1e (1 << 0) 29#define NAND_Ecc_P1e (1 << 0)
41#define NAND_Ecc_P2e (1 << 1) 30#define NAND_Ecc_P2e (1 << 1)
42#define NAND_Ecc_P4e (1 << 2) 31#define NAND_Ecc_P4e (1 << 2)
@@ -139,34 +128,11 @@ struct omap_nand_info {
139 128
140 int gpmc_cs; 129 int gpmc_cs;
141 unsigned long phys_base; 130 unsigned long phys_base;
142 void __iomem *gpmc_cs_baseaddr;
143 void __iomem *gpmc_baseaddr;
144 void __iomem *nand_pref_fifo_add;
145 struct completion comp; 131 struct completion comp;
146 int dma_ch; 132 int dma_ch;
147}; 133};
148 134
149/** 135/**
150 * omap_nand_wp - This function enable or disable the Write Protect feature
151 * @mtd: MTD device structure
152 * @mode: WP ON/OFF
153 */
154static void omap_nand_wp(struct mtd_info *mtd, int mode)
155{
156 struct omap_nand_info *info = container_of(mtd,
157 struct omap_nand_info, mtd);
158
159 unsigned long config = __raw_readl(info->gpmc_baseaddr + GPMC_CONFIG);
160
161 if (mode)
162 config &= ~(NAND_WP_BIT); /* WP is ON */
163 else
164 config |= (NAND_WP_BIT); /* WP is OFF */
165
166 __raw_writel(config, (info->gpmc_baseaddr + GPMC_CONFIG));
167}
168
169/**
170 * omap_hwcontrol - hardware specific access to control-lines 136 * omap_hwcontrol - hardware specific access to control-lines
171 * @mtd: MTD device structure 137 * @mtd: MTD device structure
172 * @cmd: command to device 138 * @cmd: command to device
@@ -181,31 +147,17 @@ static void omap_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
181{ 147{
182 struct omap_nand_info *info = container_of(mtd, 148 struct omap_nand_info *info = container_of(mtd,
183 struct omap_nand_info, mtd); 149 struct omap_nand_info, mtd);
184 switch (ctrl) {
185 case NAND_CTRL_CHANGE | NAND_CTRL_CLE:
186 info->nand.IO_ADDR_W = info->gpmc_cs_baseaddr +
187 GPMC_CS_NAND_COMMAND;
188 info->nand.IO_ADDR_R = info->gpmc_cs_baseaddr +
189 GPMC_CS_NAND_DATA;
190 break;
191
192 case NAND_CTRL_CHANGE | NAND_CTRL_ALE:
193 info->nand.IO_ADDR_W = info->gpmc_cs_baseaddr +
194 GPMC_CS_NAND_ADDRESS;
195 info->nand.IO_ADDR_R = info->gpmc_cs_baseaddr +
196 GPMC_CS_NAND_DATA;
197 break;
198
199 case NAND_CTRL_CHANGE | NAND_NCE:
200 info->nand.IO_ADDR_W = info->gpmc_cs_baseaddr +
201 GPMC_CS_NAND_DATA;
202 info->nand.IO_ADDR_R = info->gpmc_cs_baseaddr +
203 GPMC_CS_NAND_DATA;
204 break;
205 }
206 150
207 if (cmd != NAND_CMD_NONE) 151 if (cmd != NAND_CMD_NONE) {
208 __raw_writeb(cmd, info->nand.IO_ADDR_W); 152 if (ctrl & NAND_CLE)
153 gpmc_nand_write(info->gpmc_cs, GPMC_NAND_COMMAND, cmd);
154
155 else if (ctrl & NAND_ALE)
156 gpmc_nand_write(info->gpmc_cs, GPMC_NAND_ADDRESS, cmd);
157
158 else /* NAND_NCE */
159 gpmc_nand_write(info->gpmc_cs, GPMC_NAND_DATA, cmd);
160 }
209} 161}
210 162
211/** 163/**
@@ -232,11 +184,14 @@ static void omap_write_buf8(struct mtd_info *mtd, const u_char *buf, int len)
232 struct omap_nand_info *info = container_of(mtd, 184 struct omap_nand_info *info = container_of(mtd,
233 struct omap_nand_info, mtd); 185 struct omap_nand_info, mtd);
234 u_char *p = (u_char *)buf; 186 u_char *p = (u_char *)buf;
187 u32 status = 0;
235 188
236 while (len--) { 189 while (len--) {
237 iowrite8(*p++, info->nand.IO_ADDR_W); 190 iowrite8(*p++, info->nand.IO_ADDR_W);
238 while (GPMC_BUF_EMPTY == (readl(info->gpmc_baseaddr + 191 /* wait until buffer is available for write */
239 GPMC_STATUS) & GPMC_BUF_FULL)); 192 do {
193 status = gpmc_read_status(GPMC_STATUS_BUFFER);
194 } while (!status);
240 } 195 }
241} 196}
242 197
@@ -264,16 +219,16 @@ static void omap_write_buf16(struct mtd_info *mtd, const u_char * buf, int len)
264 struct omap_nand_info *info = container_of(mtd, 219 struct omap_nand_info *info = container_of(mtd,
265 struct omap_nand_info, mtd); 220 struct omap_nand_info, mtd);
266 u16 *p = (u16 *) buf; 221 u16 *p = (u16 *) buf;
267 222 u32 status = 0;
268 /* FIXME try bursts of writesw() or DMA ... */ 223 /* FIXME try bursts of writesw() or DMA ... */
269 len >>= 1; 224 len >>= 1;
270 225
271 while (len--) { 226 while (len--) {
272 iowrite16(*p++, info->nand.IO_ADDR_W); 227 iowrite16(*p++, info->nand.IO_ADDR_W);
273 228 /* wait until buffer is available for write */
274 while (GPMC_BUF_EMPTY == (readl(info->gpmc_baseaddr + 229 do {
275 GPMC_STATUS) & GPMC_BUF_FULL)) 230 status = gpmc_read_status(GPMC_STATUS_BUFFER);
276 ; 231 } while (!status);
277 } 232 }
278} 233}
279 234
@@ -287,7 +242,7 @@ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len)
287{ 242{
288 struct omap_nand_info *info = container_of(mtd, 243 struct omap_nand_info *info = container_of(mtd,
289 struct omap_nand_info, mtd); 244 struct omap_nand_info, mtd);
290 uint32_t pfpw_status = 0, r_count = 0; 245 uint32_t r_count = 0;
291 int ret = 0; 246 int ret = 0;
292 u32 *p = (u32 *)buf; 247 u32 *p = (u32 *)buf;
293 248
@@ -310,14 +265,14 @@ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len)
310 else 265 else
311 omap_read_buf8(mtd, buf, len); 266 omap_read_buf8(mtd, buf, len);
312 } else { 267 } else {
268 p = (u32 *) buf;
313 do { 269 do {
314 pfpw_status = gpmc_prefetch_status(); 270 r_count = gpmc_read_status(GPMC_PREFETCH_FIFO_CNT);
315 r_count = ((pfpw_status >> 24) & 0x7F) >> 2; 271 r_count = r_count >> 2;
316 ioread32_rep(info->nand_pref_fifo_add, p, r_count); 272 ioread32_rep(info->nand.IO_ADDR_R, p, r_count);
317 p += r_count; 273 p += r_count;
318 len -= r_count << 2; 274 len -= r_count << 2;
319 } while (len); 275 } while (len);
320
321 /* disable and stop the PFPW engine */ 276 /* disable and stop the PFPW engine */
322 gpmc_prefetch_reset(info->gpmc_cs); 277 gpmc_prefetch_reset(info->gpmc_cs);
323 } 278 }
@@ -334,13 +289,13 @@ static void omap_write_buf_pref(struct mtd_info *mtd,
334{ 289{
335 struct omap_nand_info *info = container_of(mtd, 290 struct omap_nand_info *info = container_of(mtd,
336 struct omap_nand_info, mtd); 291 struct omap_nand_info, mtd);
337 uint32_t pfpw_status = 0, w_count = 0; 292 uint32_t pref_count = 0, w_count = 0;
338 int i = 0, ret = 0; 293 int i = 0, ret = 0;
339 u16 *p = (u16 *) buf; 294 u16 *p;
340 295
341 /* take care of subpage writes */ 296 /* take care of subpage writes */
342 if (len % 2 != 0) { 297 if (len % 2 != 0) {
343 writeb(*buf, info->nand.IO_ADDR_R); 298 writeb(*buf, info->nand.IO_ADDR_W);
344 p = (u16 *)(buf + 1); 299 p = (u16 *)(buf + 1);
345 len--; 300 len--;
346 } 301 }
@@ -354,14 +309,17 @@ static void omap_write_buf_pref(struct mtd_info *mtd,
354 else 309 else
355 omap_write_buf8(mtd, buf, len); 310 omap_write_buf8(mtd, buf, len);
356 } else { 311 } else {
357 pfpw_status = gpmc_prefetch_status(); 312 p = (u16 *) buf;
358 while (pfpw_status & 0x3FFF) { 313 while (len) {
359 w_count = ((pfpw_status >> 24) & 0x7F) >> 1; 314 w_count = gpmc_read_status(GPMC_PREFETCH_FIFO_CNT);
315 w_count = w_count >> 1;
360 for (i = 0; (i < w_count) && len; i++, len -= 2) 316 for (i = 0; (i < w_count) && len; i++, len -= 2)
361 iowrite16(*p++, info->nand_pref_fifo_add); 317 iowrite16(*p++, info->nand.IO_ADDR_W);
362 pfpw_status = gpmc_prefetch_status();
363 } 318 }
364 319 /* wait for data to flushed-out before reset the prefetch */
320 do {
321 pref_count = gpmc_read_status(GPMC_PREFETCH_COUNT);
322 } while (pref_count);
365 /* disable and stop the PFPW engine */ 323 /* disable and stop the PFPW engine */
366 gpmc_prefetch_reset(info->gpmc_cs); 324 gpmc_prefetch_reset(info->gpmc_cs);
367 } 325 }
@@ -451,8 +409,9 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr,
451 /* setup and start DMA using dma_addr */ 409 /* setup and start DMA using dma_addr */
452 wait_for_completion(&info->comp); 410 wait_for_completion(&info->comp);
453 411
454 while (0x3fff & (prefetch_status = gpmc_prefetch_status())) 412 do {
455 ; 413 prefetch_status = gpmc_read_status(GPMC_PREFETCH_COUNT);
414 } while (prefetch_status);
456 /* disable and stop the PFPW engine */ 415 /* disable and stop the PFPW engine */
457 gpmc_prefetch_reset(); 416 gpmc_prefetch_reset();
458 417
@@ -530,29 +489,6 @@ static int omap_verify_buf(struct mtd_info *mtd, const u_char * buf, int len)
530} 489}
531 490
532#ifdef CONFIG_MTD_NAND_OMAP_HWECC 491#ifdef CONFIG_MTD_NAND_OMAP_HWECC
533/**
534 * omap_hwecc_init - Initialize the HW ECC for NAND flash in GPMC controller
535 * @mtd: MTD device structure
536 */
537static void omap_hwecc_init(struct mtd_info *mtd)
538{
539 struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
540 mtd);
541 struct nand_chip *chip = mtd->priv;
542 unsigned long val = 0x0;
543
544 /* Read from ECC Control Register */
545 val = __raw_readl(info->gpmc_baseaddr + GPMC_ECC_CONTROL);
546 /* Clear all ECC | Enable Reg1 */
547 val = ((0x00000001<<8) | 0x00000001);
548 __raw_writel(val, info->gpmc_baseaddr + GPMC_ECC_CONTROL);
549
550 /* Read from ECC Size Config Register */
551 val = __raw_readl(info->gpmc_baseaddr + GPMC_ECC_SIZE_CONFIG);
552 /* ECCSIZE1=512 | Select eccResultsize[0-3] */
553 val = ((((chip->ecc.size >> 1) - 1) << 22) | (0x0000000F));
554 __raw_writel(val, info->gpmc_baseaddr + GPMC_ECC_SIZE_CONFIG);
555}
556 492
557/** 493/**
558 * gen_true_ecc - This function will generate true ECC value 494 * gen_true_ecc - This function will generate true ECC value
@@ -755,19 +691,7 @@ static int omap_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
755{ 691{
756 struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, 692 struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
757 mtd); 693 mtd);
758 unsigned long val = 0x0; 694 return gpmc_calculate_ecc(info->gpmc_cs, dat, ecc_code);
759 unsigned long reg;
760
761 /* Start Reading from HW ECC1_Result = 0x200 */
762 reg = (unsigned long)(info->gpmc_baseaddr + GPMC_ECC1_RESULT);
763 val = __raw_readl(reg);
764 *ecc_code++ = val; /* P128e, ..., P1e */
765 *ecc_code++ = val >> 16; /* P128o, ..., P1o */
766 /* P2048o, P1024o, P512o, P256o, P2048e, P1024e, P512e, P256e */
767 *ecc_code++ = ((val >> 8) & 0x0f) | ((val >> 20) & 0xf0);
768 reg += 4;
769
770 return 0;
771} 695}
772 696
773/** 697/**
@@ -781,32 +705,10 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int mode)
781 mtd); 705 mtd);
782 struct nand_chip *chip = mtd->priv; 706 struct nand_chip *chip = mtd->priv;
783 unsigned int dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0; 707 unsigned int dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0;
784 unsigned long val = __raw_readl(info->gpmc_baseaddr + GPMC_ECC_CONFIG);
785
786 switch (mode) {
787 case NAND_ECC_READ:
788 __raw_writel(0x101, info->gpmc_baseaddr + GPMC_ECC_CONTROL);
789 /* (ECC 16 or 8 bit col) | ( CS ) | ECC Enable */
790 val = (dev_width << 7) | (info->gpmc_cs << 1) | (0x1);
791 break;
792 case NAND_ECC_READSYN:
793 __raw_writel(0x100, info->gpmc_baseaddr + GPMC_ECC_CONTROL);
794 /* (ECC 16 or 8 bit col) | ( CS ) | ECC Enable */
795 val = (dev_width << 7) | (info->gpmc_cs << 1) | (0x1);
796 break;
797 case NAND_ECC_WRITE:
798 __raw_writel(0x101, info->gpmc_baseaddr + GPMC_ECC_CONTROL);
799 /* (ECC 16 or 8 bit col) | ( CS ) | ECC Enable */
800 val = (dev_width << 7) | (info->gpmc_cs << 1) | (0x1);
801 break;
802 default:
803 DEBUG(MTD_DEBUG_LEVEL0, "Error: Unrecognized Mode[%d]!\n",
804 mode);
805 break;
806 }
807 708
808 __raw_writel(val, info->gpmc_baseaddr + GPMC_ECC_CONFIG); 709 gpmc_enable_hwecc(info->gpmc_cs, mode, dev_width, info->nand.ecc.size);
809} 710}
711
810#endif 712#endif
811 713
812/** 714/**
@@ -834,14 +736,10 @@ static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip)
834 else 736 else
835 timeo += (HZ * 20) / 1000; 737 timeo += (HZ * 20) / 1000;
836 738
837 this->IO_ADDR_W = (void *) info->gpmc_cs_baseaddr + 739 gpmc_nand_write(info->gpmc_cs,
838 GPMC_CS_NAND_COMMAND; 740 GPMC_NAND_COMMAND, (NAND_CMD_STATUS & 0xFF));
839 this->IO_ADDR_R = (void *) info->gpmc_cs_baseaddr + GPMC_CS_NAND_DATA;
840
841 __raw_writeb(NAND_CMD_STATUS & 0xFF, this->IO_ADDR_W);
842
843 while (time_before(jiffies, timeo)) { 741 while (time_before(jiffies, timeo)) {
844 status = __raw_readb(this->IO_ADDR_R); 742 status = gpmc_nand_read(info->gpmc_cs, GPMC_NAND_DATA);
845 if (status & NAND_STATUS_READY) 743 if (status & NAND_STATUS_READY)
846 break; 744 break;
847 cond_resched(); 745 cond_resched();
@@ -855,22 +753,22 @@ static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip)
855 */ 753 */
856static int omap_dev_ready(struct mtd_info *mtd) 754static int omap_dev_ready(struct mtd_info *mtd)
857{ 755{
756 unsigned int val = 0;
858 struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, 757 struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
859 mtd); 758 mtd);
860 unsigned int val = __raw_readl(info->gpmc_baseaddr + GPMC_IRQ_STATUS);
861 759
760 val = gpmc_read_status(GPMC_GET_IRQ_STATUS);
862 if ((val & 0x100) == 0x100) { 761 if ((val & 0x100) == 0x100) {
863 /* Clear IRQ Interrupt */ 762 /* Clear IRQ Interrupt */
864 val |= 0x100; 763 val |= 0x100;
865 val &= ~(0x0); 764 val &= ~(0x0);
866 __raw_writel(val, info->gpmc_baseaddr + GPMC_IRQ_STATUS); 765 gpmc_cs_configure(info->gpmc_cs, GPMC_SET_IRQ_STATUS, val);
867 } else { 766 } else {
868 unsigned int cnt = 0; 767 unsigned int cnt = 0;
869 while (cnt++ < 0x1FF) { 768 while (cnt++ < 0x1FF) {
870 if ((val & 0x100) == 0x100) 769 if ((val & 0x100) == 0x100)
871 return 0; 770 return 0;
872 val = __raw_readl(info->gpmc_baseaddr + 771 val = gpmc_read_status(GPMC_GET_IRQ_STATUS);
873 GPMC_IRQ_STATUS);
874 } 772 }
875 } 773 }
876 774
@@ -901,8 +799,6 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
901 info->pdev = pdev; 799 info->pdev = pdev;
902 800
903 info->gpmc_cs = pdata->cs; 801 info->gpmc_cs = pdata->cs;
904 info->gpmc_baseaddr = pdata->gpmc_baseaddr;
905 info->gpmc_cs_baseaddr = pdata->gpmc_cs_baseaddr;
906 info->phys_base = pdata->phys_base; 802 info->phys_base = pdata->phys_base;
907 803
908 info->mtd.priv = &info->nand; 804 info->mtd.priv = &info->nand;
@@ -913,7 +809,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
913 info->nand.options |= NAND_SKIP_BBTSCAN; 809 info->nand.options |= NAND_SKIP_BBTSCAN;
914 810
915 /* NAND write protect off */ 811 /* NAND write protect off */
916 omap_nand_wp(&info->mtd, NAND_WP_OFF); 812 gpmc_cs_configure(info->gpmc_cs, GPMC_CONFIG_WP, 0);
917 813
918 if (!request_mem_region(info->phys_base, NAND_IO_SIZE, 814 if (!request_mem_region(info->phys_base, NAND_IO_SIZE,
919 pdev->dev.driver->name)) { 815 pdev->dev.driver->name)) {
@@ -948,8 +844,6 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
948 } 844 }
949 845
950 if (use_prefetch) { 846 if (use_prefetch) {
951 /* copy the virtual address of nand base for fifo access */
952 info->nand_pref_fifo_add = info->nand.IO_ADDR_R;
953 847
954 info->nand.read_buf = omap_read_buf_pref; 848 info->nand.read_buf = omap_read_buf_pref;
955 info->nand.write_buf = omap_write_buf_pref; 849 info->nand.write_buf = omap_write_buf_pref;
@@ -989,8 +883,6 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
989 info->nand.ecc.correct = omap_correct_data; 883 info->nand.ecc.correct = omap_correct_data;
990 info->nand.ecc.mode = NAND_ECC_HW; 884 info->nand.ecc.mode = NAND_ECC_HW;
991 885
992 /* init HW ECC */
993 omap_hwecc_init(&info->mtd);
994#else 886#else
995 info->nand.ecc.mode = NAND_ECC_SOFT; 887 info->nand.ecc.mode = NAND_ECC_SOFT;
996#endif 888#endif
@@ -1040,7 +932,7 @@ static int omap_nand_remove(struct platform_device *pdev)
1040 932
1041 /* Release NAND device, its internal structures and partitions */ 933 /* Release NAND device, its internal structures and partitions */
1042 nand_release(&info->mtd); 934 nand_release(&info->mtd);
1043 iounmap(info->nand_pref_fifo_add); 935 iounmap(info->nand.IO_ADDR_R);
1044 kfree(&info->mtd); 936 kfree(&info->mtd);
1045 return 0; 937 return 0;
1046} 938}