aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSukumar Ghorai <s-ghorai@ti.com>2010-07-09 05:14:45 -0400
committerTony Lindgren <tony@atomide.com>2010-08-02 08:30:38 -0400
commit2c01946c6b9ebaa5a89710bc42ca224a7f52f227 (patch)
tree419e5a73823ffec9a23b22334b4c5ee936272e49
parent948d38e799f0ab87cf8ed9113fcdaaee61acf321 (diff)
omap3 nand: cleanup virtual address usages
This patch removes direct reference of gpmc address from generic nand platform code. Nand platform code now uses wrapper functions which are implemented in gpmc module. Signed-off-by: Sukumar Ghorai <s-ghorai@ti.com> Signed-off-by: Tony Lindgren <tony@atomide.com>
-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}